From 6b4b7f44e8f70a6d42ebf2036d0934a986b973ef Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Fri, 20 Aug 2021 13:02:33 +0300 Subject: [PATCH 001/958] setup new token on metachain for delegation --- .../config/systemSmartContractsConfig.toml | 1 + config/systemSmartContractsConfig.go | 5 +- epochStart/metachain/systemSCs.go | 40 ++++++++++ epochStart/metachain/systemSCs_test.go | 5 +- factory/processComponents_test.go | 5 +- genesis/process/genesisBlockCreator_test.go | 5 +- .../multiShard/hardFork/hardFork_test.go | 5 +- integrationTests/testInitializer.go | 10 ++- integrationTests/testProcessorNode.go | 10 ++- integrationTests/vm/testInitializer.go | 5 +- .../metachain/vmContainerFactory_test.go | 10 ++- vm/address.go | 3 + vm/errors.go | 3 + vm/factory/systemSCFactory_test.go | 5 +- vm/interface.go | 2 + vm/mock/systemEIStub.go | 13 ++++ vm/systemSmartContracts/eei.go | 32 ++++++++ vm/systemSmartContracts/esdt.go | 74 ++++++++++++++++++- vm/systemSmartContracts/esdt_test.go | 3 +- 19 files changed, 208 insertions(+), 28 deletions(-) diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index c5e418a9749..ed2623ff1f8 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -15,6 +15,7 @@ [ESDTSystemSCConfig] BaseIssuingCost = "5000000000000000000" #5 eGLD OwnerAddress = "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c" + DelegationTicker = "DEL" [GovernanceSystemSCConfig] FirstWhitelistedAddress = "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80" #should use a multisign contract instead of a wallet address diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index 98d5206c3ee..f4fa1863fcd 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -27,8 +27,9 @@ type StakingSystemSCConfig struct { // ESDTSystemSCConfig defines a set of constant to initialize the esdt system smart contract type ESDTSystemSCConfig struct { - BaseIssuingCost string - OwnerAddress string + BaseIssuingCost string + OwnerAddress string + DelegationTicker string } // GovernanceSystemSCConfigV1 holds the initial set of values that were used to initialise the diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 8583a55d1ef..07288f1e286 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -71,6 +71,7 @@ type systemSCProcessor struct { esdtEnableEpoch uint32 saveJailedAlwaysEnableEpoch uint32 governanceEnableEpoch uint32 + builtInOnMetaEnableEpoch uint32 maxNodesEnableConfig []config.MaxNodesChangeConfig maxNodes uint32 flagSwitchJailedWaiting atomic.Flag @@ -84,6 +85,7 @@ type systemSCProcessor struct { flagESDTEnabled atomic.Flag flagSaveJailedAlwaysEnabled atomic.Flag flagGovernanceEnabled atomic.Flag + flagBuiltInOnMetaEnabled atomic.Flag esdtOwnerAddressBytes []byte mapNumSwitchedPerShard map[uint32]uint32 mapNumSwitchablePerShard map[uint32]uint32 @@ -179,6 +181,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, + builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, } log.Debug("systemSC: enable epoch for switch jail waiting", "epoch", s.switchEnableEpoch) @@ -189,6 +192,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr log.Debug("systemSC: enable epoch for correct last unjailed", "epoch", s.correctLastUnJailEpoch) log.Debug("systemSC: enable epoch for save jailed always", "epoch", s.saveJailedAlwaysEnableEpoch) log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) + log.Debug("systemSC: enable epoch for create NFT on meta", "epoch", s.builtInOnMetaEnableEpoch) s.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(s.maxNodesEnableConfig, args.MaxNodesEnableConfig) @@ -297,6 +301,13 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } + if s.flagBuiltInOnMetaEnabled.IsSet() { + err := s.initTokenOnMeta() + if err != nil { + return err + } + } + return nil } @@ -1101,6 +1112,32 @@ func (s *systemSCProcessor) updateToGovernanceV2() error { return nil } +func (s *systemSCProcessor) initTokenOnMeta() error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.ESDTSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{}, + }, + RecipientAddr: vm.ESDTSCAddress, + Function: "initNFTOnMeta", + } + vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) + if errRun != nil { + return fmt.Errorf("%w when setting up NFTs on metachain", errRun) + } + if vmOutput.ReturnCode != vmcommon.Ok { + return fmt.Errorf("got return code %s when setting up NFTs on metachain", vmOutput.ReturnCode) + } + + err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + return nil +} + func (s *systemSCProcessor) getValidatorSystemAccount() (state.UserAccountHandler, error) { validatorAccount, err := s.userAccountsDB.LoadAccount(vm.ValidatorSCAddress) if err != nil { @@ -1494,4 +1531,7 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagGovernanceEnabled.Toggle(epoch == s.governanceEnableEpoch) log.Debug("systemProcessor: governanceV2", "enabled", s.flagGovernanceEnabled.IsSet()) + + s.flagBuiltInOnMetaEnabled.Toggle(epoch == s.builtInOnMetaEnableEpoch) + log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 7e7c02109b7..9212df386f5 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -930,8 +930,9 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS Marshalizer: marshalizer, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/factory/processComponents_test.go b/factory/processComponents_test.go index fbdc9bcdb28..6dcfb53447c 100644 --- a/factory/processComponents_test.go +++ b/factory/processComponents_test.go @@ -158,8 +158,9 @@ func getProcessArgs( ImportStartHandler: &testscommon.ImportStartHandlerStub{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + BaseIssuingCost: "1000", + OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/genesis/process/genesisBlockCreator_test.go b/genesis/process/genesisBlockCreator_test.go index 17d3515d492..dabd7719912 100644 --- a/genesis/process/genesisBlockCreator_test.go +++ b/genesis/process/genesisBlockCreator_test.go @@ -83,8 +83,9 @@ func createMockArgument( HardForkConfig: config.HardforkConfig{}, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "5000000000000000000000", - OwnerAddress: "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp", + BaseIssuingCost: "5000000000000000000000", + OwnerAddress: "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index ec6cdf36a4b..c4bc445b00f 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -441,8 +441,9 @@ func hardForkImport( TrieStorageManagers: node.TrieStorageManagers, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index a104864102d..334a9185982 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -580,8 +580,9 @@ func CreateFullGenesisBlocks( TrieStorageManagers: trieStorageManagers, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ FirstWhitelistedAddress: DelegationManagerConfigChangeAddress, @@ -693,8 +694,9 @@ func CreateGenesisMetaBlock( HardForkConfig: config.HardforkConfig{}, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 95d4b5dc0e0..5c4f6840100 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -815,8 +815,9 @@ func (tpn *TestProcessorNode) createFullSCQueryService() { Marshalizer: TestMarshalizer, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ @@ -1589,8 +1590,9 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors() { Marshalizer: TestMarshalizer, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index ac6d74eef77..624af4f06f6 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -686,8 +686,9 @@ func createEpochConfig() *config.EpochConfig { func createSystemSCConfig() *config.SystemSmartContractsConfig { return &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "5000000000000000000", - OwnerAddress: "3132333435363738393031323334353637383930313233343536373839303233", + BaseIssuingCost: "5000000000000000000", + OwnerAddress: "3132333435363738393031323334353637383930313233343536373839303233", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 1fcc3319804..577a863be0c 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -57,8 +57,9 @@ func createVmContainerMockArgument(gasSchedule core.GasScheduleNotifier) ArgsNew Marshalizer: &mock.MarshalizerMock{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "100000000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "100000000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ @@ -301,8 +302,9 @@ func TestVmContainerFactory_Create(t *testing.T) { Marshalizer: &mock.MarshalizerMock{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "100000000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "100000000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/vm/address.go b/vm/address.go index 89ffe44d44f..97e248a27da 100644 --- a/vm/address.go +++ b/vm/address.go @@ -21,5 +21,8 @@ var EndOfEpochAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 255, // DelegationManagerSCAddress is the hard-coded address for the delegation manager smart contract var DelegationManagerSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255} +// DelegationTokenSCAddress is the hard-coded address for the delegation token smart contract +var DelegationTokenSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 255, 255} + // FirstDelegationSCAddress is the hard-coded address for the first delegation contract, the other will follow var FirstDelegationSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255} diff --git a/vm/errors.go b/vm/errors.go index 21c4432fb0e..a39cb1eee84 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -247,3 +247,6 @@ var ErrProposalNotFound = errors.New("proposal was not found in storage") // ErrInvalidNumOfInitialWhiteListedAddress signals that 0 initial whiteListed addresses were provided to the governance contract var ErrInvalidNumOfInitialWhiteListedAddress = errors.New("0 initial whiteListed addresses provided to the governance contract") + +// ErrInvalidDelegationTicker signals that invalid delegation ticker name was provided +var ErrInvalidDelegationTicker = errors.New("invalid delegation ticker name") diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index f254980ac1b..5f95aad78d2 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -30,8 +30,9 @@ func createMockNewSystemScFactoryArgs() ArgsNewSystemSCFactory { Hasher: &mock.HasherMock{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "100000000", - OwnerAddress: "aaaaaa", + BaseIssuingCost: "100000000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ diff --git a/vm/interface.go b/vm/interface.go index d03f1ca6344..039312229fa 100644 --- a/vm/interface.go +++ b/vm/interface.go @@ -55,6 +55,7 @@ type SystemEI interface { CanUnJail(blsKey []byte) bool IsBadRating(blsKey []byte) bool CleanStorageUpdates() + ProcessBuiltInFunction(sender, destination []byte, function string, arguments [][]byte) error IsInterfaceNil() bool } @@ -122,4 +123,5 @@ type BlockchainHook interface { Close() error GetSnapshot() int RevertToSnapshot(snapshot int) error + ProcessBuiltInFunction(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) } diff --git a/vm/mock/systemEIStub.go b/vm/mock/systemEIStub.go index 83ea3233dcc..96003b63119 100644 --- a/vm/mock/systemEIStub.go +++ b/vm/mock/systemEIStub.go @@ -37,6 +37,7 @@ type SystemEIStub struct { GasLeftCalled func() uint64 CleanStorageUpdatesCalled func() ReturnMessage string + ProcessBuiltInFunctionCalled func(sender, destination []byte, function string, arguments [][]byte) error } // GasLeft - @@ -267,6 +268,18 @@ func (s *SystemEIStub) CleanStorageUpdates() { } } +// ProcessBuiltInFunction - +func (s *SystemEIStub) ProcessBuiltInFunction( + sender, destination []byte, + function string, + arguments [][]byte, +) error { + if s.ProcessBuiltInFunctionCalled != nil { + return s.ProcessBuiltInFunctionCalled(sender, destination, function, arguments) + } + return nil +} + // IsInterfaceNil - func (s *SystemEIStub) IsInterfaceNil() bool { return s == nil diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index d7128a37cb8..b968d00f96b 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -1,6 +1,7 @@ package systemSmartContracts import ( + "errors" "math/big" "github.com/ElrondNetwork/elrond-go-core/core" @@ -447,6 +448,37 @@ func (host *vmContext) AddReturnMessage(message string) { host.returnMessage += "@" + message } +// ProcessBuiltInFunction will process the given built in function and will merge the generated output accounts and logs +func (host *vmContext) ProcessBuiltInFunction( + sender, destination []byte, + function string, + arguments [][]byte, +) error { + vmInput := createDirectCallInput(destination, sender, big.NewInt(0), function, arguments) + vmOutput, err := host.blockChainHook.ProcessBuiltInFunction(vmInput) + if err != nil { + return err + } + if vmOutput.ReturnCode != vmcommon.Ok { + return errors.New(vmOutput.ReturnMessage) + } + + for address, outAcc := range vmOutput.OutputAccounts { + if len(outAcc.OutputTransfers) > 0 { + leftAccount, exist := host.outputAccounts[address] + if !exist { + leftAccount = &vmcommon.OutputAccount{} + host.outputAccounts[address] = leftAccount + } + leftAccount.OutputTransfers = append(leftAccount.OutputTransfers, outAcc.OutputTransfers...) + } + } + + //TODO: add logs after merge with logs PR on meta + + return nil +} + // BlockChainHook returns the blockchain hook func (host *vmContext) BlockChainHook() vm.BlockchainHook { return host.blockChainHook diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 367b3a8b368..8ff909dc54c 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -53,6 +53,7 @@ type esdt struct { hasher hashing.Hasher mutExecution sync.RWMutex addressPubKeyConverter core.PubkeyConverter + delegationTicker string enabledEpoch uint32 flagEnabled atomic.Flag @@ -60,6 +61,8 @@ type esdt struct { flagGlobalMintBurn atomic.Flag transferRoleEnableEpoch uint32 flagTransferRole atomic.Flag + esdtOnMetachainEnableEpoch uint32 + flagESDTOnMeta atomic.Flag } // ArgsNewESDTSmartContract defines the arguments needed for the esdt contract @@ -96,7 +99,9 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { if len(args.EndOfEpochSCAddress) == 0 { return nil, vm.ErrNilEndOfEpochSmartContractAddress } - + if !isTickerValid([]byte(args.ESDTSCConfig.DelegationTicker)) { + return nil, vm.ErrInvalidDelegationTicker + } baseIssuingCost, okConvert := big.NewInt(0).SetString(args.ESDTSCConfig.BaseIssuingCost, conversionBase) if !okConvert || baseIssuingCost.Cmp(big.NewInt(0)) < 0 { return nil, vm.ErrInvalidBaseIssuingCost @@ -115,12 +120,15 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { enabledEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, globalMintBurnDisableEpoch: args.EpochConfig.EnableEpochs.GlobalMintBurnDisableEpoch, transferRoleEnableEpoch: args.EpochConfig.EnableEpochs.ESDTTransferRoleEnableEpoch, + esdtOnMetachainEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, endOfEpochSCAddress: args.EndOfEpochSCAddress, addressPubKeyConverter: args.AddressPubKeyConverter, + delegationTicker: args.ESDTSCConfig.DelegationTicker, } log.Debug("esdt: enable epoch for esdt", "epoch", e.enabledEpoch) log.Debug("esdt: enable epoch for contract global mint and burn", "epoch", e.globalMintBurnDisableEpoch) log.Debug("esdt: enable epoch for contract transfer role", "epoch", e.transferRoleEnableEpoch) + log.Debug("esdt: enable epoch for esdt on metachain", "epoch", e.esdtOnMetachainEnableEpoch) args.EpochNotifier.RegisterNotifyHandler(e) @@ -196,6 +204,8 @@ func (e *esdt) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { return e.getAllAddressesAndRoles(args) case "getContractConfig": return e.getContractConfig(args) + case "initDelegationESDTOnMeta": + return e.initDelegationESDTOnMeta(args) } e.eei.AddReturnMessage("invalid method to call") @@ -217,6 +227,65 @@ func (e *esdt) init(_ *vmcommon.ContractCallInput) vmcommon.ReturnCode { return vmcommon.Ok } +func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !e.flagESDTOnMeta.IsSet() { + e.eei.AddReturnMessage("invalid method to call") + return vmcommon.FunctionNotFound + } + if !bytes.Equal(args.CallerAddr, e.eSDTSCAddress) { + e.eei.AddReturnMessage("only system address can call this") + return vmcommon.UserError + } + if len(args.Arguments) != 0 { + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + return vmcommon.UserError + } + + tokenIdentifier, err := e.createNewToken( + vm.DelegationTokenSCAddress, + []byte(e.delegationTicker), + []byte(e.delegationTicker), + big.NewInt(0), + 0, + nil, + []byte(core.SemiFungibleESDT)) + if err != nil { + e.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + token, err := e.getExistingToken(tokenIdentifier) + if err != nil { + e.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + esdtRole, _ := getRolesForAddress(token, vm.DelegationTokenSCAddress) + esdtRole.Roles = append(esdtRole.Roles, []byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)) + token.SpecialRoles = append(token.SpecialRoles, esdtRole) + + err = e.saveToken(tokenIdentifier, token) + if err != nil { + e.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + err = e.eei.ProcessBuiltInFunction( + e.eSDTSCAddress, + vm.DelegationTokenSCAddress, + core.BuiltInFunctionSetESDTRole, + [][]byte{[]byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)}, + ) + if err != nil { + e.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + func (e *esdt) checkBasicCreateArguments(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { err := e.eei.UseGas(e.gasCost.MetaChainSystemSCsCost.ESDTIssue) if err != nil { @@ -1565,6 +1634,9 @@ func (e *esdt) EpochConfirmed(epoch uint32, _ uint64) { e.flagTransferRole.Toggle(epoch >= e.transferRoleEnableEpoch) log.Debug("ESDT contract transfer role", "enabled", e.flagTransferRole.IsSet()) + + e.flagESDTOnMeta.Toggle(epoch >= e.esdtOnMetachainEnableEpoch) + log.Debug("ESDT on metachain", "enabled", e.flagESDTOnMeta.IsSet()) } // SetNewGasCost is called whenever a gas cost was changed diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index b3ff6a68aa2..fa04ecd42ac 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -28,7 +28,8 @@ func createMockArgumentsForESDT() ArgsNewESDTSmartContract { Eei: &mock.SystemEIStub{}, GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{ESDTIssue: 10}}, ESDTSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", + BaseIssuingCost: "1000", + DelegationTicker: "DEL", }, ESDTSCAddress: []byte("address"), Marshalizer: &mock.MarshalizerMock{}, From 8060a1ab3ad702b3e72088b7ad68b8471fc2a0b3 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Fri, 20 Aug 2021 13:33:52 +0300 Subject: [PATCH 002/958] fixing setup and tests --- epochStart/metachain/systemSCs.go | 4 ++-- epochStart/metachain/systemSCs_test.go | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 07288f1e286..0e3aa6afb70 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -1120,14 +1120,14 @@ func (s *systemSCProcessor) initTokenOnMeta() error { Arguments: [][]byte{}, }, RecipientAddr: vm.ESDTSCAddress, - Function: "initNFTOnMeta", + Function: "initDelegationESDTOnMeta", } vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) if errRun != nil { return fmt.Errorf("%w when setting up NFTs on metachain", errRun) } if vmOutput.ReturnCode != vmcommon.Ok { - return fmt.Errorf("got return code %s when setting up NFTs on metachain", vmOutput.ReturnCode) + return fmt.Errorf("got return code %s, return message %s when setting up NFTs on metachain", vmOutput.ReturnCode, vmOutput.ReturnMessage) } err := s.processSCOutputAccounts(vmOutput) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 9212df386f5..ab5c68b8744 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -34,6 +34,7 @@ import ( vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" "github.com/ElrondNetwork/elrond-go/process/peer" + "github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions" "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" @@ -50,7 +51,6 @@ import ( "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" vmcommon "github.com/ElrondNetwork/elrond-vm-common" - vmcommonBuiltInFunctions "github.com/ElrondNetwork/elrond-vm-common/builtInFunctions" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -898,8 +898,21 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS StakingV2EnableEpoch: stakingV2EnableEpoch, } vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) - + gasSchedule := arwenConfig.MakeGasMapForTests() + gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) blockChain, _ := blockchain.NewMetaChain(&mock.AppStatusHandlerStub{}) + argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ + GasSchedule: gasScheduleNotifier, + MapDNSAddresses: make(map[string]struct{}), + Marshalizer: marshalizer, + Accounts: userAccountsDB, + ShardCoordinator: &mock.ShardCoordinatorStub{SelfIdCalled: func() uint32 { + return core.MetachainShardId + }}, + EpochNotifier: epochNotifier, + } + builtInFuncs, _ := builtInFunctions.CreateBuiltInFunctionContainer(argsBuiltIn) + testDataPool := dataRetrieverMock.NewPoolsHolderMock() argsHook := hooks.ArgBlockChainHook{ Accounts: userAccountsDB, @@ -909,13 +922,12 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ShardCoordinator: &mock.ShardCoordinatorStub{}, Marshalizer: marshalizer, Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, - BuiltInFunctions: vmcommonBuiltInFunctions.NewBuiltInFunctionContainer(), + BuiltInFunctions: builtInFuncs, DataPool: testDataPool, CompiledSCPool: testDataPool.SmartContracts(), NilCompiledSCStore: true, } - gasSchedule := arwenConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) @@ -924,7 +936,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ArgBlockChainHook: argsHook, Economics: createEconomicsData(), MessageSignVerifier: signVerifer, - GasSchedule: mock.NewGasScheduleNotifierMock(gasSchedule), + GasSchedule: gasScheduleNotifier, NodesConfigProvider: nodesSetup, Hasher: hasher, Marshalizer: marshalizer, From 270fcc8f2431a09a701b627e45615c5b71b8b6c9 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Fri, 20 Aug 2021 16:30:19 +0300 Subject: [PATCH 003/958] adding new functions --- vm/systemSmartContracts/delegation.go | 108 +++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index c09626191d5..8fd67d75318 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -64,6 +64,8 @@ type delegation struct { validatorToDelegationEnableEpoch uint32 flagReDelegateBelowMinCheck atomic.Flag reDelegateBelowMinCheckEnableEpoch uint32 + liquidStakingEnableEpoch uint32 + flagLiquidStaking atomic.Flag } // ArgsNewDelegation defines the arguments to create the delegation smart contract @@ -135,12 +137,13 @@ func NewDelegationSystemSC(args ArgsNewDelegation) (*delegation, error) { stakingV2Enabled: atomic.Flag{}, validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, reDelegateBelowMinCheckEnableEpoch: args.EpochConfig.EnableEpochs.ReDelegateBelowMinCheckEnableEpoch, + liquidStakingEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, } log.Debug("delegation: enable epoch for delegation smart contract", "epoch", d.enableDelegationEpoch) log.Debug("delegation: enable epoch for staking v2", "epoch", d.stakingV2EnableEpoch) log.Debug("delegation: enable epoch for validator to delegation", "epoch", d.validatorToDelegationEnableEpoch) log.Debug("delegation: enable epoch for re-delegate below minimum check", "epoch", d.reDelegateBelowMinCheckEnableEpoch) - + log.Debug("delegation: enable epoch for liquid staking", "epoch", d.liquidStakingEnableEpoch) var okValue bool d.unJailPrice, okValue = big.NewInt(0).SetString(args.StakingSCConfig.UnJailValue, conversionBase) @@ -270,6 +273,16 @@ func (d *delegation) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return d.setMetaData(args) case "getMetaData": return d.getMetaData(args) + case "claimDelegatedPosition": + return d.claimDelegatedPosition(args) + case "claimRewardsFromPosition": + return d.claimRewardsFromDelegatedPosition(args) + case "reDelegateRewardsFromPosition": + return d.reDelegateRewardsFromPosition(args) + case "unDelegateWithPosition": + return d.unDelegateWithPosition(args) + case "returnPosition": + return d.returnPosition(args) } d.eei.AddReturnMessage(args.Function + " is an unknown function") @@ -588,6 +601,10 @@ func (d *delegation) checkInputForWhitelisting(args *vmcommon.ContractCallInput) d.eei.AddReturnMessage("non-payable function") return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -751,6 +768,10 @@ func (d *delegation) checkOwnerCallValueGasAndDuplicates(args *vmcommon.Contract d.eei.AddReturnMessage(vm.ErrDuplicatesFoundInArguments.Error()) return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } return vmcommon.Ok } @@ -1242,6 +1263,10 @@ func (d *delegation) unJailNodes(args *vmcommon.ContractCallInput) vmcommon.Retu d.eei.AddReturnMessage(err.Error()) return vmcommon.OutOfGas } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } duplicates := checkForDuplicates(args.Arguments) if duplicates { d.eei.AddReturnMessage(vm.ErrDuplicatesFoundInArguments.Error()) @@ -1300,6 +1325,10 @@ func (d *delegation) reDelegateRewards(args *vmcommon.ContractCallInput) vmcommo d.eei.AddReturnMessage("must be called without arguments") return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { @@ -1475,6 +1504,10 @@ func (d *delegation) delegate(args *vmcommon.ContractCallInput) vmcommon.ReturnC d.eei.AddReturnMessage("error getting minimum delegation amount " + err.Error()) return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } minDelegationAmount := delegationManagement.MinDelegationAmount if args.CallValue.Cmp(minDelegationAmount) < 0 { @@ -1571,6 +1604,10 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } valueToUnDelegate := big.NewInt(0).SetBytes(args.Arguments[0]) if valueToUnDelegate.Cmp(zero) <= 0 { d.eei.AddReturnMessage("invalid value to undelegate") @@ -1750,6 +1787,10 @@ func (d *delegation) getRewardData(args *vmcommon.ContractCallInput) vmcommon.Re d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -1870,6 +1911,10 @@ func (d *delegation) claimRewards(args *vmcommon.ContractCallInput) vmcommon.Ret d.eei.AddReturnMessage("wrong number of arguments") return vmcommon.FunctionWrongSignature } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } isNew, delegator, err := d.getOrCreateDelegatorData(args.CallerAddr) if err != nil { @@ -1946,6 +1991,11 @@ func (d *delegation) withdraw(args *vmcommon.ContractCallInput) vmcommon.ReturnC d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } + err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -2130,6 +2180,10 @@ func (d *delegation) checkArgumentsForGeneralViewFunc(args *vmcommon.ContractCal d.eei.AddReturnMessage(vm.ErrInvalidNumOfArguments.Error()) return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return vmcommon.UserError + } return vmcommon.Ok } @@ -2321,6 +2375,10 @@ func (d *delegation) checkArgumentsForUserViewFunc(args *vmcommon.ContractCallIn d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return nil, vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") + return nil, vmcommon.UserError + } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -2827,6 +2885,51 @@ func getDelegationManagement( return managementData, nil } +func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !d.flagLiquidStaking.IsSet() { + d.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (d *delegation) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !d.flagLiquidStaking.IsSet() { + d.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (d *delegation) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !d.flagLiquidStaking.IsSet() { + d.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (d *delegation) unDelegateWithPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !d.flagLiquidStaking.IsSet() { + d.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (d *delegation) returnPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !d.flagLiquidStaking.IsSet() { + d.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError + } + + return vmcommon.Ok +} + // SetNewGasCost is called whenever a gas cost was changed func (d *delegation) SetNewGasCost(gasCost vm.GasCost) { d.mutExecution.Lock() @@ -2847,6 +2950,9 @@ func (d *delegation) EpochConfirmed(epoch uint32, _ uint64) { d.flagReDelegateBelowMinCheck.Toggle(epoch >= d.reDelegateBelowMinCheckEnableEpoch) log.Debug("delegationSC: re-delegate below minimum check", "enabled", d.flagReDelegateBelowMinCheck.IsSet()) + + d.flagLiquidStaking.Toggle(epoch >= d.liquidStakingEnableEpoch) + log.Debug("delegationSC: liquid staking", "enabled", d.flagLiquidStaking.IsSet()) } // CanUseContract returns true if contract can be used From 008dbf1d4d1c4f80be5e1d71f297fbd65d2d7475 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Fri, 20 Aug 2021 17:16:56 +0300 Subject: [PATCH 004/958] add gas provided on built in function call --- vm/interface.go | 7 +++++++ vm/systemSmartContracts/eei.go | 1 + 2 files changed, 8 insertions(+) diff --git a/vm/interface.go b/vm/interface.go index 039312229fa..912a1fbf0f8 100644 --- a/vm/interface.go +++ b/vm/interface.go @@ -60,6 +60,13 @@ type SystemEI interface { IsInterfaceNil() bool } +// NFTManagement defines the interface to create/send/burn NFTs +type NFTManagement interface { + CreateNFT() error + SendNFT() error + BurnNFT() error +} + // EconomicsHandler defines the methods to get data from the economics component type EconomicsHandler interface { GenesisTotalSupply() *big.Int diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index b968d00f96b..e3cb4fbd03f 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -455,6 +455,7 @@ func (host *vmContext) ProcessBuiltInFunction( arguments [][]byte, ) error { vmInput := createDirectCallInput(destination, sender, big.NewInt(0), function, arguments) + vmInput.GasProvided = host.GasLeft() vmOutput, err := host.blockChainHook.ProcessBuiltInFunction(vmInput) if err != nil { return err From 58ef56b58e6d6666da76127f85385ad68d134c99 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Mon, 23 Aug 2021 15:24:23 +0300 Subject: [PATCH 005/958] adding a new contract --- vm/address.go | 4 +- vm/factory/systemSCFactory.go | 25 ++ vm/interface.go | 7 - vm/systemSmartContracts/delegation.go | 100 ----- vm/systemSmartContracts/delegation.pb.go | 403 ++++++++++++++--- vm/systemSmartContracts/esdt.go | 6 +- vm/systemSmartContracts/liquidStaking.go | 159 +++++++ vm/systemSmartContracts/liquidStaking.pb.go | 424 ++++++++++++++++++ .../proto/liquidStaking.proto | 13 + 9 files changed, 956 insertions(+), 185 deletions(-) create mode 100644 vm/systemSmartContracts/liquidStaking.go create mode 100644 vm/systemSmartContracts/liquidStaking.pb.go create mode 100644 vm/systemSmartContracts/proto/liquidStaking.proto diff --git a/vm/address.go b/vm/address.go index 97e248a27da..736cb632248 100644 --- a/vm/address.go +++ b/vm/address.go @@ -21,8 +21,8 @@ var EndOfEpochAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 255, // DelegationManagerSCAddress is the hard-coded address for the delegation manager smart contract var DelegationManagerSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255} -// DelegationTokenSCAddress is the hard-coded address for the delegation token smart contract -var DelegationTokenSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 255, 255} +// LiquidStakingSCAddress is the hard-coded address for the delegation token smart contract +var LiquidStakingSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 255, 255} // FirstDelegationSCAddress is the hard-coded address for the first delegation contract, the other will follow var FirstDelegationSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255} diff --git a/vm/factory/systemSCFactory.go b/vm/factory/systemSCFactory.go index f452e3e9495..8f158173a1d 100644 --- a/vm/factory/systemSCFactory.go +++ b/vm/factory/systemSCFactory.go @@ -291,6 +291,21 @@ func (scf *systemSCFactory) createDelegationManagerContract() (vm.SystemSmartCon return delegationManager, err } +func (scf *systemSCFactory) createLiquidStakingContract() (vm.SystemSmartContract, error) { + argsLiquidStaking := systemSmartContracts.ArgsNewLiquidStaking{ + Eei: scf.systemEI, + DelegationMgrSCAddress: vm.DelegationManagerSCAddress, + GasCost: scf.gasCost, + Marshalizer: scf.marshalizer, + Hasher: scf.hasher, + EpochNotifier: scf.epochNotifier, + EndOfEpochAddress: vm.EndOfEpochAddress, + EpochConfig: *scf.epochConfig, + } + liquidStaking, err := systemSmartContracts.NewLiquidStakingSystemSC(argsLiquidStaking) + return liquidStaking, err +} + // CreateForGenesis instantiates all the system smart contracts and returns a container containing them to be used in the genesis process func (scf *systemSCFactory) CreateForGenesis() (vm.SystemSCContainer, error) { staking, err := scf.createStakingContract() @@ -368,6 +383,16 @@ func (scf *systemSCFactory) Create() (vm.SystemSCContainer, error) { return nil, err } + liquidStaking, err := scf.createLiquidStakingContract() + if err != nil { + return nil, err + } + + err = scf.systemSCsContainer.Add(vm.LiquidStakingSCAddress, liquidStaking) + if err != nil { + return nil, err + } + err = scf.systemEI.SetSystemSCContainer(scf.systemSCsContainer) if err != nil { return nil, err diff --git a/vm/interface.go b/vm/interface.go index 912a1fbf0f8..039312229fa 100644 --- a/vm/interface.go +++ b/vm/interface.go @@ -60,13 +60,6 @@ type SystemEI interface { IsInterfaceNil() bool } -// NFTManagement defines the interface to create/send/burn NFTs -type NFTManagement interface { - CreateNFT() error - SendNFT() error - BurnNFT() error -} - // EconomicsHandler defines the methods to get data from the economics component type EconomicsHandler interface { GenesisTotalSupply() *big.Int diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 8fd67d75318..40cc0a9dead 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -182,7 +182,6 @@ func (d *delegation) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCo d.eei.AddReturnMessage("first delegation sc address cannot be called") return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") return vmcommon.UserError @@ -273,16 +272,6 @@ func (d *delegation) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return d.setMetaData(args) case "getMetaData": return d.getMetaData(args) - case "claimDelegatedPosition": - return d.claimDelegatedPosition(args) - case "claimRewardsFromPosition": - return d.claimRewardsFromDelegatedPosition(args) - case "reDelegateRewardsFromPosition": - return d.reDelegateRewardsFromPosition(args) - case "unDelegateWithPosition": - return d.unDelegateWithPosition(args) - case "returnPosition": - return d.returnPosition(args) } d.eei.AddReturnMessage(args.Function + " is an unknown function") @@ -601,10 +590,6 @@ func (d *delegation) checkInputForWhitelisting(args *vmcommon.ContractCallInput) d.eei.AddReturnMessage("non-payable function") return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -768,10 +753,6 @@ func (d *delegation) checkOwnerCallValueGasAndDuplicates(args *vmcommon.Contract d.eei.AddReturnMessage(vm.ErrDuplicatesFoundInArguments.Error()) return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } return vmcommon.Ok } @@ -1263,10 +1244,6 @@ func (d *delegation) unJailNodes(args *vmcommon.ContractCallInput) vmcommon.Retu d.eei.AddReturnMessage(err.Error()) return vmcommon.OutOfGas } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } duplicates := checkForDuplicates(args.Arguments) if duplicates { d.eei.AddReturnMessage(vm.ErrDuplicatesFoundInArguments.Error()) @@ -1325,10 +1302,6 @@ func (d *delegation) reDelegateRewards(args *vmcommon.ContractCallInput) vmcommo d.eei.AddReturnMessage("must be called without arguments") return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { @@ -1504,10 +1477,6 @@ func (d *delegation) delegate(args *vmcommon.ContractCallInput) vmcommon.ReturnC d.eei.AddReturnMessage("error getting minimum delegation amount " + err.Error()) return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } minDelegationAmount := delegationManagement.MinDelegationAmount if args.CallValue.Cmp(minDelegationAmount) < 0 { @@ -1604,10 +1573,6 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } valueToUnDelegate := big.NewInt(0).SetBytes(args.Arguments[0]) if valueToUnDelegate.Cmp(zero) <= 0 { d.eei.AddReturnMessage("invalid value to undelegate") @@ -1787,10 +1752,6 @@ func (d *delegation) getRewardData(args *vmcommon.ContractCallInput) vmcommon.Re d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -1911,10 +1872,6 @@ func (d *delegation) claimRewards(args *vmcommon.ContractCallInput) vmcommon.Ret d.eei.AddReturnMessage("wrong number of arguments") return vmcommon.FunctionWrongSignature } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } isNew, delegator, err := d.getOrCreateDelegatorData(args.CallerAddr) if err != nil { @@ -1991,10 +1948,6 @@ func (d *delegation) withdraw(args *vmcommon.ContractCallInput) vmcommon.ReturnC d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { @@ -2180,10 +2133,6 @@ func (d *delegation) checkArgumentsForGeneralViewFunc(args *vmcommon.ContractCal d.eei.AddReturnMessage(vm.ErrInvalidNumOfArguments.Error()) return vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return vmcommon.UserError - } return vmcommon.Ok } @@ -2375,10 +2324,6 @@ func (d *delegation) checkArgumentsForUserViewFunc(args *vmcommon.ContractCallIn d.eei.AddReturnMessage(vm.ErrCallValueMustBeZero.Error()) return nil, vmcommon.UserError } - if len(args.ESDTTransfers) > 0 { - d.eei.AddReturnMessage("cannot transfer ESDT to system SCs") - return nil, vmcommon.UserError - } err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -2885,51 +2830,6 @@ func getDelegationManagement( return managementData, nil } -func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.flagLiquidStaking.IsSet() { - d.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (d *delegation) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.flagLiquidStaking.IsSet() { - d.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (d *delegation) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.flagLiquidStaking.IsSet() { - d.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (d *delegation) unDelegateWithPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.flagLiquidStaking.IsSet() { - d.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (d *delegation) returnPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.flagLiquidStaking.IsSet() { - d.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError - } - - return vmcommon.Ok -} - // SetNewGasCost is called whenever a gas cost was changed func (d *delegation) SetNewGasCost(gasCost vm.GasCost) { d.mutExecution.Lock() diff --git a/vm/systemSmartContracts/delegation.pb.go b/vm/systemSmartContracts/delegation.pb.go index b79f3c4bac9..9d7e546ddf4 100644 --- a/vm/systemSmartContracts/delegation.pb.go +++ b/vm/systemSmartContracts/delegation.pb.go @@ -634,6 +634,53 @@ func (m *RewardComputationData) GetServiceFee() uint64 { return 0 } +type LiquidStakingAttributes struct { + ContractAddress []byte `protobuf:"bytes,1,opt,name=ContractAddress,proto3" json:"ContractAddress"` + RewardsCheckpoint uint32 `protobuf:"varint,2,opt,name=RewardsCheckpoint,proto3" json:"RewardsCheckpoint"` +} + +func (m *LiquidStakingAttributes) Reset() { *m = LiquidStakingAttributes{} } +func (*LiquidStakingAttributes) ProtoMessage() {} +func (*LiquidStakingAttributes) Descriptor() ([]byte, []int) { + return fileDescriptor_b823c7d67e95582e, []int{10} +} +func (m *LiquidStakingAttributes) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LiquidStakingAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LiquidStakingAttributes) XXX_Merge(src proto.Message) { + xxx_messageInfo_LiquidStakingAttributes.Merge(m, src) +} +func (m *LiquidStakingAttributes) XXX_Size() int { + return m.Size() +} +func (m *LiquidStakingAttributes) XXX_DiscardUnknown() { + xxx_messageInfo_LiquidStakingAttributes.DiscardUnknown(m) +} + +var xxx_messageInfo_LiquidStakingAttributes proto.InternalMessageInfo + +func (m *LiquidStakingAttributes) GetContractAddress() []byte { + if m != nil { + return m.ContractAddress + } + return nil +} + +func (m *LiquidStakingAttributes) GetRewardsCheckpoint() uint32 { + if m != nil { + return m.RewardsCheckpoint + } + return 0 +} + func init() { proto.RegisterType((*DelegationManagement)(nil), "proto.DelegationManagement") proto.RegisterType((*DelegationContractList)(nil), "proto.DelegationContractList") @@ -645,84 +692,88 @@ func init() { proto.RegisterType((*GlobalFundData)(nil), "proto.GlobalFundData") proto.RegisterType((*NodesData)(nil), "proto.NodesData") proto.RegisterType((*RewardComputationData)(nil), "proto.RewardComputationData") + proto.RegisterType((*LiquidStakingAttributes)(nil), "proto.LiquidStakingAttributes") } func init() { proto.RegisterFile("delegation.proto", fileDescriptor_b823c7d67e95582e) } var fileDescriptor_b823c7d67e95582e = []byte{ - // 1145 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0xe3, 0xc4, - 0x17, 0x8f, 0xd3, 0x74, 0xb7, 0xfb, 0x9a, 0xec, 0xb7, 0x3b, 0xdb, 0x7e, 0x89, 0x00, 0xd9, 0x55, - 0x24, 0xa4, 0x4a, 0xa8, 0xa9, 0xf8, 0x21, 0x21, 0xc1, 0x85, 0x3a, 0x6d, 0x51, 0xb4, 0x6d, 0x8a, - 0x26, 0x2d, 0xbf, 0x05, 0x9a, 0xc4, 0x53, 0x77, 0xd4, 0x78, 0x26, 0xb2, 0xc7, 0xdb, 0x56, 0x5c, - 0xe0, 0x84, 0x40, 0x42, 0x02, 0x71, 0xda, 0xff, 0x00, 0x71, 0xe1, 0xdf, 0xe0, 0xd8, 0x1b, 0x15, - 0x07, 0x43, 0x53, 0x09, 0x21, 0x9f, 0xf6, 0x4f, 0x40, 0x1e, 0xdb, 0x89, 0x9d, 0x78, 0xf7, 0x14, - 0x71, 0x89, 0xdf, 0xfb, 0xbc, 0xf1, 0xf3, 0x9b, 0x79, 0x9f, 0xf7, 0xe6, 0x05, 0x56, 0x2c, 0x3a, - 0xa0, 0x36, 0x91, 0x4c, 0xf0, 0xe6, 0xd0, 0x15, 0x52, 0xa0, 0x45, 0xf5, 0x78, 0x71, 0xd3, 0x66, - 0xf2, 0xd4, 0xef, 0x35, 0xfb, 0xc2, 0xd9, 0xb2, 0x85, 0x2d, 0xb6, 0x14, 0xdc, 0xf3, 0x4f, 0x94, - 0xa6, 0x14, 0x25, 0xc5, 0x6f, 0x35, 0xbe, 0xa9, 0xc0, 0xea, 0xce, 0xd8, 0xd5, 0x01, 0xe1, 0xc4, - 0xa6, 0x0e, 0xe5, 0x12, 0xbd, 0x0d, 0xf7, 0x3b, 0xbe, 0x73, 0x78, 0xd2, 0x12, 0x5c, 0xba, 0xa4, - 0x2f, 0xbd, 0xba, 0xb6, 0xae, 0x6d, 0xd4, 0x4c, 0x14, 0x06, 0xc6, 0x94, 0x05, 0x4f, 0xe9, 0xe8, - 0x35, 0x58, 0xde, 0x27, 0x9e, 0xdc, 0xb6, 0x2c, 0x97, 0x7a, 0x5e, 0xbd, 0xbc, 0xae, 0x6d, 0x54, - 0xcd, 0xff, 0x85, 0x81, 0x91, 0x85, 0x71, 0x56, 0x41, 0x6f, 0x41, 0xed, 0x80, 0xf1, 0x2e, 0x75, - 0x1f, 0xb3, 0x3e, 0xdd, 0xa3, 0xb4, 0xbe, 0xb0, 0xae, 0x6d, 0x54, 0xcc, 0x07, 0x61, 0x60, 0xe4, - 0x0d, 0x38, 0xaf, 0xaa, 0x17, 0xc9, 0x45, 0xe6, 0xc5, 0x4a, 0xe6, 0xc5, 0xac, 0x01, 0xe7, 0x55, - 0x74, 0x01, 0x70, 0xc0, 0xf8, 0x0e, 0x1d, 0x0a, 0x8f, 0xc9, 0xfa, 0xa2, 0x8a, 0xf1, 0xa3, 0x30, - 0x30, 0x32, 0xe8, 0x2f, 0x7f, 0x1a, 0x7b, 0x0e, 0x91, 0xa7, 0x5b, 0x3d, 0x66, 0x37, 0xdb, 0x5c, - 0xbe, 0x93, 0x39, 0xdb, 0xdd, 0x81, 0x2b, 0xb8, 0xd5, 0xa1, 0xf2, 0x5c, 0xb8, 0x67, 0x5b, 0x54, - 0x69, 0x9b, 0xb6, 0xd8, 0xec, 0x0b, 0x97, 0x6e, 0x59, 0x44, 0x92, 0xa6, 0xc9, 0xec, 0x36, 0x97, - 0x2d, 0xe2, 0x49, 0xea, 0xe2, 0x8c, 0x57, 0xf4, 0x93, 0x06, 0x0f, 0x95, 0x9a, 0x1e, 0xfb, 0xb6, - 0x23, 0x7c, 0x2e, 0xeb, 0x77, 0x54, 0x0c, 0x24, 0x0c, 0x8c, 0x22, 0xf3, 0x1c, 0x83, 0x29, 0x72, - 0xdf, 0xd8, 0x85, 0xff, 0x4f, 0xb0, 0x34, 0x97, 0xfb, 0xcc, 0x93, 0xe8, 0x55, 0xb8, 0x97, 0xa4, - 0x89, 0x46, 0x2c, 0x58, 0xd8, 0xa8, 0x9a, 0xb5, 0x30, 0x30, 0x26, 0x20, 0x9e, 0x88, 0x8d, 0x5f, - 0x17, 0x61, 0x25, 0xe7, 0xe7, 0x84, 0xd9, 0xe8, 0x3b, 0x0d, 0x56, 0x0e, 0xc8, 0x45, 0x06, 0x27, - 0x43, 0xc5, 0xa7, 0xaa, 0xf9, 0x79, 0x18, 0x18, 0x33, 0xb6, 0x39, 0xee, 0x75, 0xc6, 0x37, 0xfa, - 0x5e, 0x83, 0x07, 0x6d, 0xce, 0x24, 0x23, 0x83, 0xc3, 0x73, 0x4e, 0xdd, 0x3d, 0x9f, 0x5b, 0x29, - 0x49, 0xbf, 0x08, 0x03, 0x63, 0xd6, 0x38, 0xc7, 0x70, 0x66, 0x9d, 0xa3, 0x36, 0x3c, 0xdc, 0xf6, - 0xa5, 0x70, 0x88, 0x64, 0xfd, 0xed, 0xbe, 0x64, 0x8f, 0x55, 0xa4, 0xaa, 0x00, 0x96, 0xcc, 0x17, - 0x22, 0x36, 0x14, 0x98, 0x71, 0x11, 0x88, 0xf6, 0x61, 0xb5, 0x75, 0x4a, 0xb8, 0x4d, 0x49, 0x6f, - 0x40, 0xa7, 0x6a, 0x62, 0xc9, 0xac, 0x87, 0x81, 0x51, 0x68, 0xc7, 0x85, 0x28, 0x7a, 0x13, 0xaa, - 0x2d, 0x97, 0x12, 0x49, 0xad, 0x8e, 0xe0, 0x7d, 0xaa, 0x6a, 0xa4, 0x62, 0xae, 0x84, 0x81, 0x91, - 0xc3, 0x71, 0x4e, 0x8b, 0x62, 0x38, 0xe6, 0xa6, 0xe0, 0xd6, 0xfb, 0xd4, 0x65, 0xc2, 0x6a, 0xf3, - 0xdd, 0xa1, 0xe8, 0x9f, 0x7a, 0x8a, 0xdd, 0xb5, 0x38, 0x86, 0x22, 0x3b, 0x2e, 0x44, 0x11, 0x81, - 0x97, 0x5a, 0xa7, 0xb4, 0x7f, 0xd6, 0x22, 0xc3, 0x43, 0x8e, 0x69, 0x92, 0x49, 0x8a, 0xe9, 0x39, - 0x71, 0x2d, 0xaf, 0x7e, 0x57, 0x6d, 0xcc, 0x08, 0x03, 0xe3, 0x79, 0xcb, 0xf0, 0xf3, 0x8c, 0x8d, - 0x6f, 0x35, 0x40, 0x99, 0x16, 0x48, 0x25, 0xd9, 0x21, 0x92, 0xa0, 0x97, 0xa1, 0xd2, 0x21, 0x0e, - 0x4d, 0x68, 0xba, 0x14, 0x06, 0x86, 0xd2, 0xb1, 0xfa, 0x45, 0xaf, 0xc0, 0xdd, 0x0f, 0x69, 0xcf, - 0x63, 0x92, 0x26, 0xcc, 0x59, 0x0e, 0x03, 0x23, 0x85, 0x70, 0x2a, 0xa0, 0x26, 0x40, 0xdb, 0xa2, - 0x5c, 0xb2, 0x13, 0x46, 0x5d, 0x95, 0xd2, 0xaa, 0x79, 0x3f, 0x6a, 0x32, 0x13, 0x14, 0x67, 0xe4, - 0xc6, 0x93, 0x32, 0xd4, 0x67, 0xab, 0xb0, 0x2b, 0x89, 0xf4, 0x3d, 0xf4, 0x2e, 0x40, 0x57, 0x92, - 0x33, 0x6a, 0x3d, 0xa2, 0x97, 0x71, 0x21, 0x2e, 0xbf, 0xbe, 0x12, 0xf7, 0xf1, 0x66, 0x47, 0x58, - 0xd4, 0x8b, 0xe2, 0x8e, 0xdd, 0x4f, 0xd6, 0xe1, 0x8c, 0x8c, 0xda, 0x50, 0xeb, 0x08, 0x99, 0x71, - 0x52, 0x7e, 0x86, 0x13, 0xd5, 0x3e, 0x73, 0x4b, 0x71, 0x5e, 0x45, 0x7b, 0x50, 0x3d, 0xe6, 0x19, - 0x4f, 0x0b, 0xcf, 0xf0, 0xa4, 0xe8, 0x92, 0x5d, 0x89, 0x73, 0x1a, 0xda, 0x80, 0xa5, 0x8e, 0xef, - 0x1c, 0x7b, 0xd4, 0xf5, 0x92, 0xd6, 0x5d, 0x0d, 0x03, 0x63, 0x8c, 0xe1, 0xb1, 0xd4, 0xf8, 0x5d, - 0x83, 0x4a, 0x54, 0x31, 0x88, 0xc1, 0xe2, 0x07, 0x64, 0xe0, 0xa7, 0xa9, 0xe9, 0x86, 0x81, 0x11, - 0x03, 0x73, 0xac, 0xd3, 0xd8, 0x61, 0x94, 0xe6, 0xfc, 0x2d, 0xa6, 0xd2, 0x9c, 0xde, 0x60, 0xa9, - 0x80, 0x0c, 0x58, 0x54, 0x7c, 0x55, 0x19, 0xae, 0x99, 0xf7, 0xa2, 0x88, 0x14, 0x80, 0xe3, 0x47, - 0x44, 0xa6, 0xa3, 0xcb, 0x61, 0x5c, 0x88, 0xb5, 0x98, 0x4c, 0x91, 0x8e, 0xd5, 0x6f, 0xe3, 0xef, - 0x05, 0xa8, 0x25, 0x59, 0x17, 0xae, 0x22, 0x5f, 0x13, 0x40, 0x95, 0x35, 0x8d, 0x36, 0x9c, 0xec, - 0x53, 0x25, 0x76, 0x82, 0xe2, 0x8c, 0x1c, 0xdd, 0x82, 0xe9, 0xa9, 0xa6, 0xed, 0x2c, 0x6a, 0xd3, - 0x2a, 0x8d, 0x39, 0x03, 0xce, 0xab, 0xa8, 0x05, 0x0f, 0x92, 0x3a, 0x50, 0x25, 0x32, 0x14, 0x8c, - 0xcb, 0x64, 0x17, 0x6b, 0x51, 0x2f, 0x9c, 0x31, 0xe2, 0x59, 0x48, 0xb5, 0xf7, 0x63, 0xde, 0x1a, - 0x10, 0xe6, 0x50, 0x2b, 0x2d, 0xcd, 0xca, 0xa4, 0xbd, 0x4f, 0xdb, 0xe6, 0xd9, 0xde, 0xa7, 0x7d, - 0xa3, 0x27, 0x1a, 0xac, 0x1d, 0x09, 0x49, 0x06, 0x2d, 0xdf, 0xf1, 0x07, 0x51, 0x5f, 0x4a, 0x23, - 0x8a, 0xef, 0xf8, 0x7e, 0x18, 0x18, 0xc5, 0x0b, 0xe6, 0x18, 0x56, 0xf1, 0x07, 0x1a, 0x3f, 0x96, - 0xe1, 0xfe, 0x7b, 0x03, 0xd1, 0x23, 0x83, 0xe8, 0xf4, 0x55, 0xa6, 0xbf, 0x84, 0x65, 0xb5, 0x36, - 0x4e, 0x66, 0x92, 0xea, 0x8f, 0xa3, 0x59, 0x29, 0x03, 0xcf, 0x31, 0xb2, 0xac, 0x5b, 0xf4, 0xb5, - 0x06, 0x35, 0xa5, 0xa7, 0xa4, 0x48, 0x58, 0xfe, 0x69, 0xc4, 0x9b, 0x9c, 0x61, 0x8e, 0x11, 0xe4, - 0x1d, 0x37, 0x3e, 0x83, 0x7b, 0xe3, 0x6e, 0x81, 0x1a, 0x70, 0xc7, 0xdc, 0xef, 0x3e, 0xa2, 0x97, - 0xc9, 0x41, 0x40, 0x18, 0x18, 0x09, 0x82, 0x93, 0x67, 0x34, 0x8e, 0x74, 0x99, 0xcd, 0xa9, 0x75, - 0xe0, 0xd9, 0x49, 0xbc, 0x6a, 0x1c, 0x19, 0x83, 0x78, 0x22, 0x36, 0xfe, 0x28, 0xc3, 0x5a, 0x7c, - 0xfa, 0x2d, 0xe1, 0x0c, 0x7d, 0xa9, 0xfa, 0xaa, 0xfa, 0x54, 0x34, 0x85, 0x25, 0x79, 0x39, 0x12, - 0x3b, 0xcc, 0x93, 0x2e, 0xeb, 0xf9, 0x32, 0xcd, 0x80, 0x9a, 0xc2, 0x0a, 0xcc, 0xf3, 0x9c, 0xc2, - 0x0a, 0xdc, 0x4f, 0xd3, 0xa1, 0xfc, 0x9f, 0xd2, 0xa1, 0x09, 0x30, 0x33, 0x81, 0xc7, 0xd7, 0xc9, - 0x64, 0x54, 0xc8, 0xc8, 0x66, 0xe7, 0xea, 0x46, 0x2f, 0x5d, 0xdf, 0xe8, 0xa5, 0xa7, 0x37, 0xba, - 0xf6, 0xd5, 0x48, 0xd7, 0x7e, 0x1e, 0xe9, 0xda, 0x6f, 0x23, 0x5d, 0xbb, 0x1a, 0xe9, 0xda, 0xf5, - 0x48, 0xd7, 0xfe, 0x1a, 0xe9, 0xda, 0x3f, 0x23, 0xbd, 0xf4, 0x74, 0xa4, 0x6b, 0x3f, 0xdc, 0xea, - 0xa5, 0xab, 0x5b, 0xbd, 0x74, 0x7d, 0xab, 0x97, 0x3e, 0x59, 0xf5, 0x2e, 0x3d, 0x49, 0x9d, 0xae, - 0x43, 0x5c, 0x39, 0xfe, 0xdf, 0xd0, 0xbb, 0xa3, 0x2e, 0x8f, 0x37, 0xfe, 0x0d, 0x00, 0x00, 0xff, - 0xff, 0x60, 0x31, 0xda, 0xbf, 0xdd, 0x0c, 0x00, 0x00, + // 1192 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6b, 0xe3, 0xc6, + 0x17, 0xb7, 0x1c, 0x67, 0x37, 0xfb, 0x62, 0xef, 0x66, 0x67, 0x77, 0xbf, 0x6b, 0xbe, 0x2d, 0xd2, + 0x22, 0x28, 0x04, 0xca, 0x3a, 0xf4, 0x07, 0x14, 0x5a, 0x0a, 0x8d, 0x9c, 0x4d, 0x31, 0x9b, 0x78, + 0xcb, 0x78, 0xd3, 0xdf, 0xb4, 0x8c, 0xad, 0x89, 0x32, 0xc4, 0x9a, 0x71, 0xa5, 0xd1, 0x26, 0xa1, + 0x97, 0xf6, 0x54, 0x5a, 0x28, 0xb4, 0xf4, 0xb4, 0x87, 0xde, 0x4b, 0x2f, 0xfd, 0x37, 0x7a, 0xcc, + 0xad, 0xa1, 0x07, 0xb5, 0x71, 0xa0, 0x14, 0x9d, 0xf6, 0x4f, 0x28, 0x1a, 0x49, 0xb6, 0x64, 0x6b, + 0x17, 0x0a, 0xa6, 0x17, 0xeb, 0xbd, 0xcf, 0x1b, 0x3d, 0xbd, 0x99, 0xf7, 0xde, 0x67, 0x9e, 0x61, + 0xcd, 0xa6, 0x43, 0xea, 0x10, 0xc9, 0x04, 0x6f, 0x8d, 0x3c, 0x21, 0x05, 0x5a, 0x56, 0x8f, 0xff, + 0xdf, 0x75, 0x98, 0x3c, 0x08, 0xfa, 0xad, 0x81, 0x70, 0x37, 0x1c, 0xe1, 0x88, 0x0d, 0x05, 0xf7, + 0x83, 0x7d, 0xa5, 0x29, 0x45, 0x49, 0xc9, 0x5b, 0xe6, 0x57, 0x35, 0xb8, 0xb9, 0x35, 0x71, 0xb5, + 0x4b, 0x38, 0x71, 0xa8, 0x4b, 0xb9, 0x44, 0xaf, 0xc3, 0xd5, 0x6e, 0xe0, 0x3e, 0xd8, 0x6f, 0x0b, + 0x2e, 0x3d, 0x32, 0x90, 0x7e, 0x53, 0xbb, 0xa3, 0xad, 0x37, 0x2c, 0x14, 0x85, 0xc6, 0x8c, 0x05, + 0xcf, 0xe8, 0xe8, 0x25, 0x58, 0xdd, 0x21, 0xbe, 0xdc, 0xb4, 0x6d, 0x8f, 0xfa, 0x7e, 0xb3, 0x7a, + 0x47, 0x5b, 0xaf, 0x5b, 0xd7, 0xa2, 0xd0, 0xc8, 0xc3, 0x38, 0xaf, 0xa0, 0xd7, 0xa0, 0xb1, 0xcb, + 0x78, 0x8f, 0x7a, 0x8f, 0xd8, 0x80, 0x6e, 0x53, 0xda, 0x5c, 0xba, 0xa3, 0xad, 0xd7, 0xac, 0xeb, + 0x51, 0x68, 0x14, 0x0d, 0xb8, 0xa8, 0xaa, 0x17, 0xc9, 0x71, 0xee, 0xc5, 0x5a, 0xee, 0xc5, 0xbc, + 0x01, 0x17, 0x55, 0x74, 0x0c, 0xb0, 0xcb, 0xf8, 0x16, 0x1d, 0x09, 0x9f, 0xc9, 0xe6, 0xb2, 0x8a, + 0xf1, 0xfd, 0x28, 0x34, 0x72, 0xe8, 0xcf, 0x7f, 0x18, 0xdb, 0x2e, 0x91, 0x07, 0x1b, 0x7d, 0xe6, + 0xb4, 0x3a, 0x5c, 0xbe, 0x91, 0x3b, 0xdb, 0x7b, 0x43, 0x4f, 0x70, 0xbb, 0x4b, 0xe5, 0x91, 0xf0, + 0x0e, 0x37, 0xa8, 0xd2, 0xee, 0x3a, 0xe2, 0xee, 0x40, 0x78, 0x74, 0xc3, 0x26, 0x92, 0xb4, 0x2c, + 0xe6, 0x74, 0xb8, 0x6c, 0x13, 0x5f, 0x52, 0x0f, 0xe7, 0xbc, 0xa2, 0x1f, 0x34, 0xb8, 0xa1, 0xd4, + 0xec, 0xd8, 0x37, 0x5d, 0x11, 0x70, 0xd9, 0xbc, 0xa4, 0x62, 0x20, 0x51, 0x68, 0x94, 0x99, 0x17, + 0x18, 0x4c, 0x99, 0x7b, 0xf3, 0x1e, 0xfc, 0x6f, 0x8a, 0x65, 0xb9, 0xdc, 0x61, 0xbe, 0x44, 0x2f, + 0xc2, 0x95, 0x34, 0x4d, 0x34, 0xae, 0x82, 0xa5, 0xf5, 0xba, 0xd5, 0x88, 0x42, 0x63, 0x0a, 0xe2, + 0xa9, 0x68, 0xfe, 0xb2, 0x0c, 0x6b, 0x05, 0x3f, 0xfb, 0xcc, 0x41, 0xdf, 0x68, 0xb0, 0xb6, 0x4b, + 0x8e, 0x73, 0x38, 0x19, 0xa9, 0x7a, 0xaa, 0x5b, 0x9f, 0x44, 0xa1, 0x31, 0x67, 0x5b, 0xe0, 0x5e, + 0xe7, 0x7c, 0xa3, 0x6f, 0x35, 0xb8, 0xde, 0xe1, 0x4c, 0x32, 0x32, 0x7c, 0x70, 0xc4, 0xa9, 0xb7, + 0x1d, 0x70, 0x3b, 0x2b, 0xd2, 0x4f, 0xa3, 0xd0, 0x98, 0x37, 0x2e, 0x30, 0x9c, 0x79, 0xe7, 0xa8, + 0x03, 0x37, 0x36, 0x03, 0x29, 0x5c, 0x22, 0xd9, 0x60, 0x73, 0x20, 0xd9, 0x23, 0x15, 0xa9, 0x6a, + 0x80, 0x15, 0xeb, 0x76, 0x5c, 0x0d, 0x25, 0x66, 0x5c, 0x06, 0xa2, 0x1d, 0xb8, 0xd9, 0x3e, 0x20, + 0xdc, 0xa1, 0xa4, 0x3f, 0xa4, 0x33, 0x3d, 0xb1, 0x62, 0x35, 0xa3, 0xd0, 0x28, 0xb5, 0xe3, 0x52, + 0x14, 0xbd, 0x0a, 0xf5, 0xb6, 0x47, 0x89, 0xa4, 0x76, 0x57, 0xf0, 0x01, 0x55, 0x3d, 0x52, 0xb3, + 0xd6, 0xa2, 0xd0, 0x28, 0xe0, 0xb8, 0xa0, 0xc5, 0x31, 0xec, 0x71, 0x4b, 0x70, 0xfb, 0x1d, 0xea, + 0x31, 0x61, 0x77, 0xf8, 0xbd, 0x91, 0x18, 0x1c, 0xf8, 0xaa, 0xba, 0x1b, 0x49, 0x0c, 0x65, 0x76, + 0x5c, 0x8a, 0x22, 0x02, 0xcf, 0xb5, 0x0f, 0xe8, 0xe0, 0xb0, 0x4d, 0x46, 0x0f, 0x38, 0xa6, 0x69, + 0x26, 0x29, 0xa6, 0x47, 0xc4, 0xb3, 0xfd, 0xe6, 0x65, 0xb5, 0x31, 0x23, 0x0a, 0x8d, 0x67, 0x2d, + 0xc3, 0xcf, 0x32, 0x9a, 0x5f, 0x6b, 0x80, 0x72, 0x14, 0x48, 0x25, 0xd9, 0x22, 0x92, 0xa0, 0xe7, + 0xa1, 0xd6, 0x25, 0x2e, 0x4d, 0xcb, 0x74, 0x25, 0x0a, 0x0d, 0xa5, 0x63, 0xf5, 0x8b, 0x5e, 0x80, + 0xcb, 0xef, 0xd1, 0xbe, 0xcf, 0x24, 0x4d, 0x2b, 0x67, 0x35, 0x0a, 0x8d, 0x0c, 0xc2, 0x99, 0x80, + 0x5a, 0x00, 0x1d, 0x9b, 0x72, 0xc9, 0xf6, 0x19, 0xf5, 0x54, 0x4a, 0xeb, 0xd6, 0xd5, 0x98, 0x64, + 0xa6, 0x28, 0xce, 0xc9, 0xe6, 0xe3, 0x2a, 0x34, 0xe7, 0xbb, 0xb0, 0x27, 0x89, 0x0c, 0x7c, 0xf4, + 0x16, 0x40, 0x4f, 0x92, 0x43, 0x6a, 0xdf, 0xa7, 0x27, 0x49, 0x23, 0xae, 0xbe, 0xbc, 0x96, 0xf0, + 0x78, 0xab, 0x2b, 0x6c, 0xea, 0xc7, 0x71, 0x27, 0xee, 0xa7, 0xeb, 0x70, 0x4e, 0x46, 0x1d, 0x68, + 0x74, 0x85, 0xcc, 0x39, 0xa9, 0x3e, 0xc5, 0x89, 0xa2, 0xcf, 0xc2, 0x52, 0x5c, 0x54, 0xd1, 0x36, + 0xd4, 0xf7, 0x78, 0xce, 0xd3, 0xd2, 0x53, 0x3c, 0xa9, 0x72, 0xc9, 0xaf, 0xc4, 0x05, 0x0d, 0xad, + 0xc3, 0x4a, 0x37, 0x70, 0xf7, 0x7c, 0xea, 0xf9, 0x29, 0x75, 0xd7, 0xa3, 0xd0, 0x98, 0x60, 0x78, + 0x22, 0x99, 0xbf, 0x69, 0x50, 0x8b, 0x3b, 0x06, 0x31, 0x58, 0x7e, 0x97, 0x0c, 0x83, 0x2c, 0x35, + 0xbd, 0x28, 0x34, 0x12, 0x60, 0x81, 0x7d, 0x9a, 0x38, 0x8c, 0xd3, 0x5c, 0xbc, 0xc5, 0x54, 0x9a, + 0xb3, 0x1b, 0x2c, 0x13, 0x90, 0x01, 0xcb, 0xaa, 0x5e, 0x55, 0x86, 0x1b, 0xd6, 0x95, 0x38, 0x22, + 0x05, 0xe0, 0xe4, 0x11, 0x17, 0xd3, 0xc3, 0x93, 0x51, 0xd2, 0x88, 0x8d, 0xa4, 0x98, 0x62, 0x1d, + 0xab, 0x5f, 0xf3, 0xaf, 0x25, 0x68, 0xa4, 0x59, 0x17, 0x9e, 0x2a, 0xbe, 0x16, 0x80, 0x6a, 0x6b, + 0x1a, 0x6f, 0x38, 0xdd, 0xa7, 0x4a, 0xec, 0x14, 0xc5, 0x39, 0x39, 0xbe, 0x05, 0xb3, 0x53, 0xcd, + 0xe8, 0x2c, 0xa6, 0x69, 0x95, 0xc6, 0x82, 0x01, 0x17, 0x55, 0xd4, 0x86, 0xeb, 0x69, 0x1f, 0xa8, + 0x16, 0x19, 0x09, 0xc6, 0x65, 0xba, 0x8b, 0x5b, 0x31, 0x17, 0xce, 0x19, 0xf1, 0x3c, 0xa4, 0xe8, + 0x7d, 0x8f, 0xb7, 0x87, 0x84, 0xb9, 0xd4, 0xce, 0x5a, 0xb3, 0x36, 0xa5, 0xf7, 0x59, 0xdb, 0x22, + 0xe9, 0x7d, 0xd6, 0x37, 0x7a, 0xac, 0xc1, 0xad, 0x87, 0x42, 0x92, 0x61, 0x3b, 0x70, 0x83, 0x61, + 0xcc, 0x4b, 0x59, 0x44, 0xc9, 0x1d, 0x3f, 0x88, 0x42, 0xa3, 0x7c, 0xc1, 0x02, 0xc3, 0x2a, 0xff, + 0x80, 0xf9, 0x7d, 0x15, 0xae, 0xbe, 0x3d, 0x14, 0x7d, 0x32, 0x8c, 0x4f, 0x5f, 0x65, 0xfa, 0x73, + 0x58, 0x55, 0x6b, 0x93, 0x64, 0xa6, 0xa9, 0xfe, 0x20, 0x9e, 0x95, 0x72, 0xf0, 0x02, 0x23, 0xcb, + 0xbb, 0x45, 0x5f, 0x6a, 0xd0, 0x50, 0x7a, 0x56, 0x14, 0x69, 0x95, 0x7f, 0x14, 0xd7, 0x4d, 0xc1, + 0xb0, 0xc0, 0x08, 0x8a, 0x8e, 0xcd, 0x8f, 0xe1, 0xca, 0x84, 0x2d, 0x90, 0x09, 0x97, 0xac, 0x9d, + 0xde, 0x7d, 0x7a, 0x92, 0x1e, 0x04, 0x44, 0xa1, 0x91, 0x22, 0x38, 0x7d, 0xc6, 0xe3, 0x48, 0x8f, + 0x39, 0x9c, 0xda, 0xbb, 0xbe, 0x93, 0xc6, 0xab, 0xc6, 0x91, 0x09, 0x88, 0xa7, 0xa2, 0xf9, 0x7b, + 0x15, 0x6e, 0x25, 0xa7, 0xdf, 0x16, 0xee, 0x28, 0x90, 0x8a, 0x57, 0xd5, 0xa7, 0xe2, 0x29, 0x2c, + 0xcd, 0xcb, 0x43, 0xb1, 0xc5, 0x7c, 0xe9, 0xb1, 0x7e, 0x20, 0xb3, 0x0c, 0xa8, 0x29, 0xac, 0xc4, + 0xbc, 0xc8, 0x29, 0xac, 0xc4, 0xfd, 0x6c, 0x39, 0x54, 0xff, 0xd3, 0x72, 0x68, 0x01, 0xcc, 0x4d, + 0xe0, 0xc9, 0x75, 0x32, 0x1d, 0x15, 0x72, 0xb2, 0xf9, 0xa3, 0x06, 0xb7, 0x77, 0xd8, 0x67, 0x01, + 0xb3, 0xe3, 0x5c, 0x32, 0xee, 0x6c, 0xca, 0x74, 0x1f, 0x3e, 0x7a, 0x13, 0xae, 0x65, 0xd7, 0x57, + 0xc6, 0xa0, 0xc9, 0xc9, 0xde, 0x88, 0x42, 0x63, 0xd6, 0x84, 0x67, 0x81, 0x72, 0x5e, 0xaa, 0xfe, + 0x3b, 0x5e, 0xb2, 0xba, 0xa7, 0xe7, 0x7a, 0xe5, 0xec, 0x5c, 0xaf, 0x3c, 0x39, 0xd7, 0xb5, 0x2f, + 0xc6, 0xba, 0xf6, 0xd3, 0x58, 0xd7, 0x7e, 0x1d, 0xeb, 0xda, 0xe9, 0x58, 0xd7, 0xce, 0xc6, 0xba, + 0xf6, 0xe7, 0x58, 0xd7, 0xfe, 0x1e, 0xeb, 0x95, 0x27, 0x63, 0x5d, 0xfb, 0xee, 0x42, 0xaf, 0x9c, + 0x5e, 0xe8, 0x95, 0xb3, 0x0b, 0xbd, 0xf2, 0xe1, 0x4d, 0xff, 0xc4, 0x97, 0xd4, 0xed, 0xb9, 0xc4, + 0x93, 0x93, 0xff, 0x35, 0xfd, 0x4b, 0xea, 0x72, 0x7b, 0xe5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x06, 0x92, 0xd0, 0x46, 0x7d, 0x0d, 0x00, 0x00, } func (this *DelegationManagement) Equal(that interface{}) bool { @@ -1104,6 +1155,33 @@ func (this *RewardComputationData) Equal(that interface{}) bool { } return true } +func (this *LiquidStakingAttributes) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LiquidStakingAttributes) + if !ok { + that2, ok := that.(LiquidStakingAttributes) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.ContractAddress, that1.ContractAddress) { + return false + } + if this.RewardsCheckpoint != that1.RewardsCheckpoint { + return false + } + return true +} func (this *DelegationManagement) GoString() string { if this == nil { return "nil" @@ -1237,6 +1315,17 @@ func (this *RewardComputationData) GoString() string { s = append(s, "}") return strings.Join(s, "") } +func (this *LiquidStakingAttributes) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&systemSmartContracts.LiquidStakingAttributes{") + s = append(s, "ContractAddress: "+fmt.Sprintf("%#v", this.ContractAddress)+",\n") + s = append(s, "RewardsCheckpoint: "+fmt.Sprintf("%#v", this.RewardsCheckpoint)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func valueToGoStringDelegation(v interface{}, typ string) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -1792,6 +1881,41 @@ func (m *RewardComputationData) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *LiquidStakingAttributes) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LiquidStakingAttributes) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LiquidStakingAttributes) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RewardsCheckpoint != 0 { + i = encodeVarintDelegation(dAtA, i, uint64(m.RewardsCheckpoint)) + i-- + dAtA[i] = 0x10 + } + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintDelegation(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintDelegation(dAtA []byte, offset int, v uint64) int { offset -= sovDelegation(v) base := offset @@ -2049,6 +2173,22 @@ func (m *RewardComputationData) Size() (n int) { return n } +func (m *LiquidStakingAttributes) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovDelegation(uint64(l)) + } + if m.RewardsCheckpoint != 0 { + n += 1 + sovDelegation(uint64(m.RewardsCheckpoint)) + } + return n +} + func sovDelegation(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2197,6 +2337,17 @@ func (this *RewardComputationData) String() string { }, "") return s } +func (this *LiquidStakingAttributes) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LiquidStakingAttributes{`, + `ContractAddress:` + fmt.Sprintf("%v", this.ContractAddress) + `,`, + `RewardsCheckpoint:` + fmt.Sprintf("%v", this.RewardsCheckpoint) + `,`, + `}`, + }, "") + return s +} func valueToStringDelegation(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -3841,6 +3992,112 @@ func (m *RewardComputationData) Unmarshal(dAtA []byte) error { } return nil } +func (m *LiquidStakingAttributes) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDelegation + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LiquidStakingAttributes: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LiquidStakingAttributes: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDelegation + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthDelegation + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthDelegation + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddress = append(m.ContractAddress[:0], dAtA[iNdEx:postIndex]...) + if m.ContractAddress == nil { + m.ContractAddress = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardsCheckpoint", wireType) + } + m.RewardsCheckpoint = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDelegation + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RewardsCheckpoint |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipDelegation(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDelegation + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDelegation + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipDelegation(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 8ff909dc54c..56f5639c703 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -244,7 +244,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm } tokenIdentifier, err := e.createNewToken( - vm.DelegationTokenSCAddress, + vm.LiquidStakingSCAddress, []byte(e.delegationTicker), []byte(e.delegationTicker), big.NewInt(0), @@ -262,7 +262,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } - esdtRole, _ := getRolesForAddress(token, vm.DelegationTokenSCAddress) + esdtRole, _ := getRolesForAddress(token, vm.LiquidStakingSCAddress) esdtRole.Roles = append(esdtRole.Roles, []byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)) token.SpecialRoles = append(token.SpecialRoles, esdtRole) @@ -274,7 +274,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm err = e.eei.ProcessBuiltInFunction( e.eSDTSCAddress, - vm.DelegationTokenSCAddress, + vm.LiquidStakingSCAddress, core.BuiltInFunctionSetESDTRole, [][]byte{[]byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)}, ) diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go new file mode 100644 index 00000000000..f66bbde69de --- /dev/null +++ b/vm/systemSmartContracts/liquidStaking.go @@ -0,0 +1,159 @@ +//go:generate protoc -I=proto -I=$GOPATH/src -I=$GOPATH/src/github.com/ElrondNetwork/protobuf/protobuf --gogoslick_out=. liquidStaking.proto +package systemSmartContracts + +import ( + "fmt" + "sync" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/atomic" + "github.com/ElrondNetwork/elrond-go-core/core/check" + "github.com/ElrondNetwork/elrond-go-core/hashing" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/vm" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" +) + +type liquidStaking struct { + eei vm.SystemEI + sigVerifier vm.MessageSignVerifier + delegationMgrSCAddress []byte + endOfEpochAddr []byte + gasCost vm.GasCost + marshalizer marshal.Marshalizer + hasher hashing.Hasher + mutExecution sync.RWMutex + liquidStakingEnableEpoch uint32 + flagLiquidStaking atomic.Flag +} + +// ArgsNewLiquidStaking defines the arguments to create the liquid staking smart contract +type ArgsNewLiquidStaking struct { + EpochConfig config.EpochConfig + Eei vm.SystemEI + DelegationMgrSCAddress []byte + EndOfEpochAddress []byte + GasCost vm.GasCost + Marshalizer marshal.Marshalizer + Hasher hashing.Hasher + EpochNotifier vm.EpochNotifier +} + +// NewLiquidStakingSystemSC creates a new liquid staking system SC +func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) { + if check.IfNil(args.Eei) { + return nil, vm.ErrNilSystemEnvironmentInterface + } + if len(args.DelegationMgrSCAddress) < 1 { + return nil, fmt.Errorf("%w for delegation manager sc address", vm.ErrInvalidAddress) + } + if len(args.EndOfEpochAddress) < 1 { + return nil, fmt.Errorf("%w for end of epoch address", vm.ErrInvalidAddress) + } + if check.IfNil(args.Marshalizer) { + return nil, vm.ErrNilMarshalizer + } + if check.IfNil(args.Hasher) { + return nil, vm.ErrNilHasher + } + if check.IfNil(args.EpochNotifier) { + return nil, vm.ErrNilEpochNotifier + } + + l := &liquidStaking{ + eei: args.Eei, + delegationMgrSCAddress: args.DelegationMgrSCAddress, + endOfEpochAddr: args.EndOfEpochAddress, + gasCost: args.GasCost, + marshalizer: args.Marshalizer, + hasher: args.Hasher, + liquidStakingEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, + } + log.Debug("liquid staking: enable epoch", "epoch", l.liquidStakingEnableEpoch) + + args.EpochNotifier.RegisterNotifyHandler(l) + + return l, nil +} + +// Execute calls one of the functions from the delegation contract and runs the code according to the input +func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + l.mutExecution.RLock() + defer l.mutExecution.RUnlock() + + err := CheckIfNil(args) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if !l.flagLiquidStaking.IsSet() { + l.eei.AddReturnMessage("liquid staking contract is not enabled") + return vmcommon.UserError + } + + switch args.Function { + case core.SCDeployInitFunctionName: + return l.init(args) + case "claimDelegatedPosition": + return l.claimDelegatedPosition(args) + case "claimRewardsFromPosition": + return l.claimRewardsFromDelegatedPosition(args) + case "reDelegateRewardsFromPosition": + return l.reDelegateRewardsFromPosition(args) + case "unDelegateWithPosition": + return l.unDelegateWithPosition(args) + case "returnPosition": + return l.returnPosition(args) + } + + l.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError +} + +func (l *liquidStaking) init(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok +} + +func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok +} + +func (l *liquidStaking) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok +} + +func (l *liquidStaking) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok +} + +func (l *liquidStaking) unDelegateWithPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok +} + +func (l *liquidStaking) returnPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok +} + +// SetNewGasCost is called whenever a gas cost was changed +func (l *liquidStaking) SetNewGasCost(gasCost vm.GasCost) { + l.mutExecution.Lock() + l.gasCost = gasCost + l.mutExecution.Unlock() +} + +// EpochConfirmed is called whenever a new epoch is confirmed +func (l *liquidStaking) EpochConfirmed(epoch uint32, _ uint64) { + l.flagLiquidStaking.Toggle(epoch >= l.liquidStakingEnableEpoch) + log.Debug("liquid staking system sc", "enabled", l.flagLiquidStaking.IsSet()) +} + +// CanUseContract returns true if contract can be used +func (l *liquidStaking) CanUseContract() bool { + return l.flagLiquidStaking.IsSet() +} + +// IsInterfaceNil returns true if underlying object is nil +func (l *liquidStaking) IsInterfaceNil() bool { + return l == nil +} diff --git a/vm/systemSmartContracts/liquidStaking.pb.go b/vm/systemSmartContracts/liquidStaking.pb.go new file mode 100644 index 00000000000..4f0068f3ccd --- /dev/null +++ b/vm/systemSmartContracts/liquidStaking.pb.go @@ -0,0 +1,424 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: liquidStaking.proto + +package systemSmartContracts + +import ( + bytes "bytes" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type LiquidStakingAttributes struct { + ContractAddress []byte `protobuf:"bytes,1,opt,name=ContractAddress,proto3" json:"ContractAddress"` + RewardsCheckpoint uint32 `protobuf:"varint,2,opt,name=RewardsCheckpoint,proto3" json:"RewardsCheckpoint"` +} + +func (m *LiquidStakingAttributes) Reset() { *m = LiquidStakingAttributes{} } +func (*LiquidStakingAttributes) ProtoMessage() {} +func (*LiquidStakingAttributes) Descriptor() ([]byte, []int) { + return fileDescriptor_ba9d71ac181fc9d8, []int{0} +} +func (m *LiquidStakingAttributes) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LiquidStakingAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LiquidStakingAttributes) XXX_Merge(src proto.Message) { + xxx_messageInfo_LiquidStakingAttributes.Merge(m, src) +} +func (m *LiquidStakingAttributes) XXX_Size() int { + return m.Size() +} +func (m *LiquidStakingAttributes) XXX_DiscardUnknown() { + xxx_messageInfo_LiquidStakingAttributes.DiscardUnknown(m) +} + +var xxx_messageInfo_LiquidStakingAttributes proto.InternalMessageInfo + +func (m *LiquidStakingAttributes) GetContractAddress() []byte { + if m != nil { + return m.ContractAddress + } + return nil +} + +func (m *LiquidStakingAttributes) GetRewardsCheckpoint() uint32 { + if m != nil { + return m.RewardsCheckpoint + } + return 0 +} + +func init() { + proto.RegisterType((*LiquidStakingAttributes)(nil), "proto.LiquidStakingAttributes") +} + +func init() { proto.RegisterFile("liquidStaking.proto", fileDescriptor_ba9d71ac181fc9d8) } + +var fileDescriptor_ba9d71ac181fc9d8 = []byte{ + // 253 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xce, 0xc9, 0x2c, 0x2c, + 0xcd, 0x4c, 0x09, 0x2e, 0x49, 0xcc, 0xce, 0xcc, 0x4b, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, + 0x62, 0x05, 0x53, 0x52, 0xba, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, + 0xe9, 0xf9, 0xe9, 0xf9, 0xfa, 0x60, 0xe1, 0xa4, 0xd2, 0x34, 0x30, 0x0f, 0xcc, 0x01, 0xb3, 0x20, + 0xba, 0x94, 0xe6, 0x32, 0x72, 0x89, 0xfb, 0x20, 0x9b, 0xe6, 0x58, 0x52, 0x52, 0x94, 0x99, 0x54, + 0x5a, 0x92, 0x5a, 0x2c, 0x64, 0xcb, 0xc5, 0xef, 0x9c, 0x9f, 0x57, 0x52, 0x94, 0x98, 0x5c, 0xe2, + 0x98, 0x92, 0x52, 0x94, 0x5a, 0x5c, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe3, 0x24, 0xfc, 0xea, + 0x9e, 0x3c, 0xba, 0x54, 0x10, 0xba, 0x80, 0x90, 0x33, 0x97, 0x60, 0x50, 0x6a, 0x79, 0x62, 0x51, + 0x4a, 0xb1, 0x73, 0x46, 0x6a, 0x72, 0x76, 0x41, 0x7e, 0x66, 0x5e, 0x89, 0x04, 0x93, 0x02, 0xa3, + 0x06, 0xaf, 0x93, 0xe8, 0xab, 0x7b, 0xf2, 0x98, 0x92, 0x41, 0x98, 0x42, 0x4e, 0x7e, 0x17, 0x1e, + 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xf0, 0xe1, 0xa1, 0x1c, 0x63, 0xc3, 0x23, 0x39, 0xc6, 0x15, + 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc6, 0x23, 0x39, 0xc6, + 0x07, 0x8f, 0xe4, 0x18, 0x5f, 0x3c, 0x92, 0x63, 0xf8, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, + 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x12, 0x29, 0xae, 0x2c, 0x2e, 0x49, + 0xcd, 0x0d, 0xce, 0x4d, 0x2c, 0x2a, 0x81, 0x39, 0xad, 0x38, 0x89, 0x0d, 0xec, 0x6d, 0x63, 0x40, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x17, 0xf9, 0x32, 0x43, 0x01, 0x00, 0x00, +} + +func (this *LiquidStakingAttributes) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LiquidStakingAttributes) + if !ok { + that2, ok := that.(LiquidStakingAttributes) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.ContractAddress, that1.ContractAddress) { + return false + } + if this.RewardsCheckpoint != that1.RewardsCheckpoint { + return false + } + return true +} +func (this *LiquidStakingAttributes) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&systemSmartContracts.LiquidStakingAttributes{") + s = append(s, "ContractAddress: "+fmt.Sprintf("%#v", this.ContractAddress)+",\n") + s = append(s, "RewardsCheckpoint: "+fmt.Sprintf("%#v", this.RewardsCheckpoint)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringLiquidStaking(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} +func (m *LiquidStakingAttributes) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LiquidStakingAttributes) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LiquidStakingAttributes) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RewardsCheckpoint != 0 { + i = encodeVarintLiquidStaking(dAtA, i, uint64(m.RewardsCheckpoint)) + i-- + dAtA[i] = 0x10 + } + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintLiquidStaking(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintLiquidStaking(dAtA []byte, offset int, v uint64) int { + offset -= sovLiquidStaking(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *LiquidStakingAttributes) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovLiquidStaking(uint64(l)) + } + if m.RewardsCheckpoint != 0 { + n += 1 + sovLiquidStaking(uint64(m.RewardsCheckpoint)) + } + return n +} + +func sovLiquidStaking(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozLiquidStaking(x uint64) (n int) { + return sovLiquidStaking(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *LiquidStakingAttributes) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LiquidStakingAttributes{`, + `ContractAddress:` + fmt.Sprintf("%v", this.ContractAddress) + `,`, + `RewardsCheckpoint:` + fmt.Sprintf("%v", this.RewardsCheckpoint) + `,`, + `}`, + }, "") + return s +} +func valueToStringLiquidStaking(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *LiquidStakingAttributes) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LiquidStakingAttributes: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LiquidStakingAttributes: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthLiquidStaking + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthLiquidStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddress = append(m.ContractAddress[:0], dAtA[iNdEx:postIndex]...) + if m.ContractAddress == nil { + m.ContractAddress = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardsCheckpoint", wireType) + } + m.RewardsCheckpoint = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RewardsCheckpoint |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipLiquidStaking(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLiquidStaking + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLiquidStaking + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipLiquidStaking(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLiquidStaking + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLiquidStaking + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLiquidStaking + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthLiquidStaking + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupLiquidStaking + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthLiquidStaking + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthLiquidStaking = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowLiquidStaking = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupLiquidStaking = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vm/systemSmartContracts/proto/liquidStaking.proto b/vm/systemSmartContracts/proto/liquidStaking.proto new file mode 100644 index 00000000000..a0fd3faf587 --- /dev/null +++ b/vm/systemSmartContracts/proto/liquidStaking.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package proto; + +option go_package = "systemSmartContracts"; +option (gogoproto.stable_marshaler_all) = true; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +message LiquidStakingAttributes { + bytes ContractAddress = 1 [(gogoproto.jsontag) = "ContractAddress"]; + uint32 RewardsCheckpoint = 2 [(gogoproto.jsontag) = "RewardsCheckpoint"]; +} \ No newline at end of file From 7fc7b5282f3b3fb97e815d9be90ece7de92ae204 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Mon, 23 Aug 2021 15:56:41 +0300 Subject: [PATCH 006/958] new gas cost and checks for new functions --- .../config/gasSchedules/gasScheduleV1.toml | 1 + .../config/gasSchedules/gasScheduleV2.toml | 1 + .../config/gasSchedules/gasScheduleV3.toml | 1 + epochStart/errors.go | 3 + epochStart/metachain/systemSCs.go | 61 +++++++++++++++--- factory/processComponents_test.go | 1 + .../metachain/vmContainerFactory_test.go | 1 + vm/gasCost.go | 1 + vm/systemSmartContracts/defaults/gasMap.go | 1 + vm/systemSmartContracts/liquidStaking.go | 62 +++++++++++++++++++ 10 files changed, 126 insertions(+), 7 deletions(-) diff --git a/cmd/node/config/gasSchedules/gasScheduleV1.toml b/cmd/node/config/gasSchedules/gasScheduleV1.toml index f0749a1836e..8f1065c8d0d 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV1.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV1.toml @@ -38,6 +38,7 @@ DelegationMgrOps = 50000000 ValidatorToDelegation = 500000000 GetAllNodeStates = 100000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV2.toml b/cmd/node/config/gasSchedules/gasScheduleV2.toml index ca03b7eced9..81188580970 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV2.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV2.toml @@ -36,6 +36,7 @@ RevokeVote = 500000 CloseProposal = 1000000 GetAllNodeStates = 20000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV3.toml b/cmd/node/config/gasSchedules/gasScheduleV3.toml index 406f25e192c..f98f1512db7 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV3.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV3.toml @@ -38,6 +38,7 @@ GetAllNodeStates = 20000000 UnstakeTokens = 5000000 UnbondTokens = 5000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/epochStart/errors.go b/epochStart/errors.go index 9a5bf3aa7c6..1acad10a80f 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -316,3 +316,6 @@ var ErrEmptyESDTOwnerAddress = errors.New("empty ESDT owner address") // ErrNilCurrentNetworkEpochSetter signals that a nil current network epoch setter has been provided var ErrNilCurrentNetworkEpochSetter = errors.New("nil current network epoch setter") + +// ErrCouldNotInitLiquidStakingSystemSC signals that liquid staking system sc init failed +var ErrCouldNotInitLiquidStakingSystemSC = errors.New("could not init liquid staking system sc") diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 0e3aa6afb70..7f41517b644 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -302,7 +302,12 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagBuiltInOnMetaEnabled.IsSet() { - err := s.initTokenOnMeta() + tokenID, err := s.initTokenOnMeta() + if err != nil { + return err + } + + err = s.initLiquidStakingSC(tokenID) if err != nil { return err } @@ -1112,25 +1117,67 @@ func (s *systemSCProcessor) updateToGovernanceV2() error { return nil } -func (s *systemSCProcessor) initTokenOnMeta() error { +func (s *systemSCProcessor) initTokenOnMeta() ([]byte, error) { vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ - CallerAddr: vm.ESDTSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{}, + CallerAddr: vm.ESDTSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{}, + GasProvided: math.MaxUint64, }, RecipientAddr: vm.ESDTSCAddress, Function: "initDelegationESDTOnMeta", } vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) if errRun != nil { - return fmt.Errorf("%w when setting up NFTs on metachain", errRun) + return nil, fmt.Errorf("%w when setting up NFTs on metachain", errRun) } if vmOutput.ReturnCode != vmcommon.Ok { - return fmt.Errorf("got return code %s, return message %s when setting up NFTs on metachain", vmOutput.ReturnCode, vmOutput.ReturnMessage) + return nil, fmt.Errorf("got return code %s, return message %s when setting up NFTs on metachain", vmOutput.ReturnCode, vmOutput.ReturnMessage) + } + if len(vmOutput.ReturnData) != 1 { + return nil, fmt.Errorf("invalid return data on initDelegationESDTOnMeta") } err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return nil, err + } + + return vmOutput.ReturnData[0], nil +} + +func (s *systemSCProcessor) initLiquidStakingSC(tokenID []byte) error { + codeMetaData := &vmcommon.CodeMetadata{ + Upgradeable: false, + Payable: false, + Readable: true, + } + + vmInput := &vmcommon.ContractCreateInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.EndOfEpochAddress, + Arguments: [][]byte{tokenID}, + CallValue: big.NewInt(0), + }, + ContractCode: vm.LiquidStakingSCAddress, + ContractCodeMetadata: codeMetaData.ToBytes(), + } + + vmOutput, err := s.systemVM.RunSmartContractCreate(vmInput) + if err != nil { + return err + } + if vmOutput.ReturnCode != vmcommon.Ok { + return epochStart.ErrCouldNotInitLiquidStakingSystemSC + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + err = s.updateSystemSCContractsCode(vmInput.ContractCodeMetadata) if err != nil { return err } diff --git a/factory/processComponents_test.go b/factory/processComponents_test.go index 6dcfb53447c..296d9e98551 100644 --- a/factory/processComponents_test.go +++ b/factory/processComponents_test.go @@ -230,6 +230,7 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["DelegationMgrOps"] = value gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value + gasMap["LiquidStakingOps"] = value return gasMap } diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 577a863be0c..05ef796c5af 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -421,6 +421,7 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["DelegationMgrOps"] = value gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value + gasMap["LiquidStakingOps"] = value return gasMap } diff --git a/vm/gasCost.go b/vm/gasCost.go index 6da0c558de1..c50dc941d3c 100644 --- a/vm/gasCost.go +++ b/vm/gasCost.go @@ -34,6 +34,7 @@ type MetaChainSystemSCsCost struct { DelegationMgrOps uint64 ValidatorToDelegation uint64 GetAllNodeStates uint64 + LiquidStakingOps uint64 } // BuiltInCost defines cost for built-in methods diff --git a/vm/systemSmartContracts/defaults/gasMap.go b/vm/systemSmartContracts/defaults/gasMap.go index a4cc96460c8..6fbfe728d0c 100644 --- a/vm/systemSmartContracts/defaults/gasMap.go +++ b/vm/systemSmartContracts/defaults/gasMap.go @@ -73,6 +73,7 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["DelegationMgrOps"] = value gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value + gasMap["LiquidStakingOps"] = value return gasMap } diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index f66bbde69de..d9d1a691a1d 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -2,6 +2,7 @@ package systemSmartContracts import ( + "bytes" "fmt" "sync" @@ -15,10 +16,14 @@ import ( vmcommon "github.com/ElrondNetwork/elrond-vm-common" ) +const tokenIDKey = "tokenID" +const noncePrefix = "n" + type liquidStaking struct { eei vm.SystemEI sigVerifier vm.MessageSignVerifier delegationMgrSCAddress []byte + liquidStakingSCAddress []byte endOfEpochAddr []byte gasCost vm.GasCost marshalizer marshal.Marshalizer @@ -33,6 +38,7 @@ type ArgsNewLiquidStaking struct { EpochConfig config.EpochConfig Eei vm.SystemEI DelegationMgrSCAddress []byte + LiquidStakingSCAddress []byte EndOfEpochAddress []byte GasCost vm.GasCost Marshalizer marshal.Marshalizer @@ -51,6 +57,9 @@ func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) if len(args.EndOfEpochAddress) < 1 { return nil, fmt.Errorf("%w for end of epoch address", vm.ErrInvalidAddress) } + if len(args.LiquidStakingSCAddress) < 1 { + return nil, fmt.Errorf("%w for liquid staking sc address", vm.ErrInvalidAddress) + } if check.IfNil(args.Marshalizer) { return nil, vm.ErrNilMarshalizer } @@ -65,6 +74,7 @@ func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) eei: args.Eei, delegationMgrSCAddress: args.DelegationMgrSCAddress, endOfEpochAddr: args.EndOfEpochAddress, + liquidStakingSCAddress: args.LiquidStakingSCAddress, gasCost: args.GasCost, marshalizer: args.Marshalizer, hasher: args.Hasher, @@ -112,10 +122,62 @@ func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.Retur } func (l *liquidStaking) init(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if bytes.Equal(args.CallerAddr, l.endOfEpochAddr) { + l.eei.AddReturnMessage("invalid caller") + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + l.eei.AddReturnMessage("not a payable function") + return vmcommon.UserError + } + if len(args.Arguments) != 1 { + l.eei.AddReturnMessage("invalid number of arguments") + return vmcommon.UserError + } + tokenID := args.Arguments[0] + l.eei.SetStorage([]byte(tokenIDKey), tokenID) + + return vmcommon.Ok +} + +func (l *liquidStaking) getTokenID() []byte { + return l.eei.GetStorage([]byte(tokenIDKey)) +} + +func (l *liquidStaking) checkArgumentsWhenPositionIsInput(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if len(args.ESDTTransfers) < 1 { + l.eei.AddReturnMessage("function requires liquid staking input") + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + l.eei.AddReturnMessage("function is not payable in eGLD") + return vmcommon.UserError + } + for _, esdtTransfer := range args.ESDTTransfers { + if !bytes.Equal(esdtTransfer.ESDTTokenName, l.getTokenID()) { + l.eei.AddReturnMessage("wrong liquid staking position as input") + return vmcommon.UserError + } + } + err := l.eei.UseGas(uint64(len(args.ESDTTransfers)) * l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.OutOfGas + } + return vmcommon.Ok } func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if args.CallValue.Cmp(zero) != 0 { + l.eei.AddReturnMessage("function is not payable in eGLD") + return vmcommon.UserError + } + if len(args.Arguments) == 0 { + l.eei.AddReturnMessage("not enough arguments") + return vmcommon.UserError + } + return vmcommon.Ok } From 02ea72bcaabaec95459edb64833e166ac0a5d2b6 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Mon, 23 Aug 2021 18:24:16 +0300 Subject: [PATCH 007/958] simplify interface --- process/smartContract/process.go | 3 +- vm/interface.go | 2 +- vm/mock/systemEIStub.go | 8 +- vm/systemSmartContracts/delegation.go | 181 +++++++-- vm/systemSmartContracts/delegation.pb.go | 403 ++++----------------- vm/systemSmartContracts/eei.go | 20 +- vm/systemSmartContracts/eei_test.go | 4 +- vm/systemSmartContracts/esdt.go | 79 +--- vm/systemSmartContracts/esdt_test.go | 50 +-- vm/systemSmartContracts/governance.go | 7 +- vm/systemSmartContracts/governance_test.go | 4 +- vm/systemSmartContracts/liquidStaking.go | 23 ++ vm/systemSmartContracts/validator.go | 31 +- 13 files changed, 299 insertions(+), 516 deletions(-) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index 53bde52e923..eb9d1720c13 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -2358,7 +2358,8 @@ func (sc *scProcessor) processSimpleSCR( if err != nil { return err } - if !isPayable && !bytes.Equal(scResult.RcvAddr, scResult.OriginalSender) { + isSenderMeta := sc.shardCoordinator.ComputeId(scResult.SndAddr) == core.MetachainShardId + if !isPayable && !bytes.Equal(scResult.RcvAddr, scResult.OriginalSender) && !isSenderMeta { return process.ErrAccountNotPayable } diff --git a/vm/interface.go b/vm/interface.go index 039312229fa..b6833ca74ae 100644 --- a/vm/interface.go +++ b/vm/interface.go @@ -37,7 +37,7 @@ type SystemSCContainer interface { type SystemEI interface { ExecuteOnDestContext(destination []byte, sender []byte, value *big.Int, input []byte) (*vmcommon.VMOutput, error) DeploySystemSC(baseContract []byte, newAddress []byte, ownerAddress []byte, initFunction string, value *big.Int, input [][]byte) (vmcommon.ReturnCode, error) - Transfer(destination []byte, sender []byte, value *big.Int, input []byte, gasLimit uint64) error + Transfer(destination []byte, sender []byte, value *big.Int, input []byte, gasLimit uint64) SendGlobalSettingToAll(sender []byte, input []byte) GetBalance(addr []byte) *big.Int SetStorage(key []byte, value []byte) diff --git a/vm/mock/systemEIStub.go b/vm/mock/systemEIStub.go index 96003b63119..eb02ea854c0 100644 --- a/vm/mock/systemEIStub.go +++ b/vm/mock/systemEIStub.go @@ -10,7 +10,7 @@ import ( // SystemEIStub - type SystemEIStub struct { - TransferCalled func(destination []byte, sender []byte, value *big.Int, input []byte) error + TransferCalled func(destination []byte, sender []byte, value *big.Int, input []byte, gasLimit uint64) GetBalanceCalled func(addr []byte) *big.Int SetStorageCalled func(key []byte, value []byte) AddReturnMessageCalled func(msg string) @@ -184,11 +184,11 @@ func (s *SystemEIStub) SendGlobalSettingToAll(sender []byte, input []byte) { } // Transfer - -func (s *SystemEIStub) Transfer(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) error { +func (s *SystemEIStub) Transfer(destination []byte, sender []byte, value *big.Int, input []byte, gasLimit uint64) { if s.TransferCalled != nil { - return s.TransferCalled(destination, sender, value, input) + s.TransferCalled(destination, sender, value, input, gasLimit) } - return nil + return } // GetBalance - diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 40cc0a9dead..a347dace51d 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -272,6 +272,16 @@ func (d *delegation) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return d.setMetaData(args) case "getMetaData": return d.getMetaData(args) + case "claimDelegatedPosition": + return d.claimDelegatedPosition(args) + case "claimRewardsViaLiquidStaking": + return d.claimRewardsViaLiquidStaking(args) + case "reDelegateRewardsViaLiquidStaking": + return d.reDelegateRewardsViaLiquidStaking(args) + case "unDelegateViaLiquidStaking": + return d.unDelegateViaLiquidStaking(args) + case "returnViaLiquidStaking": + return d.returnViaLiquidStaking(args) } d.eei.AddReturnMessage(args.Function + " is an unknown function") @@ -1283,11 +1293,7 @@ func (d *delegation) unJailNodes(args *vmcommon.ContractCallInput) vmcommon.Retu sendBackValue := getTransferBackFromVMOutput(vmOutput) if sendBackValue.Cmp(zero) > 0 { - err = d.eei.Transfer(args.CallerAddr, args.RecipientAddr, sendBackValue, nil, 0) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + d.eei.Transfer(args.CallerAddr, args.RecipientAddr, sendBackValue, nil, 0) } return vmcommon.Ok @@ -1818,12 +1824,30 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De isOwner := d.isOwner(callerAddress) + totalRewards, err := d.computeRewards(delegator.RewardsCheckpoint, isOwner, activeFund.Value) + + delegator.UnClaimedRewards.Add(delegator.UnClaimedRewards, totalRewards) + currentEpoch := d.eei.BlockChainHook().CurrentEpoch() + delegator.RewardsCheckpoint = currentEpoch + 1 + + return nil +} + +func (d *delegation) computeRewards( + rewardsCheckpoint uint32, + isOwner bool, + activeValue *big.Int, +) (*big.Int, error) { totalRewards := big.NewInt(0) + if activeValue.Cmp(zero) <= 0 { + return totalRewards, nil + } + currentEpoch := d.eei.BlockChainHook().CurrentEpoch() - for i := delegator.RewardsCheckpoint; i <= currentEpoch; i++ { + for i := rewardsCheckpoint; i <= currentEpoch; i++ { found, rewardData, errGet := d.getRewardComputationData(i) if errGet != nil { - return errGet + return nil, errGet } if !found { continue @@ -1847,7 +1871,7 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De rewardForDelegator := big.NewInt(0).Sub(rewardData.RewardsToDistribute, rewardsForOwner) // delegator reward is: rewardForDelegator * user stake / total active - rewardForDelegator.Mul(rewardForDelegator, activeFund.Value) + rewardForDelegator.Mul(rewardForDelegator, activeValue) rewardForDelegator.Div(rewardForDelegator, rewardData.TotalActive) if isOwner { @@ -1856,10 +1880,7 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De totalRewards.Add(totalRewards, rewardForDelegator) } - delegator.UnClaimedRewards.Add(delegator.UnClaimedRewards, totalRewards) - delegator.RewardsCheckpoint = currentEpoch + 1 - - return nil + return totalRewards, nil } func (d *delegation) claimRewards(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { @@ -1889,11 +1910,7 @@ func (d *delegation) claimRewards(args *vmcommon.ContractCallInput) vmcommon.Ret return vmcommon.UserError } - err = d.eei.Transfer(args.CallerAddr, args.RecipientAddr, delegator.UnClaimedRewards, nil, 0) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + d.eei.Transfer(args.CallerAddr, args.RecipientAddr, delegator.UnClaimedRewards, nil, 0) delegator.TotalCumulatedRewards.Add(delegator.TotalCumulatedRewards, delegator.UnClaimedRewards) delegator.UnClaimedRewards.SetUint64(0) @@ -2043,11 +2060,7 @@ func (d *delegation) withdraw(args *vmcommon.ContractCallInput) vmcommon.ReturnC return vmcommon.UserError } - err = d.eei.Transfer(args.CallerAddr, args.RecipientAddr, actualUserUnBond, nil, 0) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + d.eei.Transfer(args.CallerAddr, args.RecipientAddr, actualUserUnBond, nil, 0) err = d.deleteDelegatorIfNeeded(args.CallerAddr, delegator) if err != nil { @@ -2602,6 +2615,129 @@ func (d *delegation) getMetaData(args *vmcommon.ContractCallInput) vmcommon.Retu return vmcommon.Ok } +func (d *delegation) basicCheckForLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !d.flagLiquidStaking.IsSet() { + d.eei.AddReturnMessage(args.Function + " is an unknown function") + return vmcommon.UserError + } + if !bytes.Equal(args.CallerAddr, vm.LiquidStakingSCAddress) { + d.eei.AddReturnMessage("only liquid staking sc can call this function") + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + d.eei.AddReturnMessage("call value must be 0") + return vmcommon.UserError + } + if len(args.Arguments) < 2 { + d.eei.AddReturnMessage("not enough arguments") + return vmcommon.UserError + } + err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + address := args.Arguments[0] + value := big.NewInt(0).SetBytes(args.Arguments[1]) + if value.Cmp(zero) <= 0 { + d.eei.AddReturnMessage("invalid argument for value as bigInt") + return vmcommon.UserError + } + if len(address) != len(d.validatorSCAddr) { + d.eei.AddReturnMessage("invalid address as input") + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := d.basicCheckForLiquidStaking(args) + if returnCode != vmcommon.Ok { + return returnCode + } + + address := args.Arguments[0] + value := big.NewInt(0).SetBytes(args.Arguments[1]) + + isNew, delegator, err := d.getOrCreateDelegatorData(address) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if isNew { + d.eei.AddReturnMessage("caller is not a delegator") + return vmcommon.UserError + } + + activeFund, err := d.getFund(delegator.ActiveFund) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if value.Cmp(activeFund.Value) > 0 { + d.eei.AddReturnMessage("not enough funds to claim position") + return vmcommon.UserError + } + + activeFund.Value.Sub(activeFund.Value, value) + err = d.saveFund(delegator.ActiveFund, activeFund) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + err = d.deleteDelegatorIfNeeded(args.CallerAddr, delegator) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + d.eei.Finish(big.NewInt(int64(delegator.RewardsCheckpoint)).Bytes()) + return vmcommon.Ok +} + +func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := d.basicCheckForLiquidStaking(args) + if returnCode != vmcommon.Ok { + return returnCode + } + + if len(args.Arguments) != 3 { + d.eei.AddReturnMessage("not enough arguments") + return vmcommon.UserError + } + + address := args.Arguments[0] + value := big.NewInt(0).SetBytes(args.Arguments[1]) + checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) + + totalRewards, err := d.computeRewards(checkPoint, false, value) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + d.eei.Transfer(args.CallerAddr, address, totalRewards, nil, 0) + + return vmcommon.Ok +} + +func (d *delegation) reDelegateRewardsViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + + return vmcommon.Ok +} + +func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + + return vmcommon.Ok +} + +func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + + return vmcommon.Ok +} + func (d *delegation) executeOnValidatorSC(address []byte, function string, args [][]byte, value *big.Int) (*vmcommon.VMOutput, error) { validatorCall := function for _, key := range args { @@ -2614,7 +2750,6 @@ func (d *delegation) executeOnValidatorSC(address []byte, function string, args } return vmOutput, nil - } func (d *delegation) getDelegationContractConfig() (*DelegationConfig, error) { diff --git a/vm/systemSmartContracts/delegation.pb.go b/vm/systemSmartContracts/delegation.pb.go index 9d7e546ddf4..b79f3c4bac9 100644 --- a/vm/systemSmartContracts/delegation.pb.go +++ b/vm/systemSmartContracts/delegation.pb.go @@ -634,53 +634,6 @@ func (m *RewardComputationData) GetServiceFee() uint64 { return 0 } -type LiquidStakingAttributes struct { - ContractAddress []byte `protobuf:"bytes,1,opt,name=ContractAddress,proto3" json:"ContractAddress"` - RewardsCheckpoint uint32 `protobuf:"varint,2,opt,name=RewardsCheckpoint,proto3" json:"RewardsCheckpoint"` -} - -func (m *LiquidStakingAttributes) Reset() { *m = LiquidStakingAttributes{} } -func (*LiquidStakingAttributes) ProtoMessage() {} -func (*LiquidStakingAttributes) Descriptor() ([]byte, []int) { - return fileDescriptor_b823c7d67e95582e, []int{10} -} -func (m *LiquidStakingAttributes) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *LiquidStakingAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *LiquidStakingAttributes) XXX_Merge(src proto.Message) { - xxx_messageInfo_LiquidStakingAttributes.Merge(m, src) -} -func (m *LiquidStakingAttributes) XXX_Size() int { - return m.Size() -} -func (m *LiquidStakingAttributes) XXX_DiscardUnknown() { - xxx_messageInfo_LiquidStakingAttributes.DiscardUnknown(m) -} - -var xxx_messageInfo_LiquidStakingAttributes proto.InternalMessageInfo - -func (m *LiquidStakingAttributes) GetContractAddress() []byte { - if m != nil { - return m.ContractAddress - } - return nil -} - -func (m *LiquidStakingAttributes) GetRewardsCheckpoint() uint32 { - if m != nil { - return m.RewardsCheckpoint - } - return 0 -} - func init() { proto.RegisterType((*DelegationManagement)(nil), "proto.DelegationManagement") proto.RegisterType((*DelegationContractList)(nil), "proto.DelegationContractList") @@ -692,88 +645,84 @@ func init() { proto.RegisterType((*GlobalFundData)(nil), "proto.GlobalFundData") proto.RegisterType((*NodesData)(nil), "proto.NodesData") proto.RegisterType((*RewardComputationData)(nil), "proto.RewardComputationData") - proto.RegisterType((*LiquidStakingAttributes)(nil), "proto.LiquidStakingAttributes") } func init() { proto.RegisterFile("delegation.proto", fileDescriptor_b823c7d67e95582e) } var fileDescriptor_b823c7d67e95582e = []byte{ - // 1192 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6b, 0xe3, 0xc6, - 0x17, 0xb7, 0x1c, 0x67, 0x37, 0xfb, 0x62, 0xef, 0x66, 0x67, 0x77, 0xbf, 0x6b, 0xbe, 0x2d, 0xd2, - 0x22, 0x28, 0x04, 0xca, 0x3a, 0xf4, 0x07, 0x14, 0x5a, 0x0a, 0x8d, 0x9c, 0x4d, 0x31, 0x9b, 0x78, - 0xcb, 0x78, 0xd3, 0xdf, 0xb4, 0x8c, 0xad, 0x89, 0x32, 0xc4, 0x9a, 0x71, 0xa5, 0xd1, 0x26, 0xa1, - 0x97, 0xf6, 0x54, 0x5a, 0x28, 0xb4, 0xf4, 0xb4, 0x87, 0xde, 0x4b, 0x2f, 0xfd, 0x37, 0x7a, 0xcc, - 0xad, 0xa1, 0x07, 0xb5, 0x71, 0xa0, 0x14, 0x9d, 0xf6, 0x4f, 0x28, 0x1a, 0x49, 0xb6, 0x64, 0x6b, - 0x17, 0x0a, 0xa6, 0x17, 0xeb, 0xbd, 0xcf, 0x1b, 0x3d, 0xbd, 0x99, 0xf7, 0xde, 0x67, 0x9e, 0x61, - 0xcd, 0xa6, 0x43, 0xea, 0x10, 0xc9, 0x04, 0x6f, 0x8d, 0x3c, 0x21, 0x05, 0x5a, 0x56, 0x8f, 0xff, - 0xdf, 0x75, 0x98, 0x3c, 0x08, 0xfa, 0xad, 0x81, 0x70, 0x37, 0x1c, 0xe1, 0x88, 0x0d, 0x05, 0xf7, - 0x83, 0x7d, 0xa5, 0x29, 0x45, 0x49, 0xc9, 0x5b, 0xe6, 0x57, 0x35, 0xb8, 0xb9, 0x35, 0x71, 0xb5, - 0x4b, 0x38, 0x71, 0xa8, 0x4b, 0xb9, 0x44, 0xaf, 0xc3, 0xd5, 0x6e, 0xe0, 0x3e, 0xd8, 0x6f, 0x0b, - 0x2e, 0x3d, 0x32, 0x90, 0x7e, 0x53, 0xbb, 0xa3, 0xad, 0x37, 0x2c, 0x14, 0x85, 0xc6, 0x8c, 0x05, - 0xcf, 0xe8, 0xe8, 0x25, 0x58, 0xdd, 0x21, 0xbe, 0xdc, 0xb4, 0x6d, 0x8f, 0xfa, 0x7e, 0xb3, 0x7a, - 0x47, 0x5b, 0xaf, 0x5b, 0xd7, 0xa2, 0xd0, 0xc8, 0xc3, 0x38, 0xaf, 0xa0, 0xd7, 0xa0, 0xb1, 0xcb, - 0x78, 0x8f, 0x7a, 0x8f, 0xd8, 0x80, 0x6e, 0x53, 0xda, 0x5c, 0xba, 0xa3, 0xad, 0xd7, 0xac, 0xeb, - 0x51, 0x68, 0x14, 0x0d, 0xb8, 0xa8, 0xaa, 0x17, 0xc9, 0x71, 0xee, 0xc5, 0x5a, 0xee, 0xc5, 0xbc, - 0x01, 0x17, 0x55, 0x74, 0x0c, 0xb0, 0xcb, 0xf8, 0x16, 0x1d, 0x09, 0x9f, 0xc9, 0xe6, 0xb2, 0x8a, - 0xf1, 0xfd, 0x28, 0x34, 0x72, 0xe8, 0xcf, 0x7f, 0x18, 0xdb, 0x2e, 0x91, 0x07, 0x1b, 0x7d, 0xe6, - 0xb4, 0x3a, 0x5c, 0xbe, 0x91, 0x3b, 0xdb, 0x7b, 0x43, 0x4f, 0x70, 0xbb, 0x4b, 0xe5, 0x91, 0xf0, - 0x0e, 0x37, 0xa8, 0xd2, 0xee, 0x3a, 0xe2, 0xee, 0x40, 0x78, 0x74, 0xc3, 0x26, 0x92, 0xb4, 0x2c, - 0xe6, 0x74, 0xb8, 0x6c, 0x13, 0x5f, 0x52, 0x0f, 0xe7, 0xbc, 0xa2, 0x1f, 0x34, 0xb8, 0xa1, 0xd4, - 0xec, 0xd8, 0x37, 0x5d, 0x11, 0x70, 0xd9, 0xbc, 0xa4, 0x62, 0x20, 0x51, 0x68, 0x94, 0x99, 0x17, - 0x18, 0x4c, 0x99, 0x7b, 0xf3, 0x1e, 0xfc, 0x6f, 0x8a, 0x65, 0xb9, 0xdc, 0x61, 0xbe, 0x44, 0x2f, - 0xc2, 0x95, 0x34, 0x4d, 0x34, 0xae, 0x82, 0xa5, 0xf5, 0xba, 0xd5, 0x88, 0x42, 0x63, 0x0a, 0xe2, - 0xa9, 0x68, 0xfe, 0xb2, 0x0c, 0x6b, 0x05, 0x3f, 0xfb, 0xcc, 0x41, 0xdf, 0x68, 0xb0, 0xb6, 0x4b, - 0x8e, 0x73, 0x38, 0x19, 0xa9, 0x7a, 0xaa, 0x5b, 0x9f, 0x44, 0xa1, 0x31, 0x67, 0x5b, 0xe0, 0x5e, - 0xe7, 0x7c, 0xa3, 0x6f, 0x35, 0xb8, 0xde, 0xe1, 0x4c, 0x32, 0x32, 0x7c, 0x70, 0xc4, 0xa9, 0xb7, - 0x1d, 0x70, 0x3b, 0x2b, 0xd2, 0x4f, 0xa3, 0xd0, 0x98, 0x37, 0x2e, 0x30, 0x9c, 0x79, 0xe7, 0xa8, - 0x03, 0x37, 0x36, 0x03, 0x29, 0x5c, 0x22, 0xd9, 0x60, 0x73, 0x20, 0xd9, 0x23, 0x15, 0xa9, 0x6a, - 0x80, 0x15, 0xeb, 0x76, 0x5c, 0x0d, 0x25, 0x66, 0x5c, 0x06, 0xa2, 0x1d, 0xb8, 0xd9, 0x3e, 0x20, - 0xdc, 0xa1, 0xa4, 0x3f, 0xa4, 0x33, 0x3d, 0xb1, 0x62, 0x35, 0xa3, 0xd0, 0x28, 0xb5, 0xe3, 0x52, - 0x14, 0xbd, 0x0a, 0xf5, 0xb6, 0x47, 0x89, 0xa4, 0x76, 0x57, 0xf0, 0x01, 0x55, 0x3d, 0x52, 0xb3, - 0xd6, 0xa2, 0xd0, 0x28, 0xe0, 0xb8, 0xa0, 0xc5, 0x31, 0xec, 0x71, 0x4b, 0x70, 0xfb, 0x1d, 0xea, - 0x31, 0x61, 0x77, 0xf8, 0xbd, 0x91, 0x18, 0x1c, 0xf8, 0xaa, 0xba, 0x1b, 0x49, 0x0c, 0x65, 0x76, - 0x5c, 0x8a, 0x22, 0x02, 0xcf, 0xb5, 0x0f, 0xe8, 0xe0, 0xb0, 0x4d, 0x46, 0x0f, 0x38, 0xa6, 0x69, - 0x26, 0x29, 0xa6, 0x47, 0xc4, 0xb3, 0xfd, 0xe6, 0x65, 0xb5, 0x31, 0x23, 0x0a, 0x8d, 0x67, 0x2d, - 0xc3, 0xcf, 0x32, 0x9a, 0x5f, 0x6b, 0x80, 0x72, 0x14, 0x48, 0x25, 0xd9, 0x22, 0x92, 0xa0, 0xe7, - 0xa1, 0xd6, 0x25, 0x2e, 0x4d, 0xcb, 0x74, 0x25, 0x0a, 0x0d, 0xa5, 0x63, 0xf5, 0x8b, 0x5e, 0x80, - 0xcb, 0xef, 0xd1, 0xbe, 0xcf, 0x24, 0x4d, 0x2b, 0x67, 0x35, 0x0a, 0x8d, 0x0c, 0xc2, 0x99, 0x80, - 0x5a, 0x00, 0x1d, 0x9b, 0x72, 0xc9, 0xf6, 0x19, 0xf5, 0x54, 0x4a, 0xeb, 0xd6, 0xd5, 0x98, 0x64, - 0xa6, 0x28, 0xce, 0xc9, 0xe6, 0xe3, 0x2a, 0x34, 0xe7, 0xbb, 0xb0, 0x27, 0x89, 0x0c, 0x7c, 0xf4, - 0x16, 0x40, 0x4f, 0x92, 0x43, 0x6a, 0xdf, 0xa7, 0x27, 0x49, 0x23, 0xae, 0xbe, 0xbc, 0x96, 0xf0, - 0x78, 0xab, 0x2b, 0x6c, 0xea, 0xc7, 0x71, 0x27, 0xee, 0xa7, 0xeb, 0x70, 0x4e, 0x46, 0x1d, 0x68, - 0x74, 0x85, 0xcc, 0x39, 0xa9, 0x3e, 0xc5, 0x89, 0xa2, 0xcf, 0xc2, 0x52, 0x5c, 0x54, 0xd1, 0x36, - 0xd4, 0xf7, 0x78, 0xce, 0xd3, 0xd2, 0x53, 0x3c, 0xa9, 0x72, 0xc9, 0xaf, 0xc4, 0x05, 0x0d, 0xad, - 0xc3, 0x4a, 0x37, 0x70, 0xf7, 0x7c, 0xea, 0xf9, 0x29, 0x75, 0xd7, 0xa3, 0xd0, 0x98, 0x60, 0x78, - 0x22, 0x99, 0xbf, 0x69, 0x50, 0x8b, 0x3b, 0x06, 0x31, 0x58, 0x7e, 0x97, 0x0c, 0x83, 0x2c, 0x35, - 0xbd, 0x28, 0x34, 0x12, 0x60, 0x81, 0x7d, 0x9a, 0x38, 0x8c, 0xd3, 0x5c, 0xbc, 0xc5, 0x54, 0x9a, - 0xb3, 0x1b, 0x2c, 0x13, 0x90, 0x01, 0xcb, 0xaa, 0x5e, 0x55, 0x86, 0x1b, 0xd6, 0x95, 0x38, 0x22, - 0x05, 0xe0, 0xe4, 0x11, 0x17, 0xd3, 0xc3, 0x93, 0x51, 0xd2, 0x88, 0x8d, 0xa4, 0x98, 0x62, 0x1d, - 0xab, 0x5f, 0xf3, 0xaf, 0x25, 0x68, 0xa4, 0x59, 0x17, 0x9e, 0x2a, 0xbe, 0x16, 0x80, 0x6a, 0x6b, - 0x1a, 0x6f, 0x38, 0xdd, 0xa7, 0x4a, 0xec, 0x14, 0xc5, 0x39, 0x39, 0xbe, 0x05, 0xb3, 0x53, 0xcd, - 0xe8, 0x2c, 0xa6, 0x69, 0x95, 0xc6, 0x82, 0x01, 0x17, 0x55, 0xd4, 0x86, 0xeb, 0x69, 0x1f, 0xa8, - 0x16, 0x19, 0x09, 0xc6, 0x65, 0xba, 0x8b, 0x5b, 0x31, 0x17, 0xce, 0x19, 0xf1, 0x3c, 0xa4, 0xe8, - 0x7d, 0x8f, 0xb7, 0x87, 0x84, 0xb9, 0xd4, 0xce, 0x5a, 0xb3, 0x36, 0xa5, 0xf7, 0x59, 0xdb, 0x22, - 0xe9, 0x7d, 0xd6, 0x37, 0x7a, 0xac, 0xc1, 0xad, 0x87, 0x42, 0x92, 0x61, 0x3b, 0x70, 0x83, 0x61, - 0xcc, 0x4b, 0x59, 0x44, 0xc9, 0x1d, 0x3f, 0x88, 0x42, 0xa3, 0x7c, 0xc1, 0x02, 0xc3, 0x2a, 0xff, - 0x80, 0xf9, 0x7d, 0x15, 0xae, 0xbe, 0x3d, 0x14, 0x7d, 0x32, 0x8c, 0x4f, 0x5f, 0x65, 0xfa, 0x73, - 0x58, 0x55, 0x6b, 0x93, 0x64, 0xa6, 0xa9, 0xfe, 0x20, 0x9e, 0x95, 0x72, 0xf0, 0x02, 0x23, 0xcb, - 0xbb, 0x45, 0x5f, 0x6a, 0xd0, 0x50, 0x7a, 0x56, 0x14, 0x69, 0x95, 0x7f, 0x14, 0xd7, 0x4d, 0xc1, - 0xb0, 0xc0, 0x08, 0x8a, 0x8e, 0xcd, 0x8f, 0xe1, 0xca, 0x84, 0x2d, 0x90, 0x09, 0x97, 0xac, 0x9d, - 0xde, 0x7d, 0x7a, 0x92, 0x1e, 0x04, 0x44, 0xa1, 0x91, 0x22, 0x38, 0x7d, 0xc6, 0xe3, 0x48, 0x8f, - 0x39, 0x9c, 0xda, 0xbb, 0xbe, 0x93, 0xc6, 0xab, 0xc6, 0x91, 0x09, 0x88, 0xa7, 0xa2, 0xf9, 0x7b, - 0x15, 0x6e, 0x25, 0xa7, 0xdf, 0x16, 0xee, 0x28, 0x90, 0x8a, 0x57, 0xd5, 0xa7, 0xe2, 0x29, 0x2c, - 0xcd, 0xcb, 0x43, 0xb1, 0xc5, 0x7c, 0xe9, 0xb1, 0x7e, 0x20, 0xb3, 0x0c, 0xa8, 0x29, 0xac, 0xc4, - 0xbc, 0xc8, 0x29, 0xac, 0xc4, 0xfd, 0x6c, 0x39, 0x54, 0xff, 0xd3, 0x72, 0x68, 0x01, 0xcc, 0x4d, - 0xe0, 0xc9, 0x75, 0x32, 0x1d, 0x15, 0x72, 0xb2, 0xf9, 0xa3, 0x06, 0xb7, 0x77, 0xd8, 0x67, 0x01, - 0xb3, 0xe3, 0x5c, 0x32, 0xee, 0x6c, 0xca, 0x74, 0x1f, 0x3e, 0x7a, 0x13, 0xae, 0x65, 0xd7, 0x57, - 0xc6, 0xa0, 0xc9, 0xc9, 0xde, 0x88, 0x42, 0x63, 0xd6, 0x84, 0x67, 0x81, 0x72, 0x5e, 0xaa, 0xfe, - 0x3b, 0x5e, 0xb2, 0xba, 0xa7, 0xe7, 0x7a, 0xe5, 0xec, 0x5c, 0xaf, 0x3c, 0x39, 0xd7, 0xb5, 0x2f, - 0xc6, 0xba, 0xf6, 0xd3, 0x58, 0xd7, 0x7e, 0x1d, 0xeb, 0xda, 0xe9, 0x58, 0xd7, 0xce, 0xc6, 0xba, - 0xf6, 0xe7, 0x58, 0xd7, 0xfe, 0x1e, 0xeb, 0x95, 0x27, 0x63, 0x5d, 0xfb, 0xee, 0x42, 0xaf, 0x9c, - 0x5e, 0xe8, 0x95, 0xb3, 0x0b, 0xbd, 0xf2, 0xe1, 0x4d, 0xff, 0xc4, 0x97, 0xd4, 0xed, 0xb9, 0xc4, - 0x93, 0x93, 0xff, 0x35, 0xfd, 0x4b, 0xea, 0x72, 0x7b, 0xe5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x06, 0x92, 0xd0, 0x46, 0x7d, 0x0d, 0x00, 0x00, + // 1145 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0xe3, 0xc4, + 0x17, 0x8f, 0xd3, 0x74, 0xb7, 0xfb, 0x9a, 0xec, 0xb7, 0x3b, 0xdb, 0x7e, 0x89, 0x00, 0xd9, 0x55, + 0x24, 0xa4, 0x4a, 0xa8, 0xa9, 0xf8, 0x21, 0x21, 0xc1, 0x85, 0x3a, 0x6d, 0x51, 0xb4, 0x6d, 0x8a, + 0x26, 0x2d, 0xbf, 0x05, 0x9a, 0xc4, 0x53, 0x77, 0xd4, 0x78, 0x26, 0xb2, 0xc7, 0xdb, 0x56, 0x5c, + 0xe0, 0x84, 0x40, 0x42, 0x02, 0x71, 0xda, 0xff, 0x00, 0x71, 0xe1, 0xdf, 0xe0, 0xd8, 0x1b, 0x15, + 0x07, 0x43, 0x53, 0x09, 0x21, 0x9f, 0xf6, 0x4f, 0x40, 0x1e, 0xdb, 0x89, 0x9d, 0x78, 0xf7, 0x14, + 0x71, 0x89, 0xdf, 0xfb, 0xbc, 0xf1, 0xf3, 0x9b, 0x79, 0x9f, 0xf7, 0xe6, 0x05, 0x56, 0x2c, 0x3a, + 0xa0, 0x36, 0x91, 0x4c, 0xf0, 0xe6, 0xd0, 0x15, 0x52, 0xa0, 0x45, 0xf5, 0x78, 0x71, 0xd3, 0x66, + 0xf2, 0xd4, 0xef, 0x35, 0xfb, 0xc2, 0xd9, 0xb2, 0x85, 0x2d, 0xb6, 0x14, 0xdc, 0xf3, 0x4f, 0x94, + 0xa6, 0x14, 0x25, 0xc5, 0x6f, 0x35, 0xbe, 0xa9, 0xc0, 0xea, 0xce, 0xd8, 0xd5, 0x01, 0xe1, 0xc4, + 0xa6, 0x0e, 0xe5, 0x12, 0xbd, 0x0d, 0xf7, 0x3b, 0xbe, 0x73, 0x78, 0xd2, 0x12, 0x5c, 0xba, 0xa4, + 0x2f, 0xbd, 0xba, 0xb6, 0xae, 0x6d, 0xd4, 0x4c, 0x14, 0x06, 0xc6, 0x94, 0x05, 0x4f, 0xe9, 0xe8, + 0x35, 0x58, 0xde, 0x27, 0x9e, 0xdc, 0xb6, 0x2c, 0x97, 0x7a, 0x5e, 0xbd, 0xbc, 0xae, 0x6d, 0x54, + 0xcd, 0xff, 0x85, 0x81, 0x91, 0x85, 0x71, 0x56, 0x41, 0x6f, 0x41, 0xed, 0x80, 0xf1, 0x2e, 0x75, + 0x1f, 0xb3, 0x3e, 0xdd, 0xa3, 0xb4, 0xbe, 0xb0, 0xae, 0x6d, 0x54, 0xcc, 0x07, 0x61, 0x60, 0xe4, + 0x0d, 0x38, 0xaf, 0xaa, 0x17, 0xc9, 0x45, 0xe6, 0xc5, 0x4a, 0xe6, 0xc5, 0xac, 0x01, 0xe7, 0x55, + 0x74, 0x01, 0x70, 0xc0, 0xf8, 0x0e, 0x1d, 0x0a, 0x8f, 0xc9, 0xfa, 0xa2, 0x8a, 0xf1, 0xa3, 0x30, + 0x30, 0x32, 0xe8, 0x2f, 0x7f, 0x1a, 0x7b, 0x0e, 0x91, 0xa7, 0x5b, 0x3d, 0x66, 0x37, 0xdb, 0x5c, + 0xbe, 0x93, 0x39, 0xdb, 0xdd, 0x81, 0x2b, 0xb8, 0xd5, 0xa1, 0xf2, 0x5c, 0xb8, 0x67, 0x5b, 0x54, + 0x69, 0x9b, 0xb6, 0xd8, 0xec, 0x0b, 0x97, 0x6e, 0x59, 0x44, 0x92, 0xa6, 0xc9, 0xec, 0x36, 0x97, + 0x2d, 0xe2, 0x49, 0xea, 0xe2, 0x8c, 0x57, 0xf4, 0x93, 0x06, 0x0f, 0x95, 0x9a, 0x1e, 0xfb, 0xb6, + 0x23, 0x7c, 0x2e, 0xeb, 0x77, 0x54, 0x0c, 0x24, 0x0c, 0x8c, 0x22, 0xf3, 0x1c, 0x83, 0x29, 0x72, + 0xdf, 0xd8, 0x85, 0xff, 0x4f, 0xb0, 0x34, 0x97, 0xfb, 0xcc, 0x93, 0xe8, 0x55, 0xb8, 0x97, 0xa4, + 0x89, 0x46, 0x2c, 0x58, 0xd8, 0xa8, 0x9a, 0xb5, 0x30, 0x30, 0x26, 0x20, 0x9e, 0x88, 0x8d, 0x5f, + 0x17, 0x61, 0x25, 0xe7, 0xe7, 0x84, 0xd9, 0xe8, 0x3b, 0x0d, 0x56, 0x0e, 0xc8, 0x45, 0x06, 0x27, + 0x43, 0xc5, 0xa7, 0xaa, 0xf9, 0x79, 0x18, 0x18, 0x33, 0xb6, 0x39, 0xee, 0x75, 0xc6, 0x37, 0xfa, + 0x5e, 0x83, 0x07, 0x6d, 0xce, 0x24, 0x23, 0x83, 0xc3, 0x73, 0x4e, 0xdd, 0x3d, 0x9f, 0x5b, 0x29, + 0x49, 0xbf, 0x08, 0x03, 0x63, 0xd6, 0x38, 0xc7, 0x70, 0x66, 0x9d, 0xa3, 0x36, 0x3c, 0xdc, 0xf6, + 0xa5, 0x70, 0x88, 0x64, 0xfd, 0xed, 0xbe, 0x64, 0x8f, 0x55, 0xa4, 0xaa, 0x00, 0x96, 0xcc, 0x17, + 0x22, 0x36, 0x14, 0x98, 0x71, 0x11, 0x88, 0xf6, 0x61, 0xb5, 0x75, 0x4a, 0xb8, 0x4d, 0x49, 0x6f, + 0x40, 0xa7, 0x6a, 0x62, 0xc9, 0xac, 0x87, 0x81, 0x51, 0x68, 0xc7, 0x85, 0x28, 0x7a, 0x13, 0xaa, + 0x2d, 0x97, 0x12, 0x49, 0xad, 0x8e, 0xe0, 0x7d, 0xaa, 0x6a, 0xa4, 0x62, 0xae, 0x84, 0x81, 0x91, + 0xc3, 0x71, 0x4e, 0x8b, 0x62, 0x38, 0xe6, 0xa6, 0xe0, 0xd6, 0xfb, 0xd4, 0x65, 0xc2, 0x6a, 0xf3, + 0xdd, 0xa1, 0xe8, 0x9f, 0x7a, 0x8a, 0xdd, 0xb5, 0x38, 0x86, 0x22, 0x3b, 0x2e, 0x44, 0x11, 0x81, + 0x97, 0x5a, 0xa7, 0xb4, 0x7f, 0xd6, 0x22, 0xc3, 0x43, 0x8e, 0x69, 0x92, 0x49, 0x8a, 0xe9, 0x39, + 0x71, 0x2d, 0xaf, 0x7e, 0x57, 0x6d, 0xcc, 0x08, 0x03, 0xe3, 0x79, 0xcb, 0xf0, 0xf3, 0x8c, 0x8d, + 0x6f, 0x35, 0x40, 0x99, 0x16, 0x48, 0x25, 0xd9, 0x21, 0x92, 0xa0, 0x97, 0xa1, 0xd2, 0x21, 0x0e, + 0x4d, 0x68, 0xba, 0x14, 0x06, 0x86, 0xd2, 0xb1, 0xfa, 0x45, 0xaf, 0xc0, 0xdd, 0x0f, 0x69, 0xcf, + 0x63, 0x92, 0x26, 0xcc, 0x59, 0x0e, 0x03, 0x23, 0x85, 0x70, 0x2a, 0xa0, 0x26, 0x40, 0xdb, 0xa2, + 0x5c, 0xb2, 0x13, 0x46, 0x5d, 0x95, 0xd2, 0xaa, 0x79, 0x3f, 0x6a, 0x32, 0x13, 0x14, 0x67, 0xe4, + 0xc6, 0x93, 0x32, 0xd4, 0x67, 0xab, 0xb0, 0x2b, 0x89, 0xf4, 0x3d, 0xf4, 0x2e, 0x40, 0x57, 0x92, + 0x33, 0x6a, 0x3d, 0xa2, 0x97, 0x71, 0x21, 0x2e, 0xbf, 0xbe, 0x12, 0xf7, 0xf1, 0x66, 0x47, 0x58, + 0xd4, 0x8b, 0xe2, 0x8e, 0xdd, 0x4f, 0xd6, 0xe1, 0x8c, 0x8c, 0xda, 0x50, 0xeb, 0x08, 0x99, 0x71, + 0x52, 0x7e, 0x86, 0x13, 0xd5, 0x3e, 0x73, 0x4b, 0x71, 0x5e, 0x45, 0x7b, 0x50, 0x3d, 0xe6, 0x19, + 0x4f, 0x0b, 0xcf, 0xf0, 0xa4, 0xe8, 0x92, 0x5d, 0x89, 0x73, 0x1a, 0xda, 0x80, 0xa5, 0x8e, 0xef, + 0x1c, 0x7b, 0xd4, 0xf5, 0x92, 0xd6, 0x5d, 0x0d, 0x03, 0x63, 0x8c, 0xe1, 0xb1, 0xd4, 0xf8, 0x5d, + 0x83, 0x4a, 0x54, 0x31, 0x88, 0xc1, 0xe2, 0x07, 0x64, 0xe0, 0xa7, 0xa9, 0xe9, 0x86, 0x81, 0x11, + 0x03, 0x73, 0xac, 0xd3, 0xd8, 0x61, 0x94, 0xe6, 0xfc, 0x2d, 0xa6, 0xd2, 0x9c, 0xde, 0x60, 0xa9, + 0x80, 0x0c, 0x58, 0x54, 0x7c, 0x55, 0x19, 0xae, 0x99, 0xf7, 0xa2, 0x88, 0x14, 0x80, 0xe3, 0x47, + 0x44, 0xa6, 0xa3, 0xcb, 0x61, 0x5c, 0x88, 0xb5, 0x98, 0x4c, 0x91, 0x8e, 0xd5, 0x6f, 0xe3, 0xef, + 0x05, 0xa8, 0x25, 0x59, 0x17, 0xae, 0x22, 0x5f, 0x13, 0x40, 0x95, 0x35, 0x8d, 0x36, 0x9c, 0xec, + 0x53, 0x25, 0x76, 0x82, 0xe2, 0x8c, 0x1c, 0xdd, 0x82, 0xe9, 0xa9, 0xa6, 0xed, 0x2c, 0x6a, 0xd3, + 0x2a, 0x8d, 0x39, 0x03, 0xce, 0xab, 0xa8, 0x05, 0x0f, 0x92, 0x3a, 0x50, 0x25, 0x32, 0x14, 0x8c, + 0xcb, 0x64, 0x17, 0x6b, 0x51, 0x2f, 0x9c, 0x31, 0xe2, 0x59, 0x48, 0xb5, 0xf7, 0x63, 0xde, 0x1a, + 0x10, 0xe6, 0x50, 0x2b, 0x2d, 0xcd, 0xca, 0xa4, 0xbd, 0x4f, 0xdb, 0xe6, 0xd9, 0xde, 0xa7, 0x7d, + 0xa3, 0x27, 0x1a, 0xac, 0x1d, 0x09, 0x49, 0x06, 0x2d, 0xdf, 0xf1, 0x07, 0x51, 0x5f, 0x4a, 0x23, + 0x8a, 0xef, 0xf8, 0x7e, 0x18, 0x18, 0xc5, 0x0b, 0xe6, 0x18, 0x56, 0xf1, 0x07, 0x1a, 0x3f, 0x96, + 0xe1, 0xfe, 0x7b, 0x03, 0xd1, 0x23, 0x83, 0xe8, 0xf4, 0x55, 0xa6, 0xbf, 0x84, 0x65, 0xb5, 0x36, + 0x4e, 0x66, 0x92, 0xea, 0x8f, 0xa3, 0x59, 0x29, 0x03, 0xcf, 0x31, 0xb2, 0xac, 0x5b, 0xf4, 0xb5, + 0x06, 0x35, 0xa5, 0xa7, 0xa4, 0x48, 0x58, 0xfe, 0x69, 0xc4, 0x9b, 0x9c, 0x61, 0x8e, 0x11, 0xe4, + 0x1d, 0x37, 0x3e, 0x83, 0x7b, 0xe3, 0x6e, 0x81, 0x1a, 0x70, 0xc7, 0xdc, 0xef, 0x3e, 0xa2, 0x97, + 0xc9, 0x41, 0x40, 0x18, 0x18, 0x09, 0x82, 0x93, 0x67, 0x34, 0x8e, 0x74, 0x99, 0xcd, 0xa9, 0x75, + 0xe0, 0xd9, 0x49, 0xbc, 0x6a, 0x1c, 0x19, 0x83, 0x78, 0x22, 0x36, 0xfe, 0x28, 0xc3, 0x5a, 0x7c, + 0xfa, 0x2d, 0xe1, 0x0c, 0x7d, 0xa9, 0xfa, 0xaa, 0xfa, 0x54, 0x34, 0x85, 0x25, 0x79, 0x39, 0x12, + 0x3b, 0xcc, 0x93, 0x2e, 0xeb, 0xf9, 0x32, 0xcd, 0x80, 0x9a, 0xc2, 0x0a, 0xcc, 0xf3, 0x9c, 0xc2, + 0x0a, 0xdc, 0x4f, 0xd3, 0xa1, 0xfc, 0x9f, 0xd2, 0xa1, 0x09, 0x30, 0x33, 0x81, 0xc7, 0xd7, 0xc9, + 0x64, 0x54, 0xc8, 0xc8, 0x66, 0xe7, 0xea, 0x46, 0x2f, 0x5d, 0xdf, 0xe8, 0xa5, 0xa7, 0x37, 0xba, + 0xf6, 0xd5, 0x48, 0xd7, 0x7e, 0x1e, 0xe9, 0xda, 0x6f, 0x23, 0x5d, 0xbb, 0x1a, 0xe9, 0xda, 0xf5, + 0x48, 0xd7, 0xfe, 0x1a, 0xe9, 0xda, 0x3f, 0x23, 0xbd, 0xf4, 0x74, 0xa4, 0x6b, 0x3f, 0xdc, 0xea, + 0xa5, 0xab, 0x5b, 0xbd, 0x74, 0x7d, 0xab, 0x97, 0x3e, 0x59, 0xf5, 0x2e, 0x3d, 0x49, 0x9d, 0xae, + 0x43, 0x5c, 0x39, 0xfe, 0xdf, 0xd0, 0xbb, 0xa3, 0x2e, 0x8f, 0x37, 0xfe, 0x0d, 0x00, 0x00, 0xff, + 0xff, 0x60, 0x31, 0xda, 0xbf, 0xdd, 0x0c, 0x00, 0x00, } func (this *DelegationManagement) Equal(that interface{}) bool { @@ -1155,33 +1104,6 @@ func (this *RewardComputationData) Equal(that interface{}) bool { } return true } -func (this *LiquidStakingAttributes) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*LiquidStakingAttributes) - if !ok { - that2, ok := that.(LiquidStakingAttributes) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if !bytes.Equal(this.ContractAddress, that1.ContractAddress) { - return false - } - if this.RewardsCheckpoint != that1.RewardsCheckpoint { - return false - } - return true -} func (this *DelegationManagement) GoString() string { if this == nil { return "nil" @@ -1315,17 +1237,6 @@ func (this *RewardComputationData) GoString() string { s = append(s, "}") return strings.Join(s, "") } -func (this *LiquidStakingAttributes) GoString() string { - if this == nil { - return "nil" - } - s := make([]string, 0, 6) - s = append(s, "&systemSmartContracts.LiquidStakingAttributes{") - s = append(s, "ContractAddress: "+fmt.Sprintf("%#v", this.ContractAddress)+",\n") - s = append(s, "RewardsCheckpoint: "+fmt.Sprintf("%#v", this.RewardsCheckpoint)+",\n") - s = append(s, "}") - return strings.Join(s, "") -} func valueToGoStringDelegation(v interface{}, typ string) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -1881,41 +1792,6 @@ func (m *RewardComputationData) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *LiquidStakingAttributes) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *LiquidStakingAttributes) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *LiquidStakingAttributes) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.RewardsCheckpoint != 0 { - i = encodeVarintDelegation(dAtA, i, uint64(m.RewardsCheckpoint)) - i-- - dAtA[i] = 0x10 - } - if len(m.ContractAddress) > 0 { - i -= len(m.ContractAddress) - copy(dAtA[i:], m.ContractAddress) - i = encodeVarintDelegation(dAtA, i, uint64(len(m.ContractAddress))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func encodeVarintDelegation(dAtA []byte, offset int, v uint64) int { offset -= sovDelegation(v) base := offset @@ -2173,22 +2049,6 @@ func (m *RewardComputationData) Size() (n int) { return n } -func (m *LiquidStakingAttributes) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ContractAddress) - if l > 0 { - n += 1 + l + sovDelegation(uint64(l)) - } - if m.RewardsCheckpoint != 0 { - n += 1 + sovDelegation(uint64(m.RewardsCheckpoint)) - } - return n -} - func sovDelegation(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2337,17 +2197,6 @@ func (this *RewardComputationData) String() string { }, "") return s } -func (this *LiquidStakingAttributes) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&LiquidStakingAttributes{`, - `ContractAddress:` + fmt.Sprintf("%v", this.ContractAddress) + `,`, - `RewardsCheckpoint:` + fmt.Sprintf("%v", this.RewardsCheckpoint) + `,`, - `}`, - }, "") - return s -} func valueToStringDelegation(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -3992,112 +3841,6 @@ func (m *RewardComputationData) Unmarshal(dAtA []byte) error { } return nil } -func (m *LiquidStakingAttributes) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowDelegation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: LiquidStakingAttributes: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: LiquidStakingAttributes: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowDelegation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthDelegation - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthDelegation - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContractAddress = append(m.ContractAddress[:0], dAtA[iNdEx:postIndex]...) - if m.ContractAddress == nil { - m.ContractAddress = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RewardsCheckpoint", wireType) - } - m.RewardsCheckpoint = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowDelegation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RewardsCheckpoint |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipDelegation(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthDelegation - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthDelegation - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipDelegation(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index e3cb4fbd03f..ae269770400 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -201,13 +201,7 @@ func (host *vmContext) SendGlobalSettingToAll(_ []byte, input []byte) { // Transfer handles any necessary value transfer required and takes // the necessary steps to create accounts -func (host *vmContext) Transfer( - destination []byte, - sender []byte, - value *big.Int, - input []byte, - gasLimit uint64, -) error { +func (host *vmContext) Transfer(destination []byte, sender []byte, value *big.Int, input []byte, gasLimit uint64) { senderAcc, exists := host.outputAccounts[string(sender)] if !exists { @@ -240,7 +234,7 @@ func (host *vmContext) Transfer( } destAcc.OutputTransfers = append(destAcc.OutputTransfers, outputTransfer) - return nil + return } func (host *vmContext) copyToNewContext() *vmContext { @@ -331,10 +325,7 @@ func (host *vmContext) DeploySystemSC( } callInput := createDirectCallInput(newAddress, ownerAddress, value, initFunction, input) - err := host.Transfer(callInput.RecipientAddr, host.scAddress, callInput.CallValue, nil, 0) - if err != nil { - return vmcommon.ExecutionFailed, err - } + host.Transfer(callInput.RecipientAddr, host.scAddress, callInput.CallValue, nil, 0) contract, err := host.systemContracts.Get(baseContract) if err != nil { @@ -388,10 +379,7 @@ func (host *vmContext) ExecuteOnDestContext(destination []byte, sender []byte, v return nil, err } - err = host.Transfer(callInput.RecipientAddr, callInput.CallerAddr, callInput.CallValue, nil, 0) - if err != nil { - return nil, err - } + host.Transfer(callInput.RecipientAddr, callInput.CallerAddr, callInput.CallValue, nil, 0) vmOutput := &vmcommon.VMOutput{} currContext := host.copyToNewContext() diff --git a/vm/systemSmartContracts/eei_test.go b/vm/systemSmartContracts/eei_test.go index cec45ec5ec2..43211c0f98d 100644 --- a/vm/systemSmartContracts/eei_test.go +++ b/vm/systemSmartContracts/eei_test.go @@ -178,9 +178,7 @@ func TestVmContext_Transfer(t *testing.T) { value := big.NewInt(999) input := []byte("input") - err := vmCtx.Transfer(destination, sender, value, input, 0) - assert.Nil(t, err) - + vmCtx.Transfer(destination, sender, value, input, 0) balance := vmCtx.GetBalance(destination) assert.Equal(t, value.Uint64(), balance.Uint64()) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 56f5639c703..decd1773646 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -361,11 +361,7 @@ func (e *esdt) issue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if initialSupply.Cmp(zero) > 0 { esdtTransferData := core.BuiltInFunctionESDTTransfer + "@" + hex.EncodeToString(tokenIdentifier) + "@" + hex.EncodeToString(initialSupply.Bytes()) - err = e.eei.Transfer(args.CallerAddr, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(args.CallerAddr, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) } else { e.eei.Finish(tokenIdentifier) } @@ -609,12 +605,7 @@ func (e *esdt) burn(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { } if !token.Burnable { esdtTransferData := core.BuiltInFunctionESDTTransfer + "@" + hex.EncodeToString(args.Arguments[0]) + "@" + hex.EncodeToString(args.Arguments[1]) - err = e.eei.Transfer(args.CallerAddr, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - + e.eei.Transfer(args.CallerAddr, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) e.eei.AddReturnMessage("token is not burnable") return vmcommon.Ok } @@ -683,11 +674,7 @@ func (e *esdt) mint(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { } esdtTransferData := core.BuiltInFunctionESDTTransfer + "@" + hex.EncodeToString(args.Arguments[0]) + "@" + hex.EncodeToString(mintValue.Bytes()) - err = e.eei.Transfer(destination, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(destination, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) return vmcommon.Ok } @@ -712,11 +699,7 @@ func (e *esdt) toggleFreeze(args *vmcommon.ContractCallInput, builtInFunc string } esdtTransferData := builtInFunc + "@" + hex.EncodeToString(args.Arguments[0]) - err := e.eei.Transfer(args.Arguments[1], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(args.Arguments[1], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) return vmcommon.Ok } @@ -762,11 +745,7 @@ func (e *esdt) toggleFreezeSingleNFT(args *vmcommon.ContractCallInput, builtInFu composedArg := append(args.Arguments[0], args.Arguments[1]...) esdtTransferData := builtInFunc + "@" + hex.EncodeToString(composedArg) - err := e.eei.Transfer(args.Arguments[2], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(args.Arguments[2], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) return vmcommon.Ok } @@ -792,14 +771,10 @@ func (e *esdt) wipeTokenFromAddress( } esdtTransferData := core.BuiltInFunctionESDTWipe + "@" + hex.EncodeToString(wipeArgument) - err := e.eei.Transfer(address, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(address, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) token.NumWiped++ - err = e.saveToken(tokenID, token) + err := e.saveToken(tokenID, token) if err != nil { e.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -947,11 +922,7 @@ func (e *esdt) claim(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { } scBalance := e.eei.GetBalance(args.RecipientAddr) - err = e.eei.Transfer(args.CallerAddr, args.RecipientAddr, scBalance, nil, 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(args.CallerAddr, args.RecipientAddr, scBalance, nil, 0) return vmcommon.Ok } @@ -1273,12 +1244,7 @@ func (e *esdt) setSpecialRole(args *vmcommon.ContractCallInput) vmcommon.ReturnC } } - err = e.sendRoleChangeData(args.Arguments[0], args.Arguments[1], args.Arguments[2:], core.BuiltInFunctionSetESDTRole) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - + e.sendRoleChangeData(args.Arguments[0], args.Arguments[1], args.Arguments[2:], core.BuiltInFunctionSetESDTRole) err = e.saveToken(args.Arguments[0], token) if err != nil { e.eei.AddReturnMessage(err.Error()) @@ -1329,12 +1295,7 @@ func (e *esdt) unSetSpecialRole(args *vmcommon.ContractCallInput) vmcommon.Retur esdtRole.Roles = esdtRole.Roles[:len(esdtRole.Roles)-1] } - err := e.sendRoleChangeData(args.Arguments[0], args.Arguments[1], args.Arguments[2:], core.BuiltInFunctionUnSetESDTRole) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - + e.sendRoleChangeData(args.Arguments[0], args.Arguments[1], args.Arguments[2:], core.BuiltInFunctionUnSetESDTRole) if len(esdtRole.Roles) == 0 { for i, roles := range token.SpecialRoles { if bytes.Equal(roles.Address, address) { @@ -1354,7 +1315,7 @@ func (e *esdt) unSetSpecialRole(args *vmcommon.ContractCallInput) vmcommon.Retur e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) } - err = e.saveToken(args.Arguments[0], token) + err := e.saveToken(args.Arguments[0], token) if err != nil { e.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -1434,11 +1395,7 @@ func (e *esdt) transferNFTCreateRole(args *vmcommon.ContractCallInput) vmcommon. esdtTransferNFTCreateData := core.BuiltInFunctionESDTNFTCreateRoleTransfer + "@" + hex.EncodeToString(args.Arguments[0]) + "@" + hex.EncodeToString(args.Arguments[2]) - err = e.eei.Transfer(args.Arguments[1], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferNFTCreateData), 0) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.eei.Transfer(args.Arguments[1], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferNFTCreateData), 0) return vmcommon.Ok } @@ -1475,23 +1432,17 @@ func (e *esdt) stopNFTCreateForever(args *vmcommon.ContractCallInput) vmcommon.R return vmcommon.UserError } - err = e.sendRoleChangeData(args.Arguments[0], currentOwner, [][]byte{[]byte(core.ESDTRoleNFTCreate)}, core.BuiltInFunctionUnSetESDTRole) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - + e.sendRoleChangeData(args.Arguments[0], currentOwner, [][]byte{[]byte(core.ESDTRoleNFTCreate)}, core.BuiltInFunctionUnSetESDTRole) return vmcommon.Ok } -func (e *esdt) sendRoleChangeData(tokenID []byte, destination []byte, roles [][]byte, builtInFunc string) error { +func (e *esdt) sendRoleChangeData(tokenID []byte, destination []byte, roles [][]byte, builtInFunc string) { esdtSetRoleData := builtInFunc + "@" + hex.EncodeToString(tokenID) for _, arg := range roles { esdtSetRoleData += "@" + hex.EncodeToString(arg) } - err := e.eei.Transfer(destination, e.eSDTSCAddress, big.NewInt(0), []byte(esdtSetRoleData), 0) - return err + e.eei.Transfer(destination, e.eSDTSCAddress, big.NewInt(0), []byte(esdtSetRoleData), 0) } func (e *esdt) getAllAddressesAndRoles(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index fa04ecd42ac..722151dcf6c 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -834,9 +834,6 @@ func TestEsdt_ExecuteMintTransferFailsShouldErr(t *testing.T) { }) return marshalizedData } - args.Eei.(*mock.SystemEIStub).TransferCalled = func(destination []byte, sender []byte, value *big.Int, input []byte) error { - return err - } args.Eei.(*mock.SystemEIStub).AddReturnMessageCalled = func(msg string) { assert.Equal(t, err.Error(), msg) } @@ -1158,9 +1155,6 @@ func TestEsdt_ExecuteToggleFreezeTransferFailsShouldErr(t *testing.T) { }) return marshalizedData } - args.Eei.(*mock.SystemEIStub).TransferCalled = func(destination []byte, sender []byte, value *big.Int, input []byte) error { - return err - } args.Eei.(*mock.SystemEIStub).AddReturnMessageCalled = func(msg string) { assert.Equal(t, err.Error(), msg) } @@ -1185,9 +1179,6 @@ func TestEsdt_ExecuteToggleFreezeSingleNFTTransferFailsShouldErr(t *testing.T) { }) return marshalizedData } - args.Eei.(*mock.SystemEIStub).TransferCalled = func(destination []byte, sender []byte, value *big.Int, input []byte) error { - return err - } args.Eei.(*mock.SystemEIStub).AddReturnMessageCalled = func(msg string) { assert.Equal(t, err.Error(), msg) } @@ -1712,9 +1703,6 @@ func TestEsdt_ExecuteWipeTransferFailsShouldErr(t *testing.T) { }) return marshalizedData } - args.Eei.(*mock.SystemEIStub).TransferCalled = func(destination []byte, sender []byte, value *big.Int, input []byte) error { - return err - } args.Eei.(*mock.SystemEIStub).AddReturnMessageCalled = func(msg string) { assert.Equal(t, err.Error(), msg) } @@ -1739,9 +1727,6 @@ func TestEsdt_ExecuteWipeSingleNFTTransferFailsShouldErr(t *testing.T) { }) return marshalizedData } - args.Eei.(*mock.SystemEIStub).TransferCalled = func(destination []byte, sender []byte, value *big.Int, input []byte) error { - return err - } args.Eei.(*mock.SystemEIStub).AddReturnMessageCalled = func(msg string) { assert.Equal(t, err.Error(), msg) } @@ -3053,7 +3038,6 @@ func TestEsdt_SetSpecialRoleCheckBasicOwnershipErr(t *testing.T) { func TestEsdt_SetSpecialRoleNewSendRoleChangeDataErr(t *testing.T) { t.Parallel() - localErr := errors.New("local err") args := createMockArgumentsForESDT() eei := &mock.SystemEIStub{ GetStorageCalled: func(key []byte) []byte { @@ -3063,9 +3047,8 @@ func TestEsdt_SetSpecialRoleNewSendRoleChangeDataErr(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4275726e"), input) - return localErr }, } args.Eei = eei @@ -3100,9 +3083,8 @@ func TestEsdt_SetSpecialRoleAlreadyExists(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4275726e"), input) - return nil }, } args.Eei = eei @@ -3139,11 +3121,10 @@ func TestEsdt_SetSpecialRoleCannotSaveToken(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4275726e"), input) castedMarshalizer := args.Marshalizer.(*mock.MarshalizerMock) castedMarshalizer.Fail = true - return nil }, } args.Eei = eei @@ -3180,9 +3161,8 @@ func TestEsdt_SetSpecialRoleShouldWork(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4275726e"), input) - return nil }, SetStorageCalled: func(key []byte, value []byte) { token := &ESDTData{} @@ -3224,9 +3204,8 @@ func TestEsdt_SetSpecialRoleNFTShouldErr(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTSetRole@6d79546f6b656e@45534454526f6c654e4654437265617465"), input) - return nil }, SetStorageCalled: func(key []byte, value []byte) { token := &ESDTData{} @@ -3367,9 +3346,8 @@ func TestEsdt_SetSpecialRoleSFTShouldErr(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTSetRole@6d79546f6b656e@45534454526f6c654e46544164645175616e74697479"), input) - return nil }, SetStorageCalled: func(key []byte, value []byte) { token := &ESDTData{} @@ -3620,7 +3598,6 @@ func TestEsdt_UnsetSpecialRoleCannotRemoveRoleNotExistsShouldErr(t *testing.T) { func TestEsdt_UnsetSpecialRoleRemoveRoleTransferErr(t *testing.T) { t.Parallel() - localErr := errors.New("local err") args := createMockArgumentsForESDT() eei := &mock.SystemEIStub{ GetStorageCalled: func(key []byte) []byte { @@ -3636,9 +3613,8 @@ func TestEsdt_UnsetSpecialRoleRemoveRoleTransferErr(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTUnSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4d696e74"), input) - return localErr }, } args.Eei = eei @@ -3673,11 +3649,10 @@ func TestEsdt_UnsetSpecialRoleRemoveRoleSaveTokenErr(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTUnSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4d696e74"), input) castedMarshalizer := args.Marshalizer.(*mock.MarshalizerMock) castedMarshalizer.Fail = true - return nil }, } args.Eei = eei @@ -3712,9 +3687,8 @@ func TestEsdt_UnsetSpecialRoleRemoveRoleShouldWork(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTUnSetRole@6d79546f6b656e@45534454526f6c654c6f63616c4d696e74"), input) - return nil }, SetStorageCalled: func(key []byte, value []byte) { token := &ESDTData{} @@ -3826,9 +3800,8 @@ func TestEsdt_StopNFTCreateForeverCallShouldWork(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTUnSetRole@746f6b656e4944@45534454526f6c654e4654437265617465"), input) - return nil }, } args.Eei = eei @@ -3943,10 +3916,9 @@ func TestEsdt_TransferNFTCreateCallShouldWork(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte, _ uint64) { require.Equal(t, []byte("ESDTNFTCreateRoleTransfer@746f6b656e4944@63616c6c657232"), input) require.Equal(t, destination, []byte("caller3")) - return nil }, } args.Eei = eei diff --git a/vm/systemSmartContracts/governance.go b/vm/systemSmartContracts/governance.go index 1e8e89d2d7f..bfbb756b11c 100644 --- a/vm/systemSmartContracts/governance.go +++ b/vm/systemSmartContracts/governance.go @@ -586,12 +586,7 @@ func (g *governanceContract) claimFunds(args *vmcommon.ContractCallInput) vmcomm } g.eei.SetStorage(voteKey, nil) - - err = g.eei.Transfer(args.CallerAddr, g.governanceSCAddress, currentVoteSet.UsedBalance, nil, 0) - if err != nil { - g.eei.AddReturnMessage("transfer error on claimFunds function") - return vmcommon.ExecutionFailed - } + g.eei.Transfer(args.CallerAddr, g.governanceSCAddress, currentVoteSet.UsedBalance, nil, 0) return vmcommon.Ok } diff --git a/vm/systemSmartContracts/governance_test.go b/vm/systemSmartContracts/governance_test.go index f7b91cd6f94..d65a297eecf 100644 --- a/vm/systemSmartContracts/governance_test.go +++ b/vm/systemSmartContracts/governance_test.go @@ -1355,12 +1355,10 @@ func TestGovernanceContract_ClaimFunds(t *testing.T) { _ = args.Marshalizer.Unmarshal(finalVoteSet, value) } }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, _ []byte) error { + TransferCalled: func(destination []byte, sender []byte, value *big.Int, _ []byte, _ uint64) { transferTo = destination transferFrom = sender transferValue.Set(value) - - return nil }, } claimArgs := [][]byte{ diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index d9d1a691a1d..80b06ddcbb1 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -177,23 +177,46 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) l.eei.AddReturnMessage("not enough arguments") return vmcommon.UserError } + if len(args.ESDTTransfers) > 0 { + l.eei.AddReturnMessage("function is not payable in ESDT") + return vmcommon.UserError + } return vmcommon.Ok } func (l *liquidStaking) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } return vmcommon.Ok } func (l *liquidStaking) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } + return vmcommon.Ok } func (l *liquidStaking) unDelegateWithPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } + return vmcommon.Ok } func (l *liquidStaking) returnPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } + return vmcommon.Ok } diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 3b4aaed9fe3..15ccc3306f0 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -403,11 +403,7 @@ func (v *validatorSC) unJail(args *vmcommon.ContractCallInput) vmcommon.ReturnCo } if transferBack.Cmp(zero) > 0 { - err = v.eei.Transfer(args.CallerAddr, args.RecipientAddr, transferBack, nil, 0) - if err != nil { - v.eei.AddReturnMessage("transfer error on unJail function") - return vmcommon.UserError - } + v.eei.Transfer(args.CallerAddr, args.RecipientAddr, transferBack, nil, 0) } finalUnJailFunds := big.NewInt(0).Sub(args.CallValue, transferBack) @@ -1410,11 +1406,7 @@ func (v *validatorSC) unBondV1(args *vmcommon.ContractCallInput) vmcommon.Return } } - err := v.eei.Transfer(args.CallerAddr, args.RecipientAddr, totalUnBond, nil, 0) - if err != nil { - v.eei.AddReturnMessage("transfer error on unBond function") - return vmcommon.UserError - } + v.eei.Transfer(args.CallerAddr, args.RecipientAddr, totalUnBond, nil, 0) return vmcommon.Ok } @@ -1449,11 +1441,7 @@ func (v *validatorSC) unBond(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return returnCode } - err := v.eei.Transfer(args.CallerAddr, args.RecipientAddr, totalUnBond, nil, 0) - if err != nil { - v.eei.AddReturnMessage("transfer error on unBond function") - return vmcommon.UserError - } + v.eei.Transfer(args.CallerAddr, args.RecipientAddr, totalUnBond, nil, 0) return vmcommon.Ok } @@ -1540,11 +1528,7 @@ func (v *validatorSC) claim(args *vmcommon.ContractCallInput) vmcommon.ReturnCod return vmcommon.UserError } - err = v.eei.Transfer(args.CallerAddr, args.RecipientAddr, claimable, nil, 0) - if err != nil { - v.eei.AddReturnMessage("transfer error on finalizeUnStake function: error " + err.Error()) - return vmcommon.UserError - } + v.eei.Transfer(args.CallerAddr, args.RecipientAddr, claimable, nil, 0) return vmcommon.Ok } @@ -1744,12 +1728,7 @@ func (v *validatorSC) unBondTokens(args *vmcommon.ContractCallInput) vmcommon.Re return vmcommon.UserError } - err = v.eei.Transfer(args.CallerAddr, args.RecipientAddr, totalUnBond, nil, 0) - if err != nil { - v.eei.AddReturnMessage("transfer error on unBond function") - return vmcommon.UserError - } - + v.eei.Transfer(args.CallerAddr, args.RecipientAddr, totalUnBond, nil, 0) err = v.saveRegistrationData(args.CallerAddr, registrationData) if err != nil { v.eei.AddReturnMessage("cannot save registration data: error " + err.Error()) From d3ea50d61bc50a15d38b9309b32dba87d55dd5e1 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Mon, 23 Aug 2021 18:30:12 +0300 Subject: [PATCH 008/958] fixing test after interface change --- vm/factory/systemSCFactory.go | 1 + vm/factory/systemSCFactory_test.go | 2 +- vm/systemSmartContracts/esdt_test.go | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/vm/factory/systemSCFactory.go b/vm/factory/systemSCFactory.go index 8f158173a1d..33a041befc5 100644 --- a/vm/factory/systemSCFactory.go +++ b/vm/factory/systemSCFactory.go @@ -295,6 +295,7 @@ func (scf *systemSCFactory) createLiquidStakingContract() (vm.SystemSmartContrac argsLiquidStaking := systemSmartContracts.ArgsNewLiquidStaking{ Eei: scf.systemEI, DelegationMgrSCAddress: vm.DelegationManagerSCAddress, + LiquidStakingSCAddress: vm.LiquidStakingSCAddress, GasCost: scf.gasCost, Marshalizer: scf.marshalizer, Hasher: scf.hasher, diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index 5f95aad78d2..9e7ed2d27be 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -278,7 +278,7 @@ func TestSystemSCFactory_Create(t *testing.T) { container, err := scFactory.Create() assert.Nil(t, err) require.NotNil(t, container) - assert.Equal(t, 6, container.Len()) + assert.Equal(t, 7, container.Len()) } func TestSystemSCFactory_CreateForGenesis(t *testing.T) { diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index 722151dcf6c..fab29bead7c 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -821,7 +821,7 @@ func TestEsdt_ExecuteMintInvalidDestinationAddressShouldFail(t *testing.T) { assert.True(t, strings.Contains(eei.returnMessage, "destination address of invalid length")) } -func TestEsdt_ExecuteMintTransferFailsShouldErr(t *testing.T) { +func TestEsdt_ExecuteMintTransferNoErr(t *testing.T) { t.Parallel() err := errors.New("transfer error") @@ -842,7 +842,7 @@ func TestEsdt_ExecuteMintTransferFailsShouldErr(t *testing.T) { vmInput := getDefaultVmInputForFunc("mint", [][]byte{[]byte("esdtToken"), {200}}) output := e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) + assert.Equal(t, vmcommon.Ok, output) } func TestEsdt_ExecuteMintWithTwoArgsShouldSetOwnerAsDestination(t *testing.T) { @@ -1143,7 +1143,7 @@ func TestEsdt_ExecuteToggleFreezeNonFreezableTokenShouldFail(t *testing.T) { assert.True(t, strings.Contains(eei.returnMessage, "cannot freeze")) } -func TestEsdt_ExecuteToggleFreezeTransferFailsShouldErr(t *testing.T) { +func TestEsdt_ExecuteToggleFreezeTransferNoErr(t *testing.T) { t.Parallel() err := errors.New("transfer error") @@ -1163,10 +1163,10 @@ func TestEsdt_ExecuteToggleFreezeTransferFailsShouldErr(t *testing.T) { vmInput := getDefaultVmInputForFunc("freeze", [][]byte{[]byte("esdtToken"), getAddress()}) output := e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) + assert.Equal(t, vmcommon.Ok, output) } -func TestEsdt_ExecuteToggleFreezeSingleNFTTransferFailsShouldErr(t *testing.T) { +func TestEsdt_ExecuteToggleFreezeSingleNFTTransferNoErr(t *testing.T) { t.Parallel() err := errors.New("transfer error") @@ -1187,7 +1187,7 @@ func TestEsdt_ExecuteToggleFreezeSingleNFTTransferFailsShouldErr(t *testing.T) { vmInput := getDefaultVmInputForFunc("freezeSingleNFT", [][]byte{[]byte("esdtToken"), big.NewInt(10).Bytes(), getAddress()}) output := e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) + assert.Equal(t, vmcommon.Ok, output) } func TestEsdt_ExecuteToggleFreezeShouldWorkWithRealBech32Address(t *testing.T) { @@ -1690,7 +1690,7 @@ func TestEsdt_ExecuteWipeInvalidDestShouldFail(t *testing.T) { assert.True(t, strings.Contains(eei.returnMessage, "invalid")) } -func TestEsdt_ExecuteWipeTransferFailsShouldErr(t *testing.T) { +func TestEsdt_ExecuteWipeTransferFailsNoErr(t *testing.T) { t.Parallel() err := errors.New("transfer error") @@ -1711,10 +1711,10 @@ func TestEsdt_ExecuteWipeTransferFailsShouldErr(t *testing.T) { vmInput := getDefaultVmInputForFunc("wipe", [][]byte{[]byte("esdtToken"), getAddress()}) output := e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) + assert.Equal(t, vmcommon.Ok, output) } -func TestEsdt_ExecuteWipeSingleNFTTransferFailsShouldErr(t *testing.T) { +func TestEsdt_ExecuteWipeSingleNFTTransferNoErr(t *testing.T) { t.Parallel() err := errors.New("transfer error") @@ -1735,7 +1735,7 @@ func TestEsdt_ExecuteWipeSingleNFTTransferFailsShouldErr(t *testing.T) { vmInput := getDefaultVmInputForFunc("wipeSingleNFT", [][]byte{[]byte("esdtToken"), big.NewInt(10).Bytes(), getAddress()}) output := e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) + assert.Equal(t, vmcommon.Ok, output) } func TestEsdt_ExecuteWipeShouldWork(t *testing.T) { @@ -3595,7 +3595,7 @@ func TestEsdt_UnsetSpecialRoleCannotRemoveRoleNotExistsShouldErr(t *testing.T) { require.Equal(t, vmcommon.UserError, retCode) } -func TestEsdt_UnsetSpecialRoleRemoveRoleTransferErr(t *testing.T) { +func TestEsdt_UnsetSpecialRoleRemoveRoleTransfer(t *testing.T) { t.Parallel() args := createMockArgumentsForESDT() @@ -3628,7 +3628,7 @@ func TestEsdt_UnsetSpecialRoleRemoveRoleTransferErr(t *testing.T) { vmInput.GasProvided = 50000000 retCode := e.Execute(vmInput) - require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vmcommon.Ok, retCode) } func TestEsdt_UnsetSpecialRoleRemoveRoleSaveTokenErr(t *testing.T) { From 9bee4d47e97333dcd1bf7949e33b700cf021b6e8 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 24 Aug 2021 11:28:50 +0300 Subject: [PATCH 009/958] small fixes --- epochStart/metachain/systemSCs.go | 2 +- vm/systemSmartContracts/delegation.go | 3 +-- vm/systemSmartContracts/esdt.go | 2 ++ vm/systemSmartContracts/liquidStaking.go | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 7f41517b644..5f6d935318f 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -1156,7 +1156,7 @@ func (s *systemSCProcessor) initLiquidStakingSC(tokenID []byte) error { vmInput := &vmcommon.ContractCreateInput{ VMInput: vmcommon.VMInput{ - CallerAddr: vm.EndOfEpochAddress, + CallerAddr: vm.LiquidStakingSCAddress, Arguments: [][]byte{tokenID}, CallValue: big.NewInt(0), }, diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index a347dace51d..c1c4003da56 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -2719,13 +2719,12 @@ func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInp } d.eei.Transfer(args.CallerAddr, address, totalRewards, nil, 0) - return vmcommon.Ok } func (d *delegation) reDelegateRewardsViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok + return vmcommon.UserError } func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index decd1773646..311d0eff1e5 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -283,6 +283,8 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } + e.eei.Finish(tokenIdentifier) + return vmcommon.Ok } diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 80b06ddcbb1..8933cbf7b75 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -122,7 +122,7 @@ func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.Retur } func (l *liquidStaking) init(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if bytes.Equal(args.CallerAddr, l.endOfEpochAddr) { + if !bytes.Equal(args.CallerAddr, l.liquidStakingSCAddress) { l.eei.AddReturnMessage("invalid caller") return vmcommon.UserError } From 7aad3eb97e93446903183e3e2aa8107269acdf52 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 24 Aug 2021 14:48:48 +0300 Subject: [PATCH 010/958] finished implementation of liquid staking functions on delegation --- vm/systemSmartContracts/delegation.go | 269 +++++++++++++++++++++----- 1 file changed, 216 insertions(+), 53 deletions(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index c1c4003da56..3bb84e94afe 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1387,70 +1387,60 @@ func (d *delegation) finishDelegateUser( return vmcommon.UserError } - var err error - if len(delegator.ActiveFund) == 0 { - var fundKey []byte - fundKey, err = d.createAndSaveNextKeyFund(callerAddr, delegateValue, active) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - delegator.ActiveFund = fundKey - if isNew { - dStatus.NumUsers++ - } - } else { - err = d.addValueToFund(delegator.ActiveFund, delegateValue) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - } - - err = d.checkActiveFund(delegator) + err := d.addToActiveFund(callerAddr, delegator, delegateValue, dStatus, isNew) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - stakeArgs := d.makeStakeArgsIfAutomaticActivation(dConfig, dStatus, globalFund) - vmOutput, err := d.executeOnValidatorSC(scAddress, "stake", stakeArgs, callValue) + err = d.checkActiveFund(delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - if vmOutput.ReturnCode != vmcommon.Ok { - return vmOutput.ReturnCode - } - if len(stakeArgs) > 0 { - err = d.updateDelegationStatusAfterStake(dStatus, vmOutput.ReturnData, stakeArgs) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + returnCode := d.executeStakeAndUpdateStatus(dConfig, dStatus, globalFund, callValue, scAddress) + if returnCode != vmcommon.Ok { + return returnCode } - err = d.saveDelegationStatus(dStatus) + err = d.saveDelegatorData(callerAddr, delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - err = d.saveGlobalFundData(globalFund) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + return vmcommon.Ok +} - err = d.saveDelegatorData(callerAddr, delegator) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError +func (d *delegation) addToActiveFund( + callerAddr []byte, + delegator *DelegatorData, + delegateValue *big.Int, + dStatus *DelegationContractStatus, + isNew bool, +) error { + if len(delegator.ActiveFund) == 0 { + var fundKey []byte + fundKey, err := d.createAndSaveNextKeyFund(callerAddr, delegateValue, active) + if err != nil { + return err + } + + delegator.ActiveFund = fundKey + if isNew { + dStatus.NumUsers++ + } + + return nil + } else { + err := d.addValueToFund(delegator.ActiveFund, delegateValue) + if err != nil { + return err + } } - return vmcommon.Ok + return nil } func (d *delegation) checkActiveFund(delegator *DelegatorData) error { @@ -1585,7 +1575,15 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.UserError } - isNew, delegator, err := d.getOrCreateDelegatorData(args.CallerAddr) + return d.unDelegateValueFromAddress(valueToUnDelegate, args.CallerAddr, args.RecipientAddr) +} + +func (d *delegation) unDelegateValueFromAddress( + valueToUnDelegate *big.Int, + delegatorAddress []byte, + contractAddress []byte, +) vmcommon.ReturnCode { + isNew, delegator, err := d.getOrCreateDelegatorData(delegatorAddress) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -1605,7 +1603,7 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.UserError } - if isStakeLocked(d.eei, d.governanceSCAddr, args.CallerAddr) { + if isStakeLocked(d.eei, d.governanceSCAddr, delegatorAddress) { d.eei.AddReturnMessage("stake is locked for voting") return vmcommon.UserError } @@ -1623,12 +1621,12 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur d.eei.AddReturnMessage("invalid value to undelegate - need to undelegate all - do not leave dust behind") return vmcommon.UserError } - err = d.checkOwnerCanUnDelegate(args.CallerAddr, activeFund, valueToUnDelegate) + err = d.checkOwnerCanUnDelegate(delegatorAddress, activeFund, valueToUnDelegate) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - err = d.computeAndUpdateRewards(args.CallerAddr, delegator) + err = d.computeAndUpdateRewards(delegatorAddress, delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -1640,7 +1638,7 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.UserError } - returnData, returnCode := d.executeOnValidatorSCWithValueInArgs(args.RecipientAddr, "unStakeTokens", valueToUnDelegate) + returnData, returnCode := d.executeOnValidatorSCWithValueInArgs(contractAddress, "unStakeTokens", valueToUnDelegate) if returnCode != vmcommon.Ok { return returnCode } @@ -1658,7 +1656,7 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.UserError } - err = d.addNewUnStakedFund(args.CallerAddr, delegator, actualUserUnStake) + err = d.addNewUnStakedFund(delegatorAddress, delegator, actualUserUnStake) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -1682,7 +1680,7 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.UserError } - err = d.saveDelegatorData(args.CallerAddr, delegator) + err = d.saveDelegatorData(delegatorAddress, delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -2648,6 +2646,19 @@ func (d *delegation) basicCheckForLiquidStaking(args *vmcommon.ContractCallInput return vmcommon.UserError } + delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + minDelegationAmount := delegationManagement.MinDelegationAmount + belowMinDelegationAmount := value.Cmp(minDelegationAmount) < 0 + if belowMinDelegationAmount { + d.eei.AddReturnMessage("call value below minimum to operate") + return vmcommon.UserError + } + return vmcommon.Ok } @@ -2702,7 +2713,6 @@ func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInp if returnCode != vmcommon.Ok { return returnCode } - if len(args.Arguments) != 3 { d.eei.AddReturnMessage("not enough arguments") return vmcommon.UserError @@ -2723,16 +2733,169 @@ func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInp } func (d *delegation) reDelegateRewardsViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := d.basicCheckForLiquidStaking(args) + if returnCode != vmcommon.Ok { + return returnCode + } + if len(args.Arguments) != 3 { + d.eei.AddReturnMessage("not enough arguments") + return vmcommon.UserError + } + + value := big.NewInt(0).SetBytes(args.Arguments[1]) + checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) + totalRewards, err := d.computeRewards(checkPoint, false, value) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if totalRewards.Cmp(zero) <= 0 { + d.eei.AddReturnMessage("no rewards to redelegate via liquid staking") + return vmcommon.UserError + } + + dConfig, dStatus, globalFund, err := d.getConfigStatusAndGlobalFund() + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + globalFund.TotalActive.Add(globalFund.TotalActive, totalRewards) + withDelegationCap := dConfig.MaxDelegationCap.Cmp(zero) != 0 + if withDelegationCap && dConfig.CheckCapOnReDelegateRewards && globalFund.TotalActive.Cmp(dConfig.MaxDelegationCap) > 0 { + d.eei.AddReturnMessage("total delegation cap reached") + return vmcommon.UserError + } + + returnCode = d.executeStakeAndUpdateStatus(dConfig, dStatus, globalFund, totalRewards, args.RecipientAddr) + if returnCode != vmcommon.Ok { + return returnCode + } + d.eei.Finish(totalRewards.Bytes()) return vmcommon.UserError } -func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { +func (d *delegation) executeStakeAndUpdateStatus( + dConfig *DelegationConfig, + dStatus *DelegationContractStatus, + globalFund *GlobalFundData, + valueToStake *big.Int, + scAddress []byte, +) vmcommon.ReturnCode { + stakeArgs := d.makeStakeArgsIfAutomaticActivation(dConfig, dStatus, globalFund) + vmOutput, err := d.executeOnValidatorSC(scAddress, "stake", stakeArgs, valueToStake) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if vmOutput.ReturnCode != vmcommon.Ok { + return vmOutput.ReturnCode + } + + if len(stakeArgs) > 0 { + err = d.updateDelegationStatusAfterStake(dStatus, vmOutput.ReturnData, stakeArgs) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + } + + err = d.saveDelegationStatus(dStatus) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + err = d.saveGlobalFundData(globalFund) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } return vmcommon.Ok } +func (d *delegation) getConfigStatusAndGlobalFund() (*DelegationConfig, *DelegationContractStatus, *GlobalFundData, error) { + dConfig, err := d.getDelegationContractConfig() + if err != nil { + return nil, nil, nil, err + } + globalFund, err := d.getGlobalFundData() + if err != nil { + return nil, nil, nil, err + } + dStatus, err := d.getDelegationStatus() + if err != nil { + return nil, nil, nil, err + } + return dConfig, dStatus, globalFund, nil +} + +func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := d.returnViaLiquidStaking(args) + if returnCode != vmcommon.UserError { + return returnCode + } + + address := args.Arguments[0] + valueToUnDelegate := big.NewInt(0).SetBytes(args.Arguments[1]) + return d.unDelegateValueFromAddress(valueToUnDelegate, address, args.RecipientAddr) +} + func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := d.basicCheckForLiquidStaking(args) + if returnCode != vmcommon.Ok { + return returnCode + } + if len(args.Arguments) != 3 { + d.eei.AddReturnMessage("not enough arguments") + return vmcommon.UserError + } + + address := args.Arguments[0] + value := big.NewInt(0).SetBytes(args.Arguments[1]) + checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) + totalRewards, err := d.computeRewards(checkPoint, false, value) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + isNew, delegator, err := d.getOrCreateDelegatorData(address) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + err = d.computeAndUpdateRewards(address, delegator) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + dStatus, err := d.getDelegationStatus() + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + totalValue := big.NewInt(0).Add(totalRewards, value) + err = d.addToActiveFund(address, delegator, totalValue, dStatus, isNew) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + err = d.saveDelegationStatus(dStatus) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + err = d.saveDelegatorData(address, delegator) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } return vmcommon.Ok } From a8d4cfdb2747912f6fdc6897294491c866589055 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 24 Aug 2021 16:50:28 +0300 Subject: [PATCH 011/958] liquid staking manager contract --- vm/errors.go | 3 + vm/interface.go | 2 +- vm/mock/systemEIStub.go | 10 +- vm/systemSmartContracts/eei.go | 8 +- vm/systemSmartContracts/esdt.go | 2 +- vm/systemSmartContracts/liquidStaking.go | 160 ++++++++++++++++++++++- 6 files changed, 168 insertions(+), 17 deletions(-) diff --git a/vm/errors.go b/vm/errors.go index a39cb1eee84..fa298366e0d 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -250,3 +250,6 @@ var ErrInvalidNumOfInitialWhiteListedAddress = errors.New("0 initial whiteListed // ErrInvalidDelegationTicker signals that invalid delegation ticker name was provided var ErrInvalidDelegationTicker = errors.New("invalid delegation ticker name") + +// ErrNotEnoughReturnData signals that not enough return data was provided +var ErrNotEnoughReturnData = errors.New("not enough return data") diff --git a/vm/interface.go b/vm/interface.go index b6833ca74ae..08ae386f7e3 100644 --- a/vm/interface.go +++ b/vm/interface.go @@ -55,7 +55,7 @@ type SystemEI interface { CanUnJail(blsKey []byte) bool IsBadRating(blsKey []byte) bool CleanStorageUpdates() - ProcessBuiltInFunction(sender, destination []byte, function string, arguments [][]byte) error + ProcessBuiltInFunction(sender, destination []byte, function string, arguments [][]byte) (*vmcommon.VMOutput, error) IsInterfaceNil() bool } diff --git a/vm/mock/systemEIStub.go b/vm/mock/systemEIStub.go index eb02ea854c0..21047a521d4 100644 --- a/vm/mock/systemEIStub.go +++ b/vm/mock/systemEIStub.go @@ -37,7 +37,7 @@ type SystemEIStub struct { GasLeftCalled func() uint64 CleanStorageUpdatesCalled func() ReturnMessage string - ProcessBuiltInFunctionCalled func(sender, destination []byte, function string, arguments [][]byte) error + ProcessBuiltInFunctionCalled func(sender, destination []byte, function string, arguments [][]byte) (*vmcommon.VMOutput, error) } // GasLeft - @@ -269,15 +269,11 @@ func (s *SystemEIStub) CleanStorageUpdates() { } // ProcessBuiltInFunction - -func (s *SystemEIStub) ProcessBuiltInFunction( - sender, destination []byte, - function string, - arguments [][]byte, -) error { +func (s *SystemEIStub) ProcessBuiltInFunction(sender, destination []byte, function string, arguments [][]byte) (*vmcommon.VMOutput, error) { if s.ProcessBuiltInFunctionCalled != nil { return s.ProcessBuiltInFunctionCalled(sender, destination, function, arguments) } - return nil + return &vmcommon.VMOutput{}, nil } // IsInterfaceNil - diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index ae269770400..2656a352aaf 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -441,15 +441,15 @@ func (host *vmContext) ProcessBuiltInFunction( sender, destination []byte, function string, arguments [][]byte, -) error { +) (*vmcommon.VMOutput, error) { vmInput := createDirectCallInput(destination, sender, big.NewInt(0), function, arguments) vmInput.GasProvided = host.GasLeft() vmOutput, err := host.blockChainHook.ProcessBuiltInFunction(vmInput) if err != nil { - return err + return nil, err } if vmOutput.ReturnCode != vmcommon.Ok { - return errors.New(vmOutput.ReturnMessage) + return nil, errors.New(vmOutput.ReturnMessage) } for address, outAcc := range vmOutput.OutputAccounts { @@ -465,7 +465,7 @@ func (host *vmContext) ProcessBuiltInFunction( //TODO: add logs after merge with logs PR on meta - return nil + return vmOutput, nil } // BlockChainHook returns the blockchain hook diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 311d0eff1e5..d37f632c643 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -272,7 +272,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } - err = e.eei.ProcessBuiltInFunction( + err, _ = e.eei.ProcessBuiltInFunction( e.eSDTSCAddress, vm.LiquidStakingSCAddress, core.BuiltInFunctionSetESDTRole, diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 8933cbf7b75..7a6809d7eb7 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -3,7 +3,9 @@ package systemSmartContracts import ( "bytes" + "encoding/hex" "fmt" + "math/big" "sync" "github.com/ElrondNetwork/elrond-go-core/core" @@ -17,7 +19,8 @@ import ( ) const tokenIDKey = "tokenID" -const noncePrefix = "n" +const nonceAttributesPrefix = "n" +const attributesNoncePrefix = "a" type liquidStaking struct { eei vm.SystemEI @@ -153,9 +156,10 @@ func (l *liquidStaking) checkArgumentsWhenPositionIsInput(args *vmcommon.Contrac l.eei.AddReturnMessage("function is not payable in eGLD") return vmcommon.UserError } + definedTokenID := l.getTokenID() for _, esdtTransfer := range args.ESDTTransfers { - if !bytes.Equal(esdtTransfer.ESDTTokenName, l.getTokenID()) { - l.eei.AddReturnMessage("wrong liquid staking position as input") + if !bytes.Equal(esdtTransfer.ESDTTokenName, definedTokenID) { + l.eei.AddReturnMessage("wrong tokenID input") return vmcommon.UserError } } @@ -173,18 +177,166 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) l.eei.AddReturnMessage("function is not payable in eGLD") return vmcommon.UserError } - if len(args.Arguments) == 0 { + if len(args.Arguments) != 2 { l.eei.AddReturnMessage("not enough arguments") return vmcommon.UserError } + if len(args.Arguments)%2 != 0 { + l.eei.AddReturnMessage("invalid number of arguments") + return vmcommon.UserError + } if len(args.ESDTTransfers) > 0 { l.eei.AddReturnMessage("function is not payable in ESDT") return vmcommon.UserError } + listNonces := make([]uint64, 0) + listValues := make([]*big.Int, 0) + for i := 0; i < len(args.Arguments); i += 2 { + scAddress := args.Arguments[i] + valueToClaim := big.NewInt(0).SetBytes(args.Arguments[i+1]) + + txData := "claimDelegatedPosition" + "@" + hex.EncodeToString(args.CallerAddr) + "@" + hex.EncodeToString(valueToClaim.Bytes()) + vmOutput, err := l.eei.ExecuteOnDestContext(scAddress, args.RecipientAddr, big.NewInt(0), []byte(txData)) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + if vmOutput.ReturnCode != vmcommon.Ok { + return vmOutput.ReturnCode + } + + if len(vmOutput.ReturnData) != 1 { + l.eei.AddReturnMessage("invalid return data") + return vmcommon.UserError + } + + rewardsCheckpoint := uint32(big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64()) + nonce, err := l.createOrAddNFT(scAddress, rewardsCheckpoint, valueToClaim) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + listNonces = append(listNonces, nonce) + listValues = append(listValues, valueToClaim) + } + + err := l.sendNFTMultiTransfer(args.RecipientAddr, args.CallerAddr, listNonces, listValues) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + return vmcommon.Ok } +func (l *liquidStaking) executeOnDestinationSC( + dstSCAddress []byte, + functionToCall string, + userAddress []byte, + valueToSend *big.Int, + rewardsCheckPoint uint32, +) ([][]byte, vmcommon.ReturnCode) { + txData := functionToCall + "@" + hex.EncodeToString(userAddress) + "@" + hex.EncodeToString(valueToSend.Bytes()) + if rewardsCheckPoint > 0 { + txData += "@" + hex.EncodeToString(big.NewInt(int64(rewardsCheckPoint)).Bytes()) + } + vmOutput, err := l.eei.ExecuteOnDestContext(dstSCAddress, l.liquidStakingSCAddress, big.NewInt(0), []byte(txData)) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return nil, vmcommon.UserError + } + + if vmOutput.ReturnCode != vmcommon.Ok { + return nil, vmOutput.ReturnCode + } + + return vmOutput.ReturnData, vmcommon.Ok +} + +func (l *liquidStaking) createOrAddNFT( + delegationSCAddress []byte, + rewardsCheckpoint uint32, + value *big.Int, +) (uint64, error) { + attributes := &LiquidStakingAttributes{ + ContractAddress: delegationSCAddress, + RewardsCheckpoint: rewardsCheckpoint, + } + + marshalledData, err := l.marshalizer.Marshal(attributes) + if err != nil { + return 0, err + } + + hash := l.hasher.Compute(string(marshalledData)) + attrNonceKey := append([]byte(attributesNoncePrefix), hash...) + storageData := l.eei.GetStorage(attrNonceKey) + if len(storageData) > 0 { + nonce := big.NewInt(0).SetBytes(storageData).Uint64() + err = l.addQuantityToNFT(nonce, value) + if err != nil { + return 0, err + } + + return nonce, nil + } + + nonce, err := l.createNewNFT(value) + if err != nil { + return 0, nil + } + + return nonce, nil +} + +func (l *liquidStaking) createNewNFT(value *big.Int) (uint64, error) { + valuePlusOne := big.NewInt(0).Add(value, big.NewInt(1)) + + args := make([][]byte, 7) + args[0] = l.getTokenID() + args[1] = valuePlusOne.Bytes() + + vmOutput, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionESDTNFTCreate, args) + if err != nil { + return 0, err + } + if len(vmOutput.ReturnData) != 1 { + return 0, vm.ErrNotEnoughReturnData + } + + return big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64(), nil +} + +func (l *liquidStaking) addQuantityToNFT(nonce uint64, value *big.Int) error { + args := make([][]byte, 3) + args[0] = l.getTokenID() + args[1] = big.NewInt(0).SetUint64(nonce).Bytes() + args[2] = value.Bytes() + + _, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionESDTNFTAddQuantity, args) + if err != nil { + return err + } + + return nil +} + +func (l *liquidStaking) getAttributesForNonce(nonce uint64) (*LiquidStakingAttributes, error) { + return nil, nil +} + +func (l *liquidStaking) sendNFTMultiTransfer( + senderAddress []byte, + destinationAddress []byte, + listNonces []uint64, + listValue []*big.Int, +) error { + return nil +} + func (l *liquidStaking) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { returnCode := l.checkArgumentsWhenPositionIsInput(args) if returnCode != vmcommon.Ok { From 14caddb6211b2a2671b7e51fda9c326d2ba477cf Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 24 Aug 2021 17:28:58 +0300 Subject: [PATCH 012/958] claim multiple positions --- vm/systemSmartContracts/liquidStaking.go | 70 ++++++++++++++++++++---- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 7a6809d7eb7..ebea9228c3d 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -177,24 +177,28 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) l.eei.AddReturnMessage("function is not payable in eGLD") return vmcommon.UserError } - if len(args.Arguments) != 2 { + if len(args.Arguments) < 3 { l.eei.AddReturnMessage("not enough arguments") return vmcommon.UserError } - if len(args.Arguments)%2 != 0 { - l.eei.AddReturnMessage("invalid number of arguments") - return vmcommon.UserError - } if len(args.ESDTTransfers) > 0 { l.eei.AddReturnMessage("function is not payable in ESDT") return vmcommon.UserError } + numOfCalls := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() + minNumArguments := numOfCalls*2 + 1 + if int64(len(args.Arguments)) < minNumArguments { + l.eei.AddReturnMessage("invalid number of arguments") + return vmcommon.UserError + } + listNonces := make([]uint64, 0) listValues := make([]*big.Int, 0) - for i := 0; i < len(args.Arguments); i += 2 { - scAddress := args.Arguments[i] - valueToClaim := big.NewInt(0).SetBytes(args.Arguments[i+1]) + startIndex := int64(1) + for i := int64(0); i < numOfCalls; i++ { + scAddress := args.Arguments[startIndex+i*2] + valueToClaim := big.NewInt(0).SetBytes(args.Arguments[startIndex+i*2+1]) txData := "claimDelegatedPosition" + "@" + hex.EncodeToString(args.CallerAddr) + "@" + hex.EncodeToString(valueToClaim.Bytes()) vmOutput, err := l.eei.ExecuteOnDestContext(scAddress, args.RecipientAddr, big.NewInt(0), []byte(txData)) @@ -223,7 +227,11 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) listValues = append(listValues, valueToClaim) } - err := l.sendNFTMultiTransfer(args.RecipientAddr, args.CallerAddr, listNonces, listValues) + var additionalArgs [][]byte + if int64(len(args.Arguments)) > minNumArguments { + additionalArgs = args.Arguments[minNumArguments:] + } + err := l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, additionalArgs) if err != nil { l.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -289,6 +297,12 @@ func (l *liquidStaking) createOrAddNFT( return 0, nil } + nonceBytes := big.NewInt(0).SetUint64(nonce).Bytes() + l.eei.SetStorage(attrNonceKey, nonceBytes) + + nonceKey := append([]byte(nonceAttributesPrefix), nonceBytes...) + l.eei.SetStorage(nonceKey, marshalledData) + return nonce, nil } @@ -325,15 +339,49 @@ func (l *liquidStaking) addQuantityToNFT(nonce uint64, value *big.Int) error { } func (l *liquidStaking) getAttributesForNonce(nonce uint64) (*LiquidStakingAttributes, error) { - return nil, nil + nonceKey := append([]byte(nonceAttributesPrefix), big.NewInt(0).SetUint64(nonce).Bytes()...) + marshalledData := l.eei.GetStorage(nonceKey) + if len(marshalledData) == 0 { + return nil, vm.ErrEmptyStorage + } + + lAttr := &LiquidStakingAttributes{} + err := l.marshalizer.Unmarshal(lAttr, marshalledData) + if err != nil { + return nil, err + } + + return lAttr, nil } func (l *liquidStaking) sendNFTMultiTransfer( - senderAddress []byte, destinationAddress []byte, listNonces []uint64, listValue []*big.Int, + additionalArgs [][]byte, ) error { + + numOfTransfer := int64(len(listNonces)) + args := make([][]byte, 0) + args = append(args, destinationAddress) + args = append(args, big.NewInt(numOfTransfer).Bytes()) + + tokenID := l.getTokenID() + for i := 0; i < len(listNonces); i++ { + args = append(args, tokenID) + args = append(args, big.NewInt(0).SetUint64(listNonces[i]).Bytes()) + args = append(args, listValue[i].Bytes()) + } + + if len(additionalArgs) > 0 { + args = append(args, additionalArgs...) + } + + _, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionMultiESDTNFTTransfer, args) + if err != nil { + return err + } + return nil } From 856cf0c61efd7f3a886b04e34e5fe7c25cb3cf14 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 24 Aug 2021 19:17:50 +0300 Subject: [PATCH 013/958] fix after review --- examples/address_test.go | 3 ++ vm/systemSmartContracts/delegation.go | 8 +++-- vm/systemSmartContracts/eei.go | 2 -- vm/systemSmartContracts/esdt.go | 30 +++++++++---------- vm/systemSmartContracts/liquidStaking.go | 2 +- .../proto/liquidStaking.proto | 2 +- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/examples/address_test.go b/examples/address_test.go index cf5c098a031..b32e7220741 100644 --- a/examples/address_test.go +++ b/examples/address_test.go @@ -70,6 +70,7 @@ func TestSystemSCsAddressesAndSpecialAddresses(t *testing.T) { endOfEpochAddress := addressEncoder.Encode(vm.EndOfEpochAddress) delegationManagerScAddress := addressEncoder.Encode(vm.DelegationManagerSCAddress) firstDelegationScAddress := addressEncoder.Encode(vm.FirstDelegationSCAddress) + liquidStakingSCAddress := addressEncoder.Encode(vm.LiquidStakingSCAddress) header := []string{"Smart contract/Special address", "Address"} lines := []*display.LineData{ @@ -82,6 +83,7 @@ func TestSystemSCsAddressesAndSpecialAddresses(t *testing.T) { display.NewLineData(false, []string{"End of epoch address", endOfEpochAddress}), display.NewLineData(false, []string{"Delegation manager", delegationManagerScAddress}), display.NewLineData(false, []string{"First delegation", firstDelegationScAddress}), + display.NewLineData(false, []string{"Liquid staking", liquidStakingSCAddress}), } table, _ := display.CreateTableString(header, lines) @@ -96,4 +98,5 @@ func TestSystemSCsAddressesAndSpecialAddresses(t *testing.T) { assert.Equal(t, "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6", delegationManagerScAddress) assert.Equal(t, "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0llllsqkarq6", firstDelegationScAddress) assert.Equal(t, "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", contractDeployScAdress) + assert.Equal(t, "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9lllsm6xupm", liquidStakingSCAddress) } diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index c1c4003da56..b869f6ba075 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1825,7 +1825,9 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De isOwner := d.isOwner(callerAddress) totalRewards, err := d.computeRewards(delegator.RewardsCheckpoint, isOwner, activeFund.Value) - + if err != nil { + return err + } delegator.UnClaimedRewards.Add(delegator.UnClaimedRewards, totalRewards) currentEpoch := d.eei.BlockChainHook().CurrentEpoch() delegator.RewardsCheckpoint = currentEpoch + 1 @@ -2635,7 +2637,7 @@ func (d *delegation) basicCheckForLiquidStaking(args *vmcommon.ContractCallInput err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) if err != nil { d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError + return vmcommon.OutOfGas } address := args.Arguments[0] value := big.NewInt(0).SetBytes(args.Arguments[1]) @@ -2704,7 +2706,7 @@ func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInp } if len(args.Arguments) != 3 { - d.eei.AddReturnMessage("not enough arguments") + d.eei.AddReturnMessage("invalid number of arguments") return vmcommon.UserError } diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index ae269770400..154742c4988 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -233,8 +233,6 @@ func (host *vmContext) Transfer(destination []byte, sender []byte, value *big.In CallType: vmData.DirectCall, } destAcc.OutputTransfers = append(destAcc.OutputTransfers, outputTransfer) - - return } func (host *vmContext) copyToNewContext() *vmContext { diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 311d0eff1e5..b89c878d6b6 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -47,7 +47,7 @@ type esdt struct { gasCost vm.GasCost baseIssuingCost *big.Int ownerAddress []byte // do not use this in functions. Should use e.getEsdtOwner() - eSDTSCAddress []byte + esdtSCAddress []byte endOfEpochSCAddress []byte marshalizer marshal.Marshalizer hasher hashing.Hasher @@ -114,7 +114,7 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { //we should have called pubkeyConverter.Decode here instead of a byte slice cast. Since that change would break //backwards compatibility, the fix was carried in the epochStart/metachain/systemSCs.go ownerAddress: []byte(args.ESDTSCConfig.OwnerAddress), - eSDTSCAddress: args.ESDTSCAddress, + esdtSCAddress: args.ESDTSCAddress, hasher: args.Hasher, marshalizer: args.Marshalizer, enabledEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, @@ -232,7 +232,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm e.eei.AddReturnMessage("invalid method to call") return vmcommon.FunctionNotFound } - if !bytes.Equal(args.CallerAddr, e.eSDTSCAddress) { + if !bytes.Equal(args.CallerAddr, e.esdtSCAddress) { e.eei.AddReturnMessage("only system address can call this") return vmcommon.UserError } @@ -273,7 +273,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm } err = e.eei.ProcessBuiltInFunction( - e.eSDTSCAddress, + e.esdtSCAddress, vm.LiquidStakingSCAddress, core.BuiltInFunctionSetESDTRole, [][]byte{[]byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)}, @@ -363,7 +363,7 @@ func (e *esdt) issue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if initialSupply.Cmp(zero) > 0 { esdtTransferData := core.BuiltInFunctionESDTTransfer + "@" + hex.EncodeToString(tokenIdentifier) + "@" + hex.EncodeToString(initialSupply.Bytes()) - e.eei.Transfer(args.CallerAddr, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) + e.eei.Transfer(args.CallerAddr, e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) } else { e.eei.Finish(tokenIdentifier) } @@ -607,7 +607,7 @@ func (e *esdt) burn(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { } if !token.Burnable { esdtTransferData := core.BuiltInFunctionESDTTransfer + "@" + hex.EncodeToString(args.Arguments[0]) + "@" + hex.EncodeToString(args.Arguments[1]) - e.eei.Transfer(args.CallerAddr, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) + e.eei.Transfer(args.CallerAddr, e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) e.eei.AddReturnMessage("token is not burnable") return vmcommon.Ok } @@ -676,7 +676,7 @@ func (e *esdt) mint(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { } esdtTransferData := core.BuiltInFunctionESDTTransfer + "@" + hex.EncodeToString(args.Arguments[0]) + "@" + hex.EncodeToString(mintValue.Bytes()) - e.eei.Transfer(destination, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) + e.eei.Transfer(destination, e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) return vmcommon.Ok } @@ -701,7 +701,7 @@ func (e *esdt) toggleFreeze(args *vmcommon.ContractCallInput, builtInFunc string } esdtTransferData := builtInFunc + "@" + hex.EncodeToString(args.Arguments[0]) - e.eei.Transfer(args.Arguments[1], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) + e.eei.Transfer(args.Arguments[1], e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) return vmcommon.Ok } @@ -747,7 +747,7 @@ func (e *esdt) toggleFreezeSingleNFT(args *vmcommon.ContractCallInput, builtInFu composedArg := append(args.Arguments[0], args.Arguments[1]...) esdtTransferData := builtInFunc + "@" + hex.EncodeToString(composedArg) - e.eei.Transfer(args.Arguments[2], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) + e.eei.Transfer(args.Arguments[2], e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) return vmcommon.Ok } @@ -773,7 +773,7 @@ func (e *esdt) wipeTokenFromAddress( } esdtTransferData := core.BuiltInFunctionESDTWipe + "@" + hex.EncodeToString(wipeArgument) - e.eei.Transfer(address, e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) + e.eei.Transfer(address, e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferData), 0) token.NumWiped++ err := e.saveToken(tokenID, token) @@ -838,7 +838,7 @@ func (e *esdt) togglePause(args *vmcommon.ContractCallInput, builtInFunc string) } esdtTransferData := builtInFunc + "@" + hex.EncodeToString(args.Arguments[0]) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) return vmcommon.Ok } @@ -1256,7 +1256,7 @@ func (e *esdt) setSpecialRole(args *vmcommon.ContractCallInput) vmcommon.ReturnC firstTransferRoleSet := !transferRoleExists && isDefinedRoleInArgs(args.Arguments[2:], []byte(core.ESDTRoleTransfer)) if firstTransferRoleSet { esdtTransferData := core.BuiltInFunctionESDTSetLimitedTransfer + "@" + hex.EncodeToString(args.Arguments[0]) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } return vmcommon.Ok @@ -1314,7 +1314,7 @@ func (e *esdt) unSetSpecialRole(args *vmcommon.ContractCallInput) vmcommon.Retur lastTransferRoleWasDeleted := isDefinedRoleInArgs(args.Arguments[2:], []byte(core.ESDTRoleTransfer)) && !transferRoleExists if lastTransferRoleWasDeleted { esdtTransferData := core.BuiltInFunctionESDTUnSetLimitedTransfer + "@" + hex.EncodeToString(args.Arguments[0]) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } err := e.saveToken(args.Arguments[0], token) @@ -1397,7 +1397,7 @@ func (e *esdt) transferNFTCreateRole(args *vmcommon.ContractCallInput) vmcommon. esdtTransferNFTCreateData := core.BuiltInFunctionESDTNFTCreateRoleTransfer + "@" + hex.EncodeToString(args.Arguments[0]) + "@" + hex.EncodeToString(args.Arguments[2]) - e.eei.Transfer(args.Arguments[1], e.eSDTSCAddress, big.NewInt(0), []byte(esdtTransferNFTCreateData), 0) + e.eei.Transfer(args.Arguments[1], e.esdtSCAddress, big.NewInt(0), []byte(esdtTransferNFTCreateData), 0) return vmcommon.Ok } @@ -1444,7 +1444,7 @@ func (e *esdt) sendRoleChangeData(tokenID []byte, destination []byte, roles [][] esdtSetRoleData += "@" + hex.EncodeToString(arg) } - e.eei.Transfer(destination, e.eSDTSCAddress, big.NewInt(0), []byte(esdtSetRoleData), 0) + e.eei.Transfer(destination, e.esdtSCAddress, big.NewInt(0), []byte(esdtSetRoleData), 0) } func (e *esdt) getAllAddressesAndRoles(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 8933cbf7b75..a17ed1b7f12 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -127,7 +127,7 @@ func (l *liquidStaking) init(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return vmcommon.UserError } if args.CallValue.Cmp(zero) != 0 { - l.eei.AddReturnMessage("not a payable function") + l.eei.AddReturnMessage("function is not payable in eGLD") return vmcommon.UserError } if len(args.Arguments) != 1 { diff --git a/vm/systemSmartContracts/proto/liquidStaking.proto b/vm/systemSmartContracts/proto/liquidStaking.proto index a0fd3faf587..b9e46450c9d 100644 --- a/vm/systemSmartContracts/proto/liquidStaking.proto +++ b/vm/systemSmartContracts/proto/liquidStaking.proto @@ -10,4 +10,4 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; message LiquidStakingAttributes { bytes ContractAddress = 1 [(gogoproto.jsontag) = "ContractAddress"]; uint32 RewardsCheckpoint = 2 [(gogoproto.jsontag) = "RewardsCheckpoint"]; -} \ No newline at end of file +} From f3e4134ef4e76e7245b48ada5ea5bce4a4c029c5 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 25 Aug 2021 13:04:32 +0300 Subject: [PATCH 014/958] implementation done --- vm/systemSmartContracts/liquidStaking.go | 246 ++++++++++++++++++----- 1 file changed, 192 insertions(+), 54 deletions(-) diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index edfa7d8fb4f..1fba22ff9a2 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -114,10 +114,10 @@ func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.Retur return l.claimRewardsFromDelegatedPosition(args) case "reDelegateRewardsFromPosition": return l.reDelegateRewardsFromPosition(args) - case "unDelegateWithPosition": - return l.unDelegateWithPosition(args) + case "unDelegatePosition": + return l.returnLiquidStaking(args, "unDelegateViaLiquidStaking") case "returnPosition": - return l.returnPosition(args) + return l.returnLiquidStaking(args, "returnViaLiquidStaking") } l.eei.AddReturnMessage(args.Function + " is an unknown function") @@ -192,46 +192,151 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) l.eei.AddReturnMessage("invalid number of arguments") return vmcommon.UserError } + err := l.eei.UseGas(uint64(numOfCalls) * l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.OutOfGas + } listNonces := make([]uint64, 0) listValues := make([]*big.Int, 0) startIndex := int64(1) for i := int64(0); i < numOfCalls; i++ { - scAddress := args.Arguments[startIndex+i*2] - valueToClaim := big.NewInt(0).SetBytes(args.Arguments[startIndex+i*2+1]) + callStartIndex := startIndex + i*2 + nonce, valueToClaim, returnCode := l.claimOneDelegatedPosition(args.CallerAddr, args.Arguments[callStartIndex], args.Arguments[callStartIndex+1]) + if returnCode != vmcommon.Ok { + return returnCode + } + + listNonces = append(listNonces, nonce) + listValues = append(listValues, valueToClaim) + } + + var additionalArgs [][]byte + if int64(len(args.Arguments)) > minNumArguments { + additionalArgs = args.Arguments[minNumArguments:] + } + err = l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, additionalArgs) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } - txData := "claimDelegatedPosition" + "@" + hex.EncodeToString(args.CallerAddr) + "@" + hex.EncodeToString(valueToClaim.Bytes()) - vmOutput, err := l.eei.ExecuteOnDestContext(scAddress, args.RecipientAddr, big.NewInt(0), []byte(txData)) + return vmcommon.Ok +} + +func (l *liquidStaking) claimOneDelegatedPosition( + callerAddr []byte, + destSCAddress []byte, + valueAsBytes []byte, +) (uint64, *big.Int, vmcommon.ReturnCode) { + if len(destSCAddress) != len(l.liquidStakingSCAddress) || bytes.Equal(destSCAddress, l.liquidStakingSCAddress) { + l.eei.AddReturnMessage("invalid destination SC address") + return 0, nil, vmcommon.UserError + } + + valueToClaim := big.NewInt(0).SetBytes(valueAsBytes) + returnData, returnCode := l.executeOnDestinationSC( + destSCAddress, + "claimRewardsViaLiquidStaking", + callerAddr, + valueToClaim, + 0, + ) + if returnCode != vmcommon.Ok { + return 0, nil, returnCode + } + + if len(returnData) != 1 { + l.eei.AddReturnMessage("invalid return data") + return 0, nil, vmcommon.UserError + } + + rewardsCheckpoint := uint32(big.NewInt(0).SetBytes(returnData[0]).Uint64()) + nonce, err := l.createOrAddNFT(destSCAddress, rewardsCheckpoint, valueToClaim) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return 0, nil, vmcommon.UserError + } + + return nonce, valueToClaim, vmcommon.Ok +} + +func (l *liquidStaking) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } + + listNonces := make([]uint64, 0) + listValues := make([]*big.Int, 0) + for _, esdtTransfer := range args.ESDTTransfers { + attributes, _, execCode := l.burnAndExecuteFromESDTTransfer( + args.CallerAddr, + esdtTransfer, + "claimRewardsViaLiquidStaking", + ) + if execCode != vmcommon.Ok { + return execCode + } + + newCheckpoint := l.eei.BlockChainHook().CurrentEpoch() + 1 + nonce, err := l.createOrAddNFT(attributes.ContractAddress, newCheckpoint, esdtTransfer.ESDTValue) if err != nil { l.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - if vmOutput.ReturnCode != vmcommon.Ok { - return vmOutput.ReturnCode - } + listNonces = append(listNonces, nonce) + listValues = append(listValues, esdtTransfer.ESDTValue) + } + + err := l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, args.Arguments) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} - if len(vmOutput.ReturnData) != 1 { +func (l *liquidStaking) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } + + listNonces := make([]uint64, 0) + listValues := make([]*big.Int, 0) + for _, esdtTransfer := range args.ESDTTransfers { + attributes, returnData, execCode := l.burnAndExecuteFromESDTTransfer( + args.CallerAddr, + esdtTransfer, + "reDelegateRewardsViaLiquidStaking", + ) + if execCode != vmcommon.Ok { + return execCode + } + if len(returnData) != 1 { l.eei.AddReturnMessage("invalid return data") return vmcommon.UserError } - rewardsCheckpoint := uint32(big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64()) - nonce, err := l.createOrAddNFT(scAddress, rewardsCheckpoint, valueToClaim) + earnedRewards := big.NewInt(0).SetBytes(returnData[0]) + totalToCreate := big.NewInt(0).Add(esdtTransfer.ESDTValue, earnedRewards) + newCheckpoint := l.eei.BlockChainHook().CurrentEpoch() + 1 + + nonce, err := l.createOrAddNFT(attributes.ContractAddress, newCheckpoint, totalToCreate) if err != nil { l.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } listNonces = append(listNonces, nonce) - listValues = append(listValues, valueToClaim) + listValues = append(listValues, totalToCreate) } - var additionalArgs [][]byte - if int64(len(args.Arguments)) > minNumArguments { - additionalArgs = args.Arguments[minNumArguments:] - } - err := l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, additionalArgs) + err := l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, args.Arguments) if err != nil { l.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -240,6 +345,60 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) return vmcommon.Ok } +func (l *liquidStaking) returnLiquidStaking( + args *vmcommon.ContractCallInput, + functionToCall string, +) vmcommon.ReturnCode { + returnCode := l.checkArgumentsWhenPositionIsInput(args) + if returnCode != vmcommon.Ok { + return returnCode + } + + for _, esdtTransfer := range args.ESDTTransfers { + _, _, returnCode = l.burnAndExecuteFromESDTTransfer( + args.CallerAddr, + esdtTransfer, + functionToCall, + ) + if returnCode != vmcommon.Ok { + return returnCode + } + } + + return vmcommon.Ok +} + +func (l *liquidStaking) burnAndExecuteFromESDTTransfer( + callerAddr []byte, + esdtTransfer *vmcommon.ESDTTransfer, + functionToCall string, +) (*LiquidStakingAttributes, [][]byte, vmcommon.ReturnCode) { + attributes, err := l.getAttributesForNonce(esdtTransfer.ESDTTokenNonce) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return nil, nil, vmcommon.UserError + } + + err = l.burnNFT(esdtTransfer.ESDTTokenNonce, esdtTransfer.ESDTValue) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return nil, nil, vmcommon.UserError + } + + returnData, returnCode := l.executeOnDestinationSC( + attributes.ContractAddress, + functionToCall, + callerAddr, + esdtTransfer.ESDTValue, + attributes.RewardsCheckpoint, + ) + if returnCode != vmcommon.Ok { + return nil, nil, returnCode + } + + return attributes, returnData, vmcommon.Ok +} + func (l *liquidStaking) executeOnDestinationSC( dstSCAddress []byte, functionToCall string, @@ -338,6 +497,20 @@ func (l *liquidStaking) addQuantityToNFT(nonce uint64, value *big.Int) error { return nil } +func (l *liquidStaking) burnNFT(nonce uint64, value *big.Int) error { + args := make([][]byte, 3) + args[0] = l.getTokenID() + args[1] = big.NewInt(0).SetUint64(nonce).Bytes() + args[2] = value.Bytes() + + _, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionESDTNFTBurn, args) + if err != nil { + return err + } + + return nil +} + func (l *liquidStaking) getAttributesForNonce(nonce uint64) (*LiquidStakingAttributes, error) { nonceKey := append([]byte(nonceAttributesPrefix), big.NewInt(0).SetUint64(nonce).Bytes()...) marshalledData := l.eei.GetStorage(nonceKey) @@ -385,41 +558,6 @@ func (l *liquidStaking) sendNFTMultiTransfer( return nil } -func (l *liquidStaking) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - return vmcommon.Ok -} - -func (l *liquidStaking) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - return vmcommon.Ok -} - -func (l *liquidStaking) unDelegateWithPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - return vmcommon.Ok -} - -func (l *liquidStaking) returnPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - return vmcommon.Ok -} - // SetNewGasCost is called whenever a gas cost was changed func (l *liquidStaking) SetNewGasCost(gasCost vm.GasCost) { l.mutExecution.Lock() From db6bb033764a09cda45cccd3808048d2946850d3 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 25 Aug 2021 16:59:55 +0300 Subject: [PATCH 015/958] fix after review --- vm/errors.go | 4 ++-- vm/systemSmartContracts/delegation.go | 18 +++++++-------- vm/systemSmartContracts/liquidStaking.go | 28 ++++++++++++------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/vm/errors.go b/vm/errors.go index fa298366e0d..c2ef061ea06 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -251,5 +251,5 @@ var ErrInvalidNumOfInitialWhiteListedAddress = errors.New("0 initial whiteListed // ErrInvalidDelegationTicker signals that invalid delegation ticker name was provided var ErrInvalidDelegationTicker = errors.New("invalid delegation ticker name") -// ErrNotEnoughReturnData signals that not enough return data was provided -var ErrNotEnoughReturnData = errors.New("not enough return data") +// ErrInvalidReturnData signals that invalid return data was provided +var ErrInvalidReturnData = errors.New("invalid return data") diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index a32e8bcd122..ae48e2fd39b 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1433,11 +1433,11 @@ func (d *delegation) addToActiveFund( } return nil - } else { - err := d.addValueToFund(delegator.ActiveFund, delegateValue) - if err != nil { - return err - } + } + + err := d.addValueToFund(delegator.ActiveFund, delegateValue) + if err != nil { + return err } return nil @@ -2740,7 +2740,7 @@ func (d *delegation) reDelegateRewardsViaLiquidStaking(args *vmcommon.ContractCa return returnCode } if len(args.Arguments) != 3 { - d.eei.AddReturnMessage("not enough arguments") + d.eei.AddReturnMessage("invalid number of arguments") return vmcommon.UserError } @@ -2775,7 +2775,7 @@ func (d *delegation) reDelegateRewardsViaLiquidStaking(args *vmcommon.ContractCa } d.eei.Finish(totalRewards.Bytes()) - return vmcommon.UserError + return vmcommon.Ok } func (d *delegation) executeStakeAndUpdateStatus( @@ -2835,7 +2835,7 @@ func (d *delegation) getConfigStatusAndGlobalFund() (*DelegationConfig, *Delegat func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { returnCode := d.returnViaLiquidStaking(args) - if returnCode != vmcommon.UserError { + if returnCode != vmcommon.Ok { return returnCode } @@ -2850,7 +2850,7 @@ func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vm return returnCode } if len(args.Arguments) != 3 { - d.eei.AddReturnMessage("not enough arguments") + d.eei.AddReturnMessage("invalid number of arguments") return vmcommon.UserError } diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 1fba22ff9a2..486d1fe2fb6 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -189,7 +189,7 @@ func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) numOfCalls := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() minNumArguments := numOfCalls*2 + 1 if int64(len(args.Arguments)) < minNumArguments { - l.eei.AddReturnMessage("invalid number of arguments") + l.eei.AddReturnMessage("not enough arguments") return vmcommon.UserError } err := l.eei.UseGas(uint64(numOfCalls) * l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) @@ -379,7 +379,7 @@ func (l *liquidStaking) burnAndExecuteFromESDTTransfer( return nil, nil, vmcommon.UserError } - err = l.burnNFT(esdtTransfer.ESDTTokenNonce, esdtTransfer.ESDTValue) + err = l.burnSFT(esdtTransfer.ESDTTokenNonce, esdtTransfer.ESDTValue) if err != nil { l.eei.AddReturnMessage(err.Error()) return nil, nil, vmcommon.UserError @@ -433,17 +433,17 @@ func (l *liquidStaking) createOrAddNFT( RewardsCheckpoint: rewardsCheckpoint, } - marshalledData, err := l.marshalizer.Marshal(attributes) + marshaledData, err := l.marshalizer.Marshal(attributes) if err != nil { return 0, err } - hash := l.hasher.Compute(string(marshalledData)) + hash := l.hasher.Compute(string(marshaledData)) attrNonceKey := append([]byte(attributesNoncePrefix), hash...) storageData := l.eei.GetStorage(attrNonceKey) if len(storageData) > 0 { nonce := big.NewInt(0).SetBytes(storageData).Uint64() - err = l.addQuantityToNFT(nonce, value) + err = l.addQuantityToSFT(nonce, value) if err != nil { return 0, err } @@ -451,7 +451,7 @@ func (l *liquidStaking) createOrAddNFT( return nonce, nil } - nonce, err := l.createNewNFT(value) + nonce, err := l.createNewSFT(value) if err != nil { return 0, nil } @@ -460,12 +460,12 @@ func (l *liquidStaking) createOrAddNFT( l.eei.SetStorage(attrNonceKey, nonceBytes) nonceKey := append([]byte(nonceAttributesPrefix), nonceBytes...) - l.eei.SetStorage(nonceKey, marshalledData) + l.eei.SetStorage(nonceKey, marshaledData) return nonce, nil } -func (l *liquidStaking) createNewNFT(value *big.Int) (uint64, error) { +func (l *liquidStaking) createNewSFT(value *big.Int) (uint64, error) { valuePlusOne := big.NewInt(0).Add(value, big.NewInt(1)) args := make([][]byte, 7) @@ -477,13 +477,13 @@ func (l *liquidStaking) createNewNFT(value *big.Int) (uint64, error) { return 0, err } if len(vmOutput.ReturnData) != 1 { - return 0, vm.ErrNotEnoughReturnData + return 0, vm.ErrInvalidReturnData } return big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64(), nil } -func (l *liquidStaking) addQuantityToNFT(nonce uint64, value *big.Int) error { +func (l *liquidStaking) addQuantityToSFT(nonce uint64, value *big.Int) error { args := make([][]byte, 3) args[0] = l.getTokenID() args[1] = big.NewInt(0).SetUint64(nonce).Bytes() @@ -497,7 +497,7 @@ func (l *liquidStaking) addQuantityToNFT(nonce uint64, value *big.Int) error { return nil } -func (l *liquidStaking) burnNFT(nonce uint64, value *big.Int) error { +func (l *liquidStaking) burnSFT(nonce uint64, value *big.Int) error { args := make([][]byte, 3) args[0] = l.getTokenID() args[1] = big.NewInt(0).SetUint64(nonce).Bytes() @@ -513,13 +513,13 @@ func (l *liquidStaking) burnNFT(nonce uint64, value *big.Int) error { func (l *liquidStaking) getAttributesForNonce(nonce uint64) (*LiquidStakingAttributes, error) { nonceKey := append([]byte(nonceAttributesPrefix), big.NewInt(0).SetUint64(nonce).Bytes()...) - marshalledData := l.eei.GetStorage(nonceKey) - if len(marshalledData) == 0 { + marshaledData := l.eei.GetStorage(nonceKey) + if len(marshaledData) == 0 { return nil, vm.ErrEmptyStorage } lAttr := &LiquidStakingAttributes{} - err := l.marshalizer.Unmarshal(lAttr, marshalledData) + err := l.marshalizer.Unmarshal(lAttr, marshaledData) if err != nil { return nil, err } From 322637a89dcfe88d9fd90a2d36d412a16a0b1c39 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 25 Aug 2021 17:07:06 +0300 Subject: [PATCH 016/958] simplify --- vm/systemSmartContracts/delegation.go | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index ae48e2fd39b..cb4926d0b9d 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1420,26 +1420,20 @@ func (d *delegation) addToActiveFund( dStatus *DelegationContractStatus, isNew bool, ) error { - if len(delegator.ActiveFund) == 0 { - var fundKey []byte - fundKey, err := d.createAndSaveNextKeyFund(callerAddr, delegateValue, active) - if err != nil { - return err - } - - delegator.ActiveFund = fundKey - if isNew { - dStatus.NumUsers++ - } - - return nil + if len(delegator.ActiveFund) > 0 { + return d.addValueToFund(delegator.ActiveFund, delegateValue) } - err := d.addValueToFund(delegator.ActiveFund, delegateValue) + fundKey, err := d.createAndSaveNextKeyFund(callerAddr, delegateValue, active) if err != nil { return err } + delegator.ActiveFund = fundKey + if isNew { + dStatus.NumUsers++ + } + return nil } From 0ddbe6a02aacf77a5321d4efcd722161a9c991c8 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 26 Aug 2021 14:03:38 +0300 Subject: [PATCH 017/958] simplify --- vm/systemSmartContracts/delegation.go | 7 + vm/systemSmartContracts/delegation_test.go | 204 +++++++++++++++++++++ 2 files changed, 211 insertions(+) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index cb4926d0b9d..4f1b2520f43 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -2641,6 +2641,10 @@ func (d *delegation) basicCheckForLiquidStaking(args *vmcommon.ContractCallInput d.eei.AddReturnMessage("invalid address as input") return vmcommon.UserError } + if d.isOwner(address) { + d.eei.AddReturnMessage("owner of delegation cannot call liquid staking operations") + return vmcommon.UserError + } delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) if err != nil { @@ -2693,6 +2697,9 @@ func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vm d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } + if activeFund.Value.Cmp(zero) == 0 { + delegator.ActiveFund = nil + } err = d.deleteDelegatorIfNeeded(args.CallerAddr, delegator) if err != nil { diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index d59619c4a1d..fa85efd8432 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -4985,3 +4985,207 @@ func TestDelegation_GetWhitelistForMerge(t *testing.T) { require.Equal(t, 1, len(eei.output)) assert.Equal(t, addr, eei.output[0]) } + +func createDelegationContractAndEEI() (*delegation, *vmContext) { + args := createMockArgumentsForDelegation() + eei, _ := NewVMContext( + &mock.BlockChainHookStub{ + CurrentEpochCalled: func() uint32 { + return 2 + }, + }, + hooks.NewVMCryptoHook(), + &mock.ArgumentParserMock{}, + &stateMock.AccountsStub{}, + &mock.RaterMock{}, + ) + systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok + }}, nil + }} + + _ = eei.SetSystemSCContainer(systemSCContainerStub) + + args.Eei = eei + args.DelegationSCConfig.MaxServiceFee = 10000 + args.DelegationSCConfig.MinServiceFee = 0 + d, _ := NewDelegationSystemSC(args) + + managementData := &DelegationManagement{ + MinDeposit: big.NewInt(10), + MinDelegationAmount: big.NewInt(10), + } + marshaledData, _ := d.marshalizer.Marshal(managementData) + eei.SetStorageForAddress(d.delegationMgrSCAddress, []byte(delegationManagementKey), marshaledData) + + return d, eei +} + +func TestDelegation_FailsIfESDTTransfers(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10)}} + + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "cannot transfer ESDT to system SCs") +} + +func TestDelegation_BasicCheckForLiquidStaking(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) + + d.flagLiquidStaking.Unset() + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, vmInput.Function+" is an unknown function") + + eei.returnMessage = "" + d.flagLiquidStaking.Set() + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") + + eei.returnMessage = "" + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.CallValue = big.NewInt(10) + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "call value must be 0") + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(0) + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "not enough arguments") + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{{1}, {2}} + eei.gasRemaining = 0 + d.gasCost.MetaChainSystemSCsCost.DelegationOps = 1 + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.OutOfGas, returnCode) + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{{1}, {0}} + eei.gasRemaining = 10000 + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid argument for value as bigInt") + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{{1}, {1}} + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid address as input") + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{vm.LiquidStakingSCAddress, {1}} + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "call value below minimum to operate") + + eei.SetStorageForAddress(d.delegationMgrSCAddress, []byte(delegationManagementKey), nil) + eei.returnMessage = "" + vmInput.Arguments = [][]byte{vm.LiquidStakingSCAddress, {1}} + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key getDelegationManagementData") + + eei.returnMessage = "" + d.eei.SetStorage([]byte(ownerKey), vm.LiquidStakingSCAddress) + vmInput.Arguments = [][]byte{vm.LiquidStakingSCAddress, {1}} + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "owner of delegation cannot call liquid staking operations") +} + +func TestDelegation_ClaimDelegatedPosition(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) + + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") + + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "caller is not a delegator") + + delegator := &DelegatorData{ + RewardsCheckpoint: 10, + UnClaimedRewards: big.NewInt(0), + } + _ = d.saveDelegatorData(userAddress, delegator) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key getFund ") + + _ = d.addToActiveFund(userAddress, delegator, big.NewInt(5), &DelegationContractStatus{}, true) + _ = d.saveDelegatorData(userAddress, delegator) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "not enough funds to claim position") + + _ = d.addToActiveFund(userAddress, delegator, big.NewInt(5), &DelegationContractStatus{}, true) + _ = d.saveDelegatorData(userAddress, delegator) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key delegation status") + + _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) + delegator.ActiveFund = nil + _ = d.addToActiveFund(userAddress, delegator, big.NewInt(10), &DelegationContractStatus{}, true) + _ = d.saveDelegatorData(userAddress, delegator) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + assert.Equal(t, big.NewInt(0).SetBytes(eei.output[0]).Int64(), int64(10)) +} + +func TestDelegation_ClaimRewardsViaLiquidStaking(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) + + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") + + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid number of arguments") + + vmInput.Arguments = append(vmInput.Arguments, big.NewInt(1).Bytes()) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "not enough funds to claim position") + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + assert.Equal(t, big.NewInt(0).SetBytes(eei.output[0]).Int64(), int64(10)) +} From c975951e7bbe5e91888701009c4ec63adb6c287a Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 26 Aug 2021 16:42:33 +0300 Subject: [PATCH 018/958] added a lot of unit tests --- vm/errors.go | 3 + vm/systemSmartContracts/delegation.go | 61 ++++-- vm/systemSmartContracts/delegation_test.go | 224 ++++++++++++++++++++- vm/systemSmartContracts/liquidStaking.go | 11 +- 4 files changed, 270 insertions(+), 29 deletions(-) diff --git a/vm/errors.go b/vm/errors.go index c2ef061ea06..aed7482394d 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -253,3 +253,6 @@ var ErrInvalidDelegationTicker = errors.New("invalid delegation ticker name") // ErrInvalidReturnData signals that invalid return data was provided var ErrInvalidReturnData = errors.New("invalid return data") + +// ErrNotEnoughRemainingFunds signals that operation is invalid as remaining funds are below minimum +var ErrNotEnoughRemainingFunds = errors.New("not enough remaining funds - do not leave dust behind") diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 4f1b2520f43..5d4c875ed56 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1602,19 +1602,13 @@ func (d *delegation) unDelegateValueFromAddress( return vmcommon.UserError } - delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) - if err != nil { - d.eei.AddReturnMessage("error getting minimum delegation amount " + err.Error()) - return vmcommon.UserError - } - - minDelegationAmount := delegationManagement.MinDelegationAmount - remainedFund := big.NewInt(0).Sub(activeFund.Value, valueToUnDelegate) - if remainedFund.Cmp(zero) > 0 && remainedFund.Cmp(minDelegationAmount) < 0 { + err = d.checkRemainingFundValue(remainedFund) + if err != nil { d.eei.AddReturnMessage("invalid value to undelegate - need to undelegate all - do not leave dust behind") return vmcommon.UserError } + err = d.checkOwnerCanUnDelegate(delegatorAddress, activeFund, valueToUnDelegate) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -1683,6 +1677,20 @@ func (d *delegation) unDelegateValueFromAddress( return vmcommon.Ok } +func (d *delegation) checkRemainingFundValue(remainedFund *big.Int) error { + delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) + if err != nil { + return err + } + + minDelegationAmount := delegationManagement.MinDelegationAmount + if remainedFund.Cmp(zero) > 0 && remainedFund.Cmp(minDelegationAmount) < 0 { + return vm.ErrNotEnoughRemainingFunds + } + + return nil +} + func (d *delegation) addNewUnStakedFund( delegatorAddress []byte, delegator *DelegatorData, @@ -1804,8 +1812,12 @@ func (d *delegation) saveRewardData(epoch uint32, rewardsData *RewardComputation } func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *DelegatorData) error { + currentEpoch := d.eei.BlockChainHook().CurrentEpoch() if len(delegator.ActiveFund) == 0 { // nothing to calculate as no active funds - all were computed before + if d.flagLiquidStaking.IsSet() { + delegator.RewardsCheckpoint = currentEpoch + 1 + } return nil } @@ -1821,7 +1833,6 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De return err } delegator.UnClaimedRewards.Add(delegator.UnClaimedRewards, totalRewards) - currentEpoch := d.eei.BlockChainHook().CurrentEpoch() delegator.RewardsCheckpoint = currentEpoch + 1 return nil @@ -2691,23 +2702,41 @@ func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vm return vmcommon.UserError } + err = d.computeAndUpdateRewards(address, delegator) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + activeFund.Value.Sub(activeFund.Value, value) + err = d.checkRemainingFundValue(activeFund.Value) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + err = d.saveFund(delegator.ActiveFund, activeFund) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } + if activeFund.Value.Cmp(zero) == 0 { delegator.ActiveFund = nil } - err = d.deleteDelegatorIfNeeded(args.CallerAddr, delegator) + err = d.saveDelegatorData(address, delegator) + if err != nil { + d.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + err = d.deleteDelegatorIfNeeded(address, delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - d.eei.Finish(big.NewInt(int64(delegator.RewardsCheckpoint)).Bytes()) return vmcommon.Ok } @@ -2731,7 +2760,7 @@ func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInp return vmcommon.UserError } - d.eei.Transfer(args.CallerAddr, address, totalRewards, nil, 0) + d.eei.Transfer(address, args.RecipientAddr, totalRewards, nil, 0) return vmcommon.Ok } @@ -2858,7 +2887,7 @@ func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vm address := args.Arguments[0] value := big.NewInt(0).SetBytes(args.Arguments[1]) checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) - totalRewards, err := d.computeRewards(checkPoint, false, value) + rewardsFromPosition, err := d.computeRewards(checkPoint, false, value) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -2881,8 +2910,8 @@ func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vm return vmcommon.UserError } - totalValue := big.NewInt(0).Add(totalRewards, value) - err = d.addToActiveFund(address, delegator, totalValue, dStatus, isNew) + delegator.UnClaimedRewards.Add(delegator.UnClaimedRewards, rewardsFromPosition) + err = d.addToActiveFund(address, delegator, value, dStatus, isNew) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index fa85efd8432..6b792181f1d 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -5150,20 +5150,102 @@ func TestDelegation_ClaimDelegatedPosition(t *testing.T) { _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) delegator.ActiveFund = nil - _ = d.addToActiveFund(userAddress, delegator, big.NewInt(10), &DelegationContractStatus{}, true) + _ = d.addToActiveFund(userAddress, delegator, big.NewInt(11), &DelegationContractStatus{}, true) _ = d.saveDelegatorData(userAddress, delegator) eei.returnMessage = "" + vmInput.Arguments[1] = big.NewInt(10).Bytes() + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, vm.ErrNotEnoughRemainingFunds.Error()) + + eei.returnMessage = "" + vmInput.Arguments[1] = big.NewInt(11).Bytes() returnCode = d.Execute(vmInput) assert.Equal(t, vmcommon.Ok, returnCode) - assert.Equal(t, big.NewInt(0).SetBytes(eei.output[0]).Int64(), int64(10)) + + isNew, _, _ := d.getOrCreateDelegatorData(userAddress) + assert.True(t, isNew) } -func TestDelegation_ClaimRewardsViaLiquidStaking(t *testing.T) { +func TestDelegation_ClaimDelegatedPositionUserRemainsRewardsComputed(t *testing.T) { d, eei := createDelegationContractAndEEI() userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) + vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} + vmInput.CallerAddr = vm.LiquidStakingSCAddress + + delegator := &DelegatorData{ + RewardsCheckpoint: 0, + UnClaimedRewards: big.NewInt(0), + } + + _ = d.addToActiveFund(userAddress, delegator, big.NewInt(25), &DelegationContractStatus{}, true) + _ = d.saveDelegatorData(userAddress, delegator) + _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) + + _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(25)}) + _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(25)}) + + eei.returnMessage = "" + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + assert.Equal(t, eei.returnMessage, "") + + isNew, delegator, _ := d.getOrCreateDelegatorData(userAddress) + assert.False(t, isNew) + fund, _ := d.getFund(delegator.ActiveFund) + assert.Equal(t, fund.Value, big.NewInt(15)) + assert.Equal(t, delegator.RewardsCheckpoint, uint32(3)) + assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(20)) + + vmInput.Arguments[1] = fund.Value.Bytes() + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + assert.Equal(t, eei.returnMessage, "") + + _, delegator, _ = d.getOrCreateDelegatorData(userAddress) + assert.Equal(t, len(delegator.ActiveFund), 0) + assert.Equal(t, delegator.RewardsCheckpoint, uint32(3)) + assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(20)) +} + +func TestDelegation_ClaimRewardsViaLiquidStaking(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + vmInput := getDefaultVmInputForFunc("claimRewardsViaLiquidStaking", make([][]byte, 0)) + + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") + + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid number of arguments") + + vmInput.Arguments = append(vmInput.Arguments, big.NewInt(1).Bytes()) + + _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) + _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + outAcc := eei.outputAccounts[string(userAddress)] + assert.Equal(t, big.NewInt(20), outAcc.OutputTransfers[0].Value) +} + +func TestDelegation_ReDelegateRewardsViaLiquidStaking(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + vmInput := getDefaultVmInputForFunc("reDelegateRewardsViaLiquidStaking", make([][]byte, 0)) returnCode := d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) @@ -5182,10 +5264,142 @@ func TestDelegation_ClaimRewardsViaLiquidStaking(t *testing.T) { eei.returnMessage = "" returnCode = d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "not enough funds to claim position") + assert.Equal(t, eei.returnMessage, "no rewards to redelegate via liquid staking") + + _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) + _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key delegation contract config") + + _ = d.saveDelegationContractConfig(&DelegationConfig{MaxDelegationCap: big.NewInt(20), CheckCapOnReDelegateRewards: true}) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key getGlobalFundData") + + _ = d.saveGlobalFundData(&GlobalFundData{TotalActive: big.NewInt(10), TotalUnStaked: big.NewInt(0)}) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key delegation status") + + _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "total delegation cap reached") + + _ = d.saveDelegationContractConfig(&DelegationConfig{MaxDelegationCap: big.NewInt(20)}) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + assert.Equal(t, eei.output[0], big.NewInt(20).Bytes()) + + systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + eei.AddReturnMessage("bad call") + return vmcommon.UserError + }}, nil + }} + + _ = eei.SetSystemSCContainer(systemSCContainerStub) + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "bad call") +} + +func TestDelegation_UnDelegateViaLiquidStaking(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + vmInput := getDefaultVmInputForFunc("unDelegateViaLiquidStaking", make([][]byte, 0)) + + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") + + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid number of arguments") + + eei.returnMessage = "" + vmInput.Arguments = append(vmInput.Arguments, []byte{1}) + _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) + _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) + _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "data was not found under requested key getGlobalFundData") + + d.eei.SetStorage(userAddress, nil) eei.returnMessage = "" + _ = d.saveGlobalFundData(&GlobalFundData{TotalActive: big.NewInt(10), TotalUnStaked: big.NewInt(100)}) returnCode = d.Execute(vmInput) assert.Equal(t, vmcommon.Ok, returnCode) - assert.Equal(t, big.NewInt(0).SetBytes(eei.output[0]).Int64(), int64(10)) + + _, delegator, _ := d.getOrCreateDelegatorData(userAddress) + assert.Equal(t, len(delegator.ActiveFund), 0) + assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(10)) + assert.Equal(t, len(delegator.UnStakedFunds), 1) + unStakedFund, _ := d.getFund(delegator.UnStakedFunds[0]) + assert.Equal(t, unStakedFund.Value, big.NewInt(10)) + + globalFund, _ := d.getGlobalFundData() + assert.Equal(t, globalFund.TotalUnStaked, big.NewInt(110)) + assert.Equal(t, globalFund.TotalActive, big.NewInt(0)) +} + +func TestDelegation_ReturnViaLiquidStaking(t *testing.T) { + d, eei := createDelegationContractAndEEI() + + userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + vmInput := getDefaultVmInputForFunc("returnViaLiquidStaking", make([][]byte, 0)) + + returnCode := d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") + + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid number of arguments") + + _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) + _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) + + delegator := &DelegatorData{RewardsCheckpoint: 0, TotalCumulatedRewards: big.NewInt(0), UnClaimedRewards: big.NewInt(0)} + _ = d.addToActiveFund(userAddress, delegator, big.NewInt(10), &DelegationContractStatus{}, true) + _ = d.saveDelegatorData(userAddress, delegator) + + eei.returnMessage = "" + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "invalid number of arguments") + + vmInput.Arguments = append(vmInput.Arguments, []byte{1}) + _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) + returnCode = d.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) + + _, delegator, _ = d.getOrCreateDelegatorData(userAddress) + assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(20)) + assert.Equal(t, delegator.TotalCumulatedRewards, big.NewInt(0)) + fund, _ := d.getFund(delegator.ActiveFund) + assert.Equal(t, fund.Value, big.NewInt(20)) } diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 486d1fe2fb6..b16b509a054 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -236,7 +236,7 @@ func (l *liquidStaking) claimOneDelegatedPosition( } valueToClaim := big.NewInt(0).SetBytes(valueAsBytes) - returnData, returnCode := l.executeOnDestinationSC( + _, returnCode := l.executeOnDestinationSC( destSCAddress, "claimRewardsViaLiquidStaking", callerAddr, @@ -247,13 +247,8 @@ func (l *liquidStaking) claimOneDelegatedPosition( return 0, nil, returnCode } - if len(returnData) != 1 { - l.eei.AddReturnMessage("invalid return data") - return 0, nil, vmcommon.UserError - } - - rewardsCheckpoint := uint32(big.NewInt(0).SetBytes(returnData[0]).Uint64()) - nonce, err := l.createOrAddNFT(destSCAddress, rewardsCheckpoint, valueToClaim) + newCheckpoint := l.eei.BlockChainHook().CurrentEpoch() + 1 + nonce, err := l.createOrAddNFT(destSCAddress, newCheckpoint, valueToClaim) if err != nil { l.eei.AddReturnMessage(err.Error()) return 0, nil, vmcommon.UserError From ed753c181e68cd52e4d5e3d2751583652986b966 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 26 Aug 2021 17:37:35 +0300 Subject: [PATCH 019/958] unit testing on liquid staking --- vm/factory/systemSCFactory.go | 2 - vm/systemSmartContracts/delegation_test.go | 9 +- vm/systemSmartContracts/liquidStaking.go | 12 -- vm/systemSmartContracts/liquidStaking_test.go | 190 ++++++++++++++++++ 4 files changed, 198 insertions(+), 15 deletions(-) create mode 100644 vm/systemSmartContracts/liquidStaking_test.go diff --git a/vm/factory/systemSCFactory.go b/vm/factory/systemSCFactory.go index 33a041befc5..e75d480a9c2 100644 --- a/vm/factory/systemSCFactory.go +++ b/vm/factory/systemSCFactory.go @@ -294,13 +294,11 @@ func (scf *systemSCFactory) createDelegationManagerContract() (vm.SystemSmartCon func (scf *systemSCFactory) createLiquidStakingContract() (vm.SystemSmartContract, error) { argsLiquidStaking := systemSmartContracts.ArgsNewLiquidStaking{ Eei: scf.systemEI, - DelegationMgrSCAddress: vm.DelegationManagerSCAddress, LiquidStakingSCAddress: vm.LiquidStakingSCAddress, GasCost: scf.gasCost, Marshalizer: scf.marshalizer, Hasher: scf.hasher, EpochNotifier: scf.epochNotifier, - EndOfEpochAddress: vm.EndOfEpochAddress, EpochConfig: *scf.epochConfig, } liquidStaking, err := systemSmartContracts.NewLiquidStakingSystemSC(argsLiquidStaking) diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 6b792181f1d..a9ed33f122e 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -1786,9 +1786,16 @@ func TestDelegationSystemSC_ExecuteUnDelegateUserErrorsWhenGettingMinimumDelegat }) d.eei.SetStorage([]byte(lastFundKey), fundKey) + managementData := &DelegationManagement{ + MinDeposit: big.NewInt(50), + MinDelegationAmount: big.NewInt(50), + } + marshaledData, _ := d.marshalizer.Marshal(managementData) + eei.SetStorageForAddress(d.delegationMgrSCAddress, []byte(delegationManagementKey), marshaledData) + output := d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, output) - assert.True(t, strings.Contains(eei.returnMessage, "error getting minimum delegation amount")) + assert.True(t, strings.Contains(eei.returnMessage, "invalid value to undelegate - need to undelegate all - do not leave dust behind")) } func TestDelegationSystemSC_ExecuteUnDelegateUserNotDelegatorOrNoActiveFundShouldErr(t *testing.T) { diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index b16b509a054..bcd78151e6d 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -25,9 +25,7 @@ const attributesNoncePrefix = "a" type liquidStaking struct { eei vm.SystemEI sigVerifier vm.MessageSignVerifier - delegationMgrSCAddress []byte liquidStakingSCAddress []byte - endOfEpochAddr []byte gasCost vm.GasCost marshalizer marshal.Marshalizer hasher hashing.Hasher @@ -40,9 +38,7 @@ type liquidStaking struct { type ArgsNewLiquidStaking struct { EpochConfig config.EpochConfig Eei vm.SystemEI - DelegationMgrSCAddress []byte LiquidStakingSCAddress []byte - EndOfEpochAddress []byte GasCost vm.GasCost Marshalizer marshal.Marshalizer Hasher hashing.Hasher @@ -54,12 +50,6 @@ func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) if check.IfNil(args.Eei) { return nil, vm.ErrNilSystemEnvironmentInterface } - if len(args.DelegationMgrSCAddress) < 1 { - return nil, fmt.Errorf("%w for delegation manager sc address", vm.ErrInvalidAddress) - } - if len(args.EndOfEpochAddress) < 1 { - return nil, fmt.Errorf("%w for end of epoch address", vm.ErrInvalidAddress) - } if len(args.LiquidStakingSCAddress) < 1 { return nil, fmt.Errorf("%w for liquid staking sc address", vm.ErrInvalidAddress) } @@ -75,8 +65,6 @@ func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) l := &liquidStaking{ eei: args.Eei, - delegationMgrSCAddress: args.DelegationMgrSCAddress, - endOfEpochAddr: args.EndOfEpochAddress, liquidStakingSCAddress: args.LiquidStakingSCAddress, gasCost: args.GasCost, marshalizer: args.Marshalizer, diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go new file mode 100644 index 00000000000..81e7e49f253 --- /dev/null +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -0,0 +1,190 @@ +package systemSmartContracts + +import ( + "errors" + "math/big" + "testing" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" + stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/mock" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/stretchr/testify/assert" +) + +func createMockArgumentsForLiquidStaking() ArgsNewLiquidStaking { + return ArgsNewLiquidStaking{ + EpochConfig: config.EpochConfig{}, + Eei: &mock.SystemEIStub{}, + LiquidStakingSCAddress: vm.LiquidStakingSCAddress, + GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{LiquidStakingOps: 10}}, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &mock.HasherMock{}, + EpochNotifier: &mock.EpochNotifierStub{}, + } +} + +func createLiquidStakingContractAndEEI() (*liquidStaking, *vmContext) { + args := createMockArgumentsForLiquidStaking() + eei, _ := NewVMContext( + &mock.BlockChainHookStub{ + CurrentEpochCalled: func() uint32 { + return 2 + }, + }, + hooks.NewVMCryptoHook(), + &mock.ArgumentParserMock{}, + &stateMock.AccountsStub{}, + &mock.RaterMock{}, + ) + systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok + }}, nil + }} + + _ = eei.SetSystemSCContainer(systemSCContainerStub) + + args.Eei = eei + l, _ := NewLiquidStakingSystemSC(args) + + return l, eei +} + +func TestLiquidStaking_NilEEI(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + args.Eei = nil + _, err := NewLiquidStakingSystemSC(args) + assert.Equal(t, err, vm.ErrNilSystemEnvironmentInterface) +} + +func TestLiquidStaking_NilAddress(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + args.LiquidStakingSCAddress = nil + _, err := NewLiquidStakingSystemSC(args) + assert.True(t, errors.Is(err, vm.ErrInvalidAddress)) +} + +func TestLiquidStaking_NilMarshalizer(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + args.Marshalizer = nil + _, err := NewLiquidStakingSystemSC(args) + assert.True(t, errors.Is(err, vm.ErrNilMarshalizer)) +} + +func TestLiquidStaking_NilHasher(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + args.Hasher = nil + _, err := NewLiquidStakingSystemSC(args) + assert.True(t, errors.Is(err, vm.ErrNilHasher)) +} + +func TestLiquidStaking_NilEpochNotifier(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + args.EpochNotifier = nil + l, err := NewLiquidStakingSystemSC(args) + assert.True(t, errors.Is(err, vm.ErrNilEpochNotifier)) + assert.True(t, l.IsInterfaceNil()) +} + +func TestLiquidStaking_New(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + l, err := NewLiquidStakingSystemSC(args) + assert.Nil(t, err) + assert.NotNil(t, l) + assert.False(t, l.IsInterfaceNil()) +} + +func TestLiquidStaking_CanUseContract(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch = 10 + l, _ := NewLiquidStakingSystemSC(args) + assert.False(t, l.CanUseContract()) + + args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch = 0 + l, _ = NewLiquidStakingSystemSC(args) + assert.True(t, l.CanUseContract()) +} + +func TestLiquidStaking_SetNewGasConfig(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForLiquidStaking() + l, _ := NewLiquidStakingSystemSC(args) + + assert.Equal(t, l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps, uint64(10)) + gasCost := vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{LiquidStakingOps: 100}} + l.SetNewGasCost(gasCost) + assert.Equal(t, l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps, uint64(100)) +} + +func TestLiquidStaking_NotActiveWrongCalls(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + + returnCode := l.Execute(nil) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, vm.ErrInputArgsIsNil.Error()) + + l.flagLiquidStaking.Unset() + eei.returnMessage = "" + vmInput := getDefaultVmInputForFunc("returnViaLiquidStaking", make([][]byte, 0)) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "liquid staking contract is not enabled") + + l.flagLiquidStaking.Set() + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, vmInput.Function+" is an unknown function") +} + +func TestLiquidStaking_init(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc(core.SCDeployInitFunctionName, make([][]byte, 0)) + + eei.returnMessage = "" + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "invalid caller") + + eei.returnMessage = "" + vmInput.CallerAddr = vm.LiquidStakingSCAddress + vmInput.CallValue = big.NewInt(10) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function is not payable in eGLD") + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(0) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "invalid number of arguments") + + vmInput.Arguments = append(vmInput.Arguments, []byte("tokenID")) + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) + assert.Equal(t, l.getTokenID(), []byte("tokenID")) +} From 2df65c1ab0d1e689910978901f572400fef915bc Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 26 Aug 2021 18:46:01 +0300 Subject: [PATCH 020/958] more unit tests --- vm/systemSmartContracts/liquidStaking.go | 2 +- vm/systemSmartContracts/liquidStaking_test.go | 119 +++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index bcd78151e6d..3a4b3752b60 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -436,7 +436,7 @@ func (l *liquidStaking) createOrAddNFT( nonce, err := l.createNewSFT(value) if err != nil { - return 0, nil + return 0, err } nonceBytes := big.NewInt(0).SetUint64(nonce).Bytes() diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go index 81e7e49f253..f73ffc88b66 100644 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -1,6 +1,7 @@ package systemSmartContracts import ( + "bytes" "errors" "math/big" "testing" @@ -50,7 +51,7 @@ func createLiquidStakingContractAndEEI() (*liquidStaking, *vmContext) { args.Eei = eei l, _ := NewLiquidStakingSystemSC(args) - + l.eei.SetStorage([]byte(tokenIDKey), []byte("TKN")) return l, eei } @@ -188,3 +189,119 @@ func TestLiquidStaking_init(t *testing.T) { assert.Equal(t, returnCode, vmcommon.Ok) assert.Equal(t, l.getTokenID(), []byte("tokenID")) } + +func TestLiquidStaking_checkArgumentsWhenPosition(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc("claimRewardsFromPosition", make([][]byte, 0)) + + eei.returnMessage = "" + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function requires liquid staking input") + + eei.returnMessage = "" + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10)}} + vmInput.CallValue = big.NewInt(10) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function is not payable in eGLD") + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(0) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "wrong tokenID input") + + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID()}} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.OutOfGas) +} + +func TestLiquidStaking_ClaimDelegatedPosition(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(10) + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function is not payable in eGLD") + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(0) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "not enough arguments") + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{{3}, {2}, {3}} + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID()}} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function is not payable in ESDT") + + eei.returnMessage = "" + vmInput.ESDTTransfers = nil + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "not enough arguments") + + vmInput.Arguments[0] = []byte{1} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.OutOfGas) + + eei.returnMessage = "" + eei.gasRemaining = 1000 + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "invalid destination SC address") + + localErr := errors.New("local err") + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return nil, localErr + }} + + vmInput.Arguments[1] = bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{} + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return nil, localErr + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok + }}, nil + }} + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + if input.Function == core.BuiltInFunctionMultiESDTNFTTransfer { + return nil, localErr + } + return &vmcommon.VMOutput{ + ReturnData: [][]byte{{1}}, + }, nil + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.returnMessage = "" + vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) + eei.blockChainHook = &mock.BlockChainHookStub{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) +} From 80eba68ee64f26310b80034d21050834dbbb57c8 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sat, 28 Aug 2021 21:11:06 +0300 Subject: [PATCH 021/958] more unit tests --- vm/systemSmartContracts/liquidStaking_test.go | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go index f73ffc88b66..6001c2287fa 100644 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -305,3 +305,214 @@ func TestLiquidStaking_ClaimDelegatedPosition(t *testing.T) { returnCode = l.Execute(vmInput) assert.Equal(t, returnCode, vmcommon.Ok) } + +func TestLiquidStaking_ClaimRewardsFromDelegatedPosition(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc("claimRewardsFromPosition", make([][]byte, 0)) + vmInput.Arguments = [][]byte{{3}, {2}, {3}} + + eei.returnMessage = "" + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function requires liquid staking input") + + eei.gasRemaining = 1000 + eei.returnMessage = "" + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID(), ESDTTokenNonce: 1}} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, vm.ErrEmptyStorage.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return &vmcommon.VMOutput{ + ReturnData: [][]byte{{1}}, + }, nil + }} + _, _ = l.createOrAddNFT(vm.FirstDelegationSCAddress, 10, big.NewInt(10)) + localErr := errors.New("local err") + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return nil, localErr + }} + + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{} + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return nil, localErr + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok + }}, nil + }} + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + if input.Function == core.BuiltInFunctionMultiESDTNFTTransfer { + return nil, localErr + } + return &vmcommon.VMOutput{ + ReturnData: [][]byte{{1}}, + }, nil + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.returnMessage = "" + vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) + eei.blockChainHook = &mock.BlockChainHookStub{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) +} + +func TestLiquidStaking_ReDelegateRewardsFromPosition(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc("reDelegateRewardsFromPosition", make([][]byte, 0)) + vmInput.Arguments = [][]byte{{3}, {2}, {3}} + + eei.returnMessage = "" + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function requires liquid staking input") + + eei.gasRemaining = 1000 + eei.returnMessage = "" + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID(), ESDTTokenNonce: 1}} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, vm.ErrEmptyStorage.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return &vmcommon.VMOutput{ + ReturnData: [][]byte{{1}}, + }, nil + }} + _, _ = l.createOrAddNFT(vm.FirstDelegationSCAddress, 10, big.NewInt(10)) + localErr := errors.New("local err") + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return nil, localErr + }} + + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{} + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return nil, localErr + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok + }}, nil + }} + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + if input.Function == core.BuiltInFunctionMultiESDTNFTTransfer { + return nil, localErr + } + return &vmcommon.VMOutput{ + ReturnData: [][]byte{{1}}, + }, nil + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "invalid return data") + + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + eei.Finish(big.NewInt(10).Bytes()) + return vmcommon.Ok + }}, nil + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.returnMessage = "" + vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) + eei.blockChainHook = &mock.BlockChainHookStub{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) +} + +func TestLiquidStaking_ReturnLiquidStaking(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc("unDelegatePosition", make([][]byte, 0)) + vmInput.Arguments = [][]byte{{3}, {2}, {3}} + + eei.returnMessage = "" + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function requires liquid staking input") + + eei.gasRemaining = 1000 + eei.returnMessage = "" + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID(), ESDTTokenNonce: 1}} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, vm.ErrEmptyStorage.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return &vmcommon.VMOutput{ + ReturnData: [][]byte{{1}}, + }, nil + }} + _, _ = l.createOrAddNFT(vm.FirstDelegationSCAddress, 10, big.NewInt(10)) + localErr := errors.New("local err") + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return nil, localErr + }} + + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{} + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return nil, localErr + }} + eei.returnMessage = "" + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { + return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + return vmcommon.Ok + }}, nil + }} + eei.returnMessage = "" + vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) + eei.blockChainHook = &mock.BlockChainHookStub{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) + + vmInput.Function = "returnPosition" + eei.returnMessage = "" + vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) +} From b721689bf2ab21035a18146a458b5516326a190c Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 12:19:30 +0300 Subject: [PATCH 022/958] creating complicated integration tests --- integrationTests/testProcessorNode.go | 68 +++++++ .../vm/delegation/liquidStaking_test.go | 173 ++++++++++++++++++ testscommon/txDataBuilder/builder.go | 12 +- vm/systemSmartContracts/liquidStaking.go | 25 +++ 4 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 integrationTests/vm/delegation/liquidStaking_test.go diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 5c4f6840100..4e5291e05f2 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/hex" "fmt" + "math" "math/big" "strconv" "sync" @@ -1779,6 +1780,73 @@ func (tpn *TestProcessorNode) InitDelegationManager() { log.LogIfError(err) } +// InitLiquidStaking will initialize the liquid staking contract whenever required +func (tpn *TestProcessorNode) InitLiquidStaking() []byte { + if tpn.ShardCoordinator.SelfId() != core.MetachainShardId { + return nil + } + + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.ESDTSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{}, + GasProvided: math.MaxUint64, + }, + RecipientAddr: vm.ESDTSCAddress, + Function: "initDelegationESDTOnMeta", + } + + systemVM, err := tpn.VMContainer.Get(factory.SystemVirtualMachine) + log.LogIfError(err) + + vmOutput, err := systemVM.RunSmartContractCall(vmInput) + log.LogIfError(err) + if vmOutput.ReturnCode != vmcommon.Ok { + log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) + } + + err = tpn.processSCOutputAccounts(vmOutput) + log.LogIfError(err) + + _, err = tpn.AccntState.Commit() + log.LogIfError(err) + + codeMetaData := &vmcommon.CodeMetadata{ + Upgradeable: false, + Payable: false, + Readable: true, + } + + tokenID := vmOutput.ReturnData[0] + vmInputCreate := &vmcommon.ContractCreateInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.LiquidStakingSCAddress, + Arguments: [][]byte{tokenID}, + CallValue: zero, + }, + ContractCode: vm.DelegationManagerSCAddress, + ContractCodeMetadata: codeMetaData.ToBytes(), + } + + vmOutput, err = systemVM.RunSmartContractCreate(vmInputCreate) + log.LogIfError(err) + if vmOutput.ReturnCode != vmcommon.Ok { + log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) + } + + err = tpn.processSCOutputAccounts(vmOutput) + log.LogIfError(err) + + err = tpn.updateSystemSCContractsCode(vmInputCreate.ContractCodeMetadata, vm.LiquidStakingSCAddress) + log.LogIfError(err) + + _, err = tpn.AccntState.Commit() + log.LogIfError(err) + + return tokenID +} + func (tpn *TestProcessorNode) updateSystemSCContractsCode(contractMetadata []byte, scAddress []byte) error { userAcc, err := tpn.getUserAccount(scAddress) if err != nil { diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go new file mode 100644 index 00000000000..52638c765a5 --- /dev/null +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -0,0 +1,173 @@ +package delegation + +import ( + "bytes" + "math/big" + "testing" + "time" + + "github.com/ElrondNetwork/elrond-go-core/core" + logger "github.com/ElrondNetwork/elrond-go-logger" + "github.com/ElrondNetwork/elrond-go/integrationTests" + "github.com/ElrondNetwork/elrond-go/integrationTests/vm/esdt" + "github.com/ElrondNetwork/elrond-go/testscommon/txDataBuilder" + "github.com/ElrondNetwork/elrond-go/vm" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/stretchr/testify/require" +) + +var log = logger.GetOrCreate("liquidStaking") + +func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + nodes, idxProposers, delegationAddress, tokenID, nonce, round := setupNodesDelegationContractInitLiquidStaking(t) + + txData := txDataBuilder.NewBuilder().Clear(). + Func("claimDelegatedPosition"). + Bytes(big.NewInt(1).Bytes()). + Bytes(delegationAddress). + Bytes(big.NewInt(5000).Bytes()). + ToString() + for _, node := range nodes { + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txData, core.MinMetaTxExtraGasCost) + } + + nrRoundsToPropagateMultiShard := 12 + time.Sleep(time.Second) + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + // claim again + for _, node := range nodes { + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txData, core.MinMetaTxExtraGasCost) + } + + time.Sleep(time.Second) + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + for i := 1; i < len(nodes); i++ { + checkLPPosition(t, nodes[i].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(10000)) + } + // owner is not allowed to get LP position + checkLPPosition(t, nodes[0].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) + + oneTransfer := &vmcommon.ESDTTransfer{ + ESDTValue: big.NewInt(1000), + ESDTTokenName: tokenID, + ESDTTokenType: uint32(core.NonFungible), + ESDTTokenNonce: 1, + } + esdtTransfers := []*vmcommon.ESDTTransfer{oneTransfer, oneTransfer, oneTransfer, oneTransfer, oneTransfer} + txBuilder := txDataBuilder.NewBuilder().MultiTransferESDTNFT(esdtTransfers) + txBuilder.Bytes([]byte("unDelegatePosition")) + for _, node := range nodes { + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txBuilder.ToString(), core.MinMetaTxExtraGasCost) + } + + txBuilder = txDataBuilder.NewBuilder().MultiTransferESDTNFT(esdtTransfers) + txBuilder.Bytes([]byte("returnPosition")) + for _, node := range nodes { + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txBuilder.ToString(), core.MinMetaTxExtraGasCost) + } + time.Sleep(time.Second) + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + for _, node := range nodes { + checkLPPosition(t, node.OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) + } + +} + +func setupNodesDelegationContractInitLiquidStaking( + t *testing.T, +) ([]*integrationTests.TestProcessorNode, []int, []byte, []byte, uint64, uint64) { + numOfShards := 2 + nodesPerShard := 2 + numMetachainNodes := 2 + + nodes := integrationTests.CreateNodes( + numOfShards, + nodesPerShard, + numMetachainNodes, + ) + + defer func() { + for _, n := range nodes { + _ = n.Messenger.Close() + } + }() + + integrationTests.DisplayAndStartNodes(nodes) + + idxProposers := make([]int, numOfShards+1) + for i := 0; i < numOfShards; i++ { + idxProposers[i] = i * nodesPerShard + } + idxProposers[numOfShards] = numOfShards * nodesPerShard + + var tokenID []byte + for _, node := range nodes { + tmpTokenID := node.InitLiquidStaking() + if len(tmpTokenID) != 0 { + if len(tokenID) == 0 { + tokenID = tmpTokenID + } + + if !bytes.Equal(tokenID, tmpTokenID) { + log.Error("tokenID missmatch", "current", tmpTokenID, "old", tokenID) + } + } + } + + initialVal := big.NewInt(10000000000) + integrationTests.MintAllNodes(nodes, initialVal) + + delegationAddress := createNewDelegationSystemSC(nodes[0], nodes) + + round := uint64(0) + nonce := uint64(0) + round = integrationTests.IncrementAndPrintRound(round) + nonce++ + + time.Sleep(time.Second) + nrRoundsToPropagateMultiShard := 6 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + txData := "delegate" + for _, node := range nodes { + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(10000), delegationAddress, txData, core.MinMetaTxExtraGasCost) + } + + time.Sleep(time.Second) + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + return nodes, idxProposers, delegationAddress, tokenID, nonce, round +} + +func checkLPPosition( + t *testing.T, + address []byte, + nodes []*integrationTests.TestProcessorNode, + tokenID []byte, + nonce uint64, + value *big.Int, +) { + tokenIdentifierPlusNonce := append(tokenID, big.NewInt(0).SetUint64(nonce).Bytes()...) + esdtData := esdt.GetESDTTokenData(t, address, nodes, string(tokenIdentifierPlusNonce)) + + if value.Cmp(big.NewInt(0)) == 0 { + require.Nil(t, esdtData.TokenMetaData) + return + } + + require.NotNil(t, esdtData.TokenMetaData) + require.Equal(t, vm.LiquidStakingSCAddress, esdtData.TokenMetaData.Creator) + require.Equal(t, value.Bytes(), esdtData.Value.Bytes()) +} diff --git a/testscommon/txDataBuilder/builder.go b/testscommon/txDataBuilder/builder.go index e812f750b30..c62cc86a3d7 100644 --- a/testscommon/txDataBuilder/builder.go +++ b/testscommon/txDataBuilder/builder.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/ElrondNetwork/elrond-go-core/core" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" ) // txDataBuilder constructs a string to be used for transaction arguments @@ -147,11 +148,20 @@ func (builder *txDataBuilder) TransferESDT(token string, value int64) *txDataBui return builder.Func(core.BuiltInFunctionESDTTransfer).Str(token).Int64(value) } -//TransferESDTNFT appends to the data string all the elements required to request an ESDT NFT transfer. +// TransferESDTNFT appends to the data string all the elements required to request an ESDT NFT transfer. func (builder *txDataBuilder) TransferESDTNFT(token string, nonce int, value int64) *txDataBuilder { return builder.Func(core.BuiltInFunctionESDTNFTTransfer).Str(token).Int(nonce).Int64(value) } +// MultiTransferESDTNFT appends to the data string all the elements required to request an Multi ESDT NFT transfer. +func (builder *txDataBuilder) MultiTransferESDTNFT(transfers []*vmcommon.ESDTTransfer) *txDataBuilder { + txBuilder := builder.Func(core.BuiltInFunctionMultiESDTNFTTransfer).Int(len(transfers)) + for _, transfer := range transfers { + txBuilder.Bytes(transfer.ESDTTokenName).Int(int(transfer.ESDTTokenNonce)).BigInt(transfer.ESDTValue) + } + return txBuilder +} + // BurnESDT appends to the data string all the elements required to burn ESDT tokens. func (builder *txDataBuilder) BurnESDT(token string, value int64) *txDataBuilder { return builder.Func(core.BuiltInFunctionESDTBurn).Str(token).Int64(value) diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 3a4b3752b60..76f5c3310e8 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -106,6 +106,8 @@ func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.Retur return l.returnLiquidStaking(args, "unDelegateViaLiquidStaking") case "returnPosition": return l.returnLiquidStaking(args, "returnViaLiquidStaking") + case "readTokenID": + return l.readTokenID(args) } l.eei.AddReturnMessage(args.Function + " is an unknown function") @@ -135,6 +137,29 @@ func (l *liquidStaking) getTokenID() []byte { return l.eei.GetStorage([]byte(tokenIDKey)) } +func (l *liquidStaking) readTokenID(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if len(args.ESDTTransfers) < 1 { + l.eei.AddReturnMessage("function requires liquid staking input") + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + l.eei.AddReturnMessage("function is not payable in eGLD") + return vmcommon.UserError + } + if len(args.Arguments) > 0 { + l.eei.AddReturnMessage("function does not accept arguments") + return vmcommon.UserError + } + err := l.eei.UseGas(l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) + if err != nil { + l.eei.AddReturnMessage(err.Error()) + return vmcommon.OutOfGas + } + + l.eei.Finish(l.getTokenID()) + return vmcommon.Ok +} + func (l *liquidStaking) checkArgumentsWhenPositionIsInput(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if len(args.ESDTTransfers) < 1 { l.eei.AddReturnMessage("function requires liquid staking input") From 87dbb3b0d9dd583fba4537cd36bd7ff1e28c65e5 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 12:27:18 +0300 Subject: [PATCH 023/958] verify a lot of things --- integrationTests/vm/delegation/liquidStaking_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 52638c765a5..b815bf62407 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -54,6 +54,12 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { } // owner is not allowed to get LP position checkLPPosition(t, nodes[0].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) + metaNode := getNodeWithShardID(nodes, core.MetachainShardId) + allDelegatorAddresses := make([][]byte, 0) + for i := 1; i < len(nodes); i++ { + allDelegatorAddresses = append(allDelegatorAddresses, nodes[i].OwnAccount.Address) + } + verifyDelegatorIsDeleted(t, metaNode, allDelegatorAddresses, delegationAddress) oneTransfer := &vmcommon.ESDTTransfer{ ESDTValue: big.NewInt(1000), @@ -81,6 +87,8 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { checkLPPosition(t, node.OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) } + verifyDelegatorsStake(t, metaNode, "getUserActiveStake", allDelegatorAddresses, delegationAddress, big.NewInt(5000)) + verifyDelegatorsStake(t, metaNode, "getUserUnStakedValue", allDelegatorAddresses, delegationAddress, big.NewInt(5000)) } func setupNodesDelegationContractInitLiquidStaking( From f8d7668693f5b0f1773abf56340c578e2fd45e91 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 12:37:25 +0300 Subject: [PATCH 024/958] new read function and unit tests for it --- .../vm/delegation/liquidStaking_test.go | 6 +-- vm/systemSmartContracts/liquidStaking.go | 8 +--- vm/systemSmartContracts/liquidStaking_test.go | 39 +++++++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index b815bf62407..3a2407200bb 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -94,9 +94,9 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { func setupNodesDelegationContractInitLiquidStaking( t *testing.T, ) ([]*integrationTests.TestProcessorNode, []int, []byte, []byte, uint64, uint64) { - numOfShards := 2 - nodesPerShard := 2 - numMetachainNodes := 2 + numOfShards := 1 + nodesPerShard := 1 + numMetachainNodes := 1 nodes := integrationTests.CreateNodes( numOfShards, diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 76f5c3310e8..e4c3321d799 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -138,12 +138,8 @@ func (l *liquidStaking) getTokenID() []byte { } func (l *liquidStaking) readTokenID(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if len(args.ESDTTransfers) < 1 { - l.eei.AddReturnMessage("function requires liquid staking input") - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - l.eei.AddReturnMessage("function is not payable in eGLD") + if len(args.ESDTTransfers) != 0 || args.CallValue.Cmp(zero) != 0 { + l.eei.AddReturnMessage("function is not payable") return vmcommon.UserError } if len(args.Arguments) > 0 { diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go index 6001c2287fa..13953f779f5 100644 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -516,3 +516,42 @@ func TestLiquidStaking_ReturnLiquidStaking(t *testing.T) { returnCode = l.Execute(vmInput) assert.Equal(t, returnCode, vmcommon.Ok) } + +func TestLiquidStaking_ReadTokenID(t *testing.T) { + t.Parallel() + + l, eei := createLiquidStakingContractAndEEI() + vmInput := getDefaultVmInputForFunc("readTokenID", make([][]byte, 0)) + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(10) + returnCode := l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function is not payable") + + eei.returnMessage = "" + vmInput.CallValue = big.NewInt(0) + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID()}} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function is not payable") + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{{3}, {2}, {3}} + vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.UserError) + assert.Equal(t, eei.returnMessage, "function does not accept arguments") + + eei.returnMessage = "" + vmInput.Arguments = [][]byte{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.OutOfGas) + + eei.gasRemaining = 100000 + eei.returnMessage = "" + vmInput.Arguments = [][]byte{} + returnCode = l.Execute(vmInput) + assert.Equal(t, returnCode, vmcommon.Ok) + assert.Equal(t, eei.output[0], l.getTokenID()) +} From 0b652edf4570ff9b9332a88583018b414aab196a Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 13:24:35 +0300 Subject: [PATCH 025/958] init delegation --- integrationTests/vm/delegation/liquidStaking_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 3a2407200bb..0a63b77817d 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -120,6 +120,7 @@ func setupNodesDelegationContractInitLiquidStaking( var tokenID []byte for _, node := range nodes { + node.InitDelegationManager() tmpTokenID := node.InitLiquidStaking() if len(tmpTokenID) != 0 { if len(tokenID) == 0 { From 2d18f51fed852e8298da62727c576eb834c239ac Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 13:34:28 +0300 Subject: [PATCH 026/958] init delegation --- integrationTests/testProcessorNode.go | 2 +- integrationTests/vm/delegation/liquidStaking_test.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 4e5291e05f2..98073ed37a5 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2343,7 +2343,7 @@ func (tpn *TestProcessorNode) LoadTxSignSkBytes(skBytes []byte) { // ProposeBlock proposes a new block func (tpn *TestProcessorNode) ProposeBlock(round uint64, nonce uint64) (data.BodyHandler, data.HeaderHandler, [][]byte) { startTime := time.Now() - maxTime := time.Second * 2 + maxTime := time.Second * 200000 haveTime := func() bool { elapsedTime := time.Since(startTime) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 0a63b77817d..cbc9b3106f8 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -24,7 +24,7 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { } nodes, idxProposers, delegationAddress, tokenID, nonce, round := setupNodesDelegationContractInitLiquidStaking(t) - + _ = logger.SetLogLevel("*:TRACE") txData := txDataBuilder.NewBuilder().Clear(). Func("claimDelegatedPosition"). Bytes(big.NewInt(1).Bytes()). @@ -134,6 +134,7 @@ func setupNodesDelegationContractInitLiquidStaking( } initialVal := big.NewInt(10000000000) + initialVal.Mul(initialVal, initialVal) integrationTests.MintAllNodes(nodes, initialVal) delegationAddress := createNewDelegationSystemSC(nodes[0], nodes) From f86230fde41528482aefb00176a721057c98532d Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 15:06:00 +0300 Subject: [PATCH 027/958] more tests and small fixes --- .../vm/delegation/liquidStaking_test.go | 30 ++++---- testscommon/txDataBuilder/builder.go | 4 +- vm/systemSmartContracts/eei.go | 4 +- vm/systemSmartContracts/eei_test.go | 43 +++++++++++ vm/systemSmartContracts/esdt.go | 2 +- vm/systemSmartContracts/esdt_test.go | 76 +++++++++++++++++++ vm/systemSmartContracts/liquidStaking.go | 2 +- 7 files changed, 141 insertions(+), 20 deletions(-) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index cbc9b3106f8..c5cc130c6c4 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -24,7 +24,12 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { } nodes, idxProposers, delegationAddress, tokenID, nonce, round := setupNodesDelegationContractInitLiquidStaking(t) - _ = logger.SetLogLevel("*:TRACE") + defer func() { + for _, n := range nodes { + _ = n.Messenger.Close() + } + }() + txData := txDataBuilder.NewBuilder().Clear(). Func("claimDelegatedPosition"). Bytes(big.NewInt(1).Bytes()). @@ -68,19 +73,20 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { ESDTTokenNonce: 1, } esdtTransfers := []*vmcommon.ESDTTransfer{oneTransfer, oneTransfer, oneTransfer, oneTransfer, oneTransfer} - txBuilder := txDataBuilder.NewBuilder().MultiTransferESDTNFT(esdtTransfers) + txBuilder := txDataBuilder.NewBuilder().MultiTransferESDTNFT(vm.LiquidStakingSCAddress, esdtTransfers) txBuilder.Bytes([]byte("unDelegatePosition")) for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txBuilder.ToString(), core.MinMetaTxExtraGasCost) + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), node.OwnAccount.Address, txBuilder.ToString(), core.MinMetaTxExtraGasCost) } - txBuilder = txDataBuilder.NewBuilder().MultiTransferESDTNFT(esdtTransfers) + txBuilder = txDataBuilder.NewBuilder().MultiTransferESDTNFT(vm.LiquidStakingSCAddress, esdtTransfers) txBuilder.Bytes([]byte("returnPosition")) for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txBuilder.ToString(), core.MinMetaTxExtraGasCost) + integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), node.OwnAccount.Address, txBuilder.ToString(), core.MinMetaTxExtraGasCost) } time.Sleep(time.Second) - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + finalWait := 20 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, finalWait, nonce, round, idxProposers) time.Sleep(time.Second) for _, node := range nodes { @@ -94,9 +100,9 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { func setupNodesDelegationContractInitLiquidStaking( t *testing.T, ) ([]*integrationTests.TestProcessorNode, []int, []byte, []byte, uint64, uint64) { - numOfShards := 1 - nodesPerShard := 1 - numMetachainNodes := 1 + numOfShards := 2 + nodesPerShard := 2 + numMetachainNodes := 2 nodes := integrationTests.CreateNodes( numOfShards, @@ -104,12 +110,6 @@ func setupNodesDelegationContractInitLiquidStaking( numMetachainNodes, ) - defer func() { - for _, n := range nodes { - _ = n.Messenger.Close() - } - }() - integrationTests.DisplayAndStartNodes(nodes) idxProposers := make([]int, numOfShards+1) diff --git a/testscommon/txDataBuilder/builder.go b/testscommon/txDataBuilder/builder.go index c62cc86a3d7..5e8ba13f220 100644 --- a/testscommon/txDataBuilder/builder.go +++ b/testscommon/txDataBuilder/builder.go @@ -154,8 +154,8 @@ func (builder *txDataBuilder) TransferESDTNFT(token string, nonce int, value int } // MultiTransferESDTNFT appends to the data string all the elements required to request an Multi ESDT NFT transfer. -func (builder *txDataBuilder) MultiTransferESDTNFT(transfers []*vmcommon.ESDTTransfer) *txDataBuilder { - txBuilder := builder.Func(core.BuiltInFunctionMultiESDTNFTTransfer).Int(len(transfers)) +func (builder *txDataBuilder) MultiTransferESDTNFT(destinationAddress []byte, transfers []*vmcommon.ESDTTransfer) *txDataBuilder { + txBuilder := builder.Func(core.BuiltInFunctionMultiESDTNFTTransfer).Bytes(destinationAddress).Int(len(transfers)) for _, transfer := range transfers { txBuilder.Bytes(transfer.ESDTTokenName).Int(int(transfer.ESDTTokenNonce)).BigInt(transfer.ESDTValue) } diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index 18e99d00726..99f8d33ea0c 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -454,7 +454,9 @@ func (host *vmContext) ProcessBuiltInFunction( if len(outAcc.OutputTransfers) > 0 { leftAccount, exist := host.outputAccounts[address] if !exist { - leftAccount = &vmcommon.OutputAccount{} + leftAccount = &vmcommon.OutputAccount{ + Address: []byte(address), + } host.outputAccounts[address] = leftAccount } leftAccount.OutputTransfers = append(leftAccount.OutputTransfers, outAcc.OutputTransfers...) diff --git a/vm/systemSmartContracts/eei_test.go b/vm/systemSmartContracts/eei_test.go index 43211c0f98d..9c6fb6a1d3f 100644 --- a/vm/systemSmartContracts/eei_test.go +++ b/vm/systemSmartContracts/eei_test.go @@ -292,3 +292,46 @@ func TestVmContext_CleanStorage(t *testing.T) { vmCtx.CleanStorageUpdates() assert.Equal(t, 0, len(vmCtx.storageUpdate)) } + +func TestVmContext_ProcessBuiltInFunction(t *testing.T) { + t.Parallel() + + balance := big.NewInt(10) + account, _ := state.NewUserAccount([]byte("123")) + _ = account.AddToBalance(balance) + + blockChainHook := &mock.BlockChainHookStub{ + ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return &vmcommon.VMOutput{ReturnCode: vmcommon.OutOfGas}, nil + }, + } + + vmCtx, _ := NewVMContext( + blockChainHook, + hooks.NewVMCryptoHook(), + &mock.ArgumentParserMock{}, + &stateMock.AccountsStub{}, + &mock.RaterMock{}) + + vmOutput, err := vmCtx.ProcessBuiltInFunction(vm.LiquidStakingSCAddress, vm.LiquidStakingSCAddress, "function", [][]byte{}) + assert.Nil(t, vmOutput) + assert.NotNil(t, err) + + outTransfer := vmcommon.OutputTransfer{Value: big.NewInt(10)} + outAcc := &vmcommon.OutputAccount{OutputTransfers: []vmcommon.OutputTransfer{outTransfer}} + blockChainHook = &mock.BlockChainHookStub{ + ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + output := &vmcommon.VMOutput{} + output.OutputAccounts = make(map[string]*vmcommon.OutputAccount) + output.OutputAccounts["address"] = outAcc + return output, nil + }, + } + vmCtx.blockChainHook = blockChainHook + + vmOutput, err = vmCtx.ProcessBuiltInFunction(vm.LiquidStakingSCAddress, vm.LiquidStakingSCAddress, "function", [][]byte{}) + assert.Nil(t, err) + assert.Equal(t, len(vmCtx.outputAccounts), 1) + assert.Equal(t, len(vmOutput.OutputAccounts), 1) + assert.Equal(t, vmCtx.outputAccounts["address"].Address, []byte("address")) +} diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 11535108230..5dd64b4ec53 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -276,7 +276,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm e.esdtSCAddress, vm.LiquidStakingSCAddress, core.BuiltInFunctionSetESDTRole, - [][]byte{[]byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)}, + [][]byte{tokenIdentifier, []byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)}, ) if err != nil { e.eei.AddReturnMessage(err.Error()) diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index fab29bead7c..8bfe2f46eec 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -1,6 +1,7 @@ package systemSmartContracts import ( + "bytes" "crypto/rand" "encoding/hex" "errors" @@ -4019,3 +4020,78 @@ func TestEsdt_CanUseContract(t *testing.T) { e, _ := NewESDTSmartContract(args) require.True(t, e.CanUseContract()) } + +func TestEsdt_ExecuteInitDelegationESDT(t *testing.T) { + t.Parallel() + + args := createMockArgumentsForESDT() + args.ESDTSCAddress = vm.ESDTSCAddress + eei, _ := NewVMContext( + &mock.BlockChainHookStub{ + CurrentEpochCalled: func() uint32 { + return 2 + }, + }, + hooks.NewVMCryptoHook(), + &mock.ArgumentParserMock{}, + &stateMock.AccountsStub{}, + &mock.RaterMock{}, + ) + args.Eei = eei + e, _ := NewESDTSmartContract(args) + + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: []byte("addr"), + CallValue: big.NewInt(0), + }, + RecipientAddr: []byte("addr"), + Function: "initDelegationESDTOnMeta", + } + + eei.returnMessage = "" + e.flagESDTOnMeta.Unset() + returnCode := e.Execute(vmInput) + assert.Equal(t, vmcommon.FunctionNotFound, returnCode) + assert.Equal(t, eei.returnMessage, "invalid method to call") + + eei.returnMessage = "" + e.flagESDTOnMeta.Set() + returnCode = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, "only system address can call this") + + vmInput.CallerAddr = vm.ESDTSCAddress + vmInput.RecipientAddr = vm.ESDTSCAddress + vmInput.Arguments = [][]byte{{1}} + eei.returnMessage = "" + returnCode = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + + vmInput.Arguments = [][]byte{} + vmInput.CallValue = big.NewInt(10) + eei.returnMessage = "" + returnCode = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + + localErr := errors.New("local err") + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + return nil, localErr + }} + + vmInput.CallValue = big.NewInt(0) + eei.returnMessage = "" + returnCode = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, returnCode) + assert.Equal(t, eei.returnMessage, localErr.Error()) + + eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + doesContainTicker := bytes.Contains(input.Arguments[0], []byte(e.delegationTicker)) + assert.True(t, doesContainTicker) + return &vmcommon.VMOutput{}, nil + }} + + eei.returnMessage = "" + returnCode = e.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, returnCode) +} diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index e4c3321d799..9d1e2c05740 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -247,7 +247,7 @@ func (l *liquidStaking) claimOneDelegatedPosition( valueToClaim := big.NewInt(0).SetBytes(valueAsBytes) _, returnCode := l.executeOnDestinationSC( destSCAddress, - "claimRewardsViaLiquidStaking", + "claimDelegatedPosition", callerAddr, valueToClaim, 0, From 855a8269cffa183e6dc88429e0b7c99ab22e3a4a Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Sun, 29 Aug 2021 18:58:41 +0300 Subject: [PATCH 028/958] no build on race --- integrationTests/vm/delegation/liquidStaking_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index c5cc130c6c4..68e0fe7ebea 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -1,3 +1,5 @@ +// +build !race + package delegation import ( From d0864425bdf217c2f676458f4b5bb497ae37e5cb Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Mon, 30 Aug 2021 17:17:37 +0300 Subject: [PATCH 029/958] revert time and new function --- integrationTests/testProcessorNode.go | 2 +- .../vm/delegation/liquidStaking_test.go | 33 +++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 98073ed37a5..4e5291e05f2 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2343,7 +2343,7 @@ func (tpn *TestProcessorNode) LoadTxSignSkBytes(skBytes []byte) { // ProposeBlock proposes a new block func (tpn *TestProcessorNode) ProposeBlock(round uint64, nonce uint64) (data.BodyHandler, data.HeaderHandler, [][]byte) { startTime := time.Now() - maxTime := time.Second * 200000 + maxTime := time.Second * 2 haveTime := func() bool { elapsedTime := time.Since(startTime) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 68e0fe7ebea..c248f81f617 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -120,20 +120,7 @@ func setupNodesDelegationContractInitLiquidStaking( } idxProposers[numOfShards] = numOfShards * nodesPerShard - var tokenID []byte - for _, node := range nodes { - node.InitDelegationManager() - tmpTokenID := node.InitLiquidStaking() - if len(tmpTokenID) != 0 { - if len(tokenID) == 0 { - tokenID = tmpTokenID - } - - if !bytes.Equal(tokenID, tmpTokenID) { - log.Error("tokenID missmatch", "current", tmpTokenID, "old", tokenID) - } - } - } + tokenID := initDelegationManagementAndLiquidStaking(nodes) initialVal := big.NewInt(10000000000) initialVal.Mul(initialVal, initialVal) @@ -163,6 +150,24 @@ func setupNodesDelegationContractInitLiquidStaking( return nodes, idxProposers, delegationAddress, tokenID, nonce, round } +func initDelegationManagementAndLiquidStaking(nodes []*integrationTests.TestProcessorNode) []byte { + var tokenID []byte + for _, node := range nodes { + node.InitDelegationManager() + tmpTokenID := node.InitLiquidStaking() + if len(tmpTokenID) != 0 { + if len(tokenID) == 0 { + tokenID = tmpTokenID + } + + if !bytes.Equal(tokenID, tmpTokenID) { + log.Error("tokenID missmatch", "current", tmpTokenID, "old", tokenID) + } + } + } + return tokenID +} + func checkLPPosition( t *testing.T, address []byte, From 2583bb9c6acce9b4be000fbc1734d9ff48432260 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 14 Sep 2021 17:23:15 +0300 Subject: [PATCH 030/958] fix after merge --- testscommon/txDataBuilder/builder.go | 2 +- vm/systemSmartContracts/delegation.go | 5 +++-- vm/systemSmartContracts/eei.go | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/testscommon/txDataBuilder/builder.go b/testscommon/txDataBuilder/builder.go index a27c8d7d2cb..8572d4ec063 100644 --- a/testscommon/txDataBuilder/builder.go +++ b/testscommon/txDataBuilder/builder.go @@ -158,7 +158,7 @@ func (builder *TxDataBuilder) TransferESDTNFT(token string, nonce int, value int } // MultiTransferESDTNFT appends to the data string all the elements required to request an Multi ESDT NFT transfer. -func (builder *txDataBuilder) MultiTransferESDTNFT(destinationAddress []byte, transfers []*vmcommon.ESDTTransfer) *txDataBuilder { +func (builder *TxDataBuilder) MultiTransferESDTNFT(destinationAddress []byte, transfers []*vmcommon.ESDTTransfer) *TxDataBuilder { txBuilder := builder.Func(core.BuiltInFunctionMultiESDTNFTTransfer).Bytes(destinationAddress).Int(len(transfers)) for _, transfer := range transfers { txBuilder.Bytes(transfer.ESDTTokenName).Int(int(transfer.ESDTTokenNonce)).BigInt(transfer.ESDTValue) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 80ec89050a7..2402e02b8b1 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1597,10 +1597,11 @@ func (d *delegation) unDelegate(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.UserError } - return d.unDelegateValueFromAddress(valueToUnDelegate, args.CallerAddr, args.RecipientAddr) + return d.unDelegateValueFromAddress(args, valueToUnDelegate, args.CallerAddr, args.RecipientAddr) } func (d *delegation) unDelegateValueFromAddress( + args *vmcommon.ContractCallInput, valueToUnDelegate *big.Int, delegatorAddress []byte, contractAddress []byte, @@ -2911,7 +2912,7 @@ func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput address := args.Arguments[0] valueToUnDelegate := big.NewInt(0).SetBytes(args.Arguments[1]) - return d.unDelegateValueFromAddress(valueToUnDelegate, address, args.RecipientAddr) + return d.unDelegateValueFromAddress(args, valueToUnDelegate, address, args.RecipientAddr) } func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index 99e5c76c35e..f5955b5a1ff 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -469,7 +469,9 @@ func (host *vmContext) ProcessBuiltInFunction( } } - //TODO: add logs after merge with logs PR on meta + for _, logEntry := range vmOutput.Logs { + host.AddLogEntry(logEntry) + } return vmOutput, nil } From 035479fc065ba85e1922086a1f0aa36fd7ab9c13 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 15 Sep 2021 13:50:02 +0300 Subject: [PATCH 031/958] limit total stake value --- cmd/node/config/enableEpochs.toml | 3 ++ .../config/systemSmartContractsConfig.toml | 1 + config/epochConfig.go | 1 + config/systemSmartContractsConfig.go | 1 + node/nodeRunner.go | 1 + vm/systemSmartContracts/validator.go | 34 +++++++++++++++++++ 6 files changed, 41 insertions(+) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 182f1552dcf..6341d250669 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -108,6 +108,9 @@ # BuiltInFunctionOnMetaEnableEpoch represents the epoch when built in function processing on metachain is enabled BuiltInFunctionOnMetaEnableEpoch = 5 + # StakeLimitsEnableEpoch represents the epoch when stake limits on validators are enabled + StakeLimitsEnableEpoch = 5 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index ed2623ff1f8..3f596034890 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -11,6 +11,7 @@ MaxNumberOfNodesForStake = 36 UnJailValue = "2500000000000000000" #0.1% of genesis node price ActivateBLSPubKeyMessageVerification = false + LimitPercentage = 1.0 [ESDTSystemSCConfig] BaseIssuingCost = "5000000000000000000" #5 eGLD diff --git a/config/epochConfig.go b/config/epochConfig.go index ed176fb12fd..2541419c65a 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -49,6 +49,7 @@ type EnableEpochs struct { GlobalMintBurnDisableEpoch uint32 ESDTTransferRoleEnableEpoch uint32 BuiltInFunctionOnMetaEnableEpoch uint32 + StakeLimitsEnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index f4fa1863fcd..8e63e6867a6 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -23,6 +23,7 @@ type StakingSystemSCConfig struct { BleedPercentagePerRound float64 MaxNumberOfNodesForStake uint64 ActivateBLSPubKeyMessageVerification bool + LimitPercentage float64 } // ESDTSystemSCConfig defines a set of constant to initialize the esdt system smart contract diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 2758ebef2a3..6419b9211ce 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -146,6 +146,7 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("contract global mint and burn"), "epoch", enableEpochs.GlobalMintBurnDisableEpoch) log.Debug(readEpochFor("contract transfer role"), "epoch", enableEpochs.ESDTTransferRoleEnableEpoch) log.Debug(readEpochFor("built in functions on metachain"), "epoch", enableEpochs.BuiltInFunctionOnMetaEnableEpoch) + log.Debug(readEpochFor("limit validators"), "epoch", enableEpochs.StakeLimitsEnableEpoch) gasSchedule := configs.EpochConfig.GasSchedule diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 15ccc3306f0..03913d1daff 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -61,7 +61,12 @@ type validatorSC struct { flagValidatorToDelegation atomic.Flag enableUnbondTokensV2Epoch uint32 flagUnbondTokensV2 atomic.Flag + stakeLimitsEnableEpoch uint32 + flagStakeLimits atomic.Flag shardCoordinator sharding.Coordinator + limitPercentage float64 + totalStakeLimit *big.Int + totalNodeLimit uint32 } // ArgsValidatorSmartContract is the arguments structure to create a new ValidatorSmartContract @@ -175,12 +180,17 @@ func NewValidatorSmartContract( enableUnbondTokensV2Epoch: args.EpochConfig.EnableEpochs.UnbondTokensV2EnableEpoch, validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, shardCoordinator: args.ShardCoordinator, + stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, + limitPercentage: args.StakingSCConfig.LimitPercentage, } log.Debug("validator: enable epoch for staking v2", "epoch", reg.stakingV2Epoch) log.Debug("validator: enable epoch for stake", "epoch", reg.enableStakingEpoch) log.Debug("validator: enable epoch for double key protection", "epoch", reg.enableDoubleKeyEpoch) log.Debug("validator: enable epoch for unbond tokens v2", "epoch", reg.enableUnbondTokensV2Epoch) log.Debug("validator: enable epoch for validator to delegation", "epoch", reg.validatorToDelegationEnableEpoch) + log.Debug("validator: enable epoch for stake limits", "epoch", reg.stakeLimitsEnableEpoch) + + reg.totalStakeLimit = core.GetIntTrimmedPercentageOfValue(args.GenesisTotalSupply, reg.limitPercentage) args.EpochNotifier.RegisterNotifyHandler(reg) @@ -909,6 +919,22 @@ func (v *validatorSC) checkAllGivenKeysAreUnStaked(registrationData *ValidatorDa return mapBlsKeys, nil } +func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { + if !v.flagStakeLimits.IsSet() { + return false + } + + return registrationData.TotalStakeValue.Cmp(v.totalStakeLimit) > 0 +} + +func (v *validatorSC) isStakedNodesNumberTooHigh(registrationData *ValidatorDataV2) bool { + if !v.flagStakeLimits.IsSet() { + return false + } + + return false +} + func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { err := v.eei.UseGas(v.gasCost.MetaChainSystemSCsCost.Stake) if err != nil { @@ -942,6 +968,11 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod return vmcommon.UserError } + if v.isStakeTooHigh(registrationData) { + v.eei.AddReturnMessage("total stake limit reached") + return vmcommon.UserError + } + lenArgs := len(args.Arguments) if lenArgs == 0 { return v.updateStakeValue(registrationData, args.CallerAddr) @@ -2136,6 +2167,9 @@ func (v *validatorSC) EpochConfirmed(epoch uint32, _ uint64) { v.flagUnbondTokensV2.Toggle(epoch >= v.enableUnbondTokensV2Epoch) log.Debug("validatorSC: unbond tokens v2", "enabled", v.flagUnbondTokensV2.IsSet()) + + v.flagStakeLimits.Toggle(epoch >= v.stakeLimitsEnableEpoch) + log.Debug("validatorSC: stake limits", "enabled", v.flagStakeLimits.IsSet()) } // CanUseContract returns true if contract can be used From 37ce6cbccea730307d619c9d9bd5f89ac55a370c Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 15 Sep 2021 14:58:41 +0300 Subject: [PATCH 032/958] limits and epoch configs --- .../config/systemSmartContractsConfig.toml | 3 +- config/systemSmartContractsConfig.go | 3 +- epochStart/metachain/systemSCs_test.go | 4 ++ epochStart/mock/nodesCoordinatorStub.go | 4 ++ factory/apiResolverFactory.go | 1 + factory/blockProcessorCreator.go | 1 + factory/processComponents_test.go | 2 + genesis/process/disabled/nodesCoordinator.go | 15 ++++++ genesis/process/genesisBlockCreator_test.go | 3 ++ genesis/process/metaGenesisBlockCreator.go | 1 + .../multiShard/hardFork/hardFork_test.go | 2 + integrationTests/testInitializer.go | 6 +++ integrationTests/testProcessorNode.go | 6 +++ integrationTests/vm/testInitializer.go | 3 ++ .../factory/metachain/vmContainerFactory.go | 7 +++ .../metachain/vmContainerFactory_test.go | 10 ++++ process/mock/nodesCoordinatorMock.go | 4 ++ vm/errors.go | 9 ++++ vm/factory/systemSCFactory.go | 7 +++ vm/factory/systemSCFactory_test.go | 3 ++ vm/interface.go | 6 +++ vm/mock/nodesCoordinatorStub.go | 19 +++++++ vm/systemSmartContracts/validator.go | 50 ++++++++++++++++--- vm/systemSmartContracts/validator_test.go | 2 + 24 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 genesis/process/disabled/nodesCoordinator.go create mode 100644 vm/mock/nodesCoordinatorStub.go diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index 3f596034890..358c2780034 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -11,7 +11,8 @@ MaxNumberOfNodesForStake = 36 UnJailValue = "2500000000000000000" #0.1% of genesis node price ActivateBLSPubKeyMessageVerification = false - LimitPercentage = 1.0 + StakeLimitPercentage = 1.0 + NodeLimitPercentage = 0.5 [ESDTSystemSCConfig] BaseIssuingCost = "5000000000000000000" #5 eGLD diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index 8e63e6867a6..3652da548b9 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -23,7 +23,8 @@ type StakingSystemSCConfig struct { BleedPercentagePerRound float64 MaxNumberOfNodesForStake uint64 ActivateBLSPubKeyMessageVerification bool - LimitPercentage float64 + StakeLimitPercentage float64 + NodeLimitPercentage float64 } // ESDTSystemSCConfig defines a set of constant to initialize the esdt system smart contract diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index ab5c68b8744..0a992529150 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -967,6 +967,8 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS MaxNumberOfNodesForStake: 5, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -987,9 +989,11 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS StakeEnableEpoch: 0, DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, + StakeLimitsEnableEpoch: 10, }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, + NodesCoordinator: &mock.NodesCoordinatorStub{}, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) diff --git a/epochStart/mock/nodesCoordinatorStub.go b/epochStart/mock/nodesCoordinatorStub.go index 08d56c794f3..163bf7db7e6 100644 --- a/epochStart/mock/nodesCoordinatorStub.go +++ b/epochStart/mock/nodesCoordinatorStub.go @@ -13,6 +13,7 @@ type NodesCoordinatorStub struct { GetValidatorWithPublicKeyCalled func(publicKey []byte) (validator sharding.Validator, shardId uint32, err error) GetAllValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) ConsensusGroupSizeCalled func(shardID uint32) int + GetNumTotalEligibleCalled func() uint64 } // GetChance - @@ -52,6 +53,9 @@ func (ncm *NodesCoordinatorStub) GetAllWaitingValidatorsPublicKeys(_ uint32) (ma // GetNumTotalEligible - func (ncm *NodesCoordinatorStub) GetNumTotalEligible() uint64 { + if ncm.GetNumTotalEligibleCalled != nil { + return ncm.GetNumTotalEligibleCalled() + } return 1 } diff --git a/factory/apiResolverFactory.go b/factory/apiResolverFactory.go index cb470403b86..33251199184 100644 --- a/factory/apiResolverFactory.go +++ b/factory/apiResolverFactory.go @@ -280,6 +280,7 @@ func createScQueryElement( EpochNotifier: args.coreComponents.EpochNotifier(), EpochConfig: args.epochConfig, ShardCoordinator: args.processComponents.ShardCoordinator(), + NodesCoordinator: args.processComponents.NodesCoordinator(), } vmFactory, err = metachain.NewVMContainerFactory(argsNewVmFactory) if err != nil { diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 0baa3466f79..a4bebe846e8 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -479,6 +479,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( EpochNotifier: pcf.coreData.EpochNotifier(), EpochConfig: &pcf.epochConfig, ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + NodesCoordinator: pcf.nodesCoordinator, } vmFactory, err := metachain.NewVMContainerFactory(argsNewVMContainer) if err != nil { diff --git a/factory/processComponents_test.go b/factory/processComponents_test.go index 296d9e98551..71661eb14cd 100644 --- a/factory/processComponents_test.go +++ b/factory/processComponents_test.go @@ -190,6 +190,8 @@ func getProcessArgs( MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", diff --git a/genesis/process/disabled/nodesCoordinator.go b/genesis/process/disabled/nodesCoordinator.go new file mode 100644 index 00000000000..b71472e5343 --- /dev/null +++ b/genesis/process/disabled/nodesCoordinator.go @@ -0,0 +1,15 @@ +package disabled + +// NodesCoordinator implements the NodesCoordinator interface, it does nothing as it is disabled +type NodesCoordinator struct { +} + +// GetNumTotalEligible - +func (n *NodesCoordinator) GetNumTotalEligible() uint64 { + return 0 +} + +// IsInterfaceNil - +func (n *NodesCoordinator) IsInterfaceNil() bool { + return n == nil +} diff --git a/genesis/process/genesisBlockCreator_test.go b/genesis/process/genesisBlockCreator_test.go index dabd7719912..ccea620d71b 100644 --- a/genesis/process/genesisBlockCreator_test.go +++ b/genesis/process/genesisBlockCreator_test.go @@ -108,6 +108,8 @@ func createMockArgument( MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -129,6 +131,7 @@ func createMockArgument( SCDeployEnableEpoch: 0, RelayedTransactionsEnableEpoch: 0, PenalizedTooMuchGasEnableEpoch: 0, + StakeLimitsEnableEpoch: 10, }, }, } diff --git a/genesis/process/metaGenesisBlockCreator.go b/genesis/process/metaGenesisBlockCreator.go index 9179765f491..486758533d6 100644 --- a/genesis/process/metaGenesisBlockCreator.go +++ b/genesis/process/metaGenesisBlockCreator.go @@ -279,6 +279,7 @@ func createProcessorsForMetaGenesisBlock(arg ArgsGenesisBlockCreator, enableEpoc EpochNotifier: epochNotifier, EpochConfig: arg.EpochConfig, ShardCoordinator: arg.ShardCoordinator, + NodesCoordinator: &disabled.NodesCoordinator{}, } virtualMachineFactory, err := metachain.NewVMContainerFactory(argsNewVMContainerFactory) if err != nil { diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index c4bc445b00f..2ecdecd199a 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -466,6 +466,8 @@ func hardForkImport( MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 334a9185982..9f370acc0c2 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -605,6 +605,8 @@ func CreateFullGenesisBlocks( MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -634,6 +636,7 @@ func CreateFullGenesisBlocks( StakeEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, DelegationManagerEnableEpoch: 0, + StakeLimitsEnableEpoch: 10, }, }, } @@ -719,6 +722,8 @@ func CreateGenesisMetaBlock( MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -743,6 +748,7 @@ func CreateGenesisMetaBlock( StakeEnableEpoch: 0, DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, + StakeLimitsEnableEpoch: 10, }, }, } diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index c8a762b4088..f259b777f32 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -849,6 +849,8 @@ func (tpn *TestProcessorNode) createFullSCQueryService() { MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -872,6 +874,7 @@ func (tpn *TestProcessorNode) createFullSCQueryService() { }, }, ShardCoordinator: tpn.ShardCoordinator, + NodesCoordinator: tpn.NodesCoordinator, } vmFactory, _ = metaProcess.NewVMContainerFactory(argsNewVmFactory) } else { @@ -1617,6 +1620,8 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors() { MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -1635,6 +1640,7 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors() { EnableEpochs: tpn.EnableEpochs, }, ShardCoordinator: tpn.ShardCoordinator, + NodesCoordinator: tpn.NodesCoordinator, } vmFactory, _ := metaProcess.NewVMContainerFactory(argsVMContainerFactory) diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 624af4f06f6..ec2f9cfbb13 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -651,6 +651,7 @@ func CreateVMAndBlockchainHookMeta( EpochNotifier: &mock.EpochNotifierStub{}, EpochConfig: createEpochConfig(), ShardCoordinator: mock.NewMultiShardsCoordinatorMock(1), + NodesCoordinator: &mock.NodesCoordinatorMock{}, } argVMContainer.EpochConfig.EnableEpochs.UnbondTokensV2EnableEpoch = arg.UnbondTokensV2EnableEpoch vmFactory, err := metachain.NewVMContainerFactory(argVMContainer) @@ -719,6 +720,8 @@ func createSystemSCConfig() *config.SystemSmartContractsConfig { BleedPercentagePerRound: 0.00001, MaxNumberOfNodesForStake: 36, ActivateBLSPubKeyMessageVerification: false, + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "1250000000000000000000", diff --git a/process/factory/metachain/vmContainerFactory.go b/process/factory/metachain/vmContainerFactory.go index dbccd25ee92..de8fd813ec9 100644 --- a/process/factory/metachain/vmContainerFactory.go +++ b/process/factory/metachain/vmContainerFactory.go @@ -42,6 +42,7 @@ type vmContainerFactory struct { scFactory vm.SystemSCContainerFactory epochConfig *config.EpochConfig shardCoordinator sharding.Coordinator + nodesCoordinator vm.NodesCoordinator } // ArgsNewVMContainerFactory defines the arguments needed to create a new VM container factory @@ -59,6 +60,7 @@ type ArgsNewVMContainerFactory struct { EpochNotifier process.EpochNotifier EpochConfig *config.EpochConfig ShardCoordinator sharding.Coordinator + NodesCoordinator vm.NodesCoordinator } // NewVMContainerFactory is responsible for creating a new virtual machine factory object @@ -96,6 +98,9 @@ func NewVMContainerFactory(args ArgsNewVMContainerFactory) (*vmContainerFactory, if check.IfNil(args.ShardCoordinator) { return nil, fmt.Errorf("%w in NewVMContainerFactory", vm.ErrNilShardCoordinator) } + if check.IfNil(args.NodesCoordinator) { + return nil, fmt.Errorf("%w in NewVMContainerFactory", process.ErrNilNodesCoordinator) + } blockChainHookImpl, err := hooks.NewBlockChainHookImpl(args.ArgBlockChainHook) if err != nil { @@ -119,6 +124,7 @@ func NewVMContainerFactory(args ArgsNewVMContainerFactory) (*vmContainerFactory, addressPubKeyConverter: args.ArgBlockChainHook.PubkeyConv, epochConfig: args.EpochConfig, shardCoordinator: args.ShardCoordinator, + nodesCoordinator: args.NodesCoordinator, }, nil } @@ -190,6 +196,7 @@ func (vmf *vmContainerFactory) createSystemVMFactoryAndEEI() (vm.SystemSCContain AddressPubKeyConverter: vmf.addressPubKeyConverter, EpochConfig: vmf.epochConfig, ShardCoordinator: vmf.shardCoordinator, + NodesCoordinator: vmf.nodesCoordinator, } scFactory, err := systemVMFactory.NewSystemSCFactory(argsNewSystemScFactory) if err != nil { diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 05ef796c5af..86d46193553 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -80,6 +80,8 @@ func createVmContainerMockArgument(gasSchedule core.GasScheduleNotifier) ArgsNew BleedPercentagePerRound: 1, MaxNumberOfNodesForStake: 1, ActivateBLSPubKeyMessageVerification: false, + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, }, ValidatorAccountsDB: &stateMock.AccountsStub{}, @@ -92,6 +94,9 @@ func createVmContainerMockArgument(gasSchedule core.GasScheduleNotifier) ArgsNew }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, + NodesCoordinator: &mock.NodesCoordinatorMock{GetNumTotalEligibleCalled: func() uint64 { + return 1000 + }}, } } @@ -327,6 +332,8 @@ func TestVmContainerFactory_Create(t *testing.T) { MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -350,6 +357,9 @@ func TestVmContainerFactory_Create(t *testing.T) { }, }, ShardCoordinator: mock.NewMultiShardsCoordinatorMock(1), + NodesCoordinator: &mock.NodesCoordinatorMock{GetNumTotalEligibleCalled: func() uint64 { + return 1000 + }}, } vmf, err := NewVMContainerFactory(argsNewVMContainerFactory) assert.NotNil(t, vmf) diff --git a/process/mock/nodesCoordinatorMock.go b/process/mock/nodesCoordinatorMock.go index b7dac484c5e..127dde3cffb 100644 --- a/process/mock/nodesCoordinatorMock.go +++ b/process/mock/nodesCoordinatorMock.go @@ -26,6 +26,7 @@ type NodesCoordinatorMock struct { GetAllWaitingValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) GetAllLeavingValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) ConsensusGroupSizeCalled func(uint32) int + GetNumTotalEligibleCalled func() uint64 } // NewNodesCoordinatorMock - @@ -73,6 +74,9 @@ func (ncm *NodesCoordinatorMock) GetChance(uint32) uint32 { // GetNumTotalEligible - func (ncm *NodesCoordinatorMock) GetNumTotalEligible() uint64 { + if ncm.GetNumTotalEligibleCalled != nil { + return ncm.GetNumTotalEligibleCalled() + } return 1 } diff --git a/vm/errors.go b/vm/errors.go index aed7482394d..ae6a88db0af 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -256,3 +256,12 @@ var ErrInvalidReturnData = errors.New("invalid return data") // ErrNotEnoughRemainingFunds signals that operation is invalid as remaining funds are below minimum var ErrNotEnoughRemainingFunds = errors.New("not enough remaining funds - do not leave dust behind") + +// ErrInvalidStakeLimitPercentage signals the invalid stake limit percentage was provided +var ErrInvalidStakeLimitPercentage = errors.New("invalid stake limit percentage") + +// ErrInvalidNodeLimitPercentage signals the invalid node limit percentage was provided +var ErrInvalidNodeLimitPercentage = errors.New("invalid node limit percentage") + +// ErrNilNodesCoordinator signals that nil nodes coordinator was provided +var ErrNilNodesCoordinator = errors.New("nil nodes coordinator") diff --git a/vm/factory/systemSCFactory.go b/vm/factory/systemSCFactory.go index e75d480a9c2..a126a9d1458 100644 --- a/vm/factory/systemSCFactory.go +++ b/vm/factory/systemSCFactory.go @@ -32,6 +32,7 @@ type systemSCFactory struct { addressPubKeyConverter core.PubkeyConverter epochConfig *config.EpochConfig shardCoordinator sharding.Coordinator + nodesCoordinator vm.NodesCoordinator } // ArgsNewSystemSCFactory defines the arguments struct needed to create the system SCs @@ -48,6 +49,7 @@ type ArgsNewSystemSCFactory struct { AddressPubKeyConverter core.PubkeyConverter EpochConfig *config.EpochConfig ShardCoordinator sharding.Coordinator + NodesCoordinator vm.NodesCoordinator } // NewSystemSCFactory creates a factory which will instantiate the system smart contracts @@ -82,6 +84,9 @@ func NewSystemSCFactory(args ArgsNewSystemSCFactory) (*systemSCFactory, error) { if check.IfNil(args.ShardCoordinator) { return nil, fmt.Errorf("%w in NewSystemSCFactory", vm.ErrNilShardCoordinator) } + if check.IfNil(args.NodesCoordinator) { + return nil, fmt.Errorf("%w in NewSystemSCFactory", vm.ErrNilNodesCoordinator) + } scf := &systemSCFactory{ systemEI: args.SystemEI, @@ -95,6 +100,7 @@ func NewSystemSCFactory(args ArgsNewSystemSCFactory) (*systemSCFactory, error) { addressPubKeyConverter: args.AddressPubKeyConverter, epochConfig: args.EpochConfig, shardCoordinator: args.ShardCoordinator, + nodesCoordinator: args.NodesCoordinator, } err := scf.createGasConfig(args.GasSchedule.LatestGasSchedule()) @@ -203,6 +209,7 @@ func (scf *systemSCFactory) createValidatorContract() (vm.SystemSmartContract, e GovernanceSCAddress: vm.GovernanceSCAddress, EpochConfig: *scf.epochConfig, ShardCoordinator: scf.shardCoordinator, + NodesCoordinator: scf.nodesCoordinator, } validatorSC, err := systemSmartContracts.NewValidatorSmartContract(args) return validatorSC, err diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index 9e7ed2d27be..e7b5b2d2b62 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -55,6 +55,8 @@ func createMockNewSystemScFactoryArgs() ArgsNewSystemSCFactory { MaxNumberOfNodesForStake: 100, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, DelegationSystemSCConfig: config.DelegationSystemSCConfig{ MinServiceFee: 0, @@ -77,6 +79,7 @@ func createMockNewSystemScFactoryArgs() ArgsNewSystemSCFactory { }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, + NodesCoordinator: &mock.NodesCoordinatorStub{}, } } diff --git a/vm/interface.go b/vm/interface.go index 11369a9686d..f850fd61dd7 100644 --- a/vm/interface.go +++ b/vm/interface.go @@ -67,6 +67,12 @@ type EconomicsHandler interface { IsInterfaceNil() bool } +// NodesCoordinator defines the methods needed about nodes in system SCs from nodes coordinator +type NodesCoordinator interface { + GetNumTotalEligible() uint64 + IsInterfaceNil() bool +} + // ContextHandler defines the methods needed to execute system smart contracts type ContextHandler interface { SystemEI diff --git a/vm/mock/nodesCoordinatorStub.go b/vm/mock/nodesCoordinatorStub.go new file mode 100644 index 00000000000..de4a99e28e7 --- /dev/null +++ b/vm/mock/nodesCoordinatorStub.go @@ -0,0 +1,19 @@ +package mock + +// NodesCoordinatorStub - +type NodesCoordinatorStub struct { + GetNumTotalEligibleCalled func() uint64 +} + +// GetNumTotalEligible - +func (n *NodesCoordinatorStub) GetNumTotalEligible() uint64 { + if n.GetNumTotalEligibleCalled != nil { + return n.GetNumTotalEligibleCalled() + } + return 1000 +} + +// IsInterfaceNil - +func (n *NodesCoordinatorStub) IsInterfaceNil() bool { + return n == nil +} diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 03913d1daff..8bff84d8fde 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -21,6 +21,7 @@ import ( const unJailedFunds = "unJailFunds" const unStakeUnBondPauseKey = "unStakeUnBondPause" +const minPercentage = 0.01 var zero = big.NewInt(0) @@ -64,9 +65,9 @@ type validatorSC struct { stakeLimitsEnableEpoch uint32 flagStakeLimits atomic.Flag shardCoordinator sharding.Coordinator - limitPercentage float64 + nodesCoordinator vm.NodesCoordinator totalStakeLimit *big.Int - totalNodeLimit uint32 + nodeLimitPercentage float64 } // ArgsValidatorSmartContract is the arguments structure to create a new ValidatorSmartContract @@ -87,6 +88,7 @@ type ArgsValidatorSmartContract struct { DelegationMgrEnableEpoch uint32 EpochConfig config.EpochConfig ShardCoordinator sharding.Coordinator + NodesCoordinator vm.NodesCoordinator } // NewValidatorSmartContract creates an validator smart contract @@ -126,6 +128,15 @@ func NewValidatorSmartContract( if len(args.GovernanceSCAddress) < 1 { return nil, fmt.Errorf("%w for governance sc address", vm.ErrInvalidAddress) } + if check.IfNil(args.NodesCoordinator) { + return nil, fmt.Errorf("%w in validatorSC", vm.ErrNilNodesCoordinator) + } + if args.StakingSCConfig.NodeLimitPercentage < minPercentage { + return nil, fmt.Errorf("%w in validatorSC", vm.ErrInvalidNodeLimitPercentage) + } + if args.StakingSCConfig.StakeLimitPercentage < minPercentage { + return nil, fmt.Errorf("%w in validatorSC", vm.ErrInvalidStakeLimitPercentage) + } baseConfig := ValidatorConfig{ TotalSupply: big.NewInt(0).Set(args.GenesisTotalSupply), @@ -181,8 +192,14 @@ func NewValidatorSmartContract( validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, shardCoordinator: args.ShardCoordinator, stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, - limitPercentage: args.StakingSCConfig.LimitPercentage, + nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, } + + reg.totalStakeLimit = core.GetIntTrimmedPercentageOfValue(args.GenesisTotalSupply, args.StakingSCConfig.StakeLimitPercentage) + if reg.totalStakeLimit.Cmp(baseConfig.NodePrice) < 0 { + return nil, fmt.Errorf("%w, value is %f", vm.ErrInvalidStakeLimitPercentage, args.StakingSCConfig.StakeLimitPercentage) + } + log.Debug("validator: enable epoch for staking v2", "epoch", reg.stakingV2Epoch) log.Debug("validator: enable epoch for stake", "epoch", reg.enableStakingEpoch) log.Debug("validator: enable epoch for double key protection", "epoch", reg.enableDoubleKeyEpoch) @@ -190,8 +207,6 @@ func NewValidatorSmartContract( log.Debug("validator: enable epoch for validator to delegation", "epoch", reg.validatorToDelegationEnableEpoch) log.Debug("validator: enable epoch for stake limits", "epoch", reg.stakeLimitsEnableEpoch) - reg.totalStakeLimit = core.GetIntTrimmedPercentageOfValue(args.GenesisTotalSupply, reg.limitPercentage) - args.EpochNotifier.RegisterNotifyHandler(reg) return reg, nil @@ -817,6 +832,11 @@ func (v *validatorSC) reStakeUnStakedNodes(args *vmcommon.ContractCallInput) vmc return vmcommon.UserError } + if v.isNumberOfNodesTooHigh(registrationData) { + v.eei.AddReturnMessage("number of nodes is too high") + return vmcommon.UserError + } + numQualified := big.NewInt(0).Div(registrationData.TotalStakeValue, validatorConfig.NodePrice) if uint64(len(args.Arguments)) > numQualified.Uint64() { v.eei.AddReturnMessage("insufficient funds") @@ -927,12 +947,13 @@ func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { return registrationData.TotalStakeValue.Cmp(v.totalStakeLimit) > 0 } -func (v *validatorSC) isStakedNodesNumberTooHigh(registrationData *ValidatorDataV2) bool { +func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) bool { if !v.flagStakeLimits.IsSet() { return false } - return false + nodeLimit := float64(v.nodesCoordinator.GetNumTotalEligible()) * v.nodeLimitPercentage + return len(registrationData.BlsPubKeys) > int(nodeLimit) } func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { @@ -1068,6 +1089,11 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod args.CallerAddr, ) + if v.isNumberOfNodesTooHigh(registrationData) { + v.eei.AddReturnMessage("number of nodes is too high") + return vmcommon.UserError + } + err = v.saveRegistrationData(args.CallerAddr, registrationData) if err != nil { v.eei.AddReturnMessage("cannot save registration data: error " + err.Error()) @@ -2078,6 +2104,16 @@ func (v *validatorSC) mergeValidatorData(args *vmcommon.ContractCallInput) vmcom validatorConfig := v.getConfig(v.eei.BlockChainHook().CurrentEpoch()) finalValidatorData.LockedStake.Mul(validatorConfig.NodePrice, big.NewInt(int64(finalValidatorData.NumRegistered))) + if v.isNumberOfNodesTooHigh(finalValidatorData) { + v.eei.AddReturnMessage("number of nodes is too high") + return vmcommon.UserError + } + + if v.isStakeTooHigh(finalValidatorData) { + v.eei.AddReturnMessage("total stake limit reached") + return vmcommon.UserError + } + v.eei.SetStorage(oldAddress, nil) err = v.saveRegistrationData(delegationAddr, finalValidatorData) if err != nil { diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index bc4b9a6efc1..6e19ea3065a 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -52,6 +52,8 @@ func createMockArgumentsForValidatorSCWithSystemScAddresses( MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, Marshalizer: &mock.MarshalizerMock{}, GenesisTotalSupply: big.NewInt(100000000), From 5c7496bba66058537c5e28f3ac6469ad5288f9d9 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 15 Sep 2021 15:37:16 +0300 Subject: [PATCH 033/958] fixing tests --- genesis/process/disabled/nodesCoordinator.go | 2 +- vm/systemSmartContracts/staking_test.go | 2 ++ vm/systemSmartContracts/validator.go | 1 + vm/systemSmartContracts/validator_test.go | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/genesis/process/disabled/nodesCoordinator.go b/genesis/process/disabled/nodesCoordinator.go index b71472e5343..610230dd56f 100644 --- a/genesis/process/disabled/nodesCoordinator.go +++ b/genesis/process/disabled/nodesCoordinator.go @@ -6,7 +6,7 @@ type NodesCoordinator struct { // GetNumTotalEligible - func (n *NodesCoordinator) GetNumTotalEligible() uint64 { - return 0 + return 1600 } // IsInterfaceNil - diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 902bf2e2b0f..e50a8ec17df 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -49,6 +49,8 @@ func createMockStakingScArgumentsWithSystemScAddresses( MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, }, EpochNotifier: &mock.EpochNotifierStub{}, EpochConfig: config.EpochConfig{ diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 8bff84d8fde..eb66e1a86f1 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -193,6 +193,7 @@ func NewValidatorSmartContract( shardCoordinator: args.ShardCoordinator, stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, + nodesCoordinator: args.NodesCoordinator, } reg.totalStakeLimit = core.GetIntTrimmedPercentageOfValue(args.GenesisTotalSupply, args.StakingSCConfig.StakeLimitPercentage) diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 6e19ea3065a..46847675ee8 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -69,6 +69,7 @@ func createMockArgumentsForValidatorSCWithSystemScAddresses( }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, + NodesCoordinator: &mock.NodesCoordinatorStub{}, } return args From b0d6696cfcf37357e2bf0cc5738cd616ec6b53f8 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 16 Sep 2021 14:44:40 +0300 Subject: [PATCH 034/958] added a set of unit tests --- genesis/process/shardGenesisBlockCreator.go | 1 + go.mod | 4 +- go.sum | 6 +- .../metachain/vmContainerFactory_test.go | 12 + vm/factory/systemSCFactory_test.go | 11 + vm/systemSmartContracts/liquidStaking.go | 3 + vm/systemSmartContracts/validator.go | 2 +- vm/systemSmartContracts/validator_test.go | 216 ++++++++++++++++++ 8 files changed, 250 insertions(+), 5 deletions(-) diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index 52ac7ac70fc..6677a6b1f08 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -60,6 +60,7 @@ func createGenesisConfig() config.EnableEpochs { RelayedTransactionsV2EnableEpoch: unreachableEpoch, BuiltInFunctionOnMetaEnableEpoch: unreachableEpoch, IncrementSCRNonceInMultiTransferEnableEpoch: unreachableEpoch, + StakeLimitsEnableEpoch: unreachableEpoch, } } diff --git a/go.mod b/go.mod index 5ee8bfaf4ea..08e47303bbf 100644 --- a/go.mod +++ b/go.mod @@ -8,10 +8,10 @@ require ( github.com/ElrondNetwork/arwen-wasm-vm/v1_4 v1.4.12 github.com/ElrondNetwork/concurrent-map v0.1.3 github.com/ElrondNetwork/elastic-indexer-go v1.0.8 - github.com/ElrondNetwork/elrond-go-core v1.0.1-0.20210802100738-75f99b3e75a0 + github.com/ElrondNetwork/elrond-go-core v1.1.0 github.com/ElrondNetwork/elrond-go-crypto v1.0.1 github.com/ElrondNetwork/elrond-go-logger v1.0.5 - github.com/ElrondNetwork/elrond-vm-common v1.1.9 + github.com/ElrondNetwork/elrond-vm-common v1.2.1 github.com/ElrondNetwork/notifier-go v0.0.0-20210726084028-a78b3bbabc41 github.com/beevik/ntp v0.3.0 github.com/btcsuite/btcd v0.22.0-beta diff --git a/go.sum b/go.sum index 7ac8e140e5c..29951128ea8 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,9 @@ github.com/ElrondNetwork/elastic-indexer-go v1.0.8/go.mod h1:AUBtHo9tk/cTx0YBftb github.com/ElrondNetwork/elrond-go-core v1.0.0/go.mod h1:FQMem7fFF4+8pQ6lVsBZq6yO+smD0nV23P4bJpmPjTo= github.com/ElrondNetwork/elrond-go-core v1.0.1-0.20210721164025-65cf7f169349/go.mod h1:O9FkkTT2H9kxCzfn40TbhoCDXzGmUrRVusMomhK/Y3g= github.com/ElrondNetwork/elrond-go-core v1.0.1-0.20210729104455-83307d046997/go.mod h1:O9FkkTT2H9kxCzfn40TbhoCDXzGmUrRVusMomhK/Y3g= -github.com/ElrondNetwork/elrond-go-core v1.0.1-0.20210802100738-75f99b3e75a0 h1:G6kfIpyYe7m0jo11JrJAFuFkFHfour8qOOOm1gFh5/Q= github.com/ElrondNetwork/elrond-go-core v1.0.1-0.20210802100738-75f99b3e75a0/go.mod h1:O9FkkTT2H9kxCzfn40TbhoCDXzGmUrRVusMomhK/Y3g= +github.com/ElrondNetwork/elrond-go-core v1.1.0 h1:sWy+r6/KPuXaGpCvHNNuhObui4GmxD6GmDIyi5EEf4U= +github.com/ElrondNetwork/elrond-go-core v1.1.0/go.mod h1:O9FkkTT2H9kxCzfn40TbhoCDXzGmUrRVusMomhK/Y3g= github.com/ElrondNetwork/elrond-go-crypto v1.0.0/go.mod h1:DGiR7/j1xv729Xg8SsjYaUzWXL5svMd44REXjWS/gAc= github.com/ElrondNetwork/elrond-go-crypto v1.0.1 h1:xJUUshIZQ7h+rG7Art/9QHVyaPRV1wEjrxXYBdpmRlM= github.com/ElrondNetwork/elrond-go-crypto v1.0.1/go.mod h1:uunsvweBrrhVojL8uiQSaTPsl3YIQ9iBqtYGM6xs4s0= @@ -37,8 +38,9 @@ github.com/ElrondNetwork/elrond-go-logger v1.0.5 h1:tB/HBvV9IVeCaSrGakX+GLGu7K5U github.com/ElrondNetwork/elrond-go-logger v1.0.5/go.mod h1:cBfgx0ST/CJx8jrxJSC5aiSrvkGzcnF7sK06RD8mFxQ= github.com/ElrondNetwork/elrond-vm-common v1.1.0/go.mod h1:w3i6f8uiuRkE68Ie/gebRcLgTuHqvruJSYrFyZWuLrE= github.com/ElrondNetwork/elrond-vm-common v1.1.3/go.mod h1:09cTlI5tYUzD1bb8GEt0FcCm/qfQlidu4tIF3Dy+cWs= -github.com/ElrondNetwork/elrond-vm-common v1.1.9 h1:cGVmB6jpEoXisUUa1QV1dBOfVLJpRpcGqwaNW3QyS7A= github.com/ElrondNetwork/elrond-vm-common v1.1.9/go.mod h1:09cTlI5tYUzD1bb8GEt0FcCm/qfQlidu4tIF3Dy+cWs= +github.com/ElrondNetwork/elrond-vm-common v1.2.1 h1:UbenCVOZYBDiEgLIgBPf+Gwo3X5ycJz9btnYTVdzk24= +github.com/ElrondNetwork/elrond-vm-common v1.2.1/go.mod h1:07N31evc3GKh+tcmOXpc3xz/YsgV4yUHMo3LSlF0DIs= github.com/ElrondNetwork/notifier-go v0.0.0-20210726084028-a78b3bbabc41 h1:heGvUbSMCg+Ngir82E5dL9WYvzEK1UpmmDdthJBJzNI= github.com/ElrondNetwork/notifier-go v0.0.0-20210726084028-a78b3bbabc41/go.mod h1:VkblRkTnCWB2ITwSYsj2q6Kyzm4hRtUBH3Ezl9nxuds= github.com/ElrondNetwork/protobuf v1.3.2 h1:qoCSYiO+8GtXBEZWEjw0WPcZfM3g7QuuJrwpN+y6Mvg= diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 86d46193553..1a8044d8448 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -244,6 +244,18 @@ func TestNewVMContainerFactory_NilShardCoordinator(t *testing.T) { assert.True(t, errors.Is(err, vm.ErrNilShardCoordinator)) } +func TestNewVMContainerFactory_NilNodesCoordinatorFails(t *testing.T) { + t.Parallel() + + gasSchedule := makeGasSchedule() + argsNewVmContainerFactory := createVmContainerMockArgument(gasSchedule) + argsNewVmContainerFactory.NodesCoordinator = nil + vmf, err := NewVMContainerFactory(argsNewVmContainerFactory) + + assert.True(t, check.IfNil(vmf)) + assert.True(t, errors.Is(err, process.ErrNilNodesCoordinator)) +} + func TestNewVMContainerFactory_OkValues(t *testing.T) { t.Parallel() diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index e7b5b2d2b62..3e1710628ff 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -94,6 +94,17 @@ func TestNewSystemSCFactory_NilSystemEI(t *testing.T) { assert.True(t, errors.Is(err, vm.ErrNilSystemEnvironmentInterface)) } +func TestNewSystemSCFactory_NilNodesCoordinator(t *testing.T) { + t.Parallel() + + arguments := createMockNewSystemScFactoryArgs() + arguments.NodesCoordinator = nil + scFactory, err := NewSystemSCFactory(arguments) + + assert.Nil(t, scFactory) + assert.True(t, errors.Is(err, vm.ErrNilNodesCoordinator)) +} + func TestNewSystemSCFactory_NilSigVerifier(t *testing.T) { t.Parallel() diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 9d1e2c05740..e4f529e8b6e 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -45,6 +45,9 @@ type ArgsNewLiquidStaking struct { EpochNotifier vm.EpochNotifier } +// TODO: resolve errors if multi transfer from metachain fails. should it return - restore position or should remain at destination +// better to remain at destination + // NewLiquidStakingSystemSC creates a new liquid staking system SC func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) { if check.IfNil(args.Eei) { diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index eb66e1a86f1..245ad0a764c 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -192,7 +192,7 @@ func NewValidatorSmartContract( validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, shardCoordinator: args.ShardCoordinator, stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, - nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, + nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage / 100.0, nodesCoordinator: args.NodesCoordinator, } diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 46847675ee8..53d88fc41d6 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -229,6 +229,39 @@ func TestNewStakingValidatorSmartContract_NilValidatorSmartContractAddress(t *te assert.True(t, errors.Is(err, vm.ErrNilValidatorSmartContractAddress)) } +func TestNewStakingValidatorSmartContract_NilNodesCoordinator(t *testing.T) { + t.Parallel() + + arguments := createMockArgumentsForValidatorSC() + arguments.NodesCoordinator = nil + + asc, err := NewValidatorSmartContract(arguments) + require.Nil(t, asc) + assert.True(t, errors.Is(err, vm.ErrNilNodesCoordinator)) +} + +func TestNewStakingValidatorSmartContract_ZeroStakeLimit(t *testing.T) { + t.Parallel() + + arguments := createMockArgumentsForValidatorSC() + arguments.StakingSCConfig.StakeLimitPercentage = 0.0 + + asc, err := NewValidatorSmartContract(arguments) + require.Nil(t, asc) + assert.True(t, errors.Is(err, vm.ErrInvalidStakeLimitPercentage)) +} + +func TestNewStakingValidatorSmartContract_ZeroNodeLimit(t *testing.T) { + t.Parallel() + + arguments := createMockArgumentsForValidatorSC() + arguments.StakingSCConfig.NodeLimitPercentage = 0.0 + + asc, err := NewValidatorSmartContract(arguments) + require.Nil(t, asc) + assert.True(t, errors.Is(err, vm.ErrInvalidNodeLimitPercentage)) +} + func TestNewStakingValidatorSmartContract_NilSigVerifier(t *testing.T) { t.Parallel() @@ -362,6 +395,76 @@ func TestStakingValidatorSC_ExecuteStakeWithoutArgumentsShouldWork(t *testing.T) assert.Equal(t, vmcommon.Ok, errCode) } +func TestStakingValidatorSC_ExecuteStakeTooMuchStake(t *testing.T) { + t.Parallel() + + arguments := CreateVmContractCallInput() + validatorData := createAValidatorData(25000000, 2, 12500000) + validatorDataBytes, _ := json.Marshal(&validatorData) + + eei := &mock.SystemEIStub{} + eei.GetStorageCalled = func(key []byte) []byte { + if bytes.Equal(key, arguments.CallerAddr) { + return validatorDataBytes + } + return nil + } + eei.AddReturnMessageCalled = func(msg string) { + assert.Equal(t, msg, "total stake limit reached") + } + + args := createMockArgumentsForValidatorSC() + args.Eei = eei + + stakingValidatorSc, _ := NewValidatorSmartContract(args) + + arguments.Function = "stake" + arguments.CallValue = big.NewInt(0).Set(stakingValidatorSc.totalStakeLimit) + + errCode := stakingValidatorSc.Execute(arguments) + assert.Equal(t, vmcommon.UserError, errCode) +} + +func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { + t.Parallel() + + arguments := CreateVmContractCallInput() + + eei := &mock.SystemEIStub{} + + args := createMockArgumentsForValidatorSC() + args.Eei = eei + + args.NodesCoordinator = &mock.NodesCoordinatorStub{GetNumTotalEligibleCalled: func() uint64 { + return 1000 + }} + args.StakingSCConfig.NodeLimitPercentage = 0.5 + stakingValidatorSc, _ := NewValidatorSmartContract(args) + + validatorData := createAValidatorData(25000000, 3, 12500000) + validatorDataBytes, _ := json.Marshal(&validatorData) + + eei.GetStorageCalled = func(key []byte) []byte { + if bytes.Equal(key, arguments.CallerAddr) { + return validatorDataBytes + } + return nil + } + eei.AddReturnMessageCalled = func(msg string) { + assert.Equal(t, msg, "number of nodes is too high") + } + + key1 := []byte("Key1") + key2 := []byte("Key2") + key3 := []byte("Key3") + arguments.Function = "stake" + arguments.CallValue = big.NewInt(0).Mul(big.NewInt(3), big.NewInt(10000000)) + arguments.Arguments = [][]byte{big.NewInt(3).Bytes(), key1, []byte("msg1"), key2, []byte("msg2"), key3, []byte("msg3")} + + errCode := stakingValidatorSc.Execute(arguments) + assert.Equal(t, vmcommon.UserError, errCode) +} + func TestStakingValidatorSC_ExecuteStakeAddedNewPubKeysShouldWork(t *testing.T) { t.Parallel() @@ -1212,6 +1315,8 @@ func TestStakingValidatorSC_StakeUnStake3XRestake2(t *testing.T) { return stakingSc, nil }}) + nodesCoordinator := &mock.NodesCoordinatorStub{} + args.NodesCoordinator = nodesCoordinator args.StakingSCConfig = argsStaking.StakingSCConfig args.Eei = eei @@ -1255,9 +1360,21 @@ func TestStakingValidatorSC_StakeUnStake3XRestake2(t *testing.T) { retCode = sc.Execute(arguments) assert.Equal(t, vmcommon.Ok, retCode) + nodesCoordinator.GetNumTotalEligibleCalled = func() uint64 { + return 1 + } + arguments.Function = "reStakeUnStakedNodes" arguments.Arguments = [][]byte{stakerPubKey1, stakerPubKey2} arguments.CallValue = big.NewInt(0) + retCode = sc.Execute(arguments) + assert.Equal(t, vmcommon.UserError, retCode) + assert.Equal(t, eei.returnMessage, "number of nodes is too high") + + nodesCoordinator.GetNumTotalEligibleCalled = func() uint64 { + return 10 + } + retCode = sc.Execute(arguments) assert.Equal(t, vmcommon.Ok, retCode) } @@ -5065,6 +5182,105 @@ func TestStakingValidatorSC_MergeValidatorData(t *testing.T) { assert.Equal(t, stakedData.RewardAddress, vm.FirstDelegationSCAddress) } +func TestStakingValidatorSC_MergeValidatorDataTooMuchStake(t *testing.T) { + t.Parallel() + + blockChainHook := &mock.BlockChainHookStub{ + CurrentNonceCalled: func() uint64 { + return 100000 + }, + } + atArgParser := parsers.NewCallArgsParser() + eei, _ := NewVMContext(blockChainHook, hooks.NewVMCryptoHook(), atArgParser, &stateMock.AccountsStub{}, &mock.RaterMock{}) + + argsStaking := createMockStakingScArguments() + argsStaking.Eei = eei + argsStaking.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 + stakingSc, _ := NewStakingSmartContract(argsStaking) + eei.SetSCAddress([]byte("addr")) + _ = eei.SetSystemSCContainer(&mock.SystemSCContainerStub{GetCalled: func(key []byte) (contract vm.SystemSmartContract, err error) { + return stakingSc, nil + }}) + + args := createMockArgumentsForValidatorSC() + args.StakingSCConfig = argsStaking.StakingSCConfig + args.Eei = eei + + sc, _ := NewValidatorSmartContract(args) + arguments := CreateVmContractCallInput() + arguments.CallerAddr = vm.ESDTSCAddress + arguments.Function = "mergeValidatorData" + arguments.Arguments = [][]byte{} + arguments.CallValue = big.NewInt(0) + arguments.CallerAddr = sc.delegationMgrSCAddress + randomAddress := bytes.Repeat([]byte{1}, len(arguments.CallerAddr)) + arguments.Arguments = [][]byte{randomAddress, vm.FirstDelegationSCAddress} + + limitPer4 := big.NewInt(0).Div(sc.totalStakeLimit, big.NewInt(4)) + + stake(t, sc, limitPer4, randomAddress, randomAddress, []byte("firsstKey"), big.NewInt(1).Bytes()) + stake(t, sc, limitPer4, randomAddress, randomAddress, []byte("secondKey"), big.NewInt(1).Bytes()) + stake(t, sc, limitPer4, randomAddress, randomAddress, []byte("thirddKey"), big.NewInt(1).Bytes()) + + stake(t, sc, limitPer4, vm.FirstDelegationSCAddress, vm.FirstDelegationSCAddress, []byte("fourthKey"), big.NewInt(1).Bytes()) + stake(t, sc, limitPer4, vm.FirstDelegationSCAddress, vm.FirstDelegationSCAddress, []byte("fifthhKey"), big.NewInt(1).Bytes()) + stake(t, sc, limitPer4, vm.FirstDelegationSCAddress, vm.FirstDelegationSCAddress, []byte("sixthhKey"), big.NewInt(1).Bytes()) + + retCode := sc.Execute(arguments) + assert.Equal(t, vmcommon.UserError, retCode) + assert.Equal(t, eei.returnMessage, "total stake limit reached") +} + +func TestStakingValidatorSC_MergeValidatorDataTooMuchNodes(t *testing.T) { + t.Parallel() + + blockChainHook := &mock.BlockChainHookStub{ + CurrentNonceCalled: func() uint64 { + return 100000 + }, + } + atArgParser := parsers.NewCallArgsParser() + eei, _ := NewVMContext(blockChainHook, hooks.NewVMCryptoHook(), atArgParser, &stateMock.AccountsStub{}, &mock.RaterMock{}) + + argsStaking := createMockStakingScArguments() + argsStaking.Eei = eei + argsStaking.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 + stakingSc, _ := NewStakingSmartContract(argsStaking) + eei.SetSCAddress([]byte("addr")) + _ = eei.SetSystemSCContainer(&mock.SystemSCContainerStub{GetCalled: func(key []byte) (contract vm.SystemSmartContract, err error) { + return stakingSc, nil + }}) + + args := createMockArgumentsForValidatorSC() + args.NodesCoordinator = &mock.NodesCoordinatorStub{GetNumTotalEligibleCalled: func() uint64 { + return 5 + }} + args.StakingSCConfig = argsStaking.StakingSCConfig + args.Eei = eei + + sc, _ := NewValidatorSmartContract(args) + arguments := CreateVmContractCallInput() + arguments.CallerAddr = vm.ESDTSCAddress + arguments.Function = "mergeValidatorData" + arguments.Arguments = [][]byte{} + arguments.CallValue = big.NewInt(0) + arguments.CallerAddr = sc.delegationMgrSCAddress + randomAddress := bytes.Repeat([]byte{1}, len(arguments.CallerAddr)) + arguments.Arguments = [][]byte{randomAddress, vm.FirstDelegationSCAddress} + + stake(t, sc, stakingSc.stakeValue, randomAddress, randomAddress, []byte("firsstKey"), big.NewInt(1).Bytes()) + stake(t, sc, stakingSc.stakeValue, randomAddress, randomAddress, []byte("secondKey"), big.NewInt(1).Bytes()) + stake(t, sc, stakingSc.stakeValue, randomAddress, randomAddress, []byte("thirddKey"), big.NewInt(1).Bytes()) + + stake(t, sc, stakingSc.stakeValue, vm.FirstDelegationSCAddress, vm.FirstDelegationSCAddress, []byte("fourthKey"), big.NewInt(1).Bytes()) + stake(t, sc, stakingSc.stakeValue, vm.FirstDelegationSCAddress, vm.FirstDelegationSCAddress, []byte("fifthhKey"), big.NewInt(1).Bytes()) + stake(t, sc, stakingSc.stakeValue, vm.FirstDelegationSCAddress, vm.FirstDelegationSCAddress, []byte("sixthhKey"), big.NewInt(1).Bytes()) + + retCode := sc.Execute(arguments) + assert.Equal(t, vmcommon.UserError, retCode) + assert.Equal(t, eei.returnMessage, "number of nodes is too high") +} + func TestValidatorSC_getMinUnStakeTokensValueFromDelegationManagerMarshalizerFail(t *testing.T) { t.Parallel() From 0a8687512d9664cf509b12f67bda2ea7a4c70acc Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Tue, 21 Sep 2021 11:57:06 +0300 Subject: [PATCH 035/958] fix after review --- cmd/node/config/systemSmartContractsConfig.toml | 4 ++-- vm/systemSmartContracts/staking_test.go | 4 ++-- vm/systemSmartContracts/validator.go | 4 ++-- vm/systemSmartContracts/validator_test.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index 358c2780034..8adcf7278c7 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -11,8 +11,8 @@ MaxNumberOfNodesForStake = 36 UnJailValue = "2500000000000000000" #0.1% of genesis node price ActivateBLSPubKeyMessageVerification = false - StakeLimitPercentage = 1.0 - NodeLimitPercentage = 0.5 + StakeLimitPercentage = 0.01 #fraction of value 0.01 - 1% + NodeLimitPercentage = 0.005 #fraction of value 0.005 - 0.5% [ESDTSystemSCConfig] BaseIssuingCost = "5000000000000000000" #5 eGLD diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index e50a8ec17df..fe69a898801 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -49,8 +49,8 @@ func createMockStakingScArgumentsWithSystemScAddresses( MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", - StakeLimitPercentage: 100.0, - NodeLimitPercentage: 100.0, + StakeLimitPercentage: 1.0, + NodeLimitPercentage: 1.0, }, EpochNotifier: &mock.EpochNotifierStub{}, EpochConfig: config.EpochConfig{ diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 245ad0a764c..1924a2c494f 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -21,7 +21,7 @@ import ( const unJailedFunds = "unJailFunds" const unStakeUnBondPauseKey = "unStakeUnBondPause" -const minPercentage = 0.01 +const minPercentage = 0.0001 var zero = big.NewInt(0) @@ -192,7 +192,7 @@ func NewValidatorSmartContract( validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, shardCoordinator: args.ShardCoordinator, stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, - nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage / 100.0, + nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, nodesCoordinator: args.NodesCoordinator, } diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 53d88fc41d6..e87769dffeb 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -438,7 +438,7 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { args.NodesCoordinator = &mock.NodesCoordinatorStub{GetNumTotalEligibleCalled: func() uint64 { return 1000 }} - args.StakingSCConfig.NodeLimitPercentage = 0.5 + args.StakingSCConfig.NodeLimitPercentage = 0.005 stakingValidatorSc, _ := NewValidatorSmartContract(args) validatorData := createAValidatorData(25000000, 3, 12500000) From 814b1c73d19223daa53d73c8812ccd6fa899f285 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 15 Feb 2022 17:01:55 +0200 Subject: [PATCH 036/958] FIX: one merge conflict --- epochStart/metachain/systemSCs_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 16e8dde217f..d6209ca232e 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -927,7 +927,6 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ShardCoordinator: &mock.ShardCoordinatorStub{}, Marshalizer: marshalizer, Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, - BuiltInFunctions: vmcommonBuiltInFunctions.NewBuiltInFunctionContainer(), NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, BuiltInFunctions: builtInFuncs, DataPool: testDataPool, From ad093f27b2b73e29bcca244a68296ca080f45a66 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Feb 2022 11:34:50 +0200 Subject: [PATCH 037/958] FIX: More merge conflicts --- epochStart/metachain/systemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 5 ++--- vm/systemSmartContracts/delegation.go | 4 ++-- vm/systemSmartContracts/esdt.go | 19 ++++++------------- vm/systemSmartContracts/liquidStaking.go | 2 +- vm/systemSmartContracts/validator.go | 2 +- 6 files changed, 13 insertions(+), 21 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 478f5d3adc9..6bae07779c4 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -1579,6 +1579,6 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagGovernanceEnabled.SetValue(epoch == s.governanceEnableEpoch) log.Debug("systemProcessor: governanceV2", "enabled", s.flagGovernanceEnabled.IsSet()) - s.flagBuiltInOnMetaEnabled.Toggle(epoch == s.builtInOnMetaEnableEpoch) + s.flagBuiltInOnMetaEnabled.SetValue(epoch == s.builtInOnMetaEnableEpoch) log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index d6209ca232e..b17c828021f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -905,7 +905,6 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) gasSchedule := arwenConfig.MakeGasMapForTests() gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) - blockChain, _ := blockchain.NewMetaChain(&mock.AppStatusHandlerStub{}) argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ GasSchedule: gasScheduleNotifier, MapDNSAddresses: make(map[string]struct{}), @@ -914,9 +913,9 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ShardCoordinator: &mock.ShardCoordinatorStub{SelfIdCalled: func() uint32 { return core.MetachainShardId }}, - EpochNotifier: epochNotifier, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, } - builtInFuncs, _ := builtInFunctions.CreateBuiltInFunctionContainer(argsBuiltIn) + builtInFuncs, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) testDataPool := dataRetrieverMock.NewPoolsHolderMock() argsHook := hooks.ArgBlockChainHook{ diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 28d5bcd705c..0c861b29e1d 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -2935,7 +2935,7 @@ func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vm return vmcommon.UserError } - err = d.deleteDelegatorIfNeeded(address, delegator) + _, err = d.deleteDelegatorIfNeeded(address, delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError @@ -3393,7 +3393,7 @@ func (d *delegation) EpochConfirmed(epoch uint32, _ uint64) { d.flagDeleteDelegatorDataAfterClaimRewards.SetValue(epoch >= d.deleteDelegatorDataAfterClaimRewardsEnableEpoch) log.Debug("delegationSC: delete delegator data after claim rewards", "enabled", d.flagDeleteDelegatorDataAfterClaimRewards.IsSet()) - d.flagLiquidStaking.Toggle(epoch >= d.liquidStakingEnableEpoch) + d.flagLiquidStaking.SetValue(epoch >= d.liquidStakingEnableEpoch) log.Debug("delegationSC: liquid staking", "enabled", d.flagLiquidStaking.IsSet()) } diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 0e1b7eb3178..675b2332d7c 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -268,7 +268,7 @@ func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } - tokenIdentifier, err := e.createNewToken( + tokenIdentifier, _, err := e.createNewToken( vm.LiquidStakingSCAddress, []byte(e.delegationTicker), []byte(e.delegationTicker), @@ -1536,11 +1536,7 @@ func (e *esdt) changeToMultiShardCreate(args *vmcommon.ContractCallInput) vmcomm isAddressLastByteZero := addressWithCreateRole[len(addressWithCreateRole)-1] == 0 if !isAddressLastByteZero { multiCreateRoleOnly := [][]byte{[]byte(core.ESDTRoleNFTCreateMultiShard)} - err = e.sendRoleChangeData(args.Arguments[0], addressWithCreateRole, multiCreateRoleOnly, core.BuiltInFunctionSetESDTRole) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.sendRoleChangeData(args.Arguments[0], addressWithCreateRole, multiCreateRoleOnly, core.BuiltInFunctionSetESDTRole) } err = e.saveToken(args.Arguments[0], token) @@ -1618,15 +1614,12 @@ func (e *esdt) prepareAndSendRoleChangeData( if properties.isMultiShardNFTCreateSet { allRoles = append(allRoles, []byte(core.ESDTRoleNFTCreateMultiShard)) } - err := e.sendRoleChangeData(tokenID, address, allRoles, core.BuiltInFunctionSetESDTRole) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + e.sendRoleChangeData(tokenID, address, allRoles, core.BuiltInFunctionSetESDTRole) + firstTransferRoleSet := !properties.transferRoleExists && isDefinedRoleInArgs(roles, []byte(core.ESDTRoleTransfer)) if firstTransferRoleSet { esdtTransferData := core.BuiltInFunctionESDTSetLimitedTransfer + "@" + hex.EncodeToString(tokenID) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } return vmcommon.Ok @@ -2078,7 +2071,7 @@ func (e *esdt) EpochConfirmed(epoch uint32, _ uint64) { e.flagRegisterAndSetAllRoles.SetValue(epoch >= e.registerAndSetAllRolesEnableEpoch) log.Debug("ESDT register and set all roles", "enabled", e.flagRegisterAndSetAllRoles.IsSet()) - e.flagESDTOnMeta.Toggle(epoch >= e.esdtOnMetachainEnableEpoch) + e.flagESDTOnMeta.SetValue(epoch >= e.esdtOnMetachainEnableEpoch) log.Debug("ESDT on metachain", "enabled", e.flagESDTOnMeta.IsSet()) } diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index e4f529e8b6e..045d290d1af 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -574,7 +574,7 @@ func (l *liquidStaking) SetNewGasCost(gasCost vm.GasCost) { // EpochConfirmed is called whenever a new epoch is confirmed func (l *liquidStaking) EpochConfirmed(epoch uint32, _ uint64) { - l.flagLiquidStaking.Toggle(epoch >= l.liquidStakingEnableEpoch) + l.flagLiquidStaking.SetValue(epoch >= l.liquidStakingEnableEpoch) log.Debug("liquid staking system sc", "enabled", l.flagLiquidStaking.IsSet()) } diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 69edcbb17ba..0fa70744f6c 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -2205,7 +2205,7 @@ func (v *validatorSC) EpochConfirmed(epoch uint32, _ uint64) { v.flagUnbondTokensV2.SetValue(epoch >= v.enableUnbondTokensV2Epoch) log.Debug("validatorSC: unbond tokens v2", "enabled", v.flagUnbondTokensV2.IsSet()) - v.flagStakeLimits.Toggle(epoch >= v.stakeLimitsEnableEpoch) + v.flagStakeLimits.SetValue(epoch >= v.stakeLimitsEnableEpoch) log.Debug("validatorSC: stake limits", "enabled", v.flagStakeLimits.IsSet()) } From a6082218f55b5c799b3a08b5d6334547af175bfd Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Feb 2022 12:19:14 +0200 Subject: [PATCH 038/958] FIX: Other merge conflicts --- vm/systemSmartContracts/delegation_test.go | 31 ++----------------- vm/systemSmartContracts/esdt_test.go | 11 ++----- vm/systemSmartContracts/liquidStaking_test.go | 7 +++-- 3 files changed, 9 insertions(+), 40 deletions(-) diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 47c702a428c..e15c724f934 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -120,33 +120,6 @@ func createDelegationManagerConfig(eei *vmContext, marshalizer marshal.Marshaliz eei.SetStorageForAddress(vm.DelegationManagerSCAddress, []byte(delegationManagementKey), marshaledData) } -func createDelegationContractAndEEI() (*delegation, *vmContext) { - args := createMockArgumentsForDelegation() - eei, _ := NewVMContext( - &mock.BlockChainHookStub{ - CurrentEpochCalled: func() uint32 { - return 2 - }, - }, - hooks.NewVMCryptoHook(), - &mock.ArgumentParserMock{}, - &stateMock.AccountsStub{}, - &mock.RaterMock{}, - ) - systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - _ = eei.SetSystemSCContainer(systemSCContainerStub) - - args.Eei = eei - args.DelegationSCConfig.MaxServiceFee = 10000 - args.DelegationSCConfig.MinServiceFee = 0 - d, _ := NewDelegationSystemSC(args) - return d, eei -} - func TestNewDelegationSystemSC_NilSystemEnvironmentShouldErr(t *testing.T) { t.Parallel() @@ -5382,13 +5355,13 @@ func TestDelegation_BasicCheckForLiquidStaking(t *testing.T) { vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - d.flagLiquidStaking.Unset() + d.flagLiquidStaking.Reset() returnCode := d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, vmInput.Function+" is an unknown function") eei.returnMessage = "" - d.flagLiquidStaking.Set() + d.flagLiquidStaking.SetValue(true) returnCode = d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index 83c86403ec7..c78a35ddf4b 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -16,8 +16,8 @@ import ( vmData "github.com/ElrondNetwork/elrond-go-core/data/vm" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" - stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" + stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/mock" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -4083,11 +4083,6 @@ func TestEsdt_TransferNFTCreateCallMultiShardShouldWork(t *testing.T) { tokenBytes, _ := args.Marshalizer.Marshal(token) return tokenBytes }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, input []byte) error { - require.Equal(t, []byte("ESDTNFTCreateRoleTransfer@746f6b656e4944@3263616c6c6572"), input) - require.Equal(t, destination, []byte("3caller")) - return nil - }, } args.Eei = eei @@ -4622,13 +4617,13 @@ func TestEsdt_ExecuteInitDelegationESDT(t *testing.T) { } eei.returnMessage = "" - e.flagESDTOnMeta.Unset() + e.flagESDTOnMeta.Reset() returnCode := e.Execute(vmInput) assert.Equal(t, vmcommon.FunctionNotFound, returnCode) assert.Equal(t, eei.returnMessage, "invalid method to call") eei.returnMessage = "" - e.flagESDTOnMeta.Set() + e.flagESDTOnMeta.SetValue(true) returnCode = e.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, "only system address can call this") diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go index 13953f779f5..557919093d4 100644 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -9,6 +9,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" + "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/mock" @@ -23,7 +24,7 @@ func createMockArgumentsForLiquidStaking() ArgsNewLiquidStaking { LiquidStakingSCAddress: vm.LiquidStakingSCAddress, GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{LiquidStakingOps: 10}}, Marshalizer: &mock.MarshalizerMock{}, - Hasher: &mock.HasherMock{}, + Hasher: &hashingMocks.HasherMock{}, EpochNotifier: &mock.EpochNotifierStub{}, } } @@ -145,14 +146,14 @@ func TestLiquidStaking_NotActiveWrongCalls(t *testing.T) { assert.Equal(t, returnCode, vmcommon.UserError) assert.Equal(t, eei.returnMessage, vm.ErrInputArgsIsNil.Error()) - l.flagLiquidStaking.Unset() + l.flagLiquidStaking.Reset() eei.returnMessage = "" vmInput := getDefaultVmInputForFunc("returnViaLiquidStaking", make([][]byte, 0)) returnCode = l.Execute(vmInput) assert.Equal(t, returnCode, vmcommon.UserError) assert.Equal(t, eei.returnMessage, "liquid staking contract is not enabled") - l.flagLiquidStaking.Set() + l.flagLiquidStaking.SetValue(true) eei.returnMessage = "" returnCode = l.Execute(vmInput) assert.Equal(t, returnCode, vmcommon.UserError) From fee83c2c818acd060e32334f913e7e7c4a4a4086 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Feb 2022 13:17:26 +0200 Subject: [PATCH 039/958] FIX: Merge conflict --- integrationTests/vm/delegation/liquidStaking_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index c248f81f617..4d7067d55b1 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -1,3 +1,4 @@ +//go:build !race // +build !race package delegation @@ -176,8 +177,7 @@ func checkLPPosition( nonce uint64, value *big.Int, ) { - tokenIdentifierPlusNonce := append(tokenID, big.NewInt(0).SetUint64(nonce).Bytes()...) - esdtData := esdt.GetESDTTokenData(t, address, nodes, string(tokenIdentifierPlusNonce)) + esdtData := esdt.GetESDTTokenData(t, address, nodes, tokenID, nonce) if value.Cmp(big.NewInt(0)) == 0 { require.Nil(t, esdtData.TokenMetaData) From e9009621f8680dbbabdacb16cecfe65bf1490771 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 17 Feb 2022 17:49:51 +0200 Subject: [PATCH 040/958] FEAT: Add flag check --- config/epochConfig.go | 3 ++- epochStart/metachain/systemSCs.go | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/config/epochConfig.go b/config/epochConfig.go index 273ab9be038..1bcd2032c94 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -74,7 +74,8 @@ type EnableEpochs struct { TransformToMultiShardCreateEnableEpoch uint32 ESDTRegisterAndSetAllRolesEnableEpoch uint32 DoNotReturnOldBlockInBlockchainHookEnableEpoch uint32 - StakeLimitsEnableEpoch uint32 + StakeLimitsEnableEpoch uint32 + StakingV4EnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6bae07779c4..c8c08a664fb 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -72,6 +72,7 @@ type systemSCProcessor struct { saveJailedAlwaysEnableEpoch uint32 governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 + stakingV4EnableEpoch uint32 maxNodesEnableConfig []config.MaxNodesChangeConfig maxNodes uint32 flagSwitchJailedWaiting atomic.Flag @@ -86,6 +87,7 @@ type systemSCProcessor struct { flagSaveJailedAlwaysEnabled atomic.Flag flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag + flagStakingV4Enabled atomic.Flag esdtOwnerAddressBytes []byte mapNumSwitchedPerShard map[uint32]uint32 mapNumSwitchablePerShard map[uint32]uint32 @@ -182,6 +184,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, + stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("systemSC: enable epoch for switch jail waiting", "epoch", s.switchEnableEpoch) @@ -193,6 +196,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr log.Debug("systemSC: enable epoch for save jailed always", "epoch", s.saveJailedAlwaysEnableEpoch) log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) log.Debug("systemSC: enable epoch for create NFT on meta", "epoch", s.builtInOnMetaEnableEpoch) + log.Debug("systemSC: enable epoch for staking v4", "epoch", s.stakingV4EnableEpoch) s.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(s.maxNodesEnableConfig, args.MaxNodesEnableConfig) @@ -313,6 +317,13 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } + if s.flagStakingV4Enabled.IsSet() { + err := s.stakeNodesFromQueue(validatorInfos, math.MaxUint32, nonce) + if err != nil { + return err + } + } + return nil } @@ -1581,4 +1592,7 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagBuiltInOnMetaEnabled.SetValue(epoch == s.builtInOnMetaEnableEpoch) log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) + + s.flagStakingV4Enabled.SetValue(epoch == s.stakingV4EnableEpoch) + log.Debug("systemProcessor: staking v4 on meta", "enabled", s.flagStakingV4Enabled.IsSet()) } From 886c96f77ff24b9da66dfe20dcc66cacb22950b1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Feb 2022 13:59:41 +0200 Subject: [PATCH 041/958] FEAT: Add unit test --- epochStart/metachain/systemSCs_test.go | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index b17c828021f..fe34bdefeb8 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -996,6 +996,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, StakeLimitsEnableEpoch: 10, + StakingV4EnableEpoch: 444, }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, @@ -1036,6 +1037,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: 1000000, ESDTEnableEpoch: 1000000, + StakingV4EnableEpoch: 444, }, }, } @@ -1901,3 +1903,57 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T assert.Equal(t, peerAcc.GetList(), string(common.LeavingList)) } } + +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + s, _ := NewSystemSCProcessor(args) + + prepareStakingContractWithData( + args.UserAccountsDB, + []byte("stakedPubKey0"), + []byte("waitingPubKe0"), + args.Marshalizer, + []byte("rewardAddress"), + []byte("rewardAddress"), + ) + + listPubKeysWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2")} + addKeysToWaitingList(args.UserAccountsDB, listPubKeysWaiting, args.Marshalizer, []byte("rewardAddress"), []byte("rewardAddress")) + + listAllPubKeys := append(listPubKeysWaiting, []byte("waitingPubKe0"), []byte("stakedPubKey0"), []byte("stakedPubKey1")) + addValidatorData(args.UserAccountsDB, []byte("rewardAddress"), listAllPubKeys, big.NewInt(5000), args.Marshalizer) + _, _ = args.UserAccountsDB.Commit() + + validatorInfos := make(map[uint32][]*state.ValidatorInfo) + validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + PublicKey: []byte("stakedPubKey0"), + List: string(common.EligibleList), + RewardAddress: []byte("rewardAddress"), + AccumulatedFees: big.NewInt(0), + }) + validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + PublicKey: []byte("stakedPubKey1"), + List: string(common.EligibleList), + RewardAddress: []byte("rewardAddress"), + AccumulatedFees: big.NewInt(0), + }) + + s.flagStakingV4Enabled.SetValue(true) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + assert.Nil(t, err) + require.Equal(t, len(validatorInfos[0]), len(listAllPubKeys)) + + peerAcc, _ := s.getPeerAccount([]byte("waitingPubKe0")) + assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKe0"))) + assert.Equal(t, peerAcc.GetList(), string(common.NewList)) + + peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe1")) + assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKe1"))) + assert.Equal(t, peerAcc.GetList(), string(common.NewList)) + + peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe2")) + assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKe2"))) + assert.Equal(t, peerAcc.GetList(), string(common.NewList)) +} From 6c8f2b161a21120c02c739bccd8a2bc4ebd19936 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Feb 2022 14:18:21 +0200 Subject: [PATCH 042/958] FEAT: Add toml flag --- cmd/node/config/enableEpochs.toml | 3 +++ genesis/process/shardGenesisBlockCreator.go | 1 + 2 files changed, 4 insertions(+) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index b2cfbcbfd24..ab0821c2760 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -187,6 +187,9 @@ # StakeLimitsEnableEpoch represents the epoch when stake limits on validators are enabled StakeLimitsEnableEpoch = 5 + # StakingV4EnableEpoch represents the epoch when staking v4 is enabled + StakingV4EnableEpoch = 1000000 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index 8970b0be94f..c6655863b6e 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -113,6 +113,7 @@ func createGenesisConfig() config.EnableEpochs { ESDTRegisterAndSetAllRolesEnableEpoch: unreachableEpoch, ScheduledMiniBlocksEnableEpoch: unreachableEpoch, StakeLimitsEnableEpoch: unreachableEpoch, + StakingV4EnableEpoch: unreachableEpoch, } } From aa7ab6adbd2792690d50b522f0efc36a98d7b9c6 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Feb 2022 15:54:51 +0200 Subject: [PATCH 043/958] FEAT: Change flag name to init + add disable flag staking queue --- cmd/node/config/enableEpochs.toml | 5 ++-- config/epochConfig.go | 2 +- epochStart/metachain/systemSCs.go | 26 +++++++++++++-------- epochStart/metachain/systemSCs_test.go | 10 ++++---- genesis/process/shardGenesisBlockCreator.go | 2 +- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index ab0821c2760..8855c38ec83 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -187,8 +187,9 @@ # StakeLimitsEnableEpoch represents the epoch when stake limits on validators are enabled StakeLimitsEnableEpoch = 5 - # StakingV4EnableEpoch represents the epoch when staking v4 is enabled - StakingV4EnableEpoch = 1000000 + # StakingV4InitEnableEpoch represents the epoch when staking v4 is initialized. This is the epoch in which + # nodes queue is removed and all nodes from queue are moved to a new list + StakingV4InitEnableEpoch = 1000000 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ diff --git a/config/epochConfig.go b/config/epochConfig.go index 1bcd2032c94..3460d6206c2 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -75,7 +75,7 @@ type EnableEpochs struct { ESDTRegisterAndSetAllRolesEnableEpoch uint32 DoNotReturnOldBlockInBlockchainHookEnableEpoch uint32 StakeLimitsEnableEpoch uint32 - StakingV4EnableEpoch uint32 + StakingV4InitEnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index c8c08a664fb..86f0407626c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -72,7 +72,7 @@ type systemSCProcessor struct { saveJailedAlwaysEnableEpoch uint32 governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 - stakingV4EnableEpoch uint32 + stakingV4InitEnableEpoch uint32 maxNodesEnableConfig []config.MaxNodesChangeConfig maxNodes uint32 flagSwitchJailedWaiting atomic.Flag @@ -87,7 +87,8 @@ type systemSCProcessor struct { flagSaveJailedAlwaysEnabled atomic.Flag flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag - flagStakingV4Enabled atomic.Flag + flagInitStakingV4Enabled atomic.Flag + flagStakingQueueEnabled atomic.Flag esdtOwnerAddressBytes []byte mapNumSwitchedPerShard map[uint32]uint32 mapNumSwitchablePerShard map[uint32]uint32 @@ -184,7 +185,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, - stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, } log.Debug("systemSC: enable epoch for switch jail waiting", "epoch", s.switchEnableEpoch) @@ -196,7 +197,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr log.Debug("systemSC: enable epoch for save jailed always", "epoch", s.saveJailedAlwaysEnableEpoch) log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) log.Debug("systemSC: enable epoch for create NFT on meta", "epoch", s.builtInOnMetaEnableEpoch) - log.Debug("systemSC: enable epoch for staking v4", "epoch", s.stakingV4EnableEpoch) + log.Debug("systemSC: enable epoch for staking v4", "epoch", s.stakingV4InitEnableEpoch) s.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(s.maxNodesEnableConfig, args.MaxNodesEnableConfig) @@ -284,9 +285,11 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( return err } - err = s.stakeNodesFromQueue(validatorInfos, numUnStaked, nonce) - if err != nil { - return err + if s.flagStakingQueueEnabled.IsSet() { + err = s.stakeNodesFromQueue(validatorInfos, numUnStaked, nonce) + if err != nil { + return err + } } } @@ -317,7 +320,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } - if s.flagStakingV4Enabled.IsSet() { + if s.flagInitStakingV4Enabled.IsSet() { err := s.stakeNodesFromQueue(validatorInfos, math.MaxUint32, nonce) if err != nil { return err @@ -1593,6 +1596,9 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagBuiltInOnMetaEnabled.SetValue(epoch == s.builtInOnMetaEnableEpoch) log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) - s.flagStakingV4Enabled.SetValue(epoch == s.stakingV4EnableEpoch) - log.Debug("systemProcessor: staking v4 on meta", "enabled", s.flagStakingV4Enabled.IsSet()) + s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) + log.Debug("systemProcessor: staking v4 on meta", "enabled", s.flagInitStakingV4Enabled.IsSet()) + + s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) + log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index fe34bdefeb8..096ce587fd4 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -996,7 +996,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, StakeLimitsEnableEpoch: 10, - StakingV4EnableEpoch: 444, + StakingV4InitEnableEpoch: 444, }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, @@ -1035,9 +1035,9 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 1000000, - ESDTEnableEpoch: 1000000, - StakingV4EnableEpoch: 444, + StakingV2EnableEpoch: 1000000, + ESDTEnableEpoch: 1000000, + StakingV4InitEnableEpoch: 444, }, }, } @@ -1940,7 +1940,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { AccumulatedFees: big.NewInt(0), }) - s.flagStakingV4Enabled.SetValue(true) + s.flagInitStakingV4Enabled.SetValue(true) err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) assert.Nil(t, err) require.Equal(t, len(validatorInfos[0]), len(listAllPubKeys)) diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index c6655863b6e..bd299f9abbe 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -113,7 +113,7 @@ func createGenesisConfig() config.EnableEpochs { ESDTRegisterAndSetAllRolesEnableEpoch: unreachableEpoch, ScheduledMiniBlocksEnableEpoch: unreachableEpoch, StakeLimitsEnableEpoch: unreachableEpoch, - StakingV4EnableEpoch: unreachableEpoch, + StakingV4InitEnableEpoch: unreachableEpoch, } } From 383bd339b4dd3623bc0e5f2ef2e433c8b1f8883f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Feb 2022 16:55:42 +0200 Subject: [PATCH 044/958] FEAT: Add auction lost --- common/constants.go | 3 +++ epochStart/metachain/systemSCs.go | 24 ++++++++++++++---------- epochStart/metachain/systemSCs_test.go | 24 +++++++++++++++--------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/common/constants.go b/common/constants.go index 5c47aa54fea..d79b6b7db36 100644 --- a/common/constants.go +++ b/common/constants.go @@ -29,6 +29,9 @@ const ObserverList PeerType = "observer" // NewList - const NewList PeerType = "new" +// AuctionList - +const AuctionList PeerType = "auction" + // CombinedPeerType - represents the combination of two peerTypes const CombinedPeerType = "%s (%s)" diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 86f0407626c..1446678bb75 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -286,7 +286,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagStakingQueueEnabled.IsSet() { - err = s.stakeNodesFromQueue(validatorInfos, numUnStaked, nonce) + err = s.stakeNodesFromQueue(validatorInfos, numUnStaked, nonce, common.NewList) if err != nil { return err } @@ -321,7 +321,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagInitStakingV4Enabled.IsSet() { - err := s.stakeNodesFromQueue(validatorInfos, math.MaxUint32, nonce) + err := s.stakeNodesFromQueue(validatorInfos, math.MaxUint32, nonce, common.AuctionList) if err != nil { return err } @@ -714,11 +714,13 @@ func (s *systemSCProcessor) updateMaxNodes(validatorInfos map[uint32][]*state.Va return epochStart.ErrInvalidMaxNumberOfNodes } - sw.Start("stakeNodesFromQueue") - err = s.stakeNodesFromQueue(validatorInfos, maxNumberOfNodes-prevMaxNumberOfNodes, nonce) - sw.Stop("stakeNodesFromQueue") - if err != nil { - return err + if s.flagStakingQueueEnabled.IsSet() { + sw.Start("stakeNodesFromQueue") + err = s.stakeNodesFromQueue(validatorInfos, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) + sw.Stop("stakeNodesFromQueue") + if err != nil { + return err + } } return nil } @@ -1393,6 +1395,7 @@ func (s *systemSCProcessor) stakeNodesFromQueue( validatorInfos map[uint32][]*state.ValidatorInfo, nodesToStake uint32, nonce uint64, + list common.PeerType, ) error { if nodesToStake == 0 { return nil @@ -1424,7 +1427,7 @@ func (s *systemSCProcessor) stakeNodesFromQueue( return err } - err = s.addNewlyStakedNodesToValidatorTrie(validatorInfos, vmOutput.ReturnData, nonce) + err = s.addNewlyStakedNodesToValidatorTrie(validatorInfos, vmOutput.ReturnData, nonce, list) if err != nil { return err } @@ -1436,6 +1439,7 @@ func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( validatorInfos map[uint32][]*state.ValidatorInfo, returnData [][]byte, nonce uint64, + list common.PeerType, ) error { for i := 0; i < len(returnData); i += 2 { blsKey := returnData[i] @@ -1456,7 +1460,7 @@ func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( return err } - peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(common.NewList), uint32(nonce)) + peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce)) peerAcc.SetTempRating(s.startRating) peerAcc.SetUnStakedEpoch(common.DefaultUnstakedEpoch) @@ -1468,7 +1472,7 @@ func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( validatorInfo := &state.ValidatorInfo{ PublicKey: blsKey, ShardId: peerAcc.GetShardId(), - List: string(common.NewList), + List: string(list), Index: uint32(nonce), TempRating: s.startRating, Rating: s.startRating, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 096ce587fd4..b92421b48a2 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1935,25 +1935,31 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { }) validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), - List: string(common.EligibleList), + List: string(common.WaitingList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - s.flagInitStakingV4Enabled.SetValue(true) + s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) - assert.Nil(t, err) + require.Nil(t, err) require.Equal(t, len(validatorInfos[0]), len(listAllPubKeys)) + require.Equal(t, []byte("stakedPubKey0"), validatorInfos[0][0].PublicKey) + require.Equal(t, string(common.EligibleList), validatorInfos[0][0].List) + + require.Equal(t, []byte("stakedPubKey1"), validatorInfos[0][1].PublicKey) + require.Equal(t, string(common.WaitingList), validatorInfos[0][1].List) + peerAcc, _ := s.getPeerAccount([]byte("waitingPubKe0")) - assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKe0"))) - assert.Equal(t, peerAcc.GetList(), string(common.NewList)) + require.Equal(t, []byte("waitingPubKe0"), peerAcc.GetBLSPublicKey()) + require.Equal(t, string(common.AuctionList), peerAcc.GetList()) peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe1")) - assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKe1"))) - assert.Equal(t, peerAcc.GetList(), string(common.NewList)) + require.Equal(t, []byte("waitingPubKe1"), peerAcc.GetBLSPublicKey()) + require.Equal(t, string(common.AuctionList), peerAcc.GetList()) peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe2")) - assert.True(t, bytes.Equal(peerAcc.GetBLSPublicKey(), []byte("waitingPubKe2"))) - assert.Equal(t, peerAcc.GetList(), string(common.NewList)) + require.Equal(t, []byte("waitingPubKe2"), peerAcc.GetBLSPublicKey()) + require.Equal(t, string(common.AuctionList), peerAcc.GetList()) } From 0698a513061ffeb34c638d42dbc52d85cd5cf249 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Feb 2022 17:00:10 +0200 Subject: [PATCH 045/958] FIX: test --- epochStart/metachain/systemSCs_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index b92421b48a2..ee1f5d5872d 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1952,14 +1952,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { require.Equal(t, string(common.WaitingList), validatorInfos[0][1].List) peerAcc, _ := s.getPeerAccount([]byte("waitingPubKe0")) - require.Equal(t, []byte("waitingPubKe0"), peerAcc.GetBLSPublicKey()) require.Equal(t, string(common.AuctionList), peerAcc.GetList()) peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe1")) - require.Equal(t, []byte("waitingPubKe1"), peerAcc.GetBLSPublicKey()) require.Equal(t, string(common.AuctionList), peerAcc.GetList()) peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe2")) - require.Equal(t, []byte("waitingPubKe2"), peerAcc.GetBLSPublicKey()) require.Equal(t, string(common.AuctionList), peerAcc.GetList()) } From a0cdfc5abe5d0d43c8ca396c1d88ea60e685ee0b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Feb 2022 18:42:08 +0200 Subject: [PATCH 046/958] FEAT: Add first ugly version --- config/epochConfig.go | 1 + epochStart/metachain/systemSCs.go | 52 +++++++++++++++++++++++++- epochStart/metachain/systemSCs_test.go | 2 + 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/config/epochConfig.go b/config/epochConfig.go index 3460d6206c2..0f385b49a3c 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -76,6 +76,7 @@ type EnableEpochs struct { DoNotReturnOldBlockInBlockchainHookEnableEpoch uint32 StakeLimitsEnableEpoch uint32 StakingV4InitEnableEpoch uint32 + StakingV4EnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 1446678bb75..d1ec1298d7d 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -73,6 +73,7 @@ type systemSCProcessor struct { governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 stakingV4InitEnableEpoch uint32 + stakingV4EnableEpoch uint32 maxNodesEnableConfig []config.MaxNodesChangeConfig maxNodes uint32 flagSwitchJailedWaiting atomic.Flag @@ -89,6 +90,7 @@ type systemSCProcessor struct { flagBuiltInOnMetaEnabled atomic.Flag flagInitStakingV4Enabled atomic.Flag flagStakingQueueEnabled atomic.Flag + flagStakingV4Enabled atomic.Flag esdtOwnerAddressBytes []byte mapNumSwitchedPerShard map[uint32]uint32 mapNumSwitchablePerShard map[uint32]uint32 @@ -186,6 +188,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, + stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("systemSC: enable epoch for switch jail waiting", "epoch", s.switchEnableEpoch) @@ -197,7 +200,8 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr log.Debug("systemSC: enable epoch for save jailed always", "epoch", s.saveJailedAlwaysEnableEpoch) log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) log.Debug("systemSC: enable epoch for create NFT on meta", "epoch", s.builtInOnMetaEnableEpoch) - log.Debug("systemSC: enable epoch for staking v4", "epoch", s.stakingV4InitEnableEpoch) + log.Debug("systemSC: enable epoch for initializing staking v4", "epoch", s.stakingV4InitEnableEpoch) + log.Debug("systemSC: enable epoch for staking v4", "epoch", s.stakingV4EnableEpoch) s.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(s.maxNodesEnableConfig, args.MaxNodesEnableConfig) @@ -327,6 +331,49 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } + if s.flagStakingV4Enabled.IsSet() { + err := s.selectNodesFromAuctionList(validatorInfos) + if err != nil { + return err + } + } + + return nil +} + +func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32][]*state.ValidatorInfo) error { + auctionList := make([]*state.ValidatorInfo, 0) + noOfValidators := uint32(0) + for _, validatorsInShard := range validatorInfos { + for _, validator := range validatorsInShard { + if validator.List == string(common.AuctionList) { + auctionList = append(auctionList, validator) + } else if isValidator(validator) { + noOfValidators++ + } + } + } + + sort.Slice(auctionList, func(i, j int) bool { + pubKey1 := auctionList[i].PublicKey + pubKey2 := auctionList[j].PublicKey + + nodeTopUpPubKey1, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey1) + nodeTopUpPubKey2, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) + + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 + }) + + noOfSelectedNodes := s.maxNodes - noOfValidators + totalNodesInAuctionList := uint32(len(auctionList)) + if totalNodesInAuctionList < noOfSelectedNodes { + noOfSelectedNodes = totalNodesInAuctionList + } + for i := uint32(0); i < noOfSelectedNodes; i++ { + shardID := auctionList[i].ShardId + validatorInfos[shardID] = append(validatorInfos[shardID], auctionList[i]) + } + return nil } @@ -1605,4 +1652,7 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) + + s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) + log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingV4Enabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index ee1f5d5872d..d74c33cc473 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -997,6 +997,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS DelegationSmartContractEnableEpoch: 0, StakeLimitsEnableEpoch: 10, StakingV4InitEnableEpoch: 444, + StakingV4EnableEpoch: 445, }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, @@ -1038,6 +1039,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS StakingV2EnableEpoch: 1000000, ESDTEnableEpoch: 1000000, StakingV4InitEnableEpoch: 444, + StakingV4EnableEpoch: 445, }, }, } From 37517db363505e02b922c3a67a98bfafed98d308 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Feb 2022 11:13:04 +0200 Subject: [PATCH 047/958] FIX: Bug in addKeysToWaitingList --- epochStart/metachain/systemSCs_test.go | 38 +++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index ee1f5d5872d..b27c695b20d 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -824,6 +824,10 @@ func addKeysToWaitingList( marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) waitingListHead := &systemSmartContracts.WaitingList{} _ = marshalizer.Unmarshal(waitingListHead, marshaledData) + + waitingListAlreadyHasElements := waitingListHead.Length > 0 + waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey + waitingListHead.Length += uint32(len(waitingKeys)) lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) waitingListHead.LastKey = lastKeyInList @@ -832,7 +836,7 @@ func addKeysToWaitingList( _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) numWaitingKeys := len(waitingKeys) - previousKey := waitingListHead.FirstKey + previousKey := waitingListHead.LastKey for i, waitingKey := range waitingKeys { waitingKeyInList := []byte("w_" + string(waitingKey)) @@ -853,12 +857,22 @@ func addKeysToWaitingList( previousKey = waitingKeyInList } - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) + if waitingListAlreadyHasElements { + marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) + } else { + marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) + } + waitingListElement := &systemSmartContracts.ElementInList{} _ = marshalizer.Unmarshal(waitingListElement, marshaledData) waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) + + if waitingListAlreadyHasElements { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) + } else { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) + } _ = accountsDB.SaveAccount(stakingSCAcc) } @@ -1924,6 +1938,15 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { listAllPubKeys := append(listPubKeysWaiting, []byte("waitingPubKe0"), []byte("stakedPubKey0"), []byte("stakedPubKey1")) addValidatorData(args.UserAccountsDB, []byte("rewardAddress"), listAllPubKeys, big.NewInt(5000), args.Marshalizer) + + listPubKeysWaiting2 := [][]byte{[]byte("waitingPubKe6"), []byte("waitingPubKe7")} + addKeysToWaitingList(args.UserAccountsDB, listPubKeysWaiting2, args.Marshalizer, []byte("rewardAddres2"), []byte("rewardAddres2")) + addValidatorData(args.UserAccountsDB, []byte("rewardAddres2"), listPubKeysWaiting2, big.NewInt(5000), args.Marshalizer) + + listPubKeysWaiting3 := [][]byte{[]byte("waitingPubKe8"), []byte("waitingPubKe9")} + addKeysToWaitingList(args.UserAccountsDB, listPubKeysWaiting3, args.Marshalizer, []byte("rewardAddres3"), []byte("rewardAddres3")) + addValidatorData(args.UserAccountsDB, []byte("rewardAddres3"), listPubKeysWaiting3, big.NewInt(1000), args.Marshalizer) + _, _ = args.UserAccountsDB.Commit() validatorInfos := make(map[uint32][]*state.ValidatorInfo) @@ -1943,7 +1966,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) require.Nil(t, err) - require.Equal(t, len(validatorInfos[0]), len(listAllPubKeys)) + // require.Equal(t, len(validatorInfos[0]), len(listAllPubKeys)) + + for _, v := range validatorInfos[0] { + fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) + } require.Equal(t, []byte("stakedPubKey0"), validatorInfos[0][0].PublicKey) require.Equal(t, string(common.EligibleList), validatorInfos[0][0].List) @@ -1959,4 +1986,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe2")) require.Equal(t, string(common.AuctionList), peerAcc.GetList()) + + peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe6")) + require.Equal(t, string(common.AuctionList), peerAcc.GetList()) } From 88eb24cd437c286ac4861cdef245feb1f75cb7c9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Feb 2022 16:17:04 +0200 Subject: [PATCH 048/958] FIX: Refactor test --- epochStart/metachain/systemSCs_test.go | 111 ++++++++++++++----------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index b27c695b20d..1836eacc597 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1924,69 +1924,86 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) s, _ := NewSystemSCProcessor(args) + owner1 := []byte("owner1") + owner2 := []byte("owner2") + owner3 := []byte("owner3") + + owner1ListPubKeysWaiting := [][]byte{[]byte("waitingPubKe0"), []byte("waitingPubKe1"), []byte("waitingPubKe2")} + owner1ListPubKeysStaked := [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1")} + owner1AllPubKeys := append(owner1ListPubKeysWaiting, owner1ListPubKeysWaiting...) + + owner2ListPubKeysWaiting := [][]byte{[]byte("waitingPubKe3"), []byte("waitingPubKe4")} + owner2ListPubKeysStaked := [][]byte{[]byte("stakedPubKey2")} + owner2AllPubKeys := append(owner2ListPubKeysWaiting, owner2ListPubKeysStaked...) + + owner3ListPubKeysWaiting := [][]byte{[]byte("waitingPubKe5"), []byte("waitingPubKe6")} + prepareStakingContractWithData( args.UserAccountsDB, - []byte("stakedPubKey0"), - []byte("waitingPubKe0"), + owner1ListPubKeysStaked[0], + owner1ListPubKeysWaiting[0], args.Marshalizer, - []byte("rewardAddress"), - []byte("rewardAddress"), + owner1, + owner1, ) - listPubKeysWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2")} - addKeysToWaitingList(args.UserAccountsDB, listPubKeysWaiting, args.Marshalizer, []byte("rewardAddress"), []byte("rewardAddress")) - - listAllPubKeys := append(listPubKeysWaiting, []byte("waitingPubKe0"), []byte("stakedPubKey0"), []byte("stakedPubKey1")) - addValidatorData(args.UserAccountsDB, []byte("rewardAddress"), listAllPubKeys, big.NewInt(5000), args.Marshalizer) + // Owner1 has 2 staked nodes (one eligible, one waiting) in shard0 + 3 nodes in staking queue. + // It has enough stake so that all his staking queue nodes will be selected in the auction list + addKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting[1:], args.Marshalizer, owner1, owner1) + addValidatorData(args.UserAccountsDB, owner1, owner1AllPubKeys[1:], big.NewInt(5000), args.Marshalizer) - listPubKeysWaiting2 := [][]byte{[]byte("waitingPubKe6"), []byte("waitingPubKe7")} - addKeysToWaitingList(args.UserAccountsDB, listPubKeysWaiting2, args.Marshalizer, []byte("rewardAddres2"), []byte("rewardAddres2")) - addValidatorData(args.UserAccountsDB, []byte("rewardAddres2"), listPubKeysWaiting2, big.NewInt(5000), args.Marshalizer) + // Owner2 has 1 staked node (eligible) in shard1 + 2 nodes in staking queue. + // It has enough stake for only ONE node from staking queue to be selected in the auction list + addKeysToWaitingList(args.UserAccountsDB, owner2ListPubKeysWaiting, args.Marshalizer, owner2, owner2) + addValidatorData(args.UserAccountsDB, owner2, owner2AllPubKeys, big.NewInt(1500), args.Marshalizer) - listPubKeysWaiting3 := [][]byte{[]byte("waitingPubKe8"), []byte("waitingPubKe9")} - addKeysToWaitingList(args.UserAccountsDB, listPubKeysWaiting3, args.Marshalizer, []byte("rewardAddres3"), []byte("rewardAddres3")) - addValidatorData(args.UserAccountsDB, []byte("rewardAddres3"), listPubKeysWaiting3, big.NewInt(1000), args.Marshalizer) - - _, _ = args.UserAccountsDB.Commit() + // Owner3 has 0 staked node + 2 nodes in staking queue. + // It has enough stake so that all his staking queue nodes will be selected in the auction list + addKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) + addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ - PublicKey: []byte("stakedPubKey0"), - List: string(common.EligibleList), - RewardAddress: []byte("rewardAddress"), - AccumulatedFees: big.NewInt(0), - }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ - PublicKey: []byte("stakedPubKey1"), - List: string(common.WaitingList), - RewardAddress: []byte("rewardAddress"), - AccumulatedFees: big.NewInt(0), - }) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) require.Nil(t, err) - // require.Equal(t, len(validatorInfos[0]), len(listAllPubKeys)) - - for _, v := range validatorInfos[0] { - fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) - } - require.Equal(t, []byte("stakedPubKey0"), validatorInfos[0][0].PublicKey) - require.Equal(t, string(common.EligibleList), validatorInfos[0][0].List) + expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ + 0: { + createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1), + createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1), - require.Equal(t, []byte("stakedPubKey1"), validatorInfos[0][1].PublicKey) - require.Equal(t, string(common.WaitingList), validatorInfos[0][1].List) + createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2), - peerAcc, _ := s.getPeerAccount([]byte("waitingPubKe0")) - require.Equal(t, string(common.AuctionList), peerAcc.GetList()) - - peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe1")) - require.Equal(t, string(common.AuctionList), peerAcc.GetList()) + createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3), + createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3), + }, + 1: { + createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorInfos) +} - peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe2")) - require.Equal(t, string(common.AuctionList), peerAcc.GetList()) +// This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing +func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { + rating := uint32(0) + if list == common.NewList || list == common.AuctionList { + rating = uint32(5) + } - peerAcc, _ = s.getPeerAccount([]byte("waitingPubKe6")) - require.Equal(t, string(common.AuctionList), peerAcc.GetList()) + return &state.ValidatorInfo{ + PublicKey: pubKey, + List: string(list), + RewardAddress: owner, + AccumulatedFees: zero, + Rating: rating, + TempRating: rating, + } } From 60e4e3a6f25825b190e4d85689e8d23b69a11736 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Feb 2022 15:34:51 +0200 Subject: [PATCH 049/958] FEAT: Add temporary test --- epochStart/metachain/systemSCs.go | 47 +++++-- epochStart/metachain/systemSCs_test.go | 171 ++++++++++++++++++++++++- 2 files changed, 209 insertions(+), 9 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index d1ec1298d7d..343d3f84d90 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -255,7 +255,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagCorrectNumNodesToStake.IsSet() { - err := s.cleanAdditionalQueue() + err := s.cleanAdditionalQueue() // TODO: Deactivate this? if err != nil { return err } @@ -332,6 +332,10 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagStakingV4Enabled.IsSet() { + allNodesKeys := s.getAllNodesKeyMapOfType(validatorInfos) + + _ = s.stakingDataProvider.PrepareStakingDataForRewards(allNodesKeys) + err := s.selectNodesFromAuctionList(validatorInfos) if err != nil { return err @@ -354,24 +358,36 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 } } - sort.Slice(auctionList, func(i, j int) bool { + sort.SliceStable(auctionList, func(i, j int) bool { pubKey1 := auctionList[i].PublicKey pubKey2 := auctionList[j].PublicKey nodeTopUpPubKey1, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey1) nodeTopUpPubKey2, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) + fmt.Println(string(auctionList[i].RewardAddress) + " : " + string(pubKey1) + " : " + nodeTopUpPubKey1.String()) + fmt.Println(string(auctionList[j].RewardAddress) + " : " + string(pubKey2) + " : " + nodeTopUpPubKey2.String()) + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 }) - noOfSelectedNodes := s.maxNodes - noOfValidators + fmt.Println("AUCTION LIST -------") + for _, v := range auctionList { + topup, _ := s.stakingDataProvider.GetNodeStakedTopUp(v.PublicKey) + fmt.Println(string(v.RewardAddress) + " : " + string(v.PublicKey) + " : " + topup.String()) + } + fmt.Println("AUCTION LIST -------") + + noOfAvailableNodeSlots := s.maxNodes - noOfValidators totalNodesInAuctionList := uint32(len(auctionList)) - if totalNodesInAuctionList < noOfSelectedNodes { - noOfSelectedNodes = totalNodesInAuctionList + if totalNodesInAuctionList < noOfAvailableNodeSlots { + noOfAvailableNodeSlots = totalNodesInAuctionList } - for i := uint32(0); i < noOfSelectedNodes; i++ { - shardID := auctionList[i].ShardId - validatorInfos[shardID] = append(validatorInfos[shardID], auctionList[i]) + + for i := uint32(0); i < noOfAvailableNodeSlots; i++ { + auctionList[i].List = string(common.NewList) + //val := getValidatorInfoWithBLSKey(validatorInfos, auctionList[i].PublicKey) + //val.List = string(common.NewList) } return nil @@ -634,6 +650,20 @@ func (s *systemSCProcessor) getEligibleNodesKeyMapOfType( return eligibleNodesKeys } +func (s *systemSCProcessor) getAllNodesKeyMapOfType( + validatorsInfo map[uint32][]*state.ValidatorInfo, +) map[uint32][][]byte { + eligibleNodesKeys := make(map[uint32][][]byte) + for shardID, validatorsInfoSlice := range validatorsInfo { + eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) + for _, validatorInfo := range validatorsInfoSlice { + eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.PublicKey) + } + } + + return eligibleNodesKeys +} + func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBlock { for _, miniBlock := range miniBlocks { if miniBlock.Type != block.RewardsBlock { @@ -761,6 +791,7 @@ func (s *systemSCProcessor) updateMaxNodes(validatorInfos map[uint32][]*state.Va return epochStart.ErrInvalidMaxNumberOfNodes } + // TODO: Check if flag is not enabled, should we move staked nodes to AuctionList? if s.flagStakingQueueEnabled.IsSet() { sw.Start("stakeNodesFromQueue") err = s.stakeNodesFromQueue(validatorInfos, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 30d29f6ab35..ddc06610043 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1920,7 +1920,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T } } -func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) { t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) @@ -1993,6 +1993,112 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4(t *testing.T) { require.Equal(t, expectedValidatorsInfo, validatorInfos) } +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, MaxNumNodes: 7}} + s, _ := NewSystemSCProcessor(args) + + owner1 := []byte("owner1") + owner2 := []byte("owner2") + owner3 := []byte("owner3") + owner4 := []byte("owner4") + + owner1ListPubKeysStaked := [][]byte{[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")} + owner2ListPubKeysStaked := [][]byte{[]byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5")} + owner3ListPubKeysStaked := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} + owner4ListPubKeysStaked := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} + + prepareStakingContractWithDataWithoutWaitingList( + args.UserAccountsDB, + owner1ListPubKeysStaked[0], + args.Marshalizer, + owner1, + owner1, + ) + + // Owner1 has 2 staked nodes (one eligible, one waiting) in shard0 + 3 nodes in staking queue. + // It has enough stake so that all his staking queue nodes will be selected in the auction list + addValidatorData(args.UserAccountsDB, owner1, owner1ListPubKeysStaked[1:], big.NewInt(5000), args.Marshalizer) + addStakingData(args.UserAccountsDB, owner1ListPubKeysStaked[1:], args.Marshalizer, owner1, owner1) + + // Owner2 has 1 staked node (eligible) in shard1 + 2 nodes in staking queue. + // It has enough stake for only ONE node from staking queue to be selected in the auction list + addValidatorData(args.UserAccountsDB, owner2, owner2ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) + addStakingData(args.UserAccountsDB, owner2ListPubKeysStaked, args.Marshalizer, owner2, owner2) + + // Owner3 has 0 staked node + 2 nodes in staking queue. + // It has enough stake so that all his staking queue nodes will be selected in the auction list + addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysStaked, big.NewInt(2000), args.Marshalizer) + addStakingData(args.UserAccountsDB, owner3ListPubKeysStaked, args.Marshalizer, owner3, owner3) + + addValidatorData(args.UserAccountsDB, owner4, owner4ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) + addStakingData(args.UserAccountsDB, owner4ListPubKeysStaked, args.Marshalizer, owner4, owner4) + + validatorInfos := make(map[uint32][]*state.ValidatorInfo) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) // 1500 topup + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[2], common.AuctionList, owner1)) + + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) // 0 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[1], common.AuctionList, owner2)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[2], common.AuctionList, owner2)) + + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3)) // 0 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[1], common.AuctionList, owner3)) + + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[0], common.EligibleList, owner4)) // 500 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[1], common.AuctionList, owner4)) + + s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + + err := s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch) + require.Nil(t, err) + + owner1TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner1ListPubKeysStaked[0]) + require.Equal(t, big.NewInt(1500), owner1TopUpPerNode) + + owner2TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner2ListPubKeysStaked[0]) + require.Equal(t, big.NewInt(0), owner2TopUpPerNode) + + owner3TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner3ListPubKeysStaked[0]) + require.Equal(t, big.NewInt(0), owner3TopUpPerNode) + + owner4TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner4ListPubKeysStaked[0]) + require.Equal(t, big.NewInt(500), owner4TopUpPerNode) + + for _, v := range validatorInfos[0] { + fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) + } + + for _, v := range validatorInfos[1] { + fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) + } + + /* + expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ + 0: { + createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1), + createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1), + + createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2), + + createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3), + createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3), + }, + 1: { + createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorInfos) + + */ +} + // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { rating := uint32(0) @@ -2009,3 +2115,66 @@ func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *sta TempRating: rating, } } + +func addStakingData( + accountsDB state.AccountsAdapter, + stakedKeys [][]byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + + stakedData := &systemSmartContracts.StakedDataV2_0{ + Staked: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + + for _, key := range stakedKeys { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) + } + + _ = accountsDB.SaveAccount(stakingSCAcc) +} + +func prepareStakingContractWithDataWithoutWaitingList( + accountsDB state.AccountsAdapter, + stakedKey []byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + + stakedData := &systemSmartContracts.StakedDataV2_0{ + Staked: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(stakedKey, marshaledData) + _ = accountsDB.SaveAccount(stakingSCAcc) + + validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) + validatorData := &systemSmartContracts.ValidatorDataV2{ + RegisterNonce: 0, + Epoch: 0, + RewardAddress: rewardAddress, + TotalStakeValue: big.NewInt(10000000000), + LockedStake: big.NewInt(10000000000), + TotalUnstaked: big.NewInt(0), + NumRegistered: 2, + BlsPubKeys: [][]byte{stakedKey}, + } + + marshaledData, _ = marshalizer.Marshal(validatorData) + _ = validatorSC.DataTrieTracker().SaveKeyValue(rewardAddress, marshaledData) + + _ = accountsDB.SaveAccount(validatorSC) + _, err := accountsDB.Commit() + log.LogIfError(err) +} From bd9d10154bf68f43ef22e1a7503b5f7c7022d3b3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Feb 2022 16:41:28 +0200 Subject: [PATCH 050/958] FEAT: Change ProcessSystemSmartContract func interface to accept rand --- epochStart/metachain/systemSCs.go | 10 ++++++ epochStart/metachain/systemSCs_test.go | 36 +++++++++---------- .../mock/epochStartSystemSCStub.go | 11 ++++-- process/block/metablock.go | 8 ++--- process/interface.go | 7 +++- process/mock/epochStartSystemSCStub.go | 11 ++++-- 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 343d3f84d90..5af33c39c7a 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -218,6 +218,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, + randomness []byte, ) error { if s.flagHystNodesEnabled.IsSet() { err := s.updateSystemSCConfigMinNodes() @@ -368,6 +369,15 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 fmt.Println(string(auctionList[i].RewardAddress) + " : " + string(pubKey1) + " : " + nodeTopUpPubKey1.String()) fmt.Println(string(auctionList[j].RewardAddress) + " : " + string(pubKey2) + " : " + nodeTopUpPubKey2.String()) + if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { + // xor cu hash(key + key2) + // h = hash(keyLow, keyHigh) + // key1r := h xor key1 + // key2r = h xor key2 + + // return key1r.cmp(key2r) ==1 + } + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 }) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index ddc06610043..1bd1efaa651 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -184,7 +184,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { AccumulatedFees: big.NewInt(0), } validatorInfos[0] = append(validatorInfos[0], vInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) assert.Equal(t, len(validatorInfos[0]), 1) @@ -230,7 +230,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s validatorsInfo := make(map[uint32][]*state.ValidatorInfo) validatorsInfo[0] = append(validatorsInfo[0], jailed...) - err := s.ProcessSystemSmartContract(validatorsInfo, 0, 0) + err := s.ProcessSystemSmartContract(validatorsInfo, 0, 0, nil) assert.Nil(t, err) for i := 0; i < numWaiting; i++ { assert.Equal(t, string(common.NewList), validatorsInfo[0][i].List) @@ -301,7 +301,7 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { } validatorsInfo[0] = append(validatorsInfo[0], jailed) - err := s.ProcessSystemSmartContract(validatorsInfo, 0, 0) + err := s.ProcessSystemSmartContract(validatorsInfo, 0, 0, nil) assert.Nil(t, err) for _, vInfo := range validatorsInfo[0] { @@ -1121,7 +1121,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin _ = s.flagDelegationEnabled.SetReturningPrevious() validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) @@ -1264,7 +1264,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueue(t * ) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1316,7 +1316,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwne EpochField: 10, }) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 10) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 10, nil) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1342,7 +1342,7 @@ func TestSystemSCProcessor_ESDTInitShouldWork(t *testing.T) { require.Equal(t, 4, len(initialContractConfig)) require.Equal(t, []byte("aaaaaa"), initialContractConfig[0]) - err = s.ProcessSystemSmartContract(nil, 1, 1) + err = s.ProcessSystemSmartContract(nil, 1, 1, nil) require.Nil(t, err) @@ -1409,7 +1409,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1462,7 +1462,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) } @@ -1551,7 +1551,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) for _, vInfo := range validatorInfos[0] { @@ -1643,7 +1643,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) for _, vInfo := range validatorInfos[0] { @@ -1736,7 +1736,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( _ = args.PeerAccountsDB.SaveAccount(peerAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr2) @@ -1810,7 +1810,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractWrongValidatorInfoShouldBeC AccumulatedFees: big.NewInt(0), }) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) assert.Equal(t, len(validatorInfos[0]), 1) @@ -1906,7 +1906,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) assert.Nil(t, err) _, err = s.peerAccountsDB.GetExistingAccount([]byte("waitingPubKey")) @@ -1970,7 +1970,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ @@ -1997,7 +1997,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, MaxNumNodes: 7}} + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, MaxNumNodes: 6}} s, _ := NewSystemSCProcessor(args) owner1 := []byte("owner1") @@ -2048,12 +2048,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3)) // 0 topup validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[1], common.AuctionList, owner3)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[0], common.EligibleList, owner4)) // 500 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[0], common.JailedList, owner4)) // 500 topup validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[1], common.AuctionList, owner4)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch) + err := s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, nil) require.Nil(t, err) owner1TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner1ListPubKeysStaked[0]) diff --git a/integrationTests/mock/epochStartSystemSCStub.go b/integrationTests/mock/epochStartSystemSCStub.go index db0dd8f889a..a4da2334824 100644 --- a/integrationTests/mock/epochStartSystemSCStub.go +++ b/integrationTests/mock/epochStartSystemSCStub.go @@ -8,7 +8,7 @@ import ( // EpochStartSystemSCStub - type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error + ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, randomness []byte) error ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error ToggleUnStakeUnBondCalled func(value bool) error } @@ -22,9 +22,14 @@ func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { } // ProcessSystemSmartContract - -func (e *EpochStartSystemSCStub) ProcessSystemSmartContract(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error { +func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( + validatorInfos map[uint32][]*state.ValidatorInfo, + nonce uint64, + epoch uint32, + randomness []byte, +) error { if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorInfos, nonce, epoch) + return e.ProcessSystemSmartContractCalled(validatorInfos, nonce, epoch, randomness) } return nil } diff --git a/process/block/metablock.go b/process/block/metablock.go index d575d274d21..0150a17132e 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -403,7 +403,7 @@ func (mp *metaProcessor) processEpochStartMetaBlock( } if mp.isRewardsV2Enabled(header) { - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header.Nonce, header.Epoch) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header.Nonce, header.Epoch, header.GetPrevRandSeed()) if err != nil { return err } @@ -418,7 +418,7 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header.Nonce, header.Epoch) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header.Nonce, header.Epoch, header.GetPrevRandSeed()) if err != nil { return err } @@ -865,7 +865,7 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. var rewardMiniBlocks block.MiniBlockSlice if mp.isRewardsV2Enabled(metaBlock) { - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock.Nonce, metaBlock.Epoch) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock.Nonce, metaBlock.Epoch, metaBlock.GetPrevRandSeed()) if err != nil { return nil, err } @@ -880,7 +880,7 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock.Nonce, metaBlock.Epoch) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock.Nonce, metaBlock.Epoch, metaBlock.GetPrevRandSeed()) if err != nil { return nil, err } diff --git a/process/interface.go b/process/interface.go index 9f3eb0cecbe..ec480d5724a 100644 --- a/process/interface.go +++ b/process/interface.go @@ -871,7 +871,12 @@ type EpochStartValidatorInfoCreator interface { // EpochStartSystemSCProcessor defines the functionality for the metachain to process system smart contract and end of epoch type EpochStartSystemSCProcessor interface { - ProcessSystemSmartContract(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error + ProcessSystemSmartContract( + validatorInfos map[uint32][]*state.ValidatorInfo, + nonce uint64, + epoch uint32, + randomness []byte, + ) error ProcessDelegationRewards( miniBlocks block.MiniBlockSlice, rewardTxs epochStart.TransactionCacher, diff --git a/process/mock/epochStartSystemSCStub.go b/process/mock/epochStartSystemSCStub.go index db0dd8f889a..a4da2334824 100644 --- a/process/mock/epochStartSystemSCStub.go +++ b/process/mock/epochStartSystemSCStub.go @@ -8,7 +8,7 @@ import ( // EpochStartSystemSCStub - type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error + ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, randomness []byte) error ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error ToggleUnStakeUnBondCalled func(value bool) error } @@ -22,9 +22,14 @@ func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { } // ProcessSystemSmartContract - -func (e *EpochStartSystemSCStub) ProcessSystemSmartContract(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error { +func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( + validatorInfos map[uint32][]*state.ValidatorInfo, + nonce uint64, + epoch uint32, + randomness []byte, +) error { if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorInfos, nonce, epoch) + return e.ProcessSystemSmartContractCalled(validatorInfos, nonce, epoch, randomness) } return nil } From a838a7ffde8112b26c08a1b83f34e60d0a27c4b4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Feb 2022 17:22:31 +0200 Subject: [PATCH 051/958] FEAT: Sort by pubKey XOR rand if multiple nodes have same top up per node --- epochStart/metachain/systemSCs.go | 22 ++++++++++----- epochStart/metachain/systemSCs_test.go | 38 ++++++++++++-------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 5af33c39c7a..7ea1d751231 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -337,7 +337,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( _ = s.stakingDataProvider.PrepareStakingDataForRewards(allNodesKeys) - err := s.selectNodesFromAuctionList(validatorInfos) + err := s.selectNodesFromAuctionList(validatorInfos, randomness) if err != nil { return err } @@ -346,7 +346,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( return nil } -func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32][]*state.ValidatorInfo) error { +func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32][]*state.ValidatorInfo, randomness []byte) error { auctionList := make([]*state.ValidatorInfo, 0) noOfValidators := uint32(0) for _, validatorsInShard := range validatorInfos { @@ -370,12 +370,20 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 fmt.Println(string(auctionList[j].RewardAddress) + " : " + string(pubKey2) + " : " + nodeTopUpPubKey2.String()) if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { - // xor cu hash(key + key2) - // h = hash(keyLow, keyHigh) - // key1r := h xor key1 - // key2r = h xor key2 - // return key1r.cmp(key2r) ==1 + key1Xor := make([]byte, len(randomness)) + key2Xor := make([]byte, len(randomness)) + + for idx := range randomness { + key1Xor[idx] = pubKey1[idx] ^ randomness[idx] + key2Xor[idx] = pubKey2[idx] ^ randomness[idx] + } + + fmt.Println(fmt.Sprintf("Comparing %s with %s . Xor1 = %v ; Xor2 = %v ", + pubKey1, pubKey2, key1Xor, key2Xor, + )) + + return bytes.Compare(key1Xor, key2Xor) == 1 } return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 1bd1efaa651..85876891168 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2053,7 +2053,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, nil) + err := s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, []byte("pubKey7")) require.Nil(t, err) owner1TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner1ListPubKeysStaked[0]) @@ -2076,27 +2076,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) } - /* - expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ - 0: { - createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1), - createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1), - createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1), - createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1), - createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1), - - createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2), + expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ + 0: { + createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1), + createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1), + createValidatorInfo(owner1ListPubKeysStaked[2], common.NewList, owner1), + }, + 1: { + createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), + createValidatorInfo(owner2ListPubKeysStaked[1], common.NewList, owner2), + createValidatorInfo(owner2ListPubKeysStaked[2], common.AuctionList, owner2), - createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3), - createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3), - }, - 1: { - createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), - }, - } - require.Equal(t, expectedValidatorsInfo, validatorInfos) + createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3), + createValidatorInfo(owner3ListPubKeysStaked[1], common.AuctionList, owner3), - */ + createValidatorInfo(owner4ListPubKeysStaked[0], common.JailedList, owner4), + createValidatorInfo(owner4ListPubKeysStaked[1], common.NewList, owner4), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorInfos) } // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing From ef304726f2985168fc778cde356dadfc94761b23 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Feb 2022 17:42:48 +0200 Subject: [PATCH 052/958] FIX: Top up per node in tests --- epochStart/metachain/systemSCs.go | 3 -- epochStart/metachain/systemSCs_test.go | 38 ++++++++++++-------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 7ea1d751231..fa0ded174c7 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -366,9 +366,6 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 nodeTopUpPubKey1, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey1) nodeTopUpPubKey2, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) - fmt.Println(string(auctionList[i].RewardAddress) + " : " + string(pubKey1) + " : " + nodeTopUpPubKey1.String()) - fmt.Println(string(auctionList[j].RewardAddress) + " : " + string(pubKey2) + " : " + nodeTopUpPubKey2.String()) - if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { key1Xor := make([]byte, len(randomness)) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 85876891168..698063dd6c5 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1993,11 +1993,19 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) require.Equal(t, expectedValidatorsInfo, validatorInfos) } +// Sorted auction list should be: +// owner1 : pubKey2 : 1000 +// owner4 : pubKey9 : 500 +// owner2 : pubKey4 : 0 +// owner2 : pubKey5 : 0 +// owner3 : pubKey7 : 0 +// Comparing pubKey5 with pubKey4 . Xor1 = [0 0 0 0 0 0 2] ; Xor2 = [0 0 0 0 0 0 3] +// Comparing pubKey7 with pubKey5 . Xor1 = [0 0 0 0 0 0 0] ; Xor2 = [0 0 0 0 0 0 2] func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, MaxNumNodes: 6}} + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 6}} s, _ := NewSystemSCProcessor(args) owner1 := []byte("owner1") @@ -2010,32 +2018,20 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner3ListPubKeysStaked := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} owner4ListPubKeysStaked := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} - prepareStakingContractWithDataWithoutWaitingList( - args.UserAccountsDB, - owner1ListPubKeysStaked[0], - args.Marshalizer, - owner1, - owner1, - ) + addValidatorData(args.UserAccountsDB, owner1, owner1ListPubKeysStaked, big.NewInt(6000), args.Marshalizer) + addStakingData(args.UserAccountsDB, owner1ListPubKeysStaked, args.Marshalizer, owner1, owner1) - // Owner1 has 2 staked nodes (one eligible, one waiting) in shard0 + 3 nodes in staking queue. - // It has enough stake so that all his staking queue nodes will be selected in the auction list - addValidatorData(args.UserAccountsDB, owner1, owner1ListPubKeysStaked[1:], big.NewInt(5000), args.Marshalizer) - addStakingData(args.UserAccountsDB, owner1ListPubKeysStaked[1:], args.Marshalizer, owner1, owner1) - - // Owner2 has 1 staked node (eligible) in shard1 + 2 nodes in staking queue. - // It has enough stake for only ONE node from staking queue to be selected in the auction list addValidatorData(args.UserAccountsDB, owner2, owner2ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) addStakingData(args.UserAccountsDB, owner2ListPubKeysStaked, args.Marshalizer, owner2, owner2) - // Owner3 has 0 staked node + 2 nodes in staking queue. - // It has enough stake so that all his staking queue nodes will be selected in the auction list addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysStaked, big.NewInt(2000), args.Marshalizer) addStakingData(args.UserAccountsDB, owner3ListPubKeysStaked, args.Marshalizer, owner3, owner3) addValidatorData(args.UserAccountsDB, owner4, owner4ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) addStakingData(args.UserAccountsDB, owner4ListPubKeysStaked, args.Marshalizer, owner4, owner4) + _, err := args.UserAccountsDB.Commit() + validatorInfos := make(map[uint32][]*state.ValidatorInfo) validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) // 1500 topup validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) @@ -2053,11 +2049,13 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, []byte("pubKey7")) + err = s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, []byte("pubKey7")) require.Nil(t, err) - owner1TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner1ListPubKeysStaked[0]) - require.Equal(t, big.NewInt(1500), owner1TopUpPerNode) + for _, owner1PubKey := range owner1ListPubKeysStaked { + owner1TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner1PubKey) + require.Equal(t, big.NewInt(1000), owner1TopUpPerNode) + } owner2TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner2ListPubKeysStaked[0]) require.Equal(t, big.NewInt(0), owner2TopUpPerNode) From caa682dde834ebe1343c85f4a688390fcaa7aa14 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 24 Feb 2022 14:33:27 +0200 Subject: [PATCH 053/958] FEAT: Display auction list, refactor interface + tests --- epochStart/interface.go | 1 + epochStart/metachain/stakingDataProvider.go | 7 +- epochStart/metachain/systemSCs.go | 40 +++++-- epochStart/metachain/systemSCs_test.go | 114 ++++++-------------- epochStart/mock/stakingDataProviderStub.go | 5 + 5 files changed, 75 insertions(+), 92 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index 45c5cab69cc..2f834ef4a6b 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -161,6 +161,7 @@ type StakingDataProvider interface { PrepareStakingDataForRewards(keys map[uint32][][]byte) error FillValidatorInfo(blsKey []byte) error ComputeUnQualifiedNodes(validatorInfos map[uint32][]*state.ValidatorInfo) ([][]byte, map[string][][]byte, error) + GetBlsKeyOwner(blsKey []byte) (string, error) Clean() IsInterfaceNil() bool } diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index f42a81a663e..df0a52714df 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -91,7 +91,7 @@ func (sdp *stakingDataProvider) GetTotalTopUpStakeEligibleNodes() *big.Int { // GetNodeStakedTopUp returns the owner of provided bls key staking stats for the current epoch func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) { - owner, err := sdp.getBlsKeyOwner(blsKey) + owner, err := sdp.GetBlsKeyOwner(blsKey) if err != nil { log.Debug("GetOwnerStakingStats", "key", hex.EncodeToString(blsKey), "error", err) return nil, err @@ -163,7 +163,7 @@ func (sdp *stakingDataProvider) FillValidatorInfo(blsKey []byte) error { } func (sdp *stakingDataProvider) getAndFillOwnerStatsFromSC(blsKey []byte) (*ownerStats, error) { - owner, err := sdp.getBlsKeyOwner(blsKey) + owner, err := sdp.GetBlsKeyOwner(blsKey) if err != nil { log.Debug("error fill owner stats", "step", "get owner from bls", "key", hex.EncodeToString(blsKey), "error", err) return nil, err @@ -195,7 +195,8 @@ func (sdp *stakingDataProvider) loadDataForBlsKey(blsKey []byte) error { return nil } -func (sdp *stakingDataProvider) getBlsKeyOwner(blsKey []byte) (string, error) { +// GetBlsKeyOwner returns the owner's public key of the provided bls key +func (sdp *stakingDataProvider) GetBlsKeyOwner(blsKey []byte) (string, error) { vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ CallerAddr: vm.ValidatorSCAddress, diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index fa0ded174c7..14194dad37f 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -13,6 +13,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" vInfo "github.com/ElrondNetwork/elrond-go/common/validatorInfo" @@ -386,28 +387,49 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 }) - fmt.Println("AUCTION LIST -------") - for _, v := range auctionList { - topup, _ := s.stakingDataProvider.GetNodeStakedTopUp(v.PublicKey) - fmt.Println(string(v.RewardAddress) + " : " + string(v.PublicKey) + " : " + topup.String()) - } - fmt.Println("AUCTION LIST -------") - noOfAvailableNodeSlots := s.maxNodes - noOfValidators totalNodesInAuctionList := uint32(len(auctionList)) if totalNodesInAuctionList < noOfAvailableNodeSlots { noOfAvailableNodeSlots = totalNodesInAuctionList } + s.displayAuctionList(auctionList, noOfAvailableNodeSlots) + for i := uint32(0); i < noOfAvailableNodeSlots; i++ { auctionList[i].List = string(common.NewList) - //val := getValidatorInfoWithBLSKey(validatorInfos, auctionList[i].PublicKey) - //val.List = string(common.NewList) } return nil } +func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInfo, noOfSelectedNodes uint32) { + tableHeader := []string{"Owner", "Registered key", "TopUp per node"} + lines := make([]*display.LineData, 0, len(auctionList)) + horizontalLine := false + for idx, validator := range auctionList { + + if uint32(idx) == noOfSelectedNodes-1 { + horizontalLine = true + } else { + horizontalLine = false + } + pubKey := validator.GetPublicKey() + owner, _ := s.stakingDataProvider.GetBlsKeyOwner(pubKey) + topUp, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) + line := display.NewLineData(horizontalLine, []string{ + owner, + string(pubKey), + topUp.String(), + }) + + lines = append(lines, line) + } + + table, _ := display.CreateTableString(tableHeader, lines) + message := fmt.Sprintf("Auction list\n%s", table) + log.Warn(message) +} + // ToggleUnStakeUnBond will pause/unPause the unStake/unBond functions on the validator system sc func (s *systemSCProcessor) ToggleUnStakeUnBond(value bool) error { if !s.flagStakingV2Enabled.IsSet() { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 698063dd6c5..057a856ba9f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2006,7 +2006,6 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 6}} - s, _ := NewSystemSCProcessor(args) owner1 := []byte("owner1") owner2 := []byte("owner2") @@ -2018,61 +2017,35 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner3ListPubKeysStaked := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} owner4ListPubKeysStaked := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} - addValidatorData(args.UserAccountsDB, owner1, owner1ListPubKeysStaked, big.NewInt(6000), args.Marshalizer) - addStakingData(args.UserAccountsDB, owner1ListPubKeysStaked, args.Marshalizer, owner1, owner1) - - addValidatorData(args.UserAccountsDB, owner2, owner2ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) - addStakingData(args.UserAccountsDB, owner2ListPubKeysStaked, args.Marshalizer, owner2, owner2) - - addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysStaked, big.NewInt(2000), args.Marshalizer) - addStakingData(args.UserAccountsDB, owner3ListPubKeysStaked, args.Marshalizer, owner3, owner3) - - addValidatorData(args.UserAccountsDB, owner4, owner4ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) - addStakingData(args.UserAccountsDB, owner4ListPubKeysStaked, args.Marshalizer, owner4, owner4) - - _, err := args.UserAccountsDB.Commit() + registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1ListPubKeysStaked, big.NewInt(6000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3ListPubKeysStaked, big.NewInt(2000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) // 1500 topup + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[2], common.AuctionList, owner1)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) // 0 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[1], common.AuctionList, owner2)) validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[2], common.AuctionList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3)) // 0 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3)) validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[1], common.AuctionList, owner3)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[0], common.JailedList, owner4)) // 500 topup + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[0], common.JailedList, owner4)) validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[1], common.AuctionList, owner4)) + s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - - err = s.ProcessSystemSmartContract(validatorInfos, 0, args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, []byte("pubKey7")) + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("pubKey7")) require.Nil(t, err) - for _, owner1PubKey := range owner1ListPubKeysStaked { - owner1TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner1PubKey) - require.Equal(t, big.NewInt(1000), owner1TopUpPerNode) - } - - owner2TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner2ListPubKeysStaked[0]) - require.Equal(t, big.NewInt(0), owner2TopUpPerNode) - - owner3TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner3ListPubKeysStaked[0]) - require.Equal(t, big.NewInt(0), owner3TopUpPerNode) - - owner4TopUpPerNode, _ := s.stakingDataProvider.GetNodeStakedTopUp(owner4ListPubKeysStaked[0]) - require.Equal(t, big.NewInt(500), owner4TopUpPerNode) - - for _, v := range validatorInfos[0] { - fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) - } - - for _, v := range validatorInfos[1] { - fmt.Println(string(v.RewardAddress) + ": " + string(v.PublicKey) + " - " + v.List) - } + requireTopUpPerNodes(t, s.stakingDataProvider, owner1ListPubKeysStaked, big.NewInt(1000)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner2ListPubKeysStaked, big.NewInt(0)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner3ListPubKeysStaked, big.NewInt(0)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner4ListPubKeysStaked, big.NewInt(500)) expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ 0: { @@ -2095,6 +2068,26 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing require.Equal(t, expectedValidatorsInfo, validatorInfos) } +func registerValidatorKeys( + accountsDB state.AccountsAdapter, + ownerAddress []byte, + rewardAddress []byte, + stakedKeys [][]byte, + totalStake *big.Int, + marshaller marshal.Marshalizer, +) { + addValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) + addStakingData(accountsDB, stakedKeys, marshaller, rewardAddress, ownerAddress) + _, _ = accountsDB.Commit() +} + +func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { + for _, pubKey := range stakedPubKeys { + topUpPerNode, _ := s.GetNodeStakedTopUp(pubKey) + require.Equal(t, topUpPerNode, topUp) + } +} + // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { rating := uint32(0) @@ -2135,42 +2128,3 @@ func addStakingData( _ = accountsDB.SaveAccount(stakingSCAcc) } - -func prepareStakingContractWithDataWithoutWaitingList( - accountsDB state.AccountsAdapter, - stakedKey []byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - - stakedData := &systemSmartContracts.StakedDataV2_0{ - Staked: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(stakedKey, marshaledData) - _ = accountsDB.SaveAccount(stakingSCAcc) - - validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) - validatorData := &systemSmartContracts.ValidatorDataV2{ - RegisterNonce: 0, - Epoch: 0, - RewardAddress: rewardAddress, - TotalStakeValue: big.NewInt(10000000000), - LockedStake: big.NewInt(10000000000), - TotalUnstaked: big.NewInt(0), - NumRegistered: 2, - BlsPubKeys: [][]byte{stakedKey}, - } - - marshaledData, _ = marshalizer.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(rewardAddress, marshaledData) - - _ = accountsDB.SaveAccount(validatorSC) - _, err := accountsDB.Commit() - log.LogIfError(err) -} diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 0de1d38eba4..46bf5f430ce 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -72,6 +72,11 @@ func (sdps *StakingDataProviderStub) Clean() { } } +// GetBlsKeyOwner - +func (sdps *StakingDataProviderStub) GetBlsKeyOwner(blsKey []byte) (string, error) { + return "", nil +} + // IsInterfaceNil - func (sdps *StakingDataProviderStub) IsInterfaceNil() bool { return sdps == nil From 40ff5a7b4b7c08015dbced502c877d50b2123f8f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 24 Feb 2022 17:13:12 +0200 Subject: [PATCH 054/958] FIX: Refactor tests --- epochStart/metachain/systemSCs_test.go | 301 ++++++++++++------------- 1 file changed, 141 insertions(+), 160 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 057a856ba9f..3678fd74336 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -678,50 +678,6 @@ func createWaitingNodes(numNodes int, stakingSCAcc state.UserAccountHandler, use return validatorInfos } -func addValidatorData( - accountsDB state.AccountsAdapter, - ownerKey []byte, - registeredKeys [][]byte, - totalStake *big.Int, - marshalizer marshal.Marshalizer, -) { - validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) - validatorData := &systemSmartContracts.ValidatorDataV2{ - RegisterNonce: 0, - Epoch: 0, - RewardAddress: ownerKey, - TotalStakeValue: totalStake, - LockedStake: big.NewInt(0), - TotalUnstaked: big.NewInt(0), - BlsPubKeys: registeredKeys, - NumRegistered: uint32(len(registeredKeys)), - } - - marshaledData, _ := marshalizer.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) - - _ = accountsDB.SaveAccount(validatorSC) -} - -func addStakedData( - accountsDB state.AccountsAdapter, - stakedKey []byte, - ownerKey []byte, - marshalizer marshal.Marshalizer, -) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - stakedData := &systemSmartContracts.StakedDataV2_0{ - Staked: true, - RewardAddress: ownerKey, - OwnerAddress: ownerKey, - StakeValue: big.NewInt(0), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(stakedKey, marshaledData) - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - func prepareStakingContractWithData( accountsDB state.AccountsAdapter, stakedKey []byte, @@ -730,36 +686,10 @@ func prepareStakingContractWithData( rewardAddress []byte, ownerAddress []byte, ) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - - stakedData := &systemSmartContracts.StakedDataV2_0{ - Staked: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(stakedKey, marshaledData) - _ = accountsDB.SaveAccount(stakingSCAcc) - + addStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) saveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) + addValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) - validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) - validatorData := &systemSmartContracts.ValidatorDataV2{ - RegisterNonce: 0, - Epoch: 0, - RewardAddress: rewardAddress, - TotalStakeValue: big.NewInt(10000000000), - LockedStake: big.NewInt(10000000000), - TotalUnstaked: big.NewInt(0), - NumRegistered: 2, - BlsPubKeys: [][]byte{stakedKey, waitingKey}, - } - - marshaledData, _ = marshalizer.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(rewardAddress, marshaledData) - - _ = accountsDB.SaveAccount(validatorSC) _, err := accountsDB.Commit() log.LogIfError(err) } @@ -1371,12 +1301,13 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t []byte("rewardAddress"), []byte("rewardAddress"), ) - - addStakedData(args.UserAccountsDB, []byte("stakedPubKey1"), []byte("ownerKey"), args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey2"), []byte("ownerKey"), args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey3"), []byte("ownerKey"), args.Marshalizer) - addValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(2000), args.Marshalizer) - _, _ = args.UserAccountsDB.Commit() + registerValidatorKeys(args.UserAccountsDB, + []byte("ownerKey"), + []byte("ownerKey"), + [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, + big.NewInt(2000), + args.Marshalizer, + ) validatorInfos := make(map[uint32][]*state.ValidatorInfo) validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ @@ -1442,7 +1373,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor []byte("rewardAddress"), ) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey1"), []byte("ownerKey"), args.Marshalizer) + addStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, args.Marshalizer) addValidatorDataWithUnStakedKey(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, big.NewInt(1000), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1512,9 +1443,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra delegationAddr, ) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey1"), delegationAddr, args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey2"), delegationAddr, args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey3"), delegationAddr, args.Marshalizer) + addStakingData(args.UserAccountsDB, + delegationAddr, + delegationAddr, + [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, + args.Marshalizer, + ) allKeys := [][]byte{[]byte("stakedPubKey0"), []byte("waitingPubKey"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")} addValidatorData(args.UserAccountsDB, delegationAddr, allKeys, big.NewInt(3000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) @@ -1601,10 +1535,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional delegationAddr, ) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey1"), delegationAddr, args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey2"), delegationAddr, args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey3"), delegationAddr, args.Marshalizer) - + addStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer) listOfKeysInWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} allStakedKeys := append(listOfKeysInWaiting, []byte("waitingPubKey"), []byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")) addKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr, delegationAddr) @@ -1688,9 +1619,13 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( delegationAddr, ) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey1"), delegationAddr, args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey2"), delegationAddr, args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey3"), delegationAddr, args.Marshalizer) + addStakingData(args.UserAccountsDB, + delegationAddr, + delegationAddr, + [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, + args.Marshalizer, + ) + addValidatorData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(10000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1866,10 +1801,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T args.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 s, _ := NewSystemSCProcessor(args) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey0"), []byte("ownerKey"), args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey1"), []byte("ownerKey"), args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey2"), []byte("ownerKey"), args.Marshalizer) - addStakedData(args.UserAccountsDB, []byte("stakedPubKey3"), []byte("ownerKey"), args.Marshalizer) + addStakingData(args.UserAccountsDB, + []byte("ownerKey"), + []byte("ownerKey"), + [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, + args.Marshalizer, + ) saveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) addValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1993,14 +1930,6 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) require.Equal(t, expectedValidatorsInfo, validatorInfos) } -// Sorted auction list should be: -// owner1 : pubKey2 : 1000 -// owner4 : pubKey9 : 500 -// owner2 : pubKey4 : 0 -// owner2 : pubKey5 : 0 -// owner3 : pubKey7 : 0 -// Comparing pubKey5 with pubKey4 . Xor1 = [0 0 0 0 0 0 2] ; Xor2 = [0 0 0 0 0 0 3] -// Comparing pubKey7 with pubKey5 . Xor1 = [0 0 0 0 0 0 0] ; Xor2 = [0 0 0 0 0 0 2] func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() @@ -2012,57 +1941,83 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner3 := []byte("owner3") owner4 := []byte("owner4") - owner1ListPubKeysStaked := [][]byte{[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")} - owner2ListPubKeysStaked := [][]byte{[]byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5")} - owner3ListPubKeysStaked := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} - owner4ListPubKeysStaked := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} + owner1StakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")} + owner2StakedKeys := [][]byte{[]byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5")} + owner3StakedKeys := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} + owner4StakedKeys := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} - registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1ListPubKeysStaked, big.NewInt(6000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3ListPubKeysStaked, big.NewInt(2000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4ListPubKeysStaked, big.NewInt(3000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(3000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[2], common.AuctionList, owner1)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[1], common.AuctionList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[2], common.AuctionList, owner2)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3ListPubKeysStaked[1], common.AuctionList, owner3)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[0], common.JailedList, owner4)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4ListPubKeysStaked[1], common.AuctionList, owner4)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4)) + validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("pubKey7")) require.Nil(t, err) - requireTopUpPerNodes(t, s.stakingDataProvider, owner1ListPubKeysStaked, big.NewInt(1000)) - requireTopUpPerNodes(t, s.stakingDataProvider, owner2ListPubKeysStaked, big.NewInt(0)) - requireTopUpPerNodes(t, s.stakingDataProvider, owner3ListPubKeysStaked, big.NewInt(0)) - requireTopUpPerNodes(t, s.stakingDataProvider, owner4ListPubKeysStaked, big.NewInt(500)) + /* + - MaxNumNodes = 6 + - EligibleBlsKeys = 3 (pubKey0, pubKey1, pubKey3) + - AuctionBlsKeys = 5 + We can only select (MaxNumNodes - EligibleBlsKeys = 3) bls keys from AuctionList to be added to NewList + + Auction list is: + +--------+----------------+----------------+ + | Owner | Registered key | TopUp per node | + +--------+----------------+----------------+ + | owner1 | pubKey2 | 1000 | + | owner4 | pubKey9 | 500 | + | owner2 | pubKey4 | 0 | + +--------+----------------+----------------+ + | owner2 | pubKey5 | 0 | + | owner3 | pubKey7 | 0 | + +--------+----------------+----------------+ + The following have 0 top up per node: + - owner2 with 2 bls keys = pubKey4, pubKey5 + - owner3 with 1 bls key = pubKey7 + + Since randomness = []byte("pubKey7"), nodes will be sorted based on blsKey XOR randomness, therefore: + - XOR1 = []byte("pubKey4") XOR []byte("pubKey7") = [0 0 0 0 0 0 3] + - XOR2 = []byte("pubKey5") XOR []byte("pubKey7") = [0 0 0 0 0 0 2] + - XOR3 = []byte("pubKey7") XOR []byte("pubKey7") = [0 0 0 0 0 0 0] + */ + requireTopUpPerNodes(t, s.stakingDataProvider, owner1StakedKeys, big.NewInt(1000)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner2StakedKeys, big.NewInt(0)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(0)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(500)) expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ 0: { - createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1), - createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1), - createValidatorInfo(owner1ListPubKeysStaked[2], common.NewList, owner1), + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1), + createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1), + createValidatorInfo(owner1StakedKeys[2], common.NewList, owner1), }, 1: { - createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), - createValidatorInfo(owner2ListPubKeysStaked[1], common.NewList, owner2), - createValidatorInfo(owner2ListPubKeysStaked[2], common.AuctionList, owner2), + createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2), + createValidatorInfo(owner2StakedKeys[1], common.NewList, owner2), + createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2), - createValidatorInfo(owner3ListPubKeysStaked[0], common.LeavingList, owner3), - createValidatorInfo(owner3ListPubKeysStaked[1], common.AuctionList, owner3), + createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3), + createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3), - createValidatorInfo(owner4ListPubKeysStaked[0], common.JailedList, owner4), - createValidatorInfo(owner4ListPubKeysStaked[1], common.NewList, owner4), + createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4), + createValidatorInfo(owner4StakedKeys[1], common.NewList, owner4), }, } require.Equal(t, expectedValidatorsInfo, validatorInfos) @@ -2077,54 +2032,80 @@ func registerValidatorKeys( marshaller marshal.Marshalizer, ) { addValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) - addStakingData(accountsDB, stakedKeys, marshaller, rewardAddress, ownerAddress) - _, _ = accountsDB.Commit() + addStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) + _, err := accountsDB.Commit() + log.LogIfError(err) } -func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { - for _, pubKey := range stakedPubKeys { - topUpPerNode, _ := s.GetNodeStakedTopUp(pubKey) - require.Equal(t, topUpPerNode, topUp) +func addValidatorData( + accountsDB state.AccountsAdapter, + ownerKey []byte, + registeredKeys [][]byte, + totalStake *big.Int, + marshaller marshal.Marshalizer, +) { + validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) + validatorData := &systemSmartContracts.ValidatorDataV2{ + RegisterNonce: 0, + Epoch: 0, + RewardAddress: ownerKey, + TotalStakeValue: totalStake, + LockedStake: big.NewInt(0), + TotalUnstaked: big.NewInt(0), + BlsPubKeys: registeredKeys, + NumRegistered: uint32(len(registeredKeys)), } -} -// This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing -func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { - rating := uint32(0) - if list == common.NewList || list == common.AuctionList { - rating = uint32(5) - } + marshaledData, _ := marshaller.Marshal(validatorData) + _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) - return &state.ValidatorInfo{ - PublicKey: pubKey, - List: string(list), - RewardAddress: owner, - AccumulatedFees: zero, - Rating: rating, - TempRating: rating, - } + _ = accountsDB.SaveAccount(validatorSC) } func addStakingData( accountsDB state.AccountsAdapter, - stakedKeys [][]byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, ownerAddress []byte, + rewardAddress []byte, + stakedKeys [][]byte, + marshaller marshal.Marshalizer, ) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - stakedData := &systemSmartContracts.StakedDataV2_0{ Staked: true, RewardAddress: rewardAddress, OwnerAddress: ownerAddress, StakeValue: big.NewInt(100), } - marshaledData, _ := marshalizer.Marshal(stakedData) + marshaledData, _ := marshaller.Marshal(stakedData) + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) for _, key := range stakedKeys { _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) } _ = accountsDB.SaveAccount(stakingSCAcc) } + +func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { + for _, pubKey := range stakedPubKeys { + topUpPerNode, err := s.GetNodeStakedTopUp(pubKey) + require.Nil(t, err) + require.Equal(t, topUpPerNode, topUp) + } +} + +// This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing +func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { + rating := uint32(0) + if list == common.NewList || list == common.AuctionList { + rating = uint32(5) + } + + return &state.ValidatorInfo{ + PublicKey: pubKey, + List: string(list), + RewardAddress: owner, + AccumulatedFees: zero, + Rating: rating, + TempRating: rating, + } +} From 02160adb39d7f3a9303957431d73fc95fb55eb96 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 24 Feb 2022 18:34:38 +0200 Subject: [PATCH 055/958] FIX: Refactor code pt. 1 --- epochStart/metachain/systemSCs.go | 72 +++++++++++++++++++------------ 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 14194dad37f..57faadc2579 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -360,46 +360,64 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 } } - sort.SliceStable(auctionList, func(i, j int) bool { - pubKey1 := auctionList[i].PublicKey - pubKey2 := auctionList[j].PublicKey + err := s.sortAuctionList(auctionList, randomness) + if err != nil { + return err + } - nodeTopUpPubKey1, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey1) - nodeTopUpPubKey2, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) + auctionListSize := uint32(len(auctionList)) + noOfAvailableNodeSlots := core.MinUint32(auctionListSize, s.maxNodes-noOfValidators) + s.displayAuctionList(auctionList, noOfAvailableNodeSlots) - if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { + for i := uint32(0); i < noOfAvailableNodeSlots; i++ { + auctionList[i].List = string(common.NewList) + } + + return nil +} - key1Xor := make([]byte, len(randomness)) - key2Xor := make([]byte, len(randomness)) +func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, randomness []byte) error { + errors := make([]error, 0) - for idx := range randomness { - key1Xor[idx] = pubKey1[idx] ^ randomness[idx] - key2Xor[idx] = pubKey2[idx] ^ randomness[idx] - } + sort.SliceStable(auctionList, func(i, j int) bool { + pubKey1 := auctionList[i].PublicKey + pubKey2 := auctionList[j].PublicKey + + nodeTopUpPubKey1, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey1) + if err != nil { + errors = append(errors, err) + log.Debug(fmt.Sprintf("%v when trying to get top up per node for %s", err, hex.EncodeToString(pubKey1))) + } - fmt.Println(fmt.Sprintf("Comparing %s with %s . Xor1 = %v ; Xor2 = %v ", - pubKey1, pubKey2, key1Xor, key2Xor, - )) + nodeTopUpPubKey2, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) + if err != nil { + errors = append(errors, err) + log.Debug(fmt.Sprintf("%v when trying to get top up per node for %s", err, hex.EncodeToString(pubKey1))) + } - return bytes.Compare(key1Xor, key2Xor) == 1 + if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { + return compareByXORWithRandomness(pubKey1, pubKey2, randomness) } return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 }) - noOfAvailableNodeSlots := s.maxNodes - noOfValidators - totalNodesInAuctionList := uint32(len(auctionList)) - if totalNodesInAuctionList < noOfAvailableNodeSlots { - noOfAvailableNodeSlots = totalNodesInAuctionList + if len(errors) > 0 { + return fmt.Errorf("error(s) while trying to sort auction list; last known error %w", errors[len(errors)-1]) } + return nil +} - s.displayAuctionList(auctionList, noOfAvailableNodeSlots) +func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { + key1Xor := make([]byte, len(randomness)) + key2Xor := make([]byte, len(randomness)) - for i := uint32(0); i < noOfAvailableNodeSlots; i++ { - auctionList[i].List = string(common.NewList) + for idx := range randomness { + key1Xor[idx] = pubKey1[idx] ^ randomness[idx] + key2Xor[idx] = pubKey2[idx] ^ randomness[idx] } - return nil + return bytes.Compare(key1Xor, key2Xor) == 1 } func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInfo, noOfSelectedNodes uint32) { @@ -407,18 +425,18 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf lines := make([]*display.LineData, 0, len(auctionList)) horizontalLine := false for idx, validator := range auctionList { - if uint32(idx) == noOfSelectedNodes-1 { horizontalLine = true } else { horizontalLine = false } + pubKey := validator.GetPublicKey() owner, _ := s.stakingDataProvider.GetBlsKeyOwner(pubKey) topUp, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) line := display.NewLineData(horizontalLine, []string{ - owner, - string(pubKey), + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(pubKey), topUp.String(), }) From 5ae3d7309364827b7992b83ddfecb94341bbb945 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 25 Feb 2022 13:00:18 +0200 Subject: [PATCH 056/958] FIX: Refactor code pt. 2 --- epochStart/metachain/systemSCs.go | 41 ++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 57faadc2579..1f6357e2b04 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -336,9 +336,12 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( if s.flagStakingV4Enabled.IsSet() { allNodesKeys := s.getAllNodesKeyMapOfType(validatorInfos) - _ = s.stakingDataProvider.PrepareStakingDataForRewards(allNodesKeys) + err := s.stakingDataProvider.PrepareStakingDataForRewards(allNodesKeys) + if err != nil { + return err + } - err := s.selectNodesFromAuctionList(validatorInfos, randomness) + err = s.selectNodesFromAuctionList(validatorInfos, randomness) if err != nil { return err } @@ -425,27 +428,31 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf lines := make([]*display.LineData, 0, len(auctionList)) horizontalLine := false for idx, validator := range auctionList { - if uint32(idx) == noOfSelectedNodes-1 { - horizontalLine = true - } else { - horizontalLine = false - } - + horizontalLine = uint32(idx) == noOfSelectedNodes-1 pubKey := validator.GetPublicKey() - owner, _ := s.stakingDataProvider.GetBlsKeyOwner(pubKey) - topUp, _ := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) + + owner, err := s.stakingDataProvider.GetBlsKeyOwner(pubKey) + log.LogIfError(err) + + topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) + log.LogIfError(err) + line := display.NewLineData(horizontalLine, []string{ hex.EncodeToString([]byte(owner)), hex.EncodeToString(pubKey), topUp.String(), }) - lines = append(lines, line) } - table, _ := display.CreateTableString(tableHeader, lines) + table, err := display.CreateTableString(tableHeader, lines) + if err != nil { + log.Error("could not create table", "error", err) + return + } + message := fmt.Sprintf("Auction list\n%s", table) - log.Warn(message) + log.Debug(message) } // ToggleUnStakeUnBond will pause/unPause the unStake/unBond functions on the validator system sc @@ -708,15 +715,15 @@ func (s *systemSCProcessor) getEligibleNodesKeyMapOfType( func (s *systemSCProcessor) getAllNodesKeyMapOfType( validatorsInfo map[uint32][]*state.ValidatorInfo, ) map[uint32][][]byte { - eligibleNodesKeys := make(map[uint32][][]byte) + nodeKeys := make(map[uint32][][]byte) for shardID, validatorsInfoSlice := range validatorsInfo { - eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) + nodeKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) for _, validatorInfo := range validatorsInfoSlice { - eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.PublicKey) + nodeKeys[shardID] = append(nodeKeys[shardID], validatorInfo.PublicKey) } } - return eligibleNodesKeys + return nodeKeys } func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBlock { From 2a2dc2961f556c2c8e8099da3f581bacf84a4aa1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 11:52:42 +0200 Subject: [PATCH 057/958] FEAT: Add tests for error paths --- epochStart/errors.go | 3 + epochStart/interface.go | 2 +- epochStart/metachain/stakingDataProvider.go | 4 +- .../metachain/stakingDataProvider_test.go | 2 +- epochStart/metachain/systemSCs.go | 12 ++-- epochStart/metachain/systemSCs_test.go | 63 +++++++++++++++++++ epochStart/mock/stakingDataProviderStub.go | 4 +- 7 files changed, 78 insertions(+), 12 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 7d82dc6dee7..fcda2b0c3af 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -334,3 +334,6 @@ var ErrNilScheduledDataSyncerFactory = errors.New("nil scheduled data syncer fac // ErrCouldNotInitLiquidStakingSystemSC signals that liquid staking system sc init failed var ErrCouldNotInitLiquidStakingSystemSC = errors.New("could not init liquid staking system sc") + +// ErrSortAuctionList signals that one or more errors occurred while trying to sort auction list +var ErrSortAuctionList = errors.New("error(s) while trying to sort auction list") diff --git a/epochStart/interface.go b/epochStart/interface.go index 2f834ef4a6b..fa2dcaba7dd 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -158,7 +158,7 @@ type StakingDataProvider interface { GetTotalStakeEligibleNodes() *big.Int GetTotalTopUpStakeEligibleNodes() *big.Int GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) - PrepareStakingDataForRewards(keys map[uint32][][]byte) error + PrepareStakingData(keys map[uint32][][]byte) error FillValidatorInfo(blsKey []byte) error ComputeUnQualifiedNodes(validatorInfos map[uint32][]*state.ValidatorInfo) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index df0a52714df..2ac6f1c8f68 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -105,8 +105,8 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return ownerInfo.topUpPerNode, nil } -// PrepareStakingDataForRewards prepares the staking data for the given map of node keys per shard -func (sdp *stakingDataProvider) PrepareStakingDataForRewards(keys map[uint32][][]byte) error { +// PrepareStakingData prepares the staking data for the given map of node keys per shard +func (sdp *stakingDataProvider) PrepareStakingData(keys map[uint32][][]byte) error { sdp.Clean() for _, keysList := range keys { diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 029c5b02131..bb1e371c20e 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -366,7 +366,7 @@ func TestStakingDataProvider_PrepareStakingDataForRewards(t *testing.T) { keys := make(map[uint32][][]byte) keys[0] = append(keys[0], []byte("owner")) - err := sdp.PrepareStakingDataForRewards(keys) + err := sdp.PrepareStakingData(keys) require.NoError(t, err) } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 1f6357e2b04..b83cc448858 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -334,9 +334,9 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagStakingV4Enabled.IsSet() { - allNodesKeys := s.getAllNodesKeyMapOfType(validatorInfos) + allNodesKeys := s.getAllNodeKeys(validatorInfos) - err := s.stakingDataProvider.PrepareStakingDataForRewards(allNodesKeys) + err := s.stakingDataProvider.PrepareStakingData(allNodesKeys) if err != nil { return err } @@ -395,7 +395,7 @@ func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, nodeTopUpPubKey2, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) if err != nil { errors = append(errors, err) - log.Debug(fmt.Sprintf("%v when trying to get top up per node for %s", err, hex.EncodeToString(pubKey1))) + log.Debug(fmt.Sprintf("%v when trying to get top up per node for %s", err, hex.EncodeToString(pubKey2))) } if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { @@ -406,7 +406,7 @@ func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, }) if len(errors) > 0 { - return fmt.Errorf("error(s) while trying to sort auction list; last known error %w", errors[len(errors)-1]) + return fmt.Errorf("%w; last known error %v", epochStart.ErrSortAuctionList, errors[len(errors)-1]) } return nil } @@ -693,7 +693,7 @@ func (s *systemSCProcessor) prepareStakingDataForRewards(eligibleNodesKeys map[u log.Debug("systemSCProcessor.prepareStakingDataForRewards time measurements", sw.GetMeasurements()...) }() - return s.stakingDataProvider.PrepareStakingDataForRewards(eligibleNodesKeys) + return s.stakingDataProvider.PrepareStakingData(eligibleNodesKeys) } func (s *systemSCProcessor) getEligibleNodesKeyMapOfType( @@ -712,7 +712,7 @@ func (s *systemSCProcessor) getEligibleNodesKeyMapOfType( return eligibleNodesKeys } -func (s *systemSCProcessor) getAllNodesKeyMapOfType( +func (s *systemSCProcessor) getAllNodeKeys( validatorsInfo map[uint32][]*state.ValidatorInfo, ) map[uint32][][]byte { nodeKeys := make(map[uint32][][]byte) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 3678fd74336..7a107dd5492 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -10,6 +10,7 @@ import ( "math/big" "os" "strconv" + "strings" "testing" arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" @@ -1930,6 +1931,68 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) require.Equal(t, expectedValidatorsInfo, validatorInfos) } +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepareStakingData(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + + errProcessStakingData := errors.New("error processing staking data") + args.StakingDataProvider = &mock.StakingDataProviderStub{ + PrepareStakingDataCalled: func(keys map[uint32][][]byte) error { + return errProcessStakingData + }, + } + + owner := []byte("owner") + ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} + registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) + + validatorInfos := make(map[uint32][]*state.ValidatorInfo) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) + + s, _ := NewSystemSCProcessor(args) + s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("rand")) + require.Equal(t, errProcessStakingData, err) +} + +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingAuctionList(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + + errGetNodeTopUp := errors.New("error getting top up per node") + args.StakingDataProvider = &mock.StakingDataProviderStub{ + GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { + switch string(blsKey) { + case "pubKey0", "pubKey1": + return nil, errGetNodeTopUp + default: + require.Fail(t, "should not call this func with other params") + return nil, nil + } + }, + } + + owner := []byte("owner") + ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} + registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) + + validatorInfos := make(map[uint32][]*state.ValidatorInfo) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) + validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) + + s, _ := NewSystemSCProcessor(args) + s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + + err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("rand")) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) + require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) +} + func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 46bf5f430ce..dedd3eb56f3 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -57,8 +57,8 @@ func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int return big.NewInt(0), nil } -// PrepareStakingDataForRewards - -func (sdps *StakingDataProviderStub) PrepareStakingDataForRewards(keys map[uint32][][]byte) error { +// PrepareStakingData - +func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte) error { if sdps.PrepareStakingDataCalled != nil { return sdps.PrepareStakingDataCalled(keys) } From 473896ee55ccd1bd900873082f965527267f6df9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 12:14:06 +0200 Subject: [PATCH 058/958] FIX: Small refactor --- epochStart/metachain/systemSCs.go | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index b83cc448858..6a6f87c8197 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -351,18 +351,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32][]*state.ValidatorInfo, randomness []byte) error { - auctionList := make([]*state.ValidatorInfo, 0) - noOfValidators := uint32(0) - for _, validatorsInShard := range validatorInfos { - for _, validator := range validatorsInShard { - if validator.List == string(common.AuctionList) { - auctionList = append(auctionList, validator) - } else if isValidator(validator) { - noOfValidators++ - } - } - } - + auctionList, noOfValidators := getAuctionListAndNoOfValidators(validatorInfos) err := s.sortAuctionList(auctionList, randomness) if err != nil { return err @@ -379,6 +368,23 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32 return nil } +func getAuctionListAndNoOfValidators(validatorInfos map[uint32][]*state.ValidatorInfo) ([]*state.ValidatorInfo, uint32) { + auctionList := make([]*state.ValidatorInfo, 0) + noOfValidators := uint32(0) + + for _, validatorsInShard := range validatorInfos { + for _, validator := range validatorsInShard { + if validator.List == string(common.AuctionList) { + auctionList = append(auctionList, validator) + } else if isValidator(validator) { + noOfValidators++ + } + } + } + + return auctionList, noOfValidators +} + func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, randomness []byte) error { errors := make([]error, 0) @@ -428,7 +434,6 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf lines := make([]*display.LineData, 0, len(auctionList)) horizontalLine := false for idx, validator := range auctionList { - horizontalLine = uint32(idx) == noOfSelectedNodes-1 pubKey := validator.GetPublicKey() owner, err := s.stakingDataProvider.GetBlsKeyOwner(pubKey) @@ -437,6 +442,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) log.LogIfError(err) + horizontalLine = uint32(idx) == noOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ hex.EncodeToString([]byte(owner)), hex.EncodeToString(pubKey), From e51f952334d1376aae529fb9d2ec548ad2e36cb6 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 13:34:57 +0200 Subject: [PATCH 059/958] FEAT: Add flag in toml file --- cmd/node/config/enableEpochs.toml | 3 +++ genesis/process/shardGenesisBlockCreator.go | 1 + 2 files changed, 4 insertions(+) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 8855c38ec83..66c5dc0a8df 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -191,6 +191,9 @@ # nodes queue is removed and all nodes from queue are moved to a new list StakingV4InitEnableEpoch = 1000000 + # StakingV4EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4InitEnableEpoch + StakingV4EnableEpoch = 1000001 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index bd299f9abbe..485f2a9fbf7 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -114,6 +114,7 @@ func createGenesisConfig() config.EnableEpochs { ScheduledMiniBlocksEnableEpoch: unreachableEpoch, StakeLimitsEnableEpoch: unreachableEpoch, StakingV4InitEnableEpoch: unreachableEpoch, + StakingV4EnableEpoch: unreachableEpoch, } } From f9d87f9df85c0015ba10b9609444689ef50dad9c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 16:35:41 +0200 Subject: [PATCH 060/958] FEAT: Add staking v4 flags in staking.go --- vm/systemSmartContracts/staking.go | 91 +++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index ef0725fbca0..3287262d723 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -48,10 +48,12 @@ type stakingSC struct { flagCorrectLastUnjailed atomic.Flag flagCorrectFirstQueued atomic.Flag flagCorrectJailedNotUnstakedEmptyQueue atomic.Flag + flagStakingV4 atomic.Flag correctJailedNotUnstakedEmptyQueueEpoch uint32 correctFirstQueuedEpoch uint32 correctLastUnjailedEpoch uint32 stakingV2Epoch uint32 + stakingV4Epoch uint32 walletAddressLen int mutExecution sync.RWMutex minNodePrice *big.Int @@ -138,6 +140,7 @@ func NewStakingSmartContract( validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, correctFirstQueuedEpoch: args.EpochConfig.EnableEpochs.CorrectFirstQueuedEpoch, correctJailedNotUnstakedEmptyQueueEpoch: args.EpochConfig.EnableEpochs.CorrectJailedNotUnstakedEmptyQueueEpoch, + stakingV4Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("staking: enable epoch for stake", "epoch", reg.enableStakingEpoch) log.Debug("staking: enable epoch for staking v2", "epoch", reg.stakingV2Epoch) @@ -145,6 +148,7 @@ func NewStakingSmartContract( log.Debug("staking: enable epoch for validator to delegation", "epoch", reg.validatorToDelegationEnableEpoch) log.Debug("staking: enable epoch for correct first queued", "epoch", reg.correctFirstQueuedEpoch) log.Debug("staking: enable epoch for correct jailed not unstaked with empty queue", "epoch", reg.correctJailedNotUnstakedEmptyQueueEpoch) + log.Debug("staking: enable epoch for staking v4", "epoch", reg.stakingV4Epoch) var conversionOk bool reg.stakeValue, conversionOk = big.NewInt(0).SetString(args.StakingSCConfig.GenesisNodePrice, conversionBase) @@ -258,6 +262,10 @@ func (s *stakingSC) numSpareNodes() int64 { } func (s *stakingSC) canStake() bool { + if s.flagStakingV4.IsSet() { + return true + } + stakeConfig := s.getConfig() return stakeConfig.StakedNodes < stakeConfig.MaxNumNodes } @@ -536,10 +544,12 @@ func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0 return nil } - err := s.removeFromWaitingList(blsKey) - if err != nil { - s.eei.AddReturnMessage("error while removing from waiting") - return err + if !s.flagStakingV4.IsSet() { + err := s.removeFromWaitingList(blsKey) + if err != nil { + s.eei.AddReturnMessage("error while removing from waiting") + return err + } } s.addToStakedNodes(1) s.activeStakingFor(registrationData) @@ -588,11 +598,16 @@ func (s *stakingSC) unStakeAtEndOfEpoch(args *vmcommon.ContractCallInput) vmcomm if registrationData.Staked { s.removeFromStakedNodes() } - if registrationData.Waiting { - err = s.removeFromWaitingList(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError + + // This is an extra check. We should not save any registrationData + // with Waiting = true when staking v4 is enabled + if !s.flagStakingV4.IsSet() { + if registrationData.Waiting { + err = s.removeFromWaitingList(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } } } @@ -1147,6 +1162,10 @@ func createWaitingListKey(blsKey []byte) []byte { } func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + return vmcommon.UserError + } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { s.eei.AddReturnMessage("switchJailedWithWaiting function not allowed to be called by address " + string(args.CallerAddr)) return vmcommon.UserError @@ -1298,6 +1317,13 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.Finish([]byte(strconv.Itoa(int(0)))) + + return vmcommon.Ok + } + waitingElementKey := createWaitingListKey(args.Arguments[0]) _, err := s.getWaitingListElement(waitingElementKey) if err != nil { @@ -1364,6 +1390,13 @@ func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommo return vmcommon.OutOfGas } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.Finish([]byte(strconv.Itoa(int(0)))) + + return vmcommon.Ok + } + waitingListHead, err := s.getWaitingListHead() if err != nil { s.eei.AddReturnMessage(err.Error()) @@ -1581,14 +1614,19 @@ func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallI return vmcommon.UserError } - stakeConfig := s.getConfig() - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError + waitingListLength := int64(0) + if !s.flagStakingV4.IsSet() { + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + waitingListLength = int64(waitingListHead.Length) } - totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + int64(waitingListHead.Length) + stakeConfig := s.getConfig() + totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + waitingListLength s.eei.Finish(big.NewInt(totalRegistered).Bytes()) return vmcommon.Ok } @@ -1598,6 +1636,10 @@ func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) // backward compatibility return vmcommon.UserError } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + return vmcommon.UserError + } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") return vmcommon.UserError @@ -1682,6 +1724,10 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") return vmcommon.UserError @@ -1754,6 +1800,10 @@ func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcom s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + return vmcommon.UserError + } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") return vmcommon.UserError @@ -1964,6 +2014,10 @@ func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vm s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + return vmcommon.UserError + } if args.CallValue.Cmp(zero) != 0 { s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) @@ -2035,6 +2089,10 @@ func (s *stakingSC) addMissingNodeToQueue(args *vmcommon.ContractCallInput) vmco s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + return vmcommon.UserError + } if args.CallValue.Cmp(zero) != 0 { s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) return vmcommon.UserError @@ -2114,6 +2172,9 @@ func (s *stakingSC) EpochConfirmed(epoch uint32, _ uint64) { s.flagCorrectJailedNotUnstakedEmptyQueue.SetValue(epoch >= s.correctJailedNotUnstakedEmptyQueueEpoch) log.Debug("stakingSC: correct jailed not unstaked with empty queue", "enabled", s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet()) + + s.flagStakingV4.SetValue(epoch >= s.stakingV4Epoch) + log.Debug("stakingSC: staking v4", "enabled", s.flagStakingV4.IsSet()) } // CanUseContract returns true if contract can be used From 97398b878143be33869acccafd598d4840b7ab66 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Mon, 28 Feb 2022 17:10:54 +0200 Subject: [PATCH 061/958] repair deleting delegator --- vm/systemSmartContracts/delegation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 0c861b29e1d..63d2b1cfba0 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -2935,7 +2935,7 @@ func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vm return vmcommon.UserError } - _, err = d.deleteDelegatorIfNeeded(address, delegator) + _, err = d.deleteDelegatorOnClaimRewardsIfNeeded(address, delegator) if err != nil { d.eei.AddReturnMessage(err.Error()) return vmcommon.UserError From 36c86482ba1a1cce1fbeeaf3003752e4d3a46143 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 17:42:19 +0200 Subject: [PATCH 062/958] FEAT: Add flag to systemSCs.go --- epochStart/metachain/systemSCs.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6a6f87c8197..524dd59adfb 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -242,7 +242,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } - if s.flagCorrectLastUnjailedEnabled.IsSet() { + if s.flagCorrectLastUnjailedEnabled.IsSet() && !s.flagStakingV4Enabled.IsSet() { err := s.resetLastUnJailed() if err != nil { return err @@ -256,14 +256,14 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } - if s.flagCorrectNumNodesToStake.IsSet() { - err := s.cleanAdditionalQueue() // TODO: Deactivate this? + if s.flagCorrectNumNodesToStake.IsSet() && !s.flagStakingV4Enabled.IsSet() { + err := s.cleanAdditionalQueue() if err != nil { return err } } - if s.flagSwitchJailedWaiting.IsSet() { + if s.flagSwitchJailedWaiting.IsSet() && !s.flagStakingV4Enabled.IsSet() { err := s.computeNumWaitingPerShard(validatorInfos) if err != nil { return err From 44677a946b7e4e7ea23525c33a82b9328c9e7505 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 17:54:00 +0200 Subject: [PATCH 063/958] FIX: Broken tests --- vm/systemSmartContracts/staking_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 0b887d66b9c..6f5a0716e85 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -59,6 +59,7 @@ func createMockStakingScArgumentsWithSystemScAddresses( EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: 10, StakeEnableEpoch: 0, + StakingV4EnableEpoch: 445, }, }, } From b6fe51b22ef1eec3588c16e35d3772d825c91161 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 18:17:57 +0200 Subject: [PATCH 064/958] FIX: Flag description --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 8855c38ec83..aaa5e55abd5 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -188,7 +188,7 @@ StakeLimitsEnableEpoch = 5 # StakingV4InitEnableEpoch represents the epoch when staking v4 is initialized. This is the epoch in which - # nodes queue is removed and all nodes from queue are moved to a new list + # all nodes from staking queue are moved in the auction list StakingV4InitEnableEpoch = 1000000 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch From 759ea97f3fabb32587ad0df345122e1f8cda5f85 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 28 Feb 2022 18:20:16 +0200 Subject: [PATCH 065/958] FIX: AuctionList description --- common/constants.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/constants.go b/common/constants.go index d79b6b7db36..f4b17a892a1 100644 --- a/common/constants.go +++ b/common/constants.go @@ -29,7 +29,8 @@ const ObserverList PeerType = "observer" // NewList - const NewList PeerType = "new" -// AuctionList - +// AuctionList represents the list of peers which don't participate in consensus yet, but will be selected +// based on their top up stake const AuctionList PeerType = "auction" // CombinedPeerType - represents the combination of two peerTypes From fb072e3e5d629257d37830d9e5fac6a17b074923 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 1 Mar 2022 12:15:02 +0200 Subject: [PATCH 066/958] FEAT: Add first test --- vm/systemSmartContracts/staking_test.go | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 6f5a0716e85..23c945a0604 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -978,6 +978,65 @@ func TestStakingSc_ExecuteIsStaked(t *testing.T) { checkIsStaked(t, stakingSmartContract, callerAddress, stakerPubKey, vmcommon.UserError) } +func TestStakingSc_StakeWithStakingV4(t *testing.T) { + t.Parallel() + + blockChainHook := &mock.BlockChainHookStub{ + GetStorageDataCalled: func(accountsAddress []byte, index []byte) ([]byte, error) { + return nil, nil + }, + } + eei, _ := NewVMContext(blockChainHook, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) + stakingAccessAddress := []byte("stakingAccessAddress") + args := createMockStakingScArguments() + args.StakingSCConfig.MaxNumberOfNodesForStake = 4 + args.StakingAccessAddr = stakingAccessAddress + args.Eei = eei + + stakingSmartContract, _ := NewStakingSmartContract(args) + stakingSmartContract.flagStakingV2.SetValue(true) + + for i := 0; i < 10; i++ { + idxStr := strconv.Itoa(i) + addr := []byte("addr" + idxStr) + doStake(t, stakingSmartContract, stakingAccessAddress, addr, addr) + + if uint64(i) < stakingSmartContract.maxNumNodes { + checkIsStaked(t, stakingSmartContract, []byte("caller"), addr, vmcommon.Ok) + } else { + checkIsStaked(t, stakingSmartContract, []byte("caller"), addr, vmcommon.UserError) + require.True(t, strings.Contains(eei.returnMessage, "staking is full")) + } + } + + stakeConfig := stakingSmartContract.getConfig() + waitingList, _ := stakingSmartContract.getWaitingListHead() + require.Equal(t, int64(4), stakeConfig.StakedNodes) + require.Equal(t, uint32(6), waitingList.Length) + requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(10)) + + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + + for i := 4; i < 10; i++ { + idxStr := strconv.Itoa(i) + addr := []byte("addr" + idxStr) + err := stakingSmartContract.removeFromWaitingList(addr) + require.Nil(t, err) + } + + for i := 10; i < 20; i++ { + idxStr := strconv.Itoa(i) + addr := []byte("addr" + idxStr) + doStake(t, stakingSmartContract, stakingAccessAddress, addr, addr) + checkIsStaked(t, stakingSmartContract, []byte("caller"), addr, vmcommon.Ok) + } + stakeConfig = stakingSmartContract.getConfig() + waitingList, _ = stakingSmartContract.getWaitingListHead() + require.Equal(t, int64(14), stakeConfig.StakedNodes) + require.Equal(t, uint32(0), waitingList.Length) + requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(14)) +} + func TestStakingSc_StakeWithV1ShouldWork(t *testing.T) { t.Parallel() @@ -3284,6 +3343,18 @@ func TestStakingSc_fixMissingNodeAddOneNodeOnly(t *testing.T) { assert.Equal(t, waitingListData.blsKeys[0], blsKey) } +func requireTotalNumberOfRegisteredNodes(t *testing.T, stakingSC *stakingSC, eei *vmContext, expectedRegisteredNodes *big.Int) { + arguments := CreateVmContractCallInput() + arguments.Function = "getTotalNumberOfRegisteredNodes" + arguments.Arguments = [][]byte{} + + retCode := stakingSC.Execute(arguments) + lastOutput := eei.output[len(eei.output)-1] + noOfRegisteredNodes := big.NewInt(0).SetBytes(lastOutput) + require.Equal(t, retCode, vmcommon.Ok) + require.Equal(t, expectedRegisteredNodes, noOfRegisteredNodes) +} + func TestStakingSc_fixMissingNodeAddAsLast(t *testing.T) { t.Parallel() From b6a1141185c5da3601ef6115b3573b8d0f8f470d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 1 Mar 2022 12:24:30 +0200 Subject: [PATCH 067/958] FIX: StakingV4InitEnableEpoch value --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index aaa5e55abd5..bd31cf3875f 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -189,7 +189,7 @@ # StakingV4InitEnableEpoch represents the epoch when staking v4 is initialized. This is the epoch in which # all nodes from staking queue are moved in the auction list - StakingV4InitEnableEpoch = 1000000 + StakingV4InitEnableEpoch = 4 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ From 52651462e5f21c4e6a408b9398858a448bb7abe6 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 1 Mar 2022 14:39:22 +0200 Subject: [PATCH 068/958] FIX: Review findings --- epochStart/metachain/systemSCs.go | 6 +-- vm/systemSmartContracts/staking.go | 70 +++++++++++++----------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 524dd59adfb..9c0142f13f4 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -242,7 +242,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } - if s.flagCorrectLastUnjailedEnabled.IsSet() && !s.flagStakingV4Enabled.IsSet() { + if s.flagCorrectLastUnjailedEnabled.IsSet() { err := s.resetLastUnJailed() if err != nil { return err @@ -256,7 +256,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } - if s.flagCorrectNumNodesToStake.IsSet() && !s.flagStakingV4Enabled.IsSet() { + if s.flagCorrectNumNodesToStake.IsSet() { err := s.cleanAdditionalQueue() if err != nil { return err @@ -1697,7 +1697,7 @@ func (s *systemSCProcessor) IsInterfaceNil() bool { // EpochConfirmed is called whenever a new epoch is confirmed func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { - s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch) + s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch && epoch < s.stakingV4InitEnableEpoch) log.Debug("systemSCProcessor: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index 3287262d723..5a1efa517df 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -599,15 +599,11 @@ func (s *stakingSC) unStakeAtEndOfEpoch(args *vmcommon.ContractCallInput) vmcomm s.removeFromStakedNodes() } - // This is an extra check. We should not save any registrationData - // with Waiting = true when staking v4 is enabled - if !s.flagStakingV4.IsSet() { - if registrationData.Waiting { - err = s.removeFromWaitingList(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + if registrationData.Waiting { + err = s.removeFromWaitingList(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError } } @@ -674,12 +670,14 @@ func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod return vmcommon.Ok } - addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() - if addOneFromQueue { - _, err = s.moveFirstFromWaitingToStaked() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError + if !s.flagStakingV4.IsSet() { + addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() + if addOneFromQueue { + _, err = s.moveFirstFromWaitingToStaked() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } } } @@ -1308,6 +1306,12 @@ func (s *stakingSC) isNodeJailedOrWithBadRating(registrationData *StakedDataV2_0 } func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.Finish([]byte{0}) + + return vmcommon.Ok + } if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { s.eei.AddReturnMessage("this is only a view function") return vmcommon.UserError @@ -1317,13 +1321,6 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") - s.eei.Finish([]byte(strconv.Itoa(int(0)))) - - return vmcommon.Ok - } - waitingElementKey := createWaitingListKey(args.Arguments[0]) _, err := s.getWaitingListElement(waitingElementKey) if err != nil { @@ -1379,6 +1376,13 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm } func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.Finish([]byte(strconv.Itoa(0))) + + return vmcommon.Ok + } + if args.CallValue.Cmp(zero) != 0 { s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) return vmcommon.UserError @@ -1390,13 +1394,6 @@ func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommo return vmcommon.OutOfGas } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") - s.eei.Finish([]byte(strconv.Itoa(int(0)))) - - return vmcommon.Ok - } - waitingListHead, err := s.getWaitingListHead() if err != nil { s.eei.AddReturnMessage(err.Error()) @@ -1614,19 +1611,14 @@ func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallI return vmcommon.UserError } - waitingListLength := int64(0) - if !s.flagStakingV4.IsSet() { - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - waitingListLength = int64(waitingListHead.Length) + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError } stakeConfig := s.getConfig() - totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + waitingListLength + totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + int64(waitingListHead.Length) s.eei.Finish(big.NewInt(totalRegistered).Bytes()) return vmcommon.Ok } From 69bc7c51e0340b2e8f04e7763046fa83834a210f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 1 Mar 2022 16:47:39 +0200 Subject: [PATCH 069/958] FIX: Review findings --- cmd/node/config/enableEpochs.toml | 2 +- epochStart/errors.go | 4 +- epochStart/metachain/systemSCs.go | 81 ++++++++++++++++++------------- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 30f6f75f5cb..9c442f8dc73 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -192,7 +192,7 @@ StakingV4InitEnableEpoch = 4 # StakingV4EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4InitEnableEpoch - StakingV4EnableEpoch = 1000001 + StakingV4EnableEpoch = 5 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ diff --git a/epochStart/errors.go b/epochStart/errors.go index fcda2b0c3af..4032928d016 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -335,5 +335,5 @@ var ErrNilScheduledDataSyncerFactory = errors.New("nil scheduled data syncer fac // ErrCouldNotInitLiquidStakingSystemSC signals that liquid staking system sc init failed var ErrCouldNotInitLiquidStakingSystemSC = errors.New("could not init liquid staking system sc") -// ErrSortAuctionList signals that one or more errors occurred while trying to sort auction list -var ErrSortAuctionList = errors.New("error(s) while trying to sort auction list") +// ErrSortAuctionList signals that an error occurred while trying to sort auction list +var ErrSortAuctionList = errors.New("error while trying to sort auction list") diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6a6f87c8197..8a91e0aec80 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -15,6 +15,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" vInfo "github.com/ElrondNetwork/elrond-go/common/validatorInfo" "github.com/ElrondNetwork/elrond-go/config" @@ -257,7 +258,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagCorrectNumNodesToStake.IsSet() { - err := s.cleanAdditionalQueue() // TODO: Deactivate this? + err := s.cleanAdditionalQueue() if err != nil { return err } @@ -350,59 +351,55 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( return nil } -func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfos map[uint32][]*state.ValidatorInfo, randomness []byte) error { - auctionList, noOfValidators := getAuctionListAndNoOfValidators(validatorInfos) +func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfoMap map[uint32][]*state.ValidatorInfo, randomness []byte) error { + auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorInfoMap) err := s.sortAuctionList(auctionList, randomness) if err != nil { return err } auctionListSize := uint32(len(auctionList)) - noOfAvailableNodeSlots := core.MinUint32(auctionListSize, s.maxNodes-noOfValidators) - s.displayAuctionList(auctionList, noOfAvailableNodeSlots) + numOfAvailableNodeSlots := core.MinUint32(auctionListSize, s.maxNodes-numOfValidators) + s.displayAuctionList(auctionList, numOfAvailableNodeSlots) - for i := uint32(0); i < noOfAvailableNodeSlots; i++ { + for i := uint32(0); i < numOfAvailableNodeSlots; i++ { auctionList[i].List = string(common.NewList) } return nil } -func getAuctionListAndNoOfValidators(validatorInfos map[uint32][]*state.ValidatorInfo) ([]*state.ValidatorInfo, uint32) { +func getAuctionListAndNumOfValidators(validatorInfoMap map[uint32][]*state.ValidatorInfo) ([]*state.ValidatorInfo, uint32) { auctionList := make([]*state.ValidatorInfo, 0) - noOfValidators := uint32(0) + numOfValidators := uint32(0) - for _, validatorsInShard := range validatorInfos { + for _, validatorsInShard := range validatorInfoMap { for _, validator := range validatorsInShard { if validator.List == string(common.AuctionList) { auctionList = append(auctionList, validator) - } else if isValidator(validator) { - noOfValidators++ + continue + } + if isValidator(validator) { + numOfValidators++ } } } - return auctionList, noOfValidators + return auctionList, numOfValidators } func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, randomness []byte) error { - errors := make([]error, 0) + validatorTopUpMap, err := s.getValidatorTopUpMap(auctionList) + if err != nil { + return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) + } sort.SliceStable(auctionList, func(i, j int) bool { pubKey1 := auctionList[i].PublicKey pubKey2 := auctionList[j].PublicKey - nodeTopUpPubKey1, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey1) - if err != nil { - errors = append(errors, err) - log.Debug(fmt.Sprintf("%v when trying to get top up per node for %s", err, hex.EncodeToString(pubKey1))) - } - - nodeTopUpPubKey2, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey2) - if err != nil { - errors = append(errors, err) - log.Debug(fmt.Sprintf("%v when trying to get top up per node for %s", err, hex.EncodeToString(pubKey2))) - } + nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] + nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { return compareByXORWithRandomness(pubKey1, pubKey2, randomness) @@ -411,17 +408,32 @@ func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 }) - if len(errors) > 0 { - return fmt.Errorf("%w; last known error %v", epochStart.ErrSortAuctionList, errors[len(errors)-1]) - } return nil } +func (s *systemSCProcessor) getValidatorTopUpMap(validators []*state.ValidatorInfo) (map[string]*big.Int, error) { + ret := make(map[string]*big.Int, len(validators)) + + for _, validator := range validators { + pubKey := validator.PublicKey + topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) + if err != nil { + return nil, fmt.Errorf("%w when trying to get top up per node for %s", err, hex.EncodeToString(pubKey)) + } + + ret[string(pubKey)] = topUp + } + + return ret, nil +} + func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { - key1Xor := make([]byte, len(randomness)) - key2Xor := make([]byte, len(randomness)) + minLen := core.MinInt(len(pubKey1), len(randomness)) + + key1Xor := make([]byte, minLen) + key2Xor := make([]byte, minLen) - for idx := range randomness { + for idx := 0; idx < minLen; idx++ { key1Xor[idx] = pubKey1[idx] ^ randomness[idx] key2Xor[idx] = pubKey2[idx] ^ randomness[idx] } @@ -429,7 +441,11 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { return bytes.Compare(key1Xor, key2Xor) == 1 } -func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInfo, noOfSelectedNodes uint32) { +func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInfo, numOfSelectedNodes uint32) { + if log.GetLevel() > logger.LogDebug { + return + } + tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) horizontalLine := false @@ -442,7 +458,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) log.LogIfError(err) - horizontalLine = uint32(idx) == noOfSelectedNodes-1 + horizontalLine = uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ hex.EncodeToString([]byte(owner)), hex.EncodeToString(pubKey), @@ -859,7 +875,6 @@ func (s *systemSCProcessor) updateMaxNodes(validatorInfos map[uint32][]*state.Va return epochStart.ErrInvalidMaxNumberOfNodes } - // TODO: Check if flag is not enabled, should we move staked nodes to AuctionList? if s.flagStakingQueueEnabled.IsSet() { sw.Start("stakeNodesFromQueue") err = s.stakeNodesFromQueue(validatorInfos, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) From 30d48cadb3ae586152b6c7304aa1b9d6fed1ab68 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 2 Mar 2022 11:48:41 +0200 Subject: [PATCH 070/958] FIX: Staking v4 test --- vm/systemSmartContracts/staking_test.go | 69 +++++++++---------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 23c945a0604..8bf63f3d32d 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -981,12 +981,7 @@ func TestStakingSc_ExecuteIsStaked(t *testing.T) { func TestStakingSc_StakeWithStakingV4(t *testing.T) { t.Parallel() - blockChainHook := &mock.BlockChainHookStub{ - GetStorageDataCalled: func(accountsAddress []byte, index []byte) ([]byte, error) { - return nil, nil - }, - } - eei, _ := NewVMContext(blockChainHook, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) + eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) stakingAccessAddress := []byte("stakingAccessAddress") args := createMockStakingScArguments() args.StakingSCConfig.MaxNumberOfNodesForStake = 4 @@ -1002,22 +997,19 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { doStake(t, stakingSmartContract, stakingAccessAddress, addr, addr) if uint64(i) < stakingSmartContract.maxNumNodes { - checkIsStaked(t, stakingSmartContract, []byte("caller"), addr, vmcommon.Ok) + checkIsStaked(t, stakingSmartContract, addr, addr, vmcommon.Ok) } else { - checkIsStaked(t, stakingSmartContract, []byte("caller"), addr, vmcommon.UserError) + checkIsStaked(t, stakingSmartContract, addr, addr, vmcommon.UserError) require.True(t, strings.Contains(eei.returnMessage, "staking is full")) } } + requireRegisteredNodes(t, stakingSmartContract, eei, 4, 6) - stakeConfig := stakingSmartContract.getConfig() - waitingList, _ := stakingSmartContract.getWaitingListHead() - require.Equal(t, int64(4), stakeConfig.StakedNodes) - require.Equal(t, uint32(6), waitingList.Length) - requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(10)) + doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("addr0"), []byte("addr0"), vmcommon.Ok) + requireRegisteredNodes(t, stakingSmartContract, eei, 4, 5) stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - - for i := 4; i < 10; i++ { + for i := 5; i < 10; i++ { idxStr := strconv.Itoa(i) addr := []byte("addr" + idxStr) err := stakingSmartContract.removeFromWaitingList(addr) @@ -1028,13 +1020,12 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { idxStr := strconv.Itoa(i) addr := []byte("addr" + idxStr) doStake(t, stakingSmartContract, stakingAccessAddress, addr, addr) - checkIsStaked(t, stakingSmartContract, []byte("caller"), addr, vmcommon.Ok) + checkIsStaked(t, stakingSmartContract, addr, addr, vmcommon.Ok) } - stakeConfig = stakingSmartContract.getConfig() - waitingList, _ = stakingSmartContract.getWaitingListHead() - require.Equal(t, int64(14), stakeConfig.StakedNodes) - require.Equal(t, uint32(0), waitingList.Length) - requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(14)) + requireRegisteredNodes(t, stakingSmartContract, eei, 14, 0) + + doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("addr10"), []byte("addr10"), vmcommon.Ok) + requireRegisteredNodes(t, stakingSmartContract, eei, 13, 0) } func TestStakingSc_StakeWithV1ShouldWork(t *testing.T) { @@ -1196,14 +1187,7 @@ func TestStakingSc_ExecuteStakeStakeJailAndSwitch(t *testing.T) { _ = json.Unmarshal(marshaledData, stakedData) assert.True(t, stakedData.Jailed) assert.True(t, stakedData.Staked) - - arguments.Function = "getTotalNumberOfRegisteredNodes" - arguments.Arguments = [][]byte{} - retCode = stakingSmartContract.Execute(arguments) - assert.Equal(t, retCode, vmcommon.Ok) - - lastOutput := eei.output[len(eei.output)-1] - assert.Equal(t, lastOutput, []byte{2}) + requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(2)) } func TestStakingSc_ExecuteStakeStakeJailAndSwitchWithBoundaries(t *testing.T) { @@ -1335,14 +1319,7 @@ func TestStakingSc_ExecuteStakeStakeJailAndSwitchWithBoundaries(t *testing.T) { _ = json.Unmarshal(marshaledData, stakedData) assert.Equal(t, tt.shouldBeJailed, stakedData.Jailed) assert.Equal(t, tt.shouldBeStaked, stakedData.Staked) - - arguments.Function = "getTotalNumberOfRegisteredNodes" - arguments.Arguments = [][]byte{} - retCode = stakingSmartContract.Execute(arguments) - assert.Equal(t, vmcommon.Ok, retCode) - - lastOutput := eei.output[len(eei.output)-1] - assert.Equal(t, []byte{byte(tt.remainingStakedNodesNumber)}, lastOutput) + requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(int64(tt.remainingStakedNodesNumber))) }) } } @@ -1503,14 +1480,7 @@ func TestStakingSc_ExecuteStakeStakeStakeJailJailUnJailTwice(t *testing.T) { doGetWaitingListSize(t, stakingSmartContract, eei, 2) outPut = doGetWaitingListRegisterNonceAndRewardAddress(t, stakingSmartContract, eei) assert.Equal(t, 6, len(outPut)) - - arguments.Function = "getTotalNumberOfRegisteredNodes" - arguments.Arguments = [][]byte{} - retCode = stakingSmartContract.Execute(arguments) - assert.Equal(t, retCode, vmcommon.Ok) - - lastOutput := eei.output[len(eei.output)-1] - assert.Equal(t, lastOutput, []byte{4}) + requireTotalNumberOfRegisteredNodes(t, stakingSmartContract, eei, big.NewInt(4)) } func TestStakingSc_ExecuteStakeUnStakeJailCombinations(t *testing.T) { @@ -3343,6 +3313,15 @@ func TestStakingSc_fixMissingNodeAddOneNodeOnly(t *testing.T) { assert.Equal(t, waitingListData.blsKeys[0], blsKey) } +func requireRegisteredNodes(t *testing.T, stakingSC *stakingSC, eei *vmContext, stakedNodes int64, waitingListNodes uint32) { + stakeConfig := stakingSC.getConfig() + waitingList, _ := stakingSC.getWaitingListHead() + require.Equal(t, stakedNodes, stakeConfig.StakedNodes) + require.Equal(t, waitingListNodes, waitingList.Length) + + requireTotalNumberOfRegisteredNodes(t, stakingSC, eei, big.NewInt(stakedNodes+int64(waitingListNodes))) +} + func requireTotalNumberOfRegisteredNodes(t *testing.T, stakingSC *stakingSC, eei *vmContext, expectedRegisteredNodes *big.Int) { arguments := CreateVmContractCallInput() arguments.Function = "getTotalNumberOfRegisteredNodes" From f6b3a6e87239bd777be82cc1a17ab912ff13c8d2 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 2 Mar 2022 14:08:48 +0200 Subject: [PATCH 071/958] FEAT: Add flagStakingV4 tests in staking.go --- epochStart/metachain/systemSCs.go | 2 +- vm/errors.go | 3 + vm/systemSmartContracts/staking.go | 18 +++--- vm/systemSmartContracts/staking_test.go | 75 ++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index abfbd0b75a0..0ed8779c2cf 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -264,7 +264,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } - if s.flagSwitchJailedWaiting.IsSet() && !s.flagStakingV4Enabled.IsSet() { + if s.flagSwitchJailedWaiting.IsSet() { err := s.computeNumWaitingPerShard(validatorInfos) if err != nil { return err diff --git a/vm/errors.go b/vm/errors.go index ae6a88db0af..6a4bdfbdb3f 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -265,3 +265,6 @@ var ErrInvalidNodeLimitPercentage = errors.New("invalid node limit percentage") // ErrNilNodesCoordinator signals that nil nodes coordinator was provided var ErrNilNodesCoordinator = errors.New("nil nodes coordinator") + +// ErrWaitingListDisabled signals that waiting list has been disabled, since staking v4 is active +var ErrWaitingListDisabled = errors.New("waiting list is disabled since staking v4 activation") diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index 5a1efa517df..e4447e52c1e 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -1161,7 +1161,7 @@ func createWaitingListKey(blsKey []byte) []byte { func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { @@ -1307,7 +1307,7 @@ func (s *stakingSC) isNodeJailedOrWithBadRating(registrationData *StakedDataV2_0 func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) s.eei.Finish([]byte{0}) return vmcommon.Ok @@ -1377,8 +1377,8 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") - s.eei.Finish([]byte(strconv.Itoa(0))) + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + s.eei.Finish([]byte{0}) return vmcommon.Ok } @@ -1629,7 +1629,7 @@ func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) return vmcommon.UserError } if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { @@ -1717,7 +1717,7 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm return vmcommon.UserError } if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("invalid method to call") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { @@ -1793,7 +1793,7 @@ func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcom return vmcommon.UserError } if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { @@ -2007,7 +2007,7 @@ func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vm return vmcommon.UserError } if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -2082,7 +2082,7 @@ func (s *stakingSC) addMissingNodeToQueue(args *vmcommon.ContractCallInput) vmco return vmcommon.UserError } if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage("staking v4 enabled; waiting list is disabled") + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } if args.CallValue.Cmp(zero) != 0 { diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 8bf63f3d32d..212d9f8f156 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -981,11 +981,11 @@ func TestStakingSc_ExecuteIsStaked(t *testing.T) { func TestStakingSc_StakeWithStakingV4(t *testing.T) { t.Parallel() - eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) - stakingAccessAddress := []byte("stakingAccessAddress") args := createMockStakingScArguments() - args.StakingSCConfig.MaxNumberOfNodesForStake = 4 + stakingAccessAddress := []byte("stakingAccessAddress") args.StakingAccessAddr = stakingAccessAddress + args.StakingSCConfig.MaxNumberOfNodesForStake = 4 + eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) args.Eei = eei stakingSmartContract, _ := NewStakingSmartContract(args) @@ -1001,6 +1001,7 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { } else { checkIsStaked(t, stakingSmartContract, addr, addr, vmcommon.UserError) require.True(t, strings.Contains(eei.returnMessage, "staking is full")) + eei.returnMessage = "" } } requireRegisteredNodes(t, stakingSmartContract, eei, 4, 6) @@ -3313,6 +3314,74 @@ func TestStakingSc_fixMissingNodeAddOneNodeOnly(t *testing.T) { assert.Equal(t, waitingListData.blsKeys[0], blsKey) } +func TestStakingSC_StakingV4Flags(t *testing.T) { + t.Parallel() + + args := createMockStakingScArguments() + eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) + args.Eei = eei + + stakingSmartContract, _ := NewStakingSmartContract(args) + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + + arguments := CreateVmContractCallInput() + arguments.Arguments = [][]byte{} + arguments.Function = "getQueueIndex" + retCode := stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.Ok, retCode) + require.Equal(t, []byte{0}, eei.output[0]) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "getQueueSize" + retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.Ok, retCode) + require.Equal(t, []byte{0}, eei.output[0]) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "switchJailedWithWaiting" + retCode = stakingSmartContract.Execute(arguments) + require.Empty(t, eei.output) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "resetLastUnJailedFromQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Empty(t, eei.output) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "stakeNodesFromQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Empty(t, eei.output) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "cleanAdditionalQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Empty(t, eei.output) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "fixWaitingListQueueSize" + retCode = stakingSmartContract.Execute(arguments) + require.Empty(t, eei.output) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "addMissingNodeToQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Empty(t, eei.output) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) +} + func requireRegisteredNodes(t *testing.T, stakingSC *stakingSC, eei *vmContext, stakedNodes int64, waitingListNodes uint32) { stakeConfig := stakingSC.getConfig() waitingList, _ := stakingSC.getWaitingListHead() From c1c111fd3f92d0c591ae90d7bed5a40e980754af Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 2 Mar 2022 14:58:52 +0200 Subject: [PATCH 072/958] FEAT: Move all waiting list code from staking.go --- vm/systemSmartContracts/staking.go | 1470 ++--------------- vm/systemSmartContracts/stakingWaitingList.go | 1169 +++++++++++++ 2 files changed, 1327 insertions(+), 1312 deletions(-) create mode 100644 vm/systemSmartContracts/stakingWaitingList.go diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index e4447e52c1e..c1974344707 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -25,8 +25,6 @@ var log = logger.GetOrCreate("vm/systemsmartcontracts") const ownerKey = "owner" const nodesConfigKey = "nodesConfig" -const waitingListHeadKey = "waitingList" -const waitingElementPrefix = "w_" type stakingSC struct { eei vm.SystemEI @@ -75,13 +73,6 @@ type ArgsNewStakingSmartContract struct { EpochConfig config.EpochConfig } -type waitingListReturnData struct { - blsKeys [][]byte - stakedDataList []*StakedDataV2_0 - lastKey []byte - afterLastjailed bool -} - // NewStakingSmartContract creates a staking smart contract func NewStakingSmartContract( args ArgsNewStakingSmartContract, @@ -526,37 +517,6 @@ func (s *stakingSC) stake(args *vmcommon.ContractCallInput, onlyRegister bool) v return vmcommon.Ok } -func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { - if registrationData.Staked { - return nil - } - - registrationData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() - if !s.canStake() { - s.eei.AddReturnMessage(fmt.Sprintf("staking is full key put into waiting list %s", hex.EncodeToString(blsKey))) - err := s.addToWaitingList(blsKey, addFirst) - if err != nil { - s.eei.AddReturnMessage("error while adding to waiting") - return err - } - registrationData.Waiting = true - s.eei.Finish([]byte{waiting}) - return nil - } - - if !s.flagStakingV4.IsSet() { - err := s.removeFromWaitingList(blsKey) - if err != nil { - s.eei.AddReturnMessage("error while removing from waiting") - return err - } - } - s.addToStakedNodes(1) - s.activeStakingFor(registrationData) - - return nil -} - func (s *stakingSC) activeStakingFor(stakingData *StakedDataV2_0) { stakingData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() stakingData.Staked = true @@ -566,188 +526,6 @@ func (s *stakingSC) activeStakingFor(stakingData *StakedDataV2_0) { stakingData.Waiting = false } -func (s *stakingSC) unStakeAtEndOfEpoch(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - // backward compatibility - no need for return message - return vmcommon.UserError - } - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("not enough arguments, needed the BLS key") - return vmcommon.UserError - } - - registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) - return vmcommon.UserError - } - if len(registrationData.RewardAddress) == 0 { - s.eei.AddReturnMessage("cannot unStake a key that is not registered") - return vmcommon.UserError - } - if registrationData.Jailed && !registrationData.Staked { - s.eei.AddReturnMessage("already unStaked at switchJailedToWaiting") - return vmcommon.Ok - } - - if !registrationData.Staked && !registrationData.Waiting { - log.Debug("stakingSC.unStakeAtEndOfEpoch: cannot unStake node which was already unStaked", "blsKey", hex.EncodeToString(args.Arguments[0])) - return vmcommon.Ok - } - - if registrationData.Staked { - s.removeFromStakedNodes() - } - - if registrationData.Waiting { - err = s.removeFromWaitingList(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - } - - registrationData.Staked = false - registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() - registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() - registrationData.Waiting = false - - err = s.saveStakingData(args.Arguments[0], registrationData) - if err != nil { - s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { - s.eei.AddReturnMessage("unStake function not allowed to be called by address " + string(args.CallerAddr)) - return vmcommon.UserError - } - if len(args.Arguments) < 2 { - s.eei.AddReturnMessage("not enough arguments, needed BLS key and reward address") - return vmcommon.UserError - } - - registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) - return vmcommon.UserError - } - if len(registrationData.RewardAddress) == 0 { - s.eei.AddReturnMessage("cannot unStake a key that is not registered") - return vmcommon.UserError - } - if !bytes.Equal(args.Arguments[1], registrationData.RewardAddress) { - s.eei.AddReturnMessage("unStake possible only from staker caller") - return vmcommon.UserError - } - if s.isNodeJailedOrWithBadRating(registrationData, args.Arguments[0]) { - s.eei.AddReturnMessage("cannot unStake node which is jailed or with bad rating") - return vmcommon.UserError - } - - if !registrationData.Staked && !registrationData.Waiting { - s.eei.AddReturnMessage("cannot unStake node which was already unStaked") - return vmcommon.UserError - } - - if !registrationData.Staked { - registrationData.Waiting = false - err = s.removeFromWaitingList(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - err = s.saveStakingData(args.Arguments[0], registrationData) - if err != nil { - s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok - } - - if !s.flagStakingV4.IsSet() { - addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() - if addOneFromQueue { - _, err = s.moveFirstFromWaitingToStaked() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - } - } - - if !s.canUnStake() { - s.eei.AddReturnMessage("unStake is not possible as too many left") - return vmcommon.UserError - } - - s.removeFromStakedNodes() - registrationData.Staked = false - registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() - registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() - registrationData.Waiting = false - - err = s.saveStakingData(args.Arguments[0], registrationData) - if err != nil { - s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (s *stakingSC) moveFirstFromWaitingToStakedIfNeeded(blsKey []byte) (bool, error) { - waitingElementKey := createWaitingListKey(blsKey) - _, err := s.getWaitingListElement(waitingElementKey) - if err == nil { - // node in waiting - remove from it - and that's it - return false, s.removeFromWaitingList(blsKey) - } - - return s.moveFirstFromWaitingToStaked() -} - -func (s *stakingSC) moveFirstFromWaitingToStaked() (bool, error) { - waitingList, err := s.getWaitingListHead() - if err != nil { - return false, err - } - if waitingList.Length == 0 { - return false, nil - } - elementInList, err := s.getWaitingListElement(waitingList.FirstKey) - if err != nil { - return false, err - } - err = s.removeFromWaitingList(elementInList.BLSPublicKey) - if err != nil { - return false, err - } - - nodeData, err := s.getOrCreateRegisteredData(elementInList.BLSPublicKey) - if err != nil { - return false, err - } - if len(nodeData.RewardAddress) == 0 || nodeData.Staked { - return false, vm.ErrInvalidWaitingList - } - - nodeData.Waiting = false - nodeData.Staked = true - nodeData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() - nodeData.StakedNonce = s.eei.BlockChainHook().CurrentNonce() - nodeData.UnStakedNonce = 0 - nodeData.UnStakedEpoch = common.DefaultUnstakedEpoch - - s.addToStakedNodes(1) - return true, s.saveStakingData(elementInList.BLSPublicKey, nodeData) -} - func (s *stakingSC) unBond(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { s.eei.AddReturnMessage("unBond function not allowed to be called by address " + string(args.CallerAddr)) @@ -837,998 +615,261 @@ func (s *stakingSC) isStaked(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return vmcommon.UserError } -func (s *stakingSC) addToWaitingList(blsKey []byte, addJailed bool) error { - inWaitingListKey := createWaitingListKey(blsKey) - marshaledData := s.eei.GetStorage(inWaitingListKey) - if len(marshaledData) != 0 { - return nil - } - - waitingList, err := s.getWaitingListHead() - if err != nil { - return err +func (s *stakingSC) tryRemoveJailedNodeFromStaked(registrationData *StakedDataV2_0) { + if !s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet() { + s.removeAndSetUnstaked(registrationData) + return } - waitingList.Length += 1 - if waitingList.Length == 1 { - return s.startWaitingList(waitingList, addJailed, blsKey) + if s.canUnStake() { + s.removeAndSetUnstaked(registrationData) + return } - if addJailed { - return s.insertAfterLastJailed(waitingList, blsKey) - } + s.eei.AddReturnMessage("did not switch as not enough validators remaining") +} - return s.addToEndOfTheList(waitingList, blsKey) +func (s *stakingSC) removeAndSetUnstaked(registrationData *StakedDataV2_0) { + s.removeFromStakedNodes() + registrationData.Staked = false + registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() + registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() + registrationData.StakedNonce = math.MaxUint64 } -func (s *stakingSC) startWaitingList( - waitingList *WaitingList, - addJailed bool, - blsKey []byte, -) error { - inWaitingListKey := createWaitingListKey(blsKey) - waitingList.FirstKey = inWaitingListKey - waitingList.LastKey = inWaitingListKey - if addJailed { - waitingList.LastJailedKey = inWaitingListKey +func (s *stakingSC) updateConfigMinNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + s.eei.AddReturnMessage("updateConfigMinNodes function not allowed to be called by address " + string(args.CallerAddr)) + return vmcommon.UserError } - elementInWaiting := &ElementInList{ - BLSPublicKey: blsKey, - PreviousKey: waitingList.LastKey, - NextKey: make([]byte, 0), + stakeConfig := s.getConfig() + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("number of arguments must be 1") + return vmcommon.UserError } - return s.saveElementAndList(inWaitingListKey, elementInWaiting, waitingList) -} -func (s *stakingSC) addToEndOfTheList(waitingList *WaitingList, blsKey []byte) error { - inWaitingListKey := createWaitingListKey(blsKey) - oldLastKey := make([]byte, len(waitingList.LastKey)) - copy(oldLastKey, waitingList.LastKey) - - lastElement, err := s.getWaitingListElement(waitingList.LastKey) - if err != nil { - return err - } - lastElement.NextKey = inWaitingListKey - elementInWaiting := &ElementInList{ - BLSPublicKey: blsKey, - PreviousKey: oldLastKey, - NextKey: make([]byte, 0), + newMinNodes := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() + if newMinNodes <= 0 { + s.eei.AddReturnMessage("new minimum number of nodes zero or negative") + return vmcommon.UserError } - err = s.saveWaitingListElement(oldLastKey, lastElement) - if err != nil { - return err + if newMinNodes > int64(s.maxNumNodes) { + s.eei.AddReturnMessage("new minimum number of nodes greater than maximum number of nodes") + return vmcommon.UserError } - waitingList.LastKey = inWaitingListKey - return s.saveElementAndList(inWaitingListKey, elementInWaiting, waitingList) -} - -func (s *stakingSC) insertAfterLastJailed( - waitingList *WaitingList, - blsKey []byte, -) error { - inWaitingListKey := createWaitingListKey(blsKey) - if len(waitingList.LastJailedKey) == 0 { - previousFirstKey := make([]byte, len(waitingList.FirstKey)) - copy(previousFirstKey, waitingList.FirstKey) - waitingList.FirstKey = inWaitingListKey - waitingList.LastJailedKey = inWaitingListKey - elementInWaiting := &ElementInList{ - BLSPublicKey: blsKey, - PreviousKey: inWaitingListKey, - NextKey: previousFirstKey, - } + stakeConfig.MinNumNodes = newMinNodes + s.setConfig(stakeConfig) - if s.flagCorrectFirstQueued.IsSet() && len(previousFirstKey) > 0 { - previousFirstElement, err := s.getWaitingListElement(previousFirstKey) - if err != nil { - return err - } - previousFirstElement.PreviousKey = inWaitingListKey - err = s.saveWaitingListElement(previousFirstKey, previousFirstElement) - if err != nil { - return err - } - } + return vmcommon.Ok +} - return s.saveElementAndList(inWaitingListKey, elementInWaiting, waitingList) +func (s *stakingSC) updateConfigMaxNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagStakingV2.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError } - - lastJailedElement, err := s.getWaitingListElement(waitingList.LastJailedKey) - if err != nil { - return err + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + s.eei.AddReturnMessage("updateConfigMaxNodes function not allowed to be called by address " + string(args.CallerAddr)) + return vmcommon.UserError } - if bytes.Equal(waitingList.LastKey, waitingList.LastJailedKey) { - waitingList.LastJailedKey = inWaitingListKey - return s.addToEndOfTheList(waitingList, blsKey) + stakeConfig := s.getConfig() + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("number of arguments must be 1") + return vmcommon.UserError } - firstNonJailedElement, err := s.getWaitingListElement(lastJailedElement.NextKey) - if err != nil { - return err + newMaxNodes := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() + if newMaxNodes <= 0 { + s.eei.AddReturnMessage("new max number of nodes zero or negative") + return vmcommon.UserError } - elementInWaiting := &ElementInList{ - BLSPublicKey: blsKey, - PreviousKey: make([]byte, len(inWaitingListKey)), - NextKey: make([]byte, len(inWaitingListKey)), + if newMaxNodes < int64(s.minNumNodes) { + s.eei.AddReturnMessage("new max number of nodes less than min number of nodes") + return vmcommon.UserError } - copy(elementInWaiting.PreviousKey, waitingList.LastJailedKey) - copy(elementInWaiting.NextKey, lastJailedElement.NextKey) - lastJailedElement.NextKey = inWaitingListKey - firstNonJailedElement.PreviousKey = inWaitingListKey - waitingList.LastJailedKey = inWaitingListKey + prevMaxNumNodes := big.NewInt(stakeConfig.MaxNumNodes) + s.eei.Finish(prevMaxNumNodes.Bytes()) + stakeConfig.MaxNumNodes = newMaxNodes + s.setConfig(stakeConfig) - err = s.saveWaitingListElement(elementInWaiting.PreviousKey, lastJailedElement) - if err != nil { - return err - } - err = s.saveWaitingListElement(elementInWaiting.NextKey, firstNonJailedElement) - if err != nil { - return err - } - err = s.saveWaitingListElement(inWaitingListKey, elementInWaiting) - if err != nil { - return err - } - return s.saveWaitingListHead(waitingList) + return vmcommon.Ok } -func (s *stakingSC) saveElementAndList(key []byte, element *ElementInList, waitingList *WaitingList) error { - err := s.saveWaitingListElement(key, element) - if err != nil { - return err - } - - return s.saveWaitingListHead(waitingList) +func (s *stakingSC) isNodeJailedOrWithBadRating(registrationData *StakedDataV2_0, blsKey []byte) bool { + return registrationData.Jailed || s.eei.CanUnJail(blsKey) || s.eei.IsBadRating(blsKey) } -func (s *stakingSC) removeFromWaitingList(blsKey []byte) error { - inWaitingListKey := createWaitingListKey(blsKey) - marshaledData := s.eei.GetStorage(inWaitingListKey) - if len(marshaledData) == 0 { - return nil +func (s *stakingSC) getRewardAddress(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError } - s.eei.SetStorage(inWaitingListKey, nil) - elementToRemove := &ElementInList{} - err := s.marshalizer.Unmarshal(elementToRemove, marshaledData) - if err != nil { - return err + stakedData, returnCode := s.getStakedDataIfExists(args) + if returnCode != vmcommon.Ok { + return returnCode } - waitingList, err := s.getWaitingListHead() + s.eei.Finish([]byte(hex.EncodeToString(stakedData.RewardAddress))) + return vmcommon.Ok +} + +func (s *stakingSC) getStakedDataIfExists(args *vmcommon.ContractCallInput) (*StakedDataV2_0, vmcommon.ReturnCode) { + err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.Get) if err != nil { - return err + s.eei.AddReturnMessage("insufficient gas") + return nil, vmcommon.OutOfGas + } + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("number of arguments must be equal to 1") + return nil, vmcommon.UserError } - if waitingList.Length == 0 { - return vm.ErrInvalidWaitingList + stakedData, err := s.getOrCreateRegisteredData(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return nil, vmcommon.UserError } - waitingList.Length -= 1 - if waitingList.Length == 0 { - s.eei.SetStorage([]byte(waitingListHeadKey), nil) - return nil + if len(stakedData.RewardAddress) == 0 { + s.eei.AddReturnMessage("blsKey not registered in staking sc") + return nil, vmcommon.UserError } - // remove the first element - isFirstElementBeforeFix := !s.flagCorrectFirstQueued.IsSet() && bytes.Equal(elementToRemove.PreviousKey, inWaitingListKey) - isFirstElementAfterFix := s.flagCorrectFirstQueued.IsSet() && bytes.Equal(waitingList.FirstKey, inWaitingListKey) - if isFirstElementBeforeFix || isFirstElementAfterFix { - if bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { - waitingList.LastJailedKey = make([]byte, 0) - } - - nextElement, errGet := s.getWaitingListElement(elementToRemove.NextKey) - if errGet != nil { - return errGet - } + return stakedData, vmcommon.Ok +} - nextElement.PreviousKey = elementToRemove.NextKey - waitingList.FirstKey = elementToRemove.NextKey - return s.saveElementAndList(elementToRemove.NextKey, nextElement, waitingList) +func (s *stakingSC) getBLSKeyStatus(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError } - if !s.flagCorrectLastUnjailed.IsSet() || bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { - waitingList.LastJailedKey = make([]byte, len(elementToRemove.PreviousKey)) - copy(waitingList.LastJailedKey, elementToRemove.PreviousKey) - } - - previousElement, _ := s.getWaitingListElement(elementToRemove.PreviousKey) - // search the other way around for the element in front - if s.flagCorrectFirstQueued.IsSet() && previousElement == nil { - previousElement, err = s.searchPreviousFromHead(waitingList, inWaitingListKey, elementToRemove) - if err != nil { - return err - } - } - if previousElement == nil { - previousElement, err = s.getWaitingListElement(elementToRemove.PreviousKey) - if err != nil { - return err - } - } - if len(elementToRemove.NextKey) == 0 { - waitingList.LastKey = elementToRemove.PreviousKey - previousElement.NextKey = make([]byte, 0) - return s.saveElementAndList(elementToRemove.PreviousKey, previousElement, waitingList) - } - - nextElement, err := s.getWaitingListElement(elementToRemove.NextKey) - if err != nil { - return err - } - - nextElement.PreviousKey = elementToRemove.PreviousKey - previousElement.NextKey = elementToRemove.NextKey - - err = s.saveWaitingListElement(elementToRemove.NextKey, nextElement) - if err != nil { - return err - } - return s.saveElementAndList(elementToRemove.PreviousKey, previousElement, waitingList) -} - -func (s *stakingSC) searchPreviousFromHead(waitingList *WaitingList, inWaitingListKey []byte, elementToRemove *ElementInList) (*ElementInList, error) { - var previousElement *ElementInList - index := uint32(1) - nextKey := make([]byte, len(waitingList.FirstKey)) - copy(nextKey, waitingList.FirstKey) - for len(nextKey) != 0 && index <= waitingList.Length { - element, errGet := s.getWaitingListElement(nextKey) - if errGet != nil { - return nil, errGet - } - - if bytes.Equal(inWaitingListKey, element.NextKey) { - previousElement = element - elementToRemove.PreviousKey = createWaitingListKey(previousElement.BLSPublicKey) - return previousElement, nil - } - - nextKey = make([]byte, len(element.NextKey)) - if len(element.NextKey) == 0 { - break - } - index++ - copy(nextKey, element.NextKey) - } - return nil, vm.ErrElementNotFound -} - -func (s *stakingSC) getWaitingListElement(key []byte) (*ElementInList, error) { - marshaledData := s.eei.GetStorage(key) - if len(marshaledData) == 0 { - return nil, vm.ErrElementNotFound - } - - element := &ElementInList{} - err := s.marshalizer.Unmarshal(element, marshaledData) - if err != nil { - return nil, err - } - - return element, nil -} - -func (s *stakingSC) saveWaitingListElement(key []byte, element *ElementInList) error { - marshaledData, err := s.marshalizer.Marshal(element) - if err != nil { - return err - } - - s.eei.SetStorage(key, marshaledData) - return nil -} - -func (s *stakingSC) getWaitingListHead() (*WaitingList, error) { - waitingList := &WaitingList{ - FirstKey: make([]byte, 0), - LastKey: make([]byte, 0), - Length: 0, - LastJailedKey: make([]byte, 0), - } - marshaledData := s.eei.GetStorage([]byte(waitingListHeadKey)) - if len(marshaledData) == 0 { - return waitingList, nil - } - - err := s.marshalizer.Unmarshal(waitingList, marshaledData) - if err != nil { - return nil, err - } - - return waitingList, nil -} - -func (s *stakingSC) saveWaitingListHead(waitingList *WaitingList) error { - marshaledData, err := s.marshalizer.Marshal(waitingList) - if err != nil { - return err - } - - s.eei.SetStorage([]byte(waitingListHeadKey), marshaledData) - return nil -} - -func createWaitingListKey(blsKey []byte) []byte { - return []byte(waitingElementPrefix + string(blsKey)) -} - -func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("switchJailedWithWaiting function not allowed to be called by address " + string(args.CallerAddr)) - return vmcommon.UserError - } - if len(args.Arguments) != 1 { - return vmcommon.UserError - } - - blsKey := args.Arguments[0] - registrationData, err := s.getOrCreateRegisteredData(blsKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - if len(registrationData.RewardAddress) == 0 { - s.eei.AddReturnMessage("no need to jail as not a validator") - return vmcommon.UserError - } - if !registrationData.Staked { - s.eei.AddReturnMessage("no need to jail as not a validator") - return vmcommon.UserError - } - if registrationData.Jailed { - s.eei.AddReturnMessage(vm.ErrBLSPublicKeyAlreadyJailed.Error()) - return vmcommon.UserError - } - switched, err := s.moveFirstFromWaitingToStakedIfNeeded(blsKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - registrationData.NumJailed++ - registrationData.Jailed = true - registrationData.JailedNonce = s.eei.BlockChainHook().CurrentNonce() - - if !switched && !s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet() { - s.eei.AddReturnMessage("did not switch as nobody in waiting, but jailed") - } else { - s.tryRemoveJailedNodeFromStaked(registrationData) - } - - err = s.saveStakingData(blsKey, registrationData) - if err != nil { - s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (s *stakingSC) tryRemoveJailedNodeFromStaked(registrationData *StakedDataV2_0) { - if !s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet() { - s.removeAndSetUnstaked(registrationData) - return - } - - if s.canUnStake() { - s.removeAndSetUnstaked(registrationData) - return - } - - s.eei.AddReturnMessage("did not switch as not enough validators remaining") -} - -func (s *stakingSC) removeAndSetUnstaked(registrationData *StakedDataV2_0) { - s.removeFromStakedNodes() - registrationData.Staked = false - registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() - registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() - registrationData.StakedNonce = math.MaxUint64 -} - -func (s *stakingSC) updateConfigMinNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("updateConfigMinNodes function not allowed to be called by address " + string(args.CallerAddr)) - return vmcommon.UserError - } - - stakeConfig := s.getConfig() - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("number of arguments must be 1") - return vmcommon.UserError - } - - newMinNodes := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() - if newMinNodes <= 0 { - s.eei.AddReturnMessage("new minimum number of nodes zero or negative") - return vmcommon.UserError - } - - if newMinNodes > int64(s.maxNumNodes) { - s.eei.AddReturnMessage("new minimum number of nodes greater than maximum number of nodes") - return vmcommon.UserError - } - - stakeConfig.MinNumNodes = newMinNodes - s.setConfig(stakeConfig) - - return vmcommon.Ok -} - -func (s *stakingSC) updateConfigMaxNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("updateConfigMaxNodes function not allowed to be called by address " + string(args.CallerAddr)) - return vmcommon.UserError - } - - stakeConfig := s.getConfig() - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("number of arguments must be 1") - return vmcommon.UserError - } - - newMaxNodes := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() - if newMaxNodes <= 0 { - s.eei.AddReturnMessage("new max number of nodes zero or negative") - return vmcommon.UserError - } - - if newMaxNodes < int64(s.minNumNodes) { - s.eei.AddReturnMessage("new max number of nodes less than min number of nodes") - return vmcommon.UserError - } - - prevMaxNumNodes := big.NewInt(stakeConfig.MaxNumNodes) - s.eei.Finish(prevMaxNumNodes.Bytes()) - stakeConfig.MaxNumNodes = newMaxNodes - s.setConfig(stakeConfig) - - return vmcommon.Ok -} - -func (s *stakingSC) isNodeJailedOrWithBadRating(registrationData *StakedDataV2_0, blsKey []byte) bool { - return registrationData.Jailed || s.eei.CanUnJail(blsKey) || s.eei.IsBadRating(blsKey) -} - -func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - s.eei.Finish([]byte{0}) - - return vmcommon.Ok - } - if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { - s.eei.AddReturnMessage("this is only a view function") - return vmcommon.UserError - } - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("number of arguments must be equal to 1") - return vmcommon.UserError - } - - waitingElementKey := createWaitingListKey(args.Arguments[0]) - _, err := s.getWaitingListElement(waitingElementKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - if bytes.Equal(waitingElementKey, waitingListHead.FirstKey) { - s.eei.Finish([]byte(strconv.Itoa(1))) - return vmcommon.Ok - } - if bytes.Equal(waitingElementKey, waitingListHead.LastKey) { - s.eei.Finish([]byte(strconv.Itoa(int(waitingListHead.Length)))) - return vmcommon.Ok - } - - prevElement, err := s.getWaitingListElement(waitingListHead.FirstKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - index := uint32(2) - nextKey := make([]byte, len(waitingElementKey)) - copy(nextKey, prevElement.NextKey) - for len(nextKey) != 0 && index <= waitingListHead.Length { - if bytes.Equal(nextKey, waitingElementKey) { - s.eei.Finish([]byte(strconv.Itoa(int(index)))) - return vmcommon.Ok - } - - prevElement, err = s.getWaitingListElement(nextKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - if len(prevElement.NextKey) == 0 { - break - } - index++ - copy(nextKey, prevElement.NextKey) - } - - s.eei.AddReturnMessage("element in waiting list not found") - return vmcommon.UserError -} - -func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - s.eei.Finish([]byte{0}) - - return vmcommon.Ok - } - - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.Get) - if err != nil { - s.eei.AddReturnMessage("insufficient gas") - return vmcommon.OutOfGas - } - - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - s.eei.Finish([]byte(strconv.Itoa(int(waitingListHead.Length)))) - return vmcommon.Ok -} - -func (s *stakingSC) getRewardAddress(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - stakedData, returnCode := s.getStakedDataIfExists(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - s.eei.Finish([]byte(hex.EncodeToString(stakedData.RewardAddress))) - return vmcommon.Ok -} - -func (s *stakingSC) getStakedDataIfExists(args *vmcommon.ContractCallInput) (*StakedDataV2_0, vmcommon.ReturnCode) { - err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.Get) - if err != nil { - s.eei.AddReturnMessage("insufficient gas") - return nil, vmcommon.OutOfGas - } - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("number of arguments must be equal to 1") - return nil, vmcommon.UserError - } - stakedData, err := s.getOrCreateRegisteredData(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return nil, vmcommon.UserError - } - if len(stakedData.RewardAddress) == 0 { - s.eei.AddReturnMessage("blsKey not registered in staking sc") - return nil, vmcommon.UserError - } - - return stakedData, vmcommon.Ok -} - -func (s *stakingSC) getBLSKeyStatus(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - stakedData, returnCode := s.getStakedDataIfExists(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - if stakedData.Jailed || s.eei.CanUnJail(args.Arguments[0]) { - s.eei.Finish([]byte("jailed")) - return vmcommon.Ok - } - if stakedData.Waiting { - s.eei.Finish([]byte("queued")) - return vmcommon.Ok - } - if stakedData.Staked { - s.eei.Finish([]byte("staked")) - return vmcommon.Ok - } - - s.eei.Finish([]byte("unStaked")) - return vmcommon.Ok -} - -func (s *stakingSC) getRemainingUnbondPeriod(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - stakedData, returnCode := s.getStakedDataIfExists(args) - if returnCode != vmcommon.Ok { - return returnCode - } - if stakedData.UnStakedNonce == 0 { - s.eei.AddReturnMessage("not in unbond period") - return vmcommon.UserError - } - - currentNonce := s.eei.BlockChainHook().CurrentNonce() - passedNonce := currentNonce - stakedData.UnStakedNonce - if passedNonce >= s.unBondPeriod { - if s.flagStakingV2.IsSet() { - s.eei.Finish(zero.Bytes()) - } else { - s.eei.Finish([]byte("0")) - } - } else { - remaining := s.unBondPeriod - passedNonce - if s.flagStakingV2.IsSet() { - s.eei.Finish(big.NewInt(0).SetUint64(remaining).Bytes()) - } else { - s.eei.Finish([]byte(strconv.Itoa(int(remaining)))) - } - } - - return vmcommon.Ok -} - -func (s *stakingSC) getWaitingListRegisterNonceAndRewardAddress(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { - s.eei.AddReturnMessage("this is only a view function") - return vmcommon.UserError - } - if len(args.Arguments) != 0 { - s.eei.AddReturnMessage("number of arguments must be equal to 0") - return vmcommon.UserError - } - - waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - if len(waitingListData.stakedDataList) == 0 { - s.eei.AddReturnMessage("no one in waitingList") - return vmcommon.UserError - } - - for index, stakedData := range waitingListData.stakedDataList { - s.eei.Finish(waitingListData.blsKeys[index]) - s.eei.Finish(stakedData.RewardAddress) - s.eei.Finish(big.NewInt(int64(stakedData.RegisterNonce)).Bytes()) - } - - return vmcommon.Ok -} - -func (s *stakingSC) setOwnersOnAddresses(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("setOwnersOnAddresses function not allowed to be called by address " + string(args.CallerAddr)) - return vmcommon.UserError - } - if len(args.Arguments)%2 != 0 { - s.eei.AddReturnMessage("invalid number of arguments: expected an even number of arguments") - return vmcommon.UserError - } - for i := 0; i < len(args.Arguments); i += 2 { - stakedData, err := s.getOrCreateRegisteredData(args.Arguments[i]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - s.eei.AddReturnMessage(fmt.Sprintf("process stopped at index %d, bls key %s", i, hex.EncodeToString(args.Arguments[i]))) - return vmcommon.UserError - } - if len(stakedData.RewardAddress) == 0 { - log.Error("staking data does not exists", - "bls key", hex.EncodeToString(args.Arguments[i]), - "owner as hex", hex.EncodeToString(args.Arguments[i+1])) - continue - } - - stakedData.OwnerAddress = args.Arguments[i+1] - err = s.saveStakingData(args.Arguments[i], stakedData) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - s.eei.AddReturnMessage(fmt.Sprintf("process stopped at index %d, bls key %s", i, hex.EncodeToString(args.Arguments[i]))) - return vmcommon.UserError - } - } - - return vmcommon.Ok -} - -func (s *stakingSC) getOwner(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { - s.eei.AddReturnMessage("this is only a view function") - return vmcommon.UserError - } - if len(args.Arguments) < 1 { - s.eei.AddReturnMessage(fmt.Sprintf("invalid number of arguments: expected min %d, got %d", 1, len(args.Arguments))) - return vmcommon.UserError - } - - stakedData, errGet := s.getOrCreateRegisteredData(args.Arguments[0]) - if errGet != nil { - s.eei.AddReturnMessage(errGet.Error()) - return vmcommon.UserError - } - if len(stakedData.OwnerAddress) == 0 { - s.eei.AddReturnMessage("owner address is nil") - return vmcommon.UserError - } - - s.eei.Finish(stakedData.OwnerAddress) - return vmcommon.Ok -} - -func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - stakeConfig := s.getConfig() - totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + int64(waitingListHead.Length) - s.eei.Finish(big.NewInt(totalRegistered).Bytes()) - return vmcommon.Ok -} - -func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectLastUnjailed.IsSet() { - // backward compatibility - return vmcommon.UserError - } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") - return vmcommon.UserError - } - if len(args.Arguments) != 0 { - s.eei.AddReturnMessage("number of arguments must be equal to 0") - return vmcommon.UserError + stakedData, returnCode := s.getStakedDataIfExists(args) + if returnCode != vmcommon.Ok { + return returnCode } - waitingList, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError + if stakedData.Jailed || s.eei.CanUnJail(args.Arguments[0]) { + s.eei.Finish([]byte("jailed")) + return vmcommon.Ok } - - if len(waitingList.LastJailedKey) == 0 { + if stakedData.Waiting { + s.eei.Finish([]byte("queued")) return vmcommon.Ok } - - waitingList.LastJailedKey = make([]byte, 0) - err = s.saveWaitingListHead(waitingList) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError + if stakedData.Staked { + s.eei.Finish([]byte("staked")) + return vmcommon.Ok } + s.eei.Finish([]byte("unStaked")) return vmcommon.Ok } -func (s *stakingSC) cleanAdditionalQueueNotEnoughFunds( - waitingListData *waitingListReturnData, -) ([]string, map[string][][]byte, error) { - - listOfOwners := make([]string, 0) - mapOwnersUnStakedNodes := make(map[string][][]byte) - mapCheckedOwners := make(map[string]*validatorFundInfo) - for i := len(waitingListData.blsKeys) - 1; i >= 0; i-- { - stakedData := waitingListData.stakedDataList[i] - validatorInfo, err := s.checkValidatorFunds(mapCheckedOwners, stakedData.OwnerAddress, s.stakeValue) - if err != nil { - return nil, nil, err - } - if validatorInfo.numNodesToUnstake == 0 { - continue - } - - validatorInfo.numNodesToUnstake-- - blsKey := waitingListData.blsKeys[i] - err = s.removeFromWaitingList(blsKey) - if err != nil { - return nil, nil, err - } - - registrationData, err := s.getOrCreateRegisteredData(blsKey) - if err != nil { - return nil, nil, err - } +func (s *stakingSC) getRemainingUnbondPeriod(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError + } - registrationData.Staked = false - registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() - registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() - registrationData.Waiting = false + stakedData, returnCode := s.getStakedDataIfExists(args) + if returnCode != vmcommon.Ok { + return returnCode + } + if stakedData.UnStakedNonce == 0 { + s.eei.AddReturnMessage("not in unbond period") + return vmcommon.UserError + } - err = s.saveStakingData(blsKey, registrationData) - if err != nil { - return nil, nil, err + currentNonce := s.eei.BlockChainHook().CurrentNonce() + passedNonce := currentNonce - stakedData.UnStakedNonce + if passedNonce >= s.unBondPeriod { + if s.flagStakingV2.IsSet() { + s.eei.Finish(zero.Bytes()) + } else { + s.eei.Finish([]byte("0")) } - - _, alreadyAdded := mapOwnersUnStakedNodes[string(stakedData.OwnerAddress)] - if !alreadyAdded { - listOfOwners = append(listOfOwners, string(stakedData.OwnerAddress)) + } else { + remaining := s.unBondPeriod - passedNonce + if s.flagStakingV2.IsSet() { + s.eei.Finish(big.NewInt(0).SetUint64(remaining).Bytes()) + } else { + s.eei.Finish([]byte(strconv.Itoa(int(remaining)))) } - - mapOwnersUnStakedNodes[string(stakedData.OwnerAddress)] = append(mapOwnersUnStakedNodes[string(stakedData.OwnerAddress)], blsKey) } - return listOfOwners, mapOwnersUnStakedNodes, nil + return vmcommon.Ok } -func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { +func (s *stakingSC) setOwnersOnAddresses(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if !s.flagStakingV2.IsSet() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.UserError - } if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") - return vmcommon.UserError - } - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("number of arguments must be equal to 1") + s.eei.AddReturnMessage("setOwnersOnAddresses function not allowed to be called by address " + string(args.CallerAddr)) return vmcommon.UserError } - - numNodesToStake := big.NewInt(0).SetBytes(args.Arguments[0]).Uint64() - waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) - if err != nil { - s.eei.AddReturnMessage(err.Error()) + if len(args.Arguments)%2 != 0 { + s.eei.AddReturnMessage("invalid number of arguments: expected an even number of arguments") return vmcommon.UserError } - if len(waitingListData.blsKeys) == 0 { - s.eei.AddReturnMessage("no nodes in queue") - return vmcommon.Ok - } - - nodePriceToUse := big.NewInt(0).Set(s.minNodePrice) - if s.flagCorrectLastUnjailed.IsSet() { - nodePriceToUse.Set(s.stakeValue) - } - - stakedNodes := uint64(0) - mapCheckedOwners := make(map[string]*validatorFundInfo) - for i, blsKey := range waitingListData.blsKeys { - stakedData := waitingListData.stakedDataList[i] - if stakedNodes >= numNodesToStake { - break - } - - validatorInfo, errCheck := s.checkValidatorFunds(mapCheckedOwners, stakedData.OwnerAddress, nodePriceToUse) - if errCheck != nil { - s.eei.AddReturnMessage(errCheck.Error()) - return vmcommon.UserError - } - if validatorInfo.numNodesToUnstake > 0 { - continue - } - - s.activeStakingFor(stakedData) - err = s.saveStakingData(blsKey, stakedData) + for i := 0; i < len(args.Arguments); i += 2 { + stakedData, err := s.getOrCreateRegisteredData(args.Arguments[i]) if err != nil { s.eei.AddReturnMessage(err.Error()) + s.eei.AddReturnMessage(fmt.Sprintf("process stopped at index %d, bls key %s", i, hex.EncodeToString(args.Arguments[i]))) return vmcommon.UserError } + if len(stakedData.RewardAddress) == 0 { + log.Error("staking data does not exists", + "bls key", hex.EncodeToString(args.Arguments[i]), + "owner as hex", hex.EncodeToString(args.Arguments[i+1])) + continue + } - // remove from waiting list - err = s.removeFromWaitingList(blsKey) + stakedData.OwnerAddress = args.Arguments[i+1] + err = s.saveStakingData(args.Arguments[i], stakedData) if err != nil { s.eei.AddReturnMessage(err.Error()) + s.eei.AddReturnMessage(fmt.Sprintf("process stopped at index %d, bls key %s", i, hex.EncodeToString(args.Arguments[i]))) return vmcommon.UserError } - - stakedNodes++ - // return the change key - s.eei.Finish(blsKey) - s.eei.Finish(stakedData.RewardAddress) } - s.addToStakedNodes(int64(stakedNodes)) - return vmcommon.Ok } -func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectLastUnjailed.IsSet() { +func (s *stakingSC) getOwner(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagStakingV2.IsSet() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") + if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { + s.eei.AddReturnMessage("this is only a view function") return vmcommon.UserError } - if len(args.Arguments) != 0 { - s.eei.AddReturnMessage("number of arguments must be 0") + if len(args.Arguments) < 1 { + s.eei.AddReturnMessage(fmt.Sprintf("invalid number of arguments: expected min %d, got %d", 1, len(args.Arguments))) return vmcommon.UserError } - waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) - if err != nil { - s.eei.AddReturnMessage(err.Error()) + stakedData, errGet := s.getOrCreateRegisteredData(args.Arguments[0]) + if errGet != nil { + s.eei.AddReturnMessage(errGet.Error()) return vmcommon.UserError } - if len(waitingListData.blsKeys) == 0 { - s.eei.AddReturnMessage("no nodes in queue") - return vmcommon.Ok - } - - listOfOwners, mapOwnersAndBLSKeys, err := s.cleanAdditionalQueueNotEnoughFunds(waitingListData) - if err != nil { - s.eei.AddReturnMessage(err.Error()) + if len(stakedData.OwnerAddress) == 0 { + s.eei.AddReturnMessage("owner address is nil") return vmcommon.UserError } - for _, owner := range listOfOwners { - s.eei.Finish([]byte(owner)) - blsKeys := mapOwnersAndBLSKeys[owner] - for _, blsKey := range blsKeys { - s.eei.Finish(blsKey) - } - } - + s.eei.Finish(stakedData.OwnerAddress) return vmcommon.Ok } @@ -1950,201 +991,6 @@ func (s *stakingSC) checkValidatorFunds( return validatorInfo, nil } -func (s *stakingSC) getFirstElementsFromWaitingList(numNodes uint32) (*waitingListReturnData, error) { - waitingListData := &waitingListReturnData{} - - waitingListHead, err := s.getWaitingListHead() - if err != nil { - return nil, err - } - if waitingListHead.Length == 0 { - return waitingListData, nil - } - - blsKeysToStake := make([][]byte, 0) - stakedDataList := make([]*StakedDataV2_0, 0) - index := uint32(1) - nextKey := make([]byte, len(waitingListHead.FirstKey)) - copy(nextKey, waitingListHead.FirstKey) - for len(nextKey) != 0 && index <= waitingListHead.Length && index <= numNodes { - element, errGet := s.getWaitingListElement(nextKey) - if errGet != nil { - return nil, errGet - } - - if bytes.Equal(nextKey, waitingListHead.LastJailedKey) { - waitingListData.afterLastjailed = true - } - - stakedData, errGet := s.getOrCreateRegisteredData(element.BLSPublicKey) - if errGet != nil { - return nil, errGet - } - - blsKeysToStake = append(blsKeysToStake, element.BLSPublicKey) - stakedDataList = append(stakedDataList, stakedData) - - if len(element.NextKey) == 0 { - break - } - index++ - copy(nextKey, element.NextKey) - } - - if numNodes >= waitingListHead.Length && len(blsKeysToStake) != int(waitingListHead.Length) { - log.Warn("mismatch length on waiting list elements in stakingSC.getFirstElementsFromWaitingList") - } - - waitingListData.blsKeys = blsKeysToStake - waitingListData.stakedDataList = stakedDataList - waitingListData.lastKey = nextKey - return waitingListData, nil -} - -func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectFirstQueued.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.UserError - } - - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.FixWaitingListSize) - if err != nil { - s.eei.AddReturnMessage("insufficient gas") - return vmcommon.OutOfGas - } - - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - if waitingListHead.Length <= 1 { - return vmcommon.Ok - } - - foundLastJailedKey := len(waitingListHead.LastJailedKey) == 0 - - index := uint32(1) - nextKey := make([]byte, len(waitingListHead.FirstKey)) - copy(nextKey, waitingListHead.FirstKey) - for len(nextKey) != 0 && index <= waitingListHead.Length { - element, errGet := s.getWaitingListElement(nextKey) - if errGet != nil { - s.eei.AddReturnMessage(errGet.Error()) - return vmcommon.UserError - } - - if bytes.Equal(waitingListHead.LastJailedKey, nextKey) { - foundLastJailedKey = true - } - - _, errGet = s.getOrCreateRegisteredData(element.BLSPublicKey) - if errGet != nil { - s.eei.AddReturnMessage(errGet.Error()) - return vmcommon.UserError - } - - if len(element.NextKey) == 0 { - break - } - index++ - copy(nextKey, element.NextKey) - } - - waitingListHead.Length = index - waitingListHead.LastKey = nextKey - if !foundLastJailedKey { - waitingListHead.LastJailedKey = make([]byte, 0) - } - - err = s.saveWaitingListHead(waitingListHead) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (s *stakingSC) addMissingNodeToQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectFirstQueued.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.FixWaitingListSize) - if err != nil { - s.eei.AddReturnMessage("insufficient gas") - return vmcommon.OutOfGas - } - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("invalid number of arguments") - return vmcommon.UserError - } - - blsKey := args.Arguments[0] - _, err = s.getWaitingListElement(createWaitingListKey(blsKey)) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - for _, keyInList := range waitingListData.blsKeys { - if bytes.Equal(keyInList, blsKey) { - s.eei.AddReturnMessage("key is in queue, not missing") - return vmcommon.UserError - } - } - - waitingList, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - waitingList.Length += 1 - if waitingList.Length == 1 { - err = s.startWaitingList(waitingList, false, blsKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok - } - - err = s.addToEndOfTheList(waitingList, blsKey) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - // EpochConfirmed is called whenever a new epoch is confirmed func (s *stakingSC) EpochConfirmed(epoch uint32, _ uint64) { s.flagEnableStaking.SetValue(epoch >= s.enableStakingEpoch) diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go new file mode 100644 index 00000000000..2e554307433 --- /dev/null +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -0,0 +1,1169 @@ +package systemSmartContracts + +import ( + "bytes" + "encoding/hex" + "fmt" + "math" + "math/big" + "strconv" + + "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/vm" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" +) + +const waitingListHeadKey = "waitingList" +const waitingElementPrefix = "w_" + +type waitingListReturnData struct { + blsKeys [][]byte + stakedDataList []*StakedDataV2_0 + lastKey []byte + afterLastJailed bool +} + +func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { + if registrationData.Staked { + return nil + } + + registrationData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() + if !s.canStake() { + s.eei.AddReturnMessage(fmt.Sprintf("staking is full key put into waiting list %s", hex.EncodeToString(blsKey))) + err := s.addToWaitingList(blsKey, addFirst) + if err != nil { + s.eei.AddReturnMessage("error while adding to waiting") + return err + } + registrationData.Waiting = true + s.eei.Finish([]byte{waiting}) + return nil + } + + if !s.flagStakingV4.IsSet() { + err := s.removeFromWaitingList(blsKey) + if err != nil { + s.eei.AddReturnMessage("error while removing from waiting") + return err + } + } + s.addToStakedNodes(1) + s.activeStakingFor(registrationData) + + return nil +} + +func (s *stakingSC) unStakeAtEndOfEpoch(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + // backward compatibility - no need for return message + return vmcommon.UserError + } + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("not enough arguments, needed the BLS key") + return vmcommon.UserError + } + + registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) + return vmcommon.UserError + } + if len(registrationData.RewardAddress) == 0 { + s.eei.AddReturnMessage("cannot unStake a key that is not registered") + return vmcommon.UserError + } + if registrationData.Jailed && !registrationData.Staked { + s.eei.AddReturnMessage("already unStaked at switchJailedToWaiting") + return vmcommon.Ok + } + + if !registrationData.Staked && !registrationData.Waiting { + log.Debug("stakingSC.unStakeAtEndOfEpoch: cannot unStake node which was already unStaked", "blsKey", hex.EncodeToString(args.Arguments[0])) + return vmcommon.Ok + } + + if registrationData.Staked { + s.removeFromStakedNodes() + } + + if registrationData.Waiting { + err = s.removeFromWaitingList(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + } + + registrationData.Staked = false + registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() + registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() + registrationData.Waiting = false + + err = s.saveStakingData(args.Arguments[0], registrationData) + if err != nil { + s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { + s.eei.AddReturnMessage("unStake function not allowed to be called by address " + string(args.CallerAddr)) + return vmcommon.UserError + } + if len(args.Arguments) < 2 { + s.eei.AddReturnMessage("not enough arguments, needed BLS key and reward address") + return vmcommon.UserError + } + + registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) + return vmcommon.UserError + } + if len(registrationData.RewardAddress) == 0 { + s.eei.AddReturnMessage("cannot unStake a key that is not registered") + return vmcommon.UserError + } + if !bytes.Equal(args.Arguments[1], registrationData.RewardAddress) { + s.eei.AddReturnMessage("unStake possible only from staker caller") + return vmcommon.UserError + } + if s.isNodeJailedOrWithBadRating(registrationData, args.Arguments[0]) { + s.eei.AddReturnMessage("cannot unStake node which is jailed or with bad rating") + return vmcommon.UserError + } + + if !registrationData.Staked && !registrationData.Waiting { + s.eei.AddReturnMessage("cannot unStake node which was already unStaked") + return vmcommon.UserError + } + + if !registrationData.Staked { + registrationData.Waiting = false + err = s.removeFromWaitingList(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + err = s.saveStakingData(args.Arguments[0], registrationData) + if err != nil { + s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok + } + + if !s.flagStakingV4.IsSet() { + addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() + if addOneFromQueue { + _, err = s.moveFirstFromWaitingToStaked() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + } + } + + if !s.canUnStake() { + s.eei.AddReturnMessage("unStake is not possible as too many left") + return vmcommon.UserError + } + + s.removeFromStakedNodes() + registrationData.Staked = false + registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() + registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() + registrationData.Waiting = false + + err = s.saveStakingData(args.Arguments[0], registrationData) + if err != nil { + s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (s *stakingSC) moveFirstFromWaitingToStakedIfNeeded(blsKey []byte) (bool, error) { + waitingElementKey := createWaitingListKey(blsKey) + _, err := s.getWaitingListElement(waitingElementKey) + if err == nil { + // node in waiting - remove from it - and that's it + return false, s.removeFromWaitingList(blsKey) + } + + return s.moveFirstFromWaitingToStaked() +} + +func (s *stakingSC) moveFirstFromWaitingToStaked() (bool, error) { + waitingList, err := s.getWaitingListHead() + if err != nil { + return false, err + } + if waitingList.Length == 0 { + return false, nil + } + elementInList, err := s.getWaitingListElement(waitingList.FirstKey) + if err != nil { + return false, err + } + err = s.removeFromWaitingList(elementInList.BLSPublicKey) + if err != nil { + return false, err + } + + nodeData, err := s.getOrCreateRegisteredData(elementInList.BLSPublicKey) + if err != nil { + return false, err + } + if len(nodeData.RewardAddress) == 0 || nodeData.Staked { + return false, vm.ErrInvalidWaitingList + } + + nodeData.Waiting = false + nodeData.Staked = true + nodeData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() + nodeData.StakedNonce = s.eei.BlockChainHook().CurrentNonce() + nodeData.UnStakedNonce = 0 + nodeData.UnStakedEpoch = common.DefaultUnstakedEpoch + + s.addToStakedNodes(1) + return true, s.saveStakingData(elementInList.BLSPublicKey, nodeData) +} + +func (s *stakingSC) addToWaitingList(blsKey []byte, addJailed bool) error { + inWaitingListKey := createWaitingListKey(blsKey) + marshaledData := s.eei.GetStorage(inWaitingListKey) + if len(marshaledData) != 0 { + return nil + } + + waitingList, err := s.getWaitingListHead() + if err != nil { + return err + } + + waitingList.Length += 1 + if waitingList.Length == 1 { + return s.startWaitingList(waitingList, addJailed, blsKey) + } + + if addJailed { + return s.insertAfterLastJailed(waitingList, blsKey) + } + + return s.addToEndOfTheList(waitingList, blsKey) +} + +func (s *stakingSC) startWaitingList( + waitingList *WaitingList, + addJailed bool, + blsKey []byte, +) error { + inWaitingListKey := createWaitingListKey(blsKey) + waitingList.FirstKey = inWaitingListKey + waitingList.LastKey = inWaitingListKey + if addJailed { + waitingList.LastJailedKey = inWaitingListKey + } + + elementInWaiting := &ElementInList{ + BLSPublicKey: blsKey, + PreviousKey: waitingList.LastKey, + NextKey: make([]byte, 0), + } + return s.saveElementAndList(inWaitingListKey, elementInWaiting, waitingList) +} + +func (s *stakingSC) addToEndOfTheList(waitingList *WaitingList, blsKey []byte) error { + inWaitingListKey := createWaitingListKey(blsKey) + oldLastKey := make([]byte, len(waitingList.LastKey)) + copy(oldLastKey, waitingList.LastKey) + + lastElement, err := s.getWaitingListElement(waitingList.LastKey) + if err != nil { + return err + } + lastElement.NextKey = inWaitingListKey + elementInWaiting := &ElementInList{ + BLSPublicKey: blsKey, + PreviousKey: oldLastKey, + NextKey: make([]byte, 0), + } + + err = s.saveWaitingListElement(oldLastKey, lastElement) + if err != nil { + return err + } + + waitingList.LastKey = inWaitingListKey + return s.saveElementAndList(inWaitingListKey, elementInWaiting, waitingList) +} + +func (s *stakingSC) insertAfterLastJailed( + waitingList *WaitingList, + blsKey []byte, +) error { + inWaitingListKey := createWaitingListKey(blsKey) + if len(waitingList.LastJailedKey) == 0 { + previousFirstKey := make([]byte, len(waitingList.FirstKey)) + copy(previousFirstKey, waitingList.FirstKey) + waitingList.FirstKey = inWaitingListKey + waitingList.LastJailedKey = inWaitingListKey + elementInWaiting := &ElementInList{ + BLSPublicKey: blsKey, + PreviousKey: inWaitingListKey, + NextKey: previousFirstKey, + } + + if s.flagCorrectFirstQueued.IsSet() && len(previousFirstKey) > 0 { + previousFirstElement, err := s.getWaitingListElement(previousFirstKey) + if err != nil { + return err + } + previousFirstElement.PreviousKey = inWaitingListKey + err = s.saveWaitingListElement(previousFirstKey, previousFirstElement) + if err != nil { + return err + } + } + + return s.saveElementAndList(inWaitingListKey, elementInWaiting, waitingList) + } + + lastJailedElement, err := s.getWaitingListElement(waitingList.LastJailedKey) + if err != nil { + return err + } + + if bytes.Equal(waitingList.LastKey, waitingList.LastJailedKey) { + waitingList.LastJailedKey = inWaitingListKey + return s.addToEndOfTheList(waitingList, blsKey) + } + + firstNonJailedElement, err := s.getWaitingListElement(lastJailedElement.NextKey) + if err != nil { + return err + } + + elementInWaiting := &ElementInList{ + BLSPublicKey: blsKey, + PreviousKey: make([]byte, len(inWaitingListKey)), + NextKey: make([]byte, len(inWaitingListKey)), + } + copy(elementInWaiting.PreviousKey, waitingList.LastJailedKey) + copy(elementInWaiting.NextKey, lastJailedElement.NextKey) + + lastJailedElement.NextKey = inWaitingListKey + firstNonJailedElement.PreviousKey = inWaitingListKey + waitingList.LastJailedKey = inWaitingListKey + + err = s.saveWaitingListElement(elementInWaiting.PreviousKey, lastJailedElement) + if err != nil { + return err + } + err = s.saveWaitingListElement(elementInWaiting.NextKey, firstNonJailedElement) + if err != nil { + return err + } + err = s.saveWaitingListElement(inWaitingListKey, elementInWaiting) + if err != nil { + return err + } + return s.saveWaitingListHead(waitingList) +} + +func (s *stakingSC) saveElementAndList(key []byte, element *ElementInList, waitingList *WaitingList) error { + err := s.saveWaitingListElement(key, element) + if err != nil { + return err + } + + return s.saveWaitingListHead(waitingList) +} + +func (s *stakingSC) removeFromWaitingList(blsKey []byte) error { + inWaitingListKey := createWaitingListKey(blsKey) + marshaledData := s.eei.GetStorage(inWaitingListKey) + if len(marshaledData) == 0 { + return nil + } + s.eei.SetStorage(inWaitingListKey, nil) + + elementToRemove := &ElementInList{} + err := s.marshalizer.Unmarshal(elementToRemove, marshaledData) + if err != nil { + return err + } + + waitingList, err := s.getWaitingListHead() + if err != nil { + return err + } + if waitingList.Length == 0 { + return vm.ErrInvalidWaitingList + } + waitingList.Length -= 1 + if waitingList.Length == 0 { + s.eei.SetStorage([]byte(waitingListHeadKey), nil) + return nil + } + + // remove the first element + isFirstElementBeforeFix := !s.flagCorrectFirstQueued.IsSet() && bytes.Equal(elementToRemove.PreviousKey, inWaitingListKey) + isFirstElementAfterFix := s.flagCorrectFirstQueued.IsSet() && bytes.Equal(waitingList.FirstKey, inWaitingListKey) + if isFirstElementBeforeFix || isFirstElementAfterFix { + if bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { + waitingList.LastJailedKey = make([]byte, 0) + } + + nextElement, errGet := s.getWaitingListElement(elementToRemove.NextKey) + if errGet != nil { + return errGet + } + + nextElement.PreviousKey = elementToRemove.NextKey + waitingList.FirstKey = elementToRemove.NextKey + return s.saveElementAndList(elementToRemove.NextKey, nextElement, waitingList) + } + + if !s.flagCorrectLastUnjailed.IsSet() || bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { + waitingList.LastJailedKey = make([]byte, len(elementToRemove.PreviousKey)) + copy(waitingList.LastJailedKey, elementToRemove.PreviousKey) + } + + previousElement, _ := s.getWaitingListElement(elementToRemove.PreviousKey) + // search the other way around for the element in front + if s.flagCorrectFirstQueued.IsSet() && previousElement == nil { + previousElement, err = s.searchPreviousFromHead(waitingList, inWaitingListKey, elementToRemove) + if err != nil { + return err + } + } + if previousElement == nil { + previousElement, err = s.getWaitingListElement(elementToRemove.PreviousKey) + if err != nil { + return err + } + } + if len(elementToRemove.NextKey) == 0 { + waitingList.LastKey = elementToRemove.PreviousKey + previousElement.NextKey = make([]byte, 0) + return s.saveElementAndList(elementToRemove.PreviousKey, previousElement, waitingList) + } + + nextElement, err := s.getWaitingListElement(elementToRemove.NextKey) + if err != nil { + return err + } + + nextElement.PreviousKey = elementToRemove.PreviousKey + previousElement.NextKey = elementToRemove.NextKey + + err = s.saveWaitingListElement(elementToRemove.NextKey, nextElement) + if err != nil { + return err + } + return s.saveElementAndList(elementToRemove.PreviousKey, previousElement, waitingList) +} + +func (s *stakingSC) searchPreviousFromHead(waitingList *WaitingList, inWaitingListKey []byte, elementToRemove *ElementInList) (*ElementInList, error) { + var previousElement *ElementInList + index := uint32(1) + nextKey := make([]byte, len(waitingList.FirstKey)) + copy(nextKey, waitingList.FirstKey) + for len(nextKey) != 0 && index <= waitingList.Length { + element, errGet := s.getWaitingListElement(nextKey) + if errGet != nil { + return nil, errGet + } + + if bytes.Equal(inWaitingListKey, element.NextKey) { + previousElement = element + elementToRemove.PreviousKey = createWaitingListKey(previousElement.BLSPublicKey) + return previousElement, nil + } + + nextKey = make([]byte, len(element.NextKey)) + if len(element.NextKey) == 0 { + break + } + index++ + copy(nextKey, element.NextKey) + } + return nil, vm.ErrElementNotFound +} + +func (s *stakingSC) getWaitingListElement(key []byte) (*ElementInList, error) { + marshaledData := s.eei.GetStorage(key) + if len(marshaledData) == 0 { + return nil, vm.ErrElementNotFound + } + + element := &ElementInList{} + err := s.marshalizer.Unmarshal(element, marshaledData) + if err != nil { + return nil, err + } + + return element, nil +} + +func (s *stakingSC) saveWaitingListElement(key []byte, element *ElementInList) error { + marshaledData, err := s.marshalizer.Marshal(element) + if err != nil { + return err + } + + s.eei.SetStorage(key, marshaledData) + return nil +} + +func (s *stakingSC) getWaitingListHead() (*WaitingList, error) { + waitingList := &WaitingList{ + FirstKey: make([]byte, 0), + LastKey: make([]byte, 0), + Length: 0, + LastJailedKey: make([]byte, 0), + } + marshaledData := s.eei.GetStorage([]byte(waitingListHeadKey)) + if len(marshaledData) == 0 { + return waitingList, nil + } + + err := s.marshalizer.Unmarshal(waitingList, marshaledData) + if err != nil { + return nil, err + } + + return waitingList, nil +} + +func (s *stakingSC) saveWaitingListHead(waitingList *WaitingList) error { + marshaledData, err := s.marshalizer.Marshal(waitingList) + if err != nil { + return err + } + + s.eei.SetStorage([]byte(waitingListHeadKey), marshaledData) + return nil +} + +func createWaitingListKey(blsKey []byte) []byte { + return []byte(waitingElementPrefix + string(blsKey)) +} + +func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.UserError + } + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + s.eei.AddReturnMessage("switchJailedWithWaiting function not allowed to be called by address " + string(args.CallerAddr)) + return vmcommon.UserError + } + if len(args.Arguments) != 1 { + return vmcommon.UserError + } + + blsKey := args.Arguments[0] + registrationData, err := s.getOrCreateRegisteredData(blsKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if len(registrationData.RewardAddress) == 0 { + s.eei.AddReturnMessage("no need to jail as not a validator") + return vmcommon.UserError + } + if !registrationData.Staked { + s.eei.AddReturnMessage("no need to jail as not a validator") + return vmcommon.UserError + } + if registrationData.Jailed { + s.eei.AddReturnMessage(vm.ErrBLSPublicKeyAlreadyJailed.Error()) + return vmcommon.UserError + } + switched, err := s.moveFirstFromWaitingToStakedIfNeeded(blsKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + registrationData.NumJailed++ + registrationData.Jailed = true + registrationData.JailedNonce = s.eei.BlockChainHook().CurrentNonce() + + if !switched && !s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet() { + s.eei.AddReturnMessage("did not switch as nobody in waiting, but jailed") + } else { + s.tryRemoveJailedNodeFromStaked(registrationData) + } + + err = s.saveStakingData(blsKey, registrationData) + if err != nil { + s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + s.eei.Finish([]byte{0}) + + return vmcommon.Ok + } + if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { + s.eei.AddReturnMessage("this is only a view function") + return vmcommon.UserError + } + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("number of arguments must be equal to 1") + return vmcommon.UserError + } + + waitingElementKey := createWaitingListKey(args.Arguments[0]) + _, err := s.getWaitingListElement(waitingElementKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + if bytes.Equal(waitingElementKey, waitingListHead.FirstKey) { + s.eei.Finish([]byte(strconv.Itoa(1))) + return vmcommon.Ok + } + if bytes.Equal(waitingElementKey, waitingListHead.LastKey) { + s.eei.Finish([]byte(strconv.Itoa(int(waitingListHead.Length)))) + return vmcommon.Ok + } + + prevElement, err := s.getWaitingListElement(waitingListHead.FirstKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + index := uint32(2) + nextKey := make([]byte, len(waitingElementKey)) + copy(nextKey, prevElement.NextKey) + for len(nextKey) != 0 && index <= waitingListHead.Length { + if bytes.Equal(nextKey, waitingElementKey) { + s.eei.Finish([]byte(strconv.Itoa(int(index)))) + return vmcommon.Ok + } + + prevElement, err = s.getWaitingListElement(nextKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + if len(prevElement.NextKey) == 0 { + break + } + index++ + copy(nextKey, prevElement.NextKey) + } + + s.eei.AddReturnMessage("element in waiting list not found") + return vmcommon.UserError +} + +func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + s.eei.Finish([]byte{0}) + + return vmcommon.Ok + } + + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError + } + + err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.Get) + if err != nil { + s.eei.AddReturnMessage("insufficient gas") + return vmcommon.OutOfGas + } + + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + s.eei.Finish([]byte(strconv.Itoa(int(waitingListHead.Length)))) + return vmcommon.Ok +} + +func (s *stakingSC) getWaitingListRegisterNonceAndRewardAddress(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { + s.eei.AddReturnMessage("this is only a view function") + return vmcommon.UserError + } + if len(args.Arguments) != 0 { + s.eei.AddReturnMessage("number of arguments must be equal to 0") + return vmcommon.UserError + } + + waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if len(waitingListData.stakedDataList) == 0 { + s.eei.AddReturnMessage("no one in waitingList") + return vmcommon.UserError + } + + for index, stakedData := range waitingListData.stakedDataList { + s.eei.Finish(waitingListData.blsKeys[index]) + s.eei.Finish(stakedData.RewardAddress) + s.eei.Finish(big.NewInt(int64(stakedData.RegisterNonce)).Bytes()) + } + + return vmcommon.Ok +} + +func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagStakingV2.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError + } + + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + stakeConfig := s.getConfig() + totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + int64(waitingListHead.Length) + s.eei.Finish(big.NewInt(totalRegistered).Bytes()) + return vmcommon.Ok +} + +func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagCorrectLastUnjailed.IsSet() { + // backward compatibility + return vmcommon.UserError + } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.UserError + } + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") + return vmcommon.UserError + } + if len(args.Arguments) != 0 { + s.eei.AddReturnMessage("number of arguments must be equal to 0") + return vmcommon.UserError + } + + waitingList, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + if len(waitingList.LastJailedKey) == 0 { + return vmcommon.Ok + } + + waitingList.LastJailedKey = make([]byte, 0) + err = s.saveWaitingListHead(waitingList) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (s *stakingSC) cleanAdditionalQueueNotEnoughFunds( + waitingListData *waitingListReturnData, +) ([]string, map[string][][]byte, error) { + + listOfOwners := make([]string, 0) + mapOwnersUnStakedNodes := make(map[string][][]byte) + mapCheckedOwners := make(map[string]*validatorFundInfo) + for i := len(waitingListData.blsKeys) - 1; i >= 0; i-- { + stakedData := waitingListData.stakedDataList[i] + validatorInfo, err := s.checkValidatorFunds(mapCheckedOwners, stakedData.OwnerAddress, s.stakeValue) + if err != nil { + return nil, nil, err + } + if validatorInfo.numNodesToUnstake == 0 { + continue + } + + validatorInfo.numNodesToUnstake-- + blsKey := waitingListData.blsKeys[i] + err = s.removeFromWaitingList(blsKey) + if err != nil { + return nil, nil, err + } + + registrationData, err := s.getOrCreateRegisteredData(blsKey) + if err != nil { + return nil, nil, err + } + + registrationData.Staked = false + registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() + registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() + registrationData.Waiting = false + + err = s.saveStakingData(blsKey, registrationData) + if err != nil { + return nil, nil, err + } + + _, alreadyAdded := mapOwnersUnStakedNodes[string(stakedData.OwnerAddress)] + if !alreadyAdded { + listOfOwners = append(listOfOwners, string(stakedData.OwnerAddress)) + } + + mapOwnersUnStakedNodes[string(stakedData.OwnerAddress)] = append(mapOwnersUnStakedNodes[string(stakedData.OwnerAddress)], blsKey) + } + + return listOfOwners, mapOwnersUnStakedNodes, nil +} + +func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagStakingV2.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.UserError + } + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") + return vmcommon.UserError + } + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("number of arguments must be equal to 1") + return vmcommon.UserError + } + + numNodesToStake := big.NewInt(0).SetBytes(args.Arguments[0]).Uint64() + waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if len(waitingListData.blsKeys) == 0 { + s.eei.AddReturnMessage("no nodes in queue") + return vmcommon.Ok + } + + nodePriceToUse := big.NewInt(0).Set(s.minNodePrice) + if s.flagCorrectLastUnjailed.IsSet() { + nodePriceToUse.Set(s.stakeValue) + } + + stakedNodes := uint64(0) + mapCheckedOwners := make(map[string]*validatorFundInfo) + for i, blsKey := range waitingListData.blsKeys { + stakedData := waitingListData.stakedDataList[i] + if stakedNodes >= numNodesToStake { + break + } + + validatorInfo, errCheck := s.checkValidatorFunds(mapCheckedOwners, stakedData.OwnerAddress, nodePriceToUse) + if errCheck != nil { + s.eei.AddReturnMessage(errCheck.Error()) + return vmcommon.UserError + } + if validatorInfo.numNodesToUnstake > 0 { + continue + } + + s.activeStakingFor(stakedData) + err = s.saveStakingData(blsKey, stakedData) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + // remove from waiting list + err = s.removeFromWaitingList(blsKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + stakedNodes++ + // return the change key + s.eei.Finish(blsKey) + s.eei.Finish(stakedData.RewardAddress) + } + + s.addToStakedNodes(int64(stakedNodes)) + + return vmcommon.Ok +} + +func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagCorrectLastUnjailed.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.UserError + } + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + s.eei.AddReturnMessage("stake nodes from waiting list can be called by endOfEpochAccess address only") + return vmcommon.UserError + } + if len(args.Arguments) != 0 { + s.eei.AddReturnMessage("number of arguments must be 0") + return vmcommon.UserError + } + + waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + if len(waitingListData.blsKeys) == 0 { + s.eei.AddReturnMessage("no nodes in queue") + return vmcommon.Ok + } + + listOfOwners, mapOwnersAndBLSKeys, err := s.cleanAdditionalQueueNotEnoughFunds(waitingListData) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + for _, owner := range listOfOwners { + s.eei.Finish([]byte(owner)) + blsKeys := mapOwnersAndBLSKeys[owner] + for _, blsKey := range blsKeys { + s.eei.Finish(blsKey) + } + } + + return vmcommon.Ok +} + +func (s *stakingSC) getFirstElementsFromWaitingList(numNodes uint32) (*waitingListReturnData, error) { + waitingListData := &waitingListReturnData{} + + waitingListHead, err := s.getWaitingListHead() + if err != nil { + return nil, err + } + if waitingListHead.Length == 0 { + return waitingListData, nil + } + + blsKeysToStake := make([][]byte, 0) + stakedDataList := make([]*StakedDataV2_0, 0) + index := uint32(1) + nextKey := make([]byte, len(waitingListHead.FirstKey)) + copy(nextKey, waitingListHead.FirstKey) + for len(nextKey) != 0 && index <= waitingListHead.Length && index <= numNodes { + element, errGet := s.getWaitingListElement(nextKey) + if errGet != nil { + return nil, errGet + } + + if bytes.Equal(nextKey, waitingListHead.LastJailedKey) { + waitingListData.afterLastJailed = true + } + + stakedData, errGet := s.getOrCreateRegisteredData(element.BLSPublicKey) + if errGet != nil { + return nil, errGet + } + + blsKeysToStake = append(blsKeysToStake, element.BLSPublicKey) + stakedDataList = append(stakedDataList, stakedData) + + if len(element.NextKey) == 0 { + break + } + index++ + copy(nextKey, element.NextKey) + } + + if numNodes >= waitingListHead.Length && len(blsKeysToStake) != int(waitingListHead.Length) { + log.Warn("mismatch length on waiting list elements in stakingSC.getFirstElementsFromWaitingList") + } + + waitingListData.blsKeys = blsKeysToStake + waitingListData.stakedDataList = stakedDataList + waitingListData.lastKey = nextKey + return waitingListData, nil +} + +func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagCorrectFirstQueued.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.UserError + } + + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError + } + + err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.FixWaitingListSize) + if err != nil { + s.eei.AddReturnMessage("insufficient gas") + return vmcommon.OutOfGas + } + + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + if waitingListHead.Length <= 1 { + return vmcommon.Ok + } + + foundLastJailedKey := len(waitingListHead.LastJailedKey) == 0 + + index := uint32(1) + nextKey := make([]byte, len(waitingListHead.FirstKey)) + copy(nextKey, waitingListHead.FirstKey) + for len(nextKey) != 0 && index <= waitingListHead.Length { + element, errGet := s.getWaitingListElement(nextKey) + if errGet != nil { + s.eei.AddReturnMessage(errGet.Error()) + return vmcommon.UserError + } + + if bytes.Equal(waitingListHead.LastJailedKey, nextKey) { + foundLastJailedKey = true + } + + _, errGet = s.getOrCreateRegisteredData(element.BLSPublicKey) + if errGet != nil { + s.eei.AddReturnMessage(errGet.Error()) + return vmcommon.UserError + } + + if len(element.NextKey) == 0 { + break + } + index++ + copy(nextKey, element.NextKey) + } + + waitingListHead.Length = index + waitingListHead.LastKey = nextKey + if !foundLastJailedKey { + waitingListHead.LastJailedKey = make([]byte, 0) + } + + err = s.saveWaitingListHead(waitingListHead) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (s *stakingSC) addMissingNodeToQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagCorrectFirstQueued.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError + } + err := s.eei.UseGas(s.gasCost.MetaChainSystemSCsCost.FixWaitingListSize) + if err != nil { + s.eei.AddReturnMessage("insufficient gas") + return vmcommon.OutOfGas + } + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("invalid number of arguments") + return vmcommon.UserError + } + + blsKey := args.Arguments[0] + _, err = s.getWaitingListElement(createWaitingListKey(blsKey)) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + waitingListData, err := s.getFirstElementsFromWaitingList(math.MaxUint32) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + for _, keyInList := range waitingListData.blsKeys { + if bytes.Equal(keyInList, blsKey) { + s.eei.AddReturnMessage("key is in queue, not missing") + return vmcommon.UserError + } + } + + waitingList, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + waitingList.Length += 1 + if waitingList.Length == 1 { + err = s.startWaitingList(waitingList, false, blsKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok + } + + err = s.addToEndOfTheList(waitingList, blsKey) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} From b10b28ef0372a475f6aa6006e4659701ae8ce31e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 2 Mar 2022 15:35:05 +0200 Subject: [PATCH 073/958] FEAT: Add extra safety flag check --- vm/systemSmartContracts/staking.go | 5 +++++ vm/systemSmartContracts/staking_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index e4447e52c1e..1f8b74b4ed2 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -655,6 +655,11 @@ func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod } if !registrationData.Staked { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.ExecutionFailed + } + registrationData.Waiting = false err = s.removeFromWaitingList(args.Arguments[0]) if err != nil { diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 212d9f8f156..699258a1fc6 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -1029,6 +1029,31 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { requireRegisteredNodes(t, stakingSmartContract, eei, 13, 0) } +func TestStakingSc_UnStakeNodeFromWaitingListAfterStakingV4ShouldError(t *testing.T) { + t.Parallel() + + args := createMockStakingScArguments() + stakingAccessAddress := []byte("stakingAccessAddress") + args.StakingAccessAddr = stakingAccessAddress + args.StakingSCConfig.MaxNumberOfNodesForStake = 2 + eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) + args.Eei = eei + + stakingSmartContract, _ := NewStakingSmartContract(args) + stakingSmartContract.flagStakingV2.SetValue(true) + + doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address0"), []byte("address0")) + doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address1"), []byte("address1")) + doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2")) + requireRegisteredNodes(t, stakingSmartContract, eei, 2, 1) + + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + + eei.returnMessage = "" + doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2"), vmcommon.ExecutionFailed) + require.Equal(t, eei.returnMessage, vm.ErrWaitingListDisabled.Error()) +} + func TestStakingSc_StakeWithV1ShouldWork(t *testing.T) { t.Parallel() From 681f88073538a82a0f9e1189ec42044ac59db3dd Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 2 Mar 2022 15:37:47 +0200 Subject: [PATCH 074/958] FIX: Merge conflict --- vm/systemSmartContracts/stakingWaitingList.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index 2e554307433..b29e34c3442 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -143,6 +143,11 @@ func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod } if !registrationData.Staked { + if s.flagStakingV4.IsSet() { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.ExecutionFailed + } + registrationData.Waiting = false err = s.removeFromWaitingList(args.Arguments[0]) if err != nil { From 23675b0f4e61e94c4045c4fee18c5c33b4134e90 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 3 Mar 2022 13:08:50 +0200 Subject: [PATCH 075/958] FIX: Review findings --- epochStart/metachain/systemSCs.go | 171 ++++++++++-------- epochStart/metachain/systemSCs_test.go | 36 ++-- .../mock/epochStartSystemSCStub.go | 9 +- process/block/metablock.go | 8 +- process/interface.go | 6 +- process/mock/epochStartSystemSCStub.go | 9 +- 6 files changed, 127 insertions(+), 112 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 8a91e0aec80..b7bb7e0319e 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -217,10 +217,21 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr // ProcessSystemSmartContract does all the processing at end of epoch in case of system smart contract func (s *systemSCProcessor) ProcessSystemSmartContract( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + header data.HeaderHandler, +) error { + err := s.checkOldFlags(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) + if err != nil { + return err + } + + return s.checkNewFlags(validatorsInfoMap, header) +} + +func (s *systemSCProcessor) checkOldFlags( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, - randomness []byte, ) error { if s.flagHystNodesEnabled.IsSet() { err := s.updateSystemSCConfigMinNodes() @@ -237,7 +248,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagChangeMaxNodesEnabled.IsSet() { - err := s.updateMaxNodes(validatorInfos, nonce) + err := s.updateMaxNodes(validatorsInfoMap, nonce) if err != nil { return err } @@ -265,39 +276,27 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagSwitchJailedWaiting.IsSet() { - err := s.computeNumWaitingPerShard(validatorInfos) + err := s.computeNumWaitingPerShard(validatorsInfoMap) if err != nil { return err } - err = s.swapJailedWithWaiting(validatorInfos) + err = s.swapJailedWithWaiting(validatorsInfoMap) if err != nil { return err } } if s.flagStakingV2Enabled.IsSet() { - err := s.prepareRewardsData(validatorInfos) - if err != nil { - return err - } - - err = s.fillStakingDataForNonEligible(validatorInfos) + numUnStaked, err := s.prepareStakingAndUnStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) if err != nil { return err } - numUnStaked, err := s.unStakeNodesWithNotEnoughFunds(validatorInfos, epoch) + err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) if err != nil { return err } - - if s.flagStakingQueueEnabled.IsSet() { - err = s.stakeNodesFromQueue(validatorInfos, numUnStaked, nonce, common.NewList) - if err != nil { - return err - } - } } if s.flagESDTEnabled.IsSet() { @@ -308,6 +307,30 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } } + return nil +} + +func (s *systemSCProcessor) prepareStakingAndUnStakeNodesWithNotEnoughFunds( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + epoch uint32, +) (uint32, error) { + err := s.prepareStakingData(validatorsInfoMap) + if err != nil { + return 0, err + } + + err = s.fillStakingDataForNonEligible(validatorsInfoMap) + if err != nil { + return 0, err + } + + return s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) +} + +func (s *systemSCProcessor) checkNewFlags( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + header data.HeaderHandler, +) error { if s.flagGovernanceEnabled.IsSet() { err := s.updateToGovernanceV2() if err != nil { @@ -328,21 +351,19 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( } if s.flagInitStakingV4Enabled.IsSet() { - err := s.stakeNodesFromQueue(validatorInfos, math.MaxUint32, nonce, common.AuctionList) + err := s.stakeNodesFromQueue(validatorsInfoMap, math.MaxUint32, header.GetNonce(), common.AuctionList) if err != nil { return err } } if s.flagStakingV4Enabled.IsSet() { - allNodesKeys := s.getAllNodeKeys(validatorInfos) - - err := s.stakingDataProvider.PrepareStakingData(allNodesKeys) + _, err := s.prepareStakingAndUnStakeNodesWithNotEnoughFunds(validatorsInfoMap, header.GetEpoch()) if err != nil { return err } - err = s.selectNodesFromAuctionList(validatorInfos, randomness) + err = s.selectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) if err != nil { return err } @@ -351,8 +372,8 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( return nil } -func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfoMap map[uint32][]*state.ValidatorInfo, randomness []byte) error { - auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorInfoMap) +func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap map[uint32][]*state.ValidatorInfo, randomness []byte) error { + auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) err := s.sortAuctionList(auctionList, randomness) if err != nil { return err @@ -362,6 +383,7 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfoMap map[uint numOfAvailableNodeSlots := core.MinUint32(auctionListSize, s.maxNodes-numOfValidators) s.displayAuctionList(auctionList, numOfAvailableNodeSlots) + // TODO: Think of a better way of handling these pointers; perhaps use an interface which handles validators for i := uint32(0); i < numOfAvailableNodeSlots; i++ { auctionList[i].List = string(common.NewList) } @@ -369,11 +391,11 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorInfoMap map[uint return nil } -func getAuctionListAndNumOfValidators(validatorInfoMap map[uint32][]*state.ValidatorInfo) ([]*state.ValidatorInfo, uint32) { +func getAuctionListAndNumOfValidators(validatorsInfoMap map[uint32][]*state.ValidatorInfo) ([]*state.ValidatorInfo, uint32) { auctionList := make([]*state.ValidatorInfo, 0) numOfValidators := uint32(0) - for _, validatorsInShard := range validatorInfoMap { + for _, validatorsInShard := range validatorsInfoMap { for _, validator := range validatorsInShard { if validator.List == string(common.AuctionList) { auctionList = append(auctionList, validator) @@ -515,10 +537,10 @@ func (s *systemSCProcessor) ToggleUnStakeUnBond(value bool) error { } func (s *systemSCProcessor) unStakeNodesWithNotEnoughFunds( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32, ) (uint32, error) { - nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorInfos) + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) if err != nil { return 0, err } @@ -533,7 +555,7 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFunds( return 0, err } - validatorInfo := getValidatorInfoWithBLSKey(validatorInfos, blsKey) + validatorInfo := getValidatorInfoWithBLSKey(validatorsInfoMap, blsKey) if validatorInfo == nil { nodesUnStakedFromAdditionalQueue++ log.Debug("unStaked node which was in additional queue", "blsKey", blsKey) @@ -645,8 +667,8 @@ func (s *systemSCProcessor) updateDelegationContracts(mapOwnerKeys map[string][] return nil } -func getValidatorInfoWithBLSKey(validatorInfos map[uint32][]*state.ValidatorInfo, blsKey []byte) *state.ValidatorInfo { - for _, validatorsInfoSlice := range validatorInfos { +func getValidatorInfoWithBLSKey(validatorsInfoMap map[uint32][]*state.ValidatorInfo, blsKey []byte) *state.ValidatorInfo { + for _, validatorsInfoSlice := range validatorsInfoMap { for _, validatorInfo := range validatorsInfoSlice { if bytes.Equal(validatorInfo.PublicKey, blsKey) { return validatorInfo @@ -656,8 +678,8 @@ func getValidatorInfoWithBLSKey(validatorInfos map[uint32][]*state.ValidatorInfo return nil } -func (s *systemSCProcessor) fillStakingDataForNonEligible(validatorInfos map[uint32][]*state.ValidatorInfo) error { - for shId, validatorsInfoSlice := range validatorInfos { +func (s *systemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + for shId, validatorsInfoSlice := range validatorsInfoMap { newList := make([]*state.ValidatorInfo, 0, len(validatorsInfoSlice)) deleteCalled := false @@ -688,26 +710,23 @@ func (s *systemSCProcessor) fillStakingDataForNonEligible(validatorInfos map[uin } if deleteCalled { - validatorInfos[shId] = newList + validatorsInfoMap[shId] = newList } } return nil } -func (s *systemSCProcessor) prepareRewardsData( - validatorsInfo map[uint32][]*state.ValidatorInfo, -) error { - eligibleNodesKeys := s.getEligibleNodesKeyMapOfType(validatorsInfo) - err := s.prepareStakingDataForRewards(eligibleNodesKeys) - if err != nil { - return err +func (s *systemSCProcessor) prepareStakingData(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + nodes := make(map[uint32][][]byte) + if s.flagStakingV2Enabled.IsSet() { + nodes = s.getEligibleNodeKeys(validatorsInfoMap) } - return nil -} + if s.flagStakingV4Enabled.IsSet() { + nodes = s.getAllNodeKeys(validatorsInfoMap) + } -func (s *systemSCProcessor) prepareStakingDataForRewards(eligibleNodesKeys map[uint32][][]byte) error { sw := core.NewStopWatch() sw.Start("prepareStakingDataForRewards") defer func() { @@ -715,14 +734,14 @@ func (s *systemSCProcessor) prepareStakingDataForRewards(eligibleNodesKeys map[u log.Debug("systemSCProcessor.prepareStakingDataForRewards time measurements", sw.GetMeasurements()...) }() - return s.stakingDataProvider.PrepareStakingData(eligibleNodesKeys) + return s.stakingDataProvider.PrepareStakingData(nodes) } -func (s *systemSCProcessor) getEligibleNodesKeyMapOfType( - validatorsInfo map[uint32][]*state.ValidatorInfo, +func (s *systemSCProcessor) getEligibleNodeKeys( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, ) map[uint32][][]byte { eligibleNodesKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfo { + for shardID, validatorsInfoSlice := range validatorsInfoMap { eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) for _, validatorInfo := range validatorsInfoSlice { if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { @@ -855,7 +874,7 @@ func (s *systemSCProcessor) resetLastUnJailed() error { } // updates the configuration of the system SC if the flags permit -func (s *systemSCProcessor) updateMaxNodes(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64) error { +func (s *systemSCProcessor) updateMaxNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64) error { sw := core.NewStopWatch() sw.Start("total") defer func() { @@ -877,7 +896,7 @@ func (s *systemSCProcessor) updateMaxNodes(validatorInfos map[uint32][]*state.Va if s.flagStakingQueueEnabled.IsSet() { sw.Start("stakeNodesFromQueue") - err = s.stakeNodesFromQueue(validatorInfos, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) + err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) sw.Stop("stakeNodesFromQueue") if err != nil { return err @@ -886,8 +905,8 @@ func (s *systemSCProcessor) updateMaxNodes(validatorInfos map[uint32][]*state.Va return nil } -func (s *systemSCProcessor) computeNumWaitingPerShard(validatorInfos map[uint32][]*state.ValidatorInfo) error { - for shardID, validatorInfoList := range validatorInfos { +func (s *systemSCProcessor) computeNumWaitingPerShard(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + for shardID, validatorInfoList := range validatorsInfoMap { totalInWaiting := uint32(0) for _, validatorInfo := range validatorInfoList { switch validatorInfo.List { @@ -901,8 +920,8 @@ func (s *systemSCProcessor) computeNumWaitingPerShard(validatorInfos map[uint32] return nil } -func (s *systemSCProcessor) swapJailedWithWaiting(validatorInfos map[uint32][]*state.ValidatorInfo) error { - jailedValidators := s.getSortedJailedNodes(validatorInfos) +func (s *systemSCProcessor) swapJailedWithWaiting(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + jailedValidators := s.getSortedJailedNodes(validatorsInfoMap) log.Debug("number of jailed validators", "num", len(jailedValidators)) @@ -940,7 +959,7 @@ func (s *systemSCProcessor) swapJailedWithWaiting(validatorInfos map[uint32][]*s continue } - newValidator, err := s.stakingToValidatorStatistics(validatorInfos, jailedValidator, vmOutput) + newValidator, err := s.stakingToValidatorStatistics(validatorsInfoMap, jailedValidator, vmOutput) if err != nil { return err } @@ -954,7 +973,7 @@ func (s *systemSCProcessor) swapJailedWithWaiting(validatorInfos map[uint32][]*s } func (s *systemSCProcessor) stakingToValidatorStatistics( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, jailedValidator *state.ValidatorInfo, vmOutput *vmcommon.VMOutput, ) ([]byte, error) { @@ -1016,7 +1035,7 @@ func (s *systemSCProcessor) stakingToValidatorStatistics( } } else { // old jailed validator getting switched back after unJail with stake - must remove first from exported map - deleteNewValidatorIfExistsFromMap(validatorInfos, blsPubKey, account.GetShardId()) + deleteNewValidatorIfExistsFromMap(validatorsInfoMap, blsPubKey, account.GetShardId()) } account.SetListAndIndex(jailedValidator.ShardId, string(common.NewList), uint32(stakingData.StakedNonce)) @@ -1045,7 +1064,7 @@ func (s *systemSCProcessor) stakingToValidatorStatistics( } newValidatorInfo := s.validatorInfoCreator.PeerAccountToValidatorInfo(account) - switchJailedWithNewValidatorInMap(validatorInfos, jailedValidator, newValidatorInfo) + switchJailedWithNewValidatorInMap(validatorsInfoMap, jailedValidator, newValidatorInfo) return blsPubKey, nil } @@ -1055,29 +1074,29 @@ func isValidator(validator *state.ValidatorInfo) bool { } func deleteNewValidatorIfExistsFromMap( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, blsPubKey []byte, shardID uint32, ) { - for index, validatorInfo := range validatorInfos[shardID] { + for index, validatorInfo := range validatorsInfoMap[shardID] { if bytes.Equal(validatorInfo.PublicKey, blsPubKey) { - length := len(validatorInfos[shardID]) - validatorInfos[shardID][index] = validatorInfos[shardID][length-1] - validatorInfos[shardID][length-1] = nil - validatorInfos[shardID] = validatorInfos[shardID][:length-1] + length := len(validatorsInfoMap[shardID]) + validatorsInfoMap[shardID][index] = validatorsInfoMap[shardID][length-1] + validatorsInfoMap[shardID][length-1] = nil + validatorsInfoMap[shardID] = validatorsInfoMap[shardID][:length-1] break } } } func switchJailedWithNewValidatorInMap( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, jailedValidator *state.ValidatorInfo, newValidator *state.ValidatorInfo, ) { - for index, validatorInfo := range validatorInfos[jailedValidator.ShardId] { + for index, validatorInfo := range validatorsInfoMap[jailedValidator.ShardId] { if bytes.Equal(validatorInfo.PublicKey, jailedValidator.PublicKey) { - validatorInfos[jailedValidator.ShardId][index] = newValidator + validatorsInfoMap[jailedValidator.ShardId][index] = newValidator break } } @@ -1133,12 +1152,12 @@ func (s *systemSCProcessor) processSCOutputAccounts( return nil } -func (s *systemSCProcessor) getSortedJailedNodes(validatorInfos map[uint32][]*state.ValidatorInfo) []*state.ValidatorInfo { +func (s *systemSCProcessor) getSortedJailedNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) []*state.ValidatorInfo { newJailedValidators := make([]*state.ValidatorInfo, 0) oldJailedValidators := make([]*state.ValidatorInfo, 0) minChance := s.chanceComputer.GetChance(0) - for _, listValidators := range validatorInfos { + for _, listValidators := range validatorsInfoMap { for _, validatorInfo := range listValidators { if validatorInfo.List == string(common.JailedList) { oldJailedValidators = append(oldJailedValidators, validatorInfo) @@ -1553,7 +1572,7 @@ func (s *systemSCProcessor) cleanAdditionalQueue() error { } func (s *systemSCProcessor) stakeNodesFromQueue( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, nodesToStake uint32, nonce uint64, list common.PeerType, @@ -1588,7 +1607,7 @@ func (s *systemSCProcessor) stakeNodesFromQueue( return err } - err = s.addNewlyStakedNodesToValidatorTrie(validatorInfos, vmOutput.ReturnData, nonce, list) + err = s.addNewlyStakedNodesToValidatorTrie(validatorsInfoMap, vmOutput.ReturnData, nonce, list) if err != nil { return err } @@ -1597,7 +1616,7 @@ func (s *systemSCProcessor) stakeNodesFromQueue( } func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, returnData [][]byte, nonce uint64, list common.PeerType, @@ -1640,7 +1659,7 @@ func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( RewardAddress: rewardAddress, AccumulatedFees: big.NewInt(0), } - validatorInfos[peerAcc.GetShardId()] = append(validatorInfos[peerAcc.GetShardId()], validatorInfo) + validatorsInfoMap[peerAcc.GetShardId()] = append(validatorsInfoMap[peerAcc.GetShardId()], validatorInfo) } return nil @@ -1735,7 +1754,7 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { log.Debug("systemSCProcessor: delegation", "enabled", epoch >= s.delegationEnableEpoch) s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) - s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch) + s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch < s.stakingV4InitEnableEpoch) log.Debug("systemSCProcessor: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) log.Debug("systemSCProcessor: change of maximum number of nodes and/or shuffling percentage", "enabled", s.flagChangeMaxNodesEnabled.IsSet(), diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e787f2e1a17..2ceaaa62a26 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -185,7 +185,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { AccumulatedFees: big.NewInt(0), } validatorInfos[0] = append(validatorInfos[0], vInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) assert.Equal(t, len(validatorInfos[0]), 1) @@ -231,7 +231,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s validatorsInfo := make(map[uint32][]*state.ValidatorInfo) validatorsInfo[0] = append(validatorsInfo[0], jailed...) - err := s.ProcessSystemSmartContract(validatorsInfo, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) for i := 0; i < numWaiting; i++ { assert.Equal(t, string(common.NewList), validatorsInfo[0][i].List) @@ -302,7 +302,7 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { } validatorsInfo[0] = append(validatorsInfo[0], jailed) - err := s.ProcessSystemSmartContract(validatorsInfo, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) for _, vInfo := range validatorsInfo[0] { @@ -1055,7 +1055,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin _ = s.flagDelegationEnabled.SetReturningPrevious() validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) @@ -1198,7 +1198,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueue(t * ) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1250,7 +1250,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwne EpochField: 10, }) validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 10, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{Epoch: 10}) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1276,7 +1276,7 @@ func TestSystemSCProcessor_ESDTInitShouldWork(t *testing.T) { require.Equal(t, 4, len(initialContractConfig)) require.Equal(t, []byte("aaaaaa"), initialContractConfig[0]) - err = s.ProcessSystemSmartContract(nil, 1, 1, nil) + err = s.ProcessSystemSmartContract(nil, &block.Header{Nonce: 1, Epoch: 1}) require.Nil(t, err) @@ -1344,7 +1344,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1397,7 +1397,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) } @@ -1489,7 +1489,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) for _, vInfo := range validatorInfos[0] { @@ -1578,7 +1578,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) for _, vInfo := range validatorInfos[0] { @@ -1675,7 +1675,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( _ = args.PeerAccountsDB.SaveAccount(peerAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr2) @@ -1749,7 +1749,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractWrongValidatorInfoShouldBeC AccumulatedFees: big.NewInt(0), }) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) assert.Equal(t, len(validatorInfos[0]), 1) @@ -1847,7 +1847,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) assert.Nil(t, err) _, err = s.peerAccountsDB.GetExistingAccount([]byte("waitingPubKey")) @@ -1911,7 +1911,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, nil) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ @@ -1957,7 +1957,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("rand")) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) require.Equal(t, errProcessStakingData, err) } @@ -1990,7 +1990,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("rand")) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) require.Error(t, err) require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) @@ -2034,7 +2034,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0, []byte("pubKey7")) + err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{PrevRandSeed: []byte("pubKey7")}) require.Nil(t, err) /* diff --git a/integrationTests/mock/epochStartSystemSCStub.go b/integrationTests/mock/epochStartSystemSCStub.go index a4da2334824..9ec174c0b46 100644 --- a/integrationTests/mock/epochStartSystemSCStub.go +++ b/integrationTests/mock/epochStartSystemSCStub.go @@ -1,6 +1,7 @@ package mock import ( + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" @@ -8,7 +9,7 @@ import ( // EpochStartSystemSCStub - type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, randomness []byte) error + ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error ToggleUnStakeUnBondCalled func(value bool) error } @@ -24,12 +25,10 @@ func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { // ProcessSystemSmartContract - func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( validatorInfos map[uint32][]*state.ValidatorInfo, - nonce uint64, - epoch uint32, - randomness []byte, + header data.HeaderHandler, ) error { if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorInfos, nonce, epoch, randomness) + return e.ProcessSystemSmartContractCalled(validatorInfos, header) } return nil } diff --git a/process/block/metablock.go b/process/block/metablock.go index 0150a17132e..57dd794a7f3 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -403,7 +403,7 @@ func (mp *metaProcessor) processEpochStartMetaBlock( } if mp.isRewardsV2Enabled(header) { - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header.Nonce, header.Epoch, header.GetPrevRandSeed()) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header) if err != nil { return err } @@ -418,7 +418,7 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header.Nonce, header.Epoch, header.GetPrevRandSeed()) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header) if err != nil { return err } @@ -865,7 +865,7 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. var rewardMiniBlocks block.MiniBlockSlice if mp.isRewardsV2Enabled(metaBlock) { - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock.Nonce, metaBlock.Epoch, metaBlock.GetPrevRandSeed()) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock) if err != nil { return nil, err } @@ -880,7 +880,7 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock.Nonce, metaBlock.Epoch, metaBlock.GetPrevRandSeed()) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock) if err != nil { return nil, err } diff --git a/process/interface.go b/process/interface.go index 3244700ff3a..4dcbd304625 100644 --- a/process/interface.go +++ b/process/interface.go @@ -901,10 +901,8 @@ type EpochStartValidatorInfoCreator interface { // EpochStartSystemSCProcessor defines the functionality for the metachain to process system smart contract and end of epoch type EpochStartSystemSCProcessor interface { ProcessSystemSmartContract( - validatorInfos map[uint32][]*state.ValidatorInfo, - nonce uint64, - epoch uint32, - randomness []byte, + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + header data.HeaderHandler, ) error ProcessDelegationRewards( miniBlocks block.MiniBlockSlice, diff --git a/process/mock/epochStartSystemSCStub.go b/process/mock/epochStartSystemSCStub.go index a4da2334824..9ec174c0b46 100644 --- a/process/mock/epochStartSystemSCStub.go +++ b/process/mock/epochStartSystemSCStub.go @@ -1,6 +1,7 @@ package mock import ( + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" @@ -8,7 +9,7 @@ import ( // EpochStartSystemSCStub - type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, randomness []byte) error + ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error ToggleUnStakeUnBondCalled func(value bool) error } @@ -24,12 +25,10 @@ func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { // ProcessSystemSmartContract - func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( validatorInfos map[uint32][]*state.ValidatorInfo, - nonce uint64, - epoch uint32, - randomness []byte, + header data.HeaderHandler, ) error { if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorInfos, nonce, epoch, randomness) + return e.ProcessSystemSmartContractCalled(validatorInfos, header) } return nil } From 30c635d34b6e200794162d69514ab8a14e9167f9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 3 Mar 2022 14:13:58 +0200 Subject: [PATCH 076/958] FIX: Review findings --- vm/systemSmartContracts/staking.go | 8 ++------ vm/systemSmartContracts/staking_test.go | 12 ++---------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index 1f8b74b4ed2..6c2403e3e13 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -1313,9 +1313,7 @@ func (s *stakingSC) isNodeJailedOrWithBadRating(registrationData *StakedDataV2_0 func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - s.eei.Finish([]byte{0}) - - return vmcommon.Ok + return vmcommon.UserError } if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { s.eei.AddReturnMessage("this is only a view function") @@ -1383,9 +1381,7 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - s.eei.Finish([]byte{0}) - - return vmcommon.Ok + return vmcommon.UserError } if args.CallValue.Cmp(zero) != 0 { diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 699258a1fc6..87927073bf1 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -3353,56 +3353,48 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { arguments.Arguments = [][]byte{} arguments.Function = "getQueueIndex" retCode := stakingSmartContract.Execute(arguments) - require.Equal(t, vmcommon.Ok, retCode) - require.Equal(t, []byte{0}, eei.output[0]) + require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "getQueueSize" retCode = stakingSmartContract.Execute(arguments) - require.Equal(t, vmcommon.Ok, retCode) - require.Equal(t, []byte{0}, eei.output[0]) + require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "switchJailedWithWaiting" retCode = stakingSmartContract.Execute(arguments) - require.Empty(t, eei.output) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "resetLastUnJailedFromQueue" retCode = stakingSmartContract.Execute(arguments) - require.Empty(t, eei.output) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "stakeNodesFromQueue" retCode = stakingSmartContract.Execute(arguments) - require.Empty(t, eei.output) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "cleanAdditionalQueue" retCode = stakingSmartContract.Execute(arguments) - require.Empty(t, eei.output) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "fixWaitingListQueueSize" retCode = stakingSmartContract.Execute(arguments) - require.Empty(t, eei.output) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() arguments.Function = "addMissingNodeToQueue" retCode = stakingSmartContract.Execute(arguments) - require.Empty(t, eei.output) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) } From 072ba5cbdf2e1f4d4bf22ef5af7806915198fd2b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 3 Mar 2022 14:17:28 +0200 Subject: [PATCH 077/958] FIX: Merge conflicts --- vm/systemSmartContracts/stakingWaitingList.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index b29e34c3442..aadabe9a027 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -622,9 +622,7 @@ func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vm func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - s.eei.Finish([]byte{0}) - - return vmcommon.Ok + return vmcommon.UserError } if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { s.eei.AddReturnMessage("this is only a view function") @@ -692,9 +690,7 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if s.flagStakingV4.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - s.eei.Finish([]byte{0}) - - return vmcommon.Ok + return vmcommon.UserError } if args.CallValue.Cmp(zero) != 0 { From 9639aa5904347f89031521c621e3298d1e85ff30 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 4 Mar 2022 11:17:15 +0200 Subject: [PATCH 078/958] FIX: Review findings pt. 2 --- epochStart/metachain/systemSCs.go | 73 ++++++++++++--------- epochStart/metachain/systemSCs_test.go | 89 ++++++++++++++++++-------- 2 files changed, 103 insertions(+), 59 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index b7bb7e0319e..af43fdb138e 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -220,15 +220,15 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( validatorsInfoMap map[uint32][]*state.ValidatorInfo, header data.HeaderHandler, ) error { - err := s.checkOldFlags(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) + err := s.processWithOldFlags(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) if err != nil { return err } - return s.checkNewFlags(validatorsInfoMap, header) + return s.processWithNewFlags(validatorsInfoMap, header) } -func (s *systemSCProcessor) checkOldFlags( +func (s *systemSCProcessor) processWithOldFlags( validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32, @@ -288,7 +288,12 @@ func (s *systemSCProcessor) checkOldFlags( } if s.flagStakingV2Enabled.IsSet() { - numUnStaked, err := s.prepareStakingAndUnStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) + err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) + if err != nil { + return err + } + + numUnStaked, err := s.unStakeNonEligibleNodes(validatorsInfoMap, epoch) if err != nil { return err } @@ -310,24 +315,7 @@ func (s *systemSCProcessor) checkOldFlags( return nil } -func (s *systemSCProcessor) prepareStakingAndUnStakeNodesWithNotEnoughFunds( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - epoch uint32, -) (uint32, error) { - err := s.prepareStakingData(validatorsInfoMap) - if err != nil { - return 0, err - } - - err = s.fillStakingDataForNonEligible(validatorsInfoMap) - if err != nil { - return 0, err - } - - return s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) -} - -func (s *systemSCProcessor) checkNewFlags( +func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap map[uint32][]*state.ValidatorInfo, header data.HeaderHandler, ) error { @@ -358,7 +346,12 @@ func (s *systemSCProcessor) checkNewFlags( } if s.flagStakingV4Enabled.IsSet() { - _, err := s.prepareStakingAndUnStakeNodesWithNotEnoughFunds(validatorsInfoMap, header.GetEpoch()) + err := s.prepareStakingDataForAllNodes(validatorsInfoMap) + if err != nil { + return err + } + + _, err = s.unStakeNonEligibleNodes(validatorsInfoMap, header.GetEpoch()) if err != nil { return err } @@ -374,13 +367,19 @@ func (s *systemSCProcessor) checkNewFlags( func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap map[uint32][]*state.ValidatorInfo, randomness []byte) error { auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) + availableSlots := s.maxNodes - numOfValidators + if availableSlots <= 0 { + log.Info("not enough available slots for auction nodes; skip selecting nodes from auction list") + return nil + } + err := s.sortAuctionList(auctionList, randomness) if err != nil { return err } auctionListSize := uint32(len(auctionList)) - numOfAvailableNodeSlots := core.MinUint32(auctionListSize, s.maxNodes-numOfValidators) + numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) s.displayAuctionList(auctionList, numOfAvailableNodeSlots) // TODO: Think of a better way of handling these pointers; perhaps use an interface which handles validators @@ -717,16 +716,26 @@ func (s *systemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMap map[ return nil } -func (s *systemSCProcessor) prepareStakingData(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - nodes := make(map[uint32][][]byte) - if s.flagStakingV2Enabled.IsSet() { - nodes = s.getEligibleNodeKeys(validatorsInfoMap) - } +func (s *systemSCProcessor) prepareStakingDataForEligibleNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + eligibleNodes := s.getEligibleNodeKeys(validatorsInfoMap) + return s.prepareStakingData(eligibleNodes) +} - if s.flagStakingV4Enabled.IsSet() { - nodes = s.getAllNodeKeys(validatorsInfoMap) +func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + allNodes := s.getAllNodeKeys(validatorsInfoMap) + return s.prepareStakingData(allNodes) +} + +func (s *systemSCProcessor) unStakeNonEligibleNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32) (uint32, error) { + err := s.fillStakingDataForNonEligible(validatorsInfoMap) + if err != nil { + return 0, err } + return s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) +} + +func (s *systemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byte) error { sw := core.NewStopWatch() sw.Start("prepareStakingDataForRewards") defer func() { @@ -734,7 +743,7 @@ func (s *systemSCProcessor) prepareStakingData(validatorsInfoMap map[uint32][]*s log.Debug("systemSCProcessor.prepareStakingDataForRewards time measurements", sw.GetMeasurements()...) }() - return s.stakingDataProvider.PrepareStakingData(nodes) + return s.stakingDataProvider.PrepareStakingData(nodeKeys) } func (s *systemSCProcessor) getEligibleNodeKeys( diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 2ceaaa62a26..2eef8b33d87 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1905,13 +1905,13 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) addKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) + validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ @@ -1931,7 +1931,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), }, } - require.Equal(t, expectedValidatorsInfo, validatorInfos) + require.Equal(t, expectedValidatorsInfo, validatorsInfo) } func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepareStakingData(t *testing.T) { @@ -1950,14 +1950,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) + validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Equal(t, errProcessStakingData, err) } @@ -1965,6 +1965,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 1}} errGetNodeTopUp := errors.New("error getting top up per node") args.StakingDataProvider = &mock.StakingDataProviderStub{ @@ -1983,19 +1984,53 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) + validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Error(t, err) require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) } +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForAuctionNodes(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 1}} + + owner1 := []byte("owner1") + owner2 := []byte("owner2") + + owner1StakedKeys := [][]byte{[]byte("pubKey0")} + owner2StakedKeys := [][]byte{[]byte("pubKey1")} + + registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) + registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) + + validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1)) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2)) + + s, _ := NewSystemSCProcessor(args) + s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + require.Nil(t, err) + + expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1), + createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo) +} + func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() @@ -2017,24 +2052,24 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1)) - validatorInfos[0] = append(validatorInfos[0], createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1)) + validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1)) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1)) + validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4)) - validatorInfos[1] = append(validatorInfos[1], createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4)) + validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{PrevRandSeed: []byte("pubKey7")}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("pubKey7")}) require.Nil(t, err) /* @@ -2086,7 +2121,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing createValidatorInfo(owner4StakedKeys[1], common.NewList, owner4), }, } - require.Equal(t, expectedValidatorsInfo, validatorInfos) + require.Equal(t, expectedValidatorsInfo, validatorsInfo) } func registerValidatorKeys( From bc5259a54d7150ac76ef9607786c81aae1d2e4f3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 4 Mar 2022 11:41:20 +0200 Subject: [PATCH 079/958] FIX: Merge conflict --- genesis/process/shardGenesisBlockCreator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index e2852b97e2a..54c4c67a659 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -12,6 +12,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data/block" dataBlock "github.com/ElrondNetwork/elrond-go-core/data/block" logger "github.com/ElrondNetwork/elrond-go-logger" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/genesis" From 42b052801e2953c678617531c3bf2adc6d5b0234 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 4 Mar 2022 11:57:08 +0200 Subject: [PATCH 080/958] FIX: One review finding --- epochStart/metachain/systemSCs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index af43fdb138e..94f86a92630 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -426,7 +426,7 @@ func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, return compareByXORWithRandomness(pubKey1, pubKey2, randomness) } - return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 1 + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 }) return nil From 479692da2b7cecf2da3f52a2aa9c618ac105eb71 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 7 Mar 2022 12:38:41 +0200 Subject: [PATCH 081/958] FEAT: Add first version --- sharding/common.go | 5 +++++ sharding/hashValidatorShuffler.go | 27 ++++++++++++++++++++++--- sharding/indexHashedNodesCoordinator.go | 25 +++++++++++++++-------- sharding/interface.go | 2 ++ 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/sharding/common.go b/sharding/common.go index 5fa1a00b008..722d5896238 100644 --- a/sharding/common.go +++ b/sharding/common.go @@ -52,6 +52,7 @@ func displayNodesConfiguration( waiting map[uint32][]Validator, leaving map[uint32][]Validator, actualRemaining map[uint32][]Validator, + shuffledOut map[uint32][]Validator, nbShards uint32, ) { for shard := uint32(0); shard <= nbShards; shard++ { @@ -75,6 +76,10 @@ func displayNodesConfiguration( pk := v.PubKey() log.Debug("actually remaining", "pk", pk, "shardID", shardID) } + for _, v := range shuffledOut[shardID] { + pk := v.PubKey() + log.Debug("shuffled out", "pk", pk, "shardID", shardID) + } } } diff --git a/sharding/hashValidatorShuffler.go b/sharding/hashValidatorShuffler.go index 7409087a950..a23e13ef208 100644 --- a/sharding/hashValidatorShuffler.go +++ b/sharding/hashValidatorShuffler.go @@ -24,6 +24,7 @@ type NodesShufflerArgs struct { MaxNodesEnableConfig []config.MaxNodesChangeConfig BalanceWaitingListsEnableEpoch uint32 WaitingListFixEnableEpoch uint32 + StakingV4EnableEpoch uint32 } type shuffleNodesArg struct { @@ -32,6 +33,7 @@ type shuffleNodesArg struct { unstakeLeaving []Validator additionalLeaving []Validator newNodes []Validator + auction []Validator randomness []byte distributor ValidatorsDistributor nodesMeta uint32 @@ -40,6 +42,7 @@ type shuffleNodesArg struct { maxNodesToSwapPerShard uint32 flagBalanceWaitingLists bool flagWaitingListFix bool + flagStakingV4 bool } // TODO: Decide if transaction load statistics will be used for limiting the number of shards @@ -61,6 +64,8 @@ type randHashShuffler struct { flagBalanceWaitingLists atomic.Flag waitingListFixEnableEpoch uint32 flagWaitingListFix atomic.Flag + stakingV4EnableEpoch uint32 + flagStakingV4 atomic.Flag } // NewHashValidatorsShuffler creates a validator shuffler that uses a hash between validator key and a given @@ -85,10 +90,12 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro availableNodesConfigs: configs, balanceWaitingListsEnableEpoch: args.BalanceWaitingListsEnableEpoch, waitingListFixEnableEpoch: args.WaitingListFixEnableEpoch, + stakingV4EnableEpoch: args.StakingV4EnableEpoch, } log.Debug("randHashShuffler: enable epoch for balance waiting list", "epoch", rxs.balanceWaitingListsEnableEpoch) log.Debug("randHashShuffler: enable epoch for waiting waiting list", "epoch", rxs.waitingListFixEnableEpoch) + log.Debug("randHashShuffler: enable epoch for staking v4", "epoch", rxs.stakingV4EnableEpoch) rxs.UpdateParams(args.NodesShard, args.NodesMeta, args.Hysteresis, args.Adaptivity) @@ -176,6 +183,7 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo unstakeLeaving: args.UnStakeLeaving, additionalLeaving: args.AdditionalLeaving, newNodes: args.NewNodes, + auction: args.Auction, randomness: args.Rand, nodesMeta: nodesMeta, nodesPerShard: nodesPerShard, @@ -184,6 +192,7 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), flagWaitingListFix: rhs.flagWaitingListFix.IsSet(), + flagStakingV4: rhs.flagStakingV4.IsSet(), }) } @@ -288,9 +297,16 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) - if err != nil { - log.Warn("distributeValidators shuffledOut failed", "error", err) + if arg.flagStakingV4 { + err = distributeValidators(newWaiting, arg.auction, arg.randomness, arg.flagBalanceWaitingLists) + if err != nil { + log.Warn("distributeValidators auction list failed", "error", err) + } + } else { + err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) + if err != nil { + log.Warn("distributeValidators shuffledOut failed", "error", err) + } } actualLeaving, _ := removeValidatorsFromList(allLeaving, stillRemainingInLeaving, len(stillRemainingInLeaving)) @@ -298,6 +314,7 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { return &ResUpdateNodes{ Eligible: newEligible, Waiting: newWaiting, + ShuffledOut: shuffledOutMap, Leaving: actualLeaving, StillRemaining: stillRemainingInLeaving, }, nil @@ -779,8 +796,12 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { rhs.flagBalanceWaitingLists.SetValue(epoch >= rhs.balanceWaitingListsEnableEpoch) log.Debug("balanced waiting lists", "enabled", rhs.flagBalanceWaitingLists.IsSet()) + rhs.flagWaitingListFix.SetValue(epoch >= rhs.waitingListFixEnableEpoch) log.Debug("waiting list fix", "enabled", rhs.flagWaitingListFix.IsSet()) + + rhs.flagStakingV4.SetValue(epoch >= rhs.stakingV4EnableEpoch) + log.Debug("staking v4", "enabled", rhs.flagStakingV4.IsSet()) } func (rhs *randHashShuffler) sortConfigs() { diff --git a/sharding/indexHashedNodesCoordinator.go b/sharding/indexHashedNodesCoordinator.go index 3b27d4d1253..6047d82b47f 100644 --- a/sharding/indexHashedNodesCoordinator.go +++ b/sharding/indexHashedNodesCoordinator.go @@ -56,14 +56,16 @@ func (v validatorList) Less(i, j int) bool { // TODO: add a parameter for shardID when acting as observer type epochNodesConfig struct { - nbShards uint32 - shardID uint32 - eligibleMap map[uint32][]Validator - waitingMap map[uint32][]Validator - selectors map[uint32]RandomSelector - leavingMap map[uint32][]Validator - newList []Validator - mutNodesMaps sync.RWMutex + nbShards uint32 + shardID uint32 + eligibleMap map[uint32][]Validator + waitingMap map[uint32][]Validator + selectors map[uint32]RandomSelector + leavingMap map[uint32][]Validator + shuffledOutMap map[uint32][]Validator + newList []Validator + auctionList []Validator + mutNodesMaps sync.RWMutex } type indexHashedNodesCoordinator struct { @@ -170,6 +172,7 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed currentConfig.waitingMap, currentConfig.leavingMap, make(map[uint32][]Validator), + currentConfig.shuffledOutMap, currentConfig.nbShards) ihgs.epochStartRegistrationHandler.RegisterHandler(ihgs) @@ -607,6 +610,7 @@ func (ihgs *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa Eligible: newNodesConfig.eligibleMap, Waiting: newNodesConfig.waitingMap, NewNodes: newNodesConfig.newList, + Auction: newNodesConfig.auctionList, UnStakeLeaving: unStakeLeavingList, AdditionalLeaving: additionalLeavingList, Rand: randomness, @@ -642,6 +646,7 @@ func (ihgs *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa resUpdateNodes.Waiting, leavingNodesMap, stillRemainingNodesMap, + resUpdateNodes.ShuffledOut, newNodesConfig.nbShards) ihgs.mutSavedStateKey.Lock() @@ -702,6 +707,7 @@ func (ihgs *indexHashedNodesCoordinator) computeNodesConfigFromList( waitingMap := make(map[uint32][]Validator) leavingMap := make(map[uint32][]Validator) newNodesList := make([]Validator, 0) + auctionList := make([]Validator, 0) if ihgs.flagWaitingListFix.IsSet() && previousEpochConfig == nil { return nil, ErrNilPreviousEpochConfig @@ -739,6 +745,8 @@ func (ihgs *indexHashedNodesCoordinator) computeNodesConfigFromList( log.Debug("inactive validator", "pk", validatorInfo.PublicKey) case string(common.JailedList): log.Debug("jailed validator", "pk", validatorInfo.PublicKey) + case string(common.AuctionList): + auctionList = append(auctionList, currentValidator) } } @@ -764,6 +772,7 @@ func (ihgs *indexHashedNodesCoordinator) computeNodesConfigFromList( waitingMap: waitingMap, leavingMap: leavingMap, newList: newNodesList, + auctionList: auctionList, nbShards: uint32(nbShards), } diff --git a/sharding/interface.go b/sharding/interface.go index e18557b3e12..20a22bea95e 100644 --- a/sharding/interface.go +++ b/sharding/interface.go @@ -72,6 +72,7 @@ type ArgsUpdateNodes struct { NewNodes []Validator UnStakeLeaving []Validator AdditionalLeaving []Validator + Auction []Validator Rand []byte NbShards uint32 Epoch uint32 @@ -81,6 +82,7 @@ type ArgsUpdateNodes struct { type ResUpdateNodes struct { Eligible map[uint32][]Validator Waiting map[uint32][]Validator + ShuffledOut map[uint32][]Validator Leaving []Validator StillRemaining []Validator } From 8c1ed21e136b01a12893cc43a86ea7c69a5db230 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 7 Mar 2022 15:06:02 +0200 Subject: [PATCH 082/958] FEAT: ihnc with auction --- ...shedNodesCoordinatorRegistryWithAuction.go | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 sharding/indexHashedNodesCoordinatorRegistryWithAuction.go diff --git a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go new file mode 100644 index 00000000000..86b3a54c901 --- /dev/null +++ b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go @@ -0,0 +1,70 @@ +package sharding + +import "fmt" + +// EpochValidatorsWithAuction holds one epoch configuration for a nodes coordinator +type EpochValidatorsWithAuction struct { + *EpochValidators + AuctionValidators []*SerializableValidator `json:"auctionValidators"` +} + +// NodesCoordinatorRegistryWithAuction holds the data that can be used to initialize a nodes coordinator +type NodesCoordinatorRegistryWithAuction struct { + EpochsConfig map[string]*EpochValidatorsWithAuction `json:"epochConfigs"` + CurrentEpoch uint32 `json:"currentEpoch"` +} + +// NodesCoordinatorToRegistryWithAuction will export the nodesCoordinator data to the registry which contains auction list +func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistryWithAuction() *NodesCoordinatorRegistryWithAuction { + ihgs.mutNodesConfig.RLock() + defer ihgs.mutNodesConfig.RUnlock() + + registry := &NodesCoordinatorRegistryWithAuction{ + CurrentEpoch: ihgs.currentEpoch, + EpochsConfig: make(map[string]*EpochValidatorsWithAuction), + } + + minEpoch := 0 + lastEpoch := ihgs.getLastEpochConfig() + if lastEpoch >= nodesCoordinatorStoredEpochs { + minEpoch = int(lastEpoch) - nodesCoordinatorStoredEpochs + 1 + } + + for epoch := uint32(minEpoch); epoch <= lastEpoch; epoch++ { + epochNodesData, ok := ihgs.nodesConfig[epoch] + if !ok { + continue + } + + registry.EpochsConfig[fmt.Sprint(epoch)] = epochNodesConfigToEpochValidatorsWithAuction(epochNodesData) + } + + return registry +} + +func epochNodesConfigToEpochValidatorsWithAuction(config *epochNodesConfig) *EpochValidatorsWithAuction { + result := &EpochValidatorsWithAuction{ + EpochValidators: &EpochValidators{ + EligibleValidators: make(map[string][]*SerializableValidator, len(config.eligibleMap)), + WaitingValidators: make(map[string][]*SerializableValidator, len(config.waitingMap)), + LeavingValidators: make(map[string][]*SerializableValidator, len(config.leavingMap)), + }, + AuctionValidators: make([]*SerializableValidator, len(config.auctionList)), + } + + for k, v := range config.eligibleMap { + result.EligibleValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) + } + + for k, v := range config.waitingMap { + result.WaitingValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) + } + + for k, v := range config.leavingMap { + result.LeavingValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) + } + + result.AuctionValidators = ValidatorArrayToSerializableValidatorArray(config.auctionList) + + return result +} From d87f0635ce750c89ad8f59fd8988af09efa5e5e8 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 7 Mar 2022 16:04:49 +0200 Subject: [PATCH 083/958] FEAT: Use flag to save with auction list --- sharding/hashValidatorShuffler.go | 2 +- sharding/hashValidatorShuffler_test.go | 5 ++++ sharding/indexHashedNodesCoordinator.go | 23 +++++++++++++------ .../indexHashedNodesCoordinatorRegistry.go | 7 +++++- sharding/shardingArgs.go | 1 + 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/sharding/hashValidatorShuffler.go b/sharding/hashValidatorShuffler.go index a23e13ef208..0c47cb4bc9a 100644 --- a/sharding/hashValidatorShuffler.go +++ b/sharding/hashValidatorShuffler.go @@ -298,7 +298,7 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { } if arg.flagStakingV4 { - err = distributeValidators(newWaiting, arg.auction, arg.randomness, arg.flagBalanceWaitingLists) + err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) if err != nil { log.Warn("distributeValidators auction list failed", "error", err) } diff --git a/sharding/hashValidatorShuffler_test.go b/sharding/hashValidatorShuffler_test.go index dcf1ef6f650..f86b5177039 100644 --- a/sharding/hashValidatorShuffler_test.go +++ b/sharding/hashValidatorShuffler_test.go @@ -192,6 +192,7 @@ func createHashShufflerInter() (*randHashShuffler, error) { Adaptivity: adaptivity, ShuffleBetweenShards: true, MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -207,6 +208,7 @@ func createHashShufflerIntraShards() (*randHashShuffler, error) { Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1190,6 +1192,7 @@ func TestRandHashShuffler_UpdateParams(t *testing.T) { shuffleBetweenShards: true, validatorDistributor: &CrossShardValidatorDistributor{}, availableNodesConfigs: nil, + stakingV4EnableEpoch: 444, } shuffler.UpdateParams( @@ -2379,6 +2382,7 @@ func TestRandHashShuffler_UpdateNodeLists_All(t *testing.T) { Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) @@ -2672,6 +2676,7 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) diff --git a/sharding/indexHashedNodesCoordinator.go b/sharding/indexHashedNodesCoordinator.go index 09985a09525..3dde46becd3 100644 --- a/sharding/indexHashedNodesCoordinator.go +++ b/sharding/indexHashedNodesCoordinator.go @@ -91,9 +91,11 @@ type indexHashedNodesCoordinator struct { startEpoch uint32 publicKeyToValidatorMap map[string]*validatorWithShardID waitingListFixEnableEpoch uint32 + stakingV4EnableEpoch uint32 isFullArchive bool chanStopNode chan endProcess.ArgEndProcess flagWaitingListFix atomicFlags.Flag + flagStakingV4 atomicFlags.Flag nodeTypeProvider NodeTypeProviderHandler } @@ -107,13 +109,15 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed nodesConfig := make(map[uint32]*epochNodesConfig, nodesCoordinatorStoredEpochs) nodesConfig[arguments.Epoch] = &epochNodesConfig{ - nbShards: arguments.NbShards, - shardID: arguments.ShardIDAsObserver, - eligibleMap: make(map[uint32][]Validator), - waitingMap: make(map[uint32][]Validator), - selectors: make(map[uint32]RandomSelector), - leavingMap: make(map[uint32][]Validator), - newList: make([]Validator, 0), + nbShards: arguments.NbShards, + shardID: arguments.ShardIDAsObserver, + eligibleMap: make(map[uint32][]Validator), + waitingMap: make(map[uint32][]Validator), + selectors: make(map[uint32]RandomSelector), + leavingMap: make(map[uint32][]Validator), + shuffledOutMap: make(map[uint32][]Validator), + newList: make([]Validator, 0), + auctionList: make([]Validator, 0), } savedKey := arguments.Hasher.Compute(string(arguments.SelfPublicKey)) @@ -136,11 +140,13 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed startEpoch: arguments.StartEpoch, publicKeyToValidatorMap: make(map[string]*validatorWithShardID), waitingListFixEnableEpoch: arguments.WaitingListFixEnabledEpoch, + stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, chanStopNode: arguments.ChanStopNode, nodeTypeProvider: arguments.NodeTypeProvider, isFullArchive: arguments.IsFullArchive, } log.Debug("indexHashedNodesCoordinator: enable epoch for waiting waiting list", "epoch", ihgs.waitingListFixEnableEpoch) + log.Debug("indexHashedNodesCoordinator: staking v4", "epoch", ihgs.stakingV4EnableEpoch) ihgs.loadingFromDisk.Store(false) @@ -1204,4 +1210,7 @@ func createValidatorInfoFromBody( func (ihgs *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { ihgs.flagWaitingListFix.SetValue(epoch >= ihgs.waitingListFixEnableEpoch) log.Debug("indexHashedNodesCoordinator: waiting list fix", "enabled", ihgs.flagWaitingListFix.IsSet()) + + ihgs.flagStakingV4.SetValue(epoch >= ihgs.stakingV4EnableEpoch) + log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihgs.flagStakingV4.IsSet()) } diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index bd5b63a2b0a..62ccf37527c 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -84,7 +84,12 @@ func displayNodesConfigInfo(config map[uint32]*epochNodesConfig) { } func (ihgs *indexHashedNodesCoordinator) saveState(key []byte) error { - registry := ihgs.NodesCoordinatorToRegistry() + var registry interface{} + if ihgs.flagStakingV4.IsSet() { + registry = ihgs.NodesCoordinatorToRegistryWithAuction() + } else { + registry = ihgs.NodesCoordinatorToRegistry() + } data, err := json.Marshal(registry) if err != nil { return err diff --git a/sharding/shardingArgs.go b/sharding/shardingArgs.go index bc6aa2f8554..ebc222d7f47 100644 --- a/sharding/shardingArgs.go +++ b/sharding/shardingArgs.go @@ -29,4 +29,5 @@ type ArgNodesCoordinator struct { ChanStopNode chan endProcess.ArgEndProcess NodeTypeProvider NodeTypeProviderHandler IsFullArchive bool + StakingV4EnableEpoch uint32 } From fe9db50f1b85a842a8df374d9f2892b48b40fb82 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 09:03:05 +0200 Subject: [PATCH 084/958] FEAT: Use interface instead of *NodesCoordinatorRegistry --- epochStart/bootstrap/baseStorageHandler.go | 2 +- epochStart/bootstrap/fromLocalStorage.go | 10 +-- epochStart/bootstrap/interface.go | 4 +- epochStart/bootstrap/process.go | 6 +- epochStart/bootstrap/shardStorageHandler.go | 2 +- epochStart/bootstrap/syncValidatorStatus.go | 6 +- epochStart/mock/nodesCoordinatorStub.go | 4 +- factory/bootstrapParameters.go | 2 +- factory/interface.go | 2 +- .../indexHashedNodesCoordinatorRegistry.go | 64 ++++++++++++++++++- ...shedNodesCoordinatorRegistryWithAuction.go | 10 +-- .../bootstrapMocks/bootstrapParamsStub.go | 4 +- 12 files changed, 90 insertions(+), 26 deletions(-) diff --git a/epochStart/bootstrap/baseStorageHandler.go b/epochStart/bootstrap/baseStorageHandler.go index 352cfc10df3..8c0797d49d5 100644 --- a/epochStart/bootstrap/baseStorageHandler.go +++ b/epochStart/bootstrap/baseStorageHandler.go @@ -45,7 +45,7 @@ func (bsh *baseStorageHandler) groupMiniBlocksByShard(miniBlocks map[string]*blo func (bsh *baseStorageHandler) saveNodesCoordinatorRegistry( metaBlock data.HeaderHandler, - nodesConfig *sharding.NodesCoordinatorRegistry, + nodesConfig sharding.NodesCoordinatorRegistryHandler, ) ([]byte, error) { key := append([]byte(common.NodesCoordinatorRegistryKeyPrefix), metaBlock.GetPrevRandSeed()...) diff --git a/epochStart/bootstrap/fromLocalStorage.go b/epochStart/bootstrap/fromLocalStorage.go index daff6dc7f77..89cf93e7e29 100644 --- a/epochStart/bootstrap/fromLocalStorage.go +++ b/epochStart/bootstrap/fromLocalStorage.go @@ -191,19 +191,19 @@ func (e *epochStartBootstrap) prepareEpochFromStorage() (Parameters, error) { func (e *epochStartBootstrap) checkIfShuffledOut( pubKey []byte, - nodesConfig *sharding.NodesCoordinatorRegistry, + nodesConfig sharding.NodesCoordinatorRegistryHandler, ) (uint32, bool) { epochIDasString := fmt.Sprint(e.baseData.lastEpoch) - epochConfig := nodesConfig.EpochsConfig[epochIDasString] + epochConfig := nodesConfig.GetEpochsConfig()[epochIDasString] - newShardId, isWaitingForShard := checkIfPubkeyIsInMap(pubKey, epochConfig.WaitingValidators) + newShardId, isWaitingForShard := checkIfPubkeyIsInMap(pubKey, epochConfig.GetWaitingValidators()) if isWaitingForShard { isShuffledOut := newShardId != e.baseData.shardId e.nodeType = core.NodeTypeValidator return newShardId, isShuffledOut } - newShardId, isEligibleForShard := checkIfPubkeyIsInMap(pubKey, epochConfig.EligibleValidators) + newShardId, isEligibleForShard := checkIfPubkeyIsInMap(pubKey, epochConfig.GetEligibleValidators()) if isEligibleForShard { isShuffledOut := newShardId != e.baseData.shardId e.nodeType = core.NodeTypeValidator @@ -244,7 +244,7 @@ func checkIfValidatorIsInList( return false } -func (e *epochStartBootstrap) getLastBootstrapData(storer storage.Storer) (*bootstrapStorage.BootstrapData, *sharding.NodesCoordinatorRegistry, error) { +func (e *epochStartBootstrap) getLastBootstrapData(storer storage.Storer) (*bootstrapStorage.BootstrapData, sharding.NodesCoordinatorRegistryHandler, error) { bootStorer, err := bootstrapStorage.NewBootstrapStorer(e.coreComponentsHolder.InternalMarshalizer(), storer) if err != nil { return nil, nil, err diff --git a/epochStart/bootstrap/interface.go b/epochStart/bootstrap/interface.go index 8884fc198ee..108a78a0087 100644 --- a/epochStart/bootstrap/interface.go +++ b/epochStart/bootstrap/interface.go @@ -12,7 +12,7 @@ import ( // StartOfEpochNodesConfigHandler defines the methods to process nodesConfig from epoch start metablocks type StartOfEpochNodesConfigHandler interface { - NodesConfigFromMetaBlock(currMetaBlock data.HeaderHandler, prevMetaBlock data.HeaderHandler) (*sharding.NodesCoordinatorRegistry, uint32, error) + NodesConfigFromMetaBlock(currMetaBlock data.HeaderHandler, prevMetaBlock data.HeaderHandler) (sharding.NodesCoordinatorRegistryHandler, uint32, error) IsInterfaceNil() bool } @@ -25,7 +25,7 @@ type EpochStartMetaBlockInterceptorProcessor interface { // StartInEpochNodesCoordinator defines the methods to process and save nodesCoordinator information to storage type StartInEpochNodesCoordinator interface { EpochStartPrepare(metaHdr data.HeaderHandler, body data.BodyHandler) - NodesCoordinatorToRegistry() *sharding.NodesCoordinatorRegistry + NodesCoordinatorToRegistry() sharding.NodesCoordinatorRegistryHandler ShardIdForEpoch(epoch uint32) (uint32, error) IsInterfaceNil() bool } diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index 611479fa894..f4893c83481 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -61,7 +61,7 @@ type Parameters struct { Epoch uint32 SelfShardId uint32 NumOfShards uint32 - NodesConfig *sharding.NodesCoordinatorRegistry + NodesConfig sharding.NodesCoordinatorRegistryHandler } // ComponentsNeededForBootstrap holds the components which need to be initialized from network @@ -69,7 +69,7 @@ type ComponentsNeededForBootstrap struct { EpochStartMetaBlock data.MetaHeaderHandler PreviousEpochStart data.MetaHeaderHandler ShardHeader data.HeaderHandler - NodesConfig *sharding.NodesCoordinatorRegistry + NodesConfig sharding.NodesCoordinatorRegistryHandler Headers map[string]data.HeaderHandler ShardCoordinator sharding.Coordinator PendingMiniBlocks map[string]*block.MiniBlock @@ -125,7 +125,7 @@ type epochStartBootstrap struct { epochStartMeta data.MetaHeaderHandler prevEpochStartMeta data.MetaHeaderHandler syncedHeaders map[string]data.HeaderHandler - nodesConfig *sharding.NodesCoordinatorRegistry + nodesConfig sharding.NodesCoordinatorRegistryHandler baseData baseDataInStorage startRound int64 nodeType core.NodeType diff --git a/epochStart/bootstrap/shardStorageHandler.go b/epochStart/bootstrap/shardStorageHandler.go index ddf2401b815..3f09e7b7e02 100644 --- a/epochStart/bootstrap/shardStorageHandler.go +++ b/epochStart/bootstrap/shardStorageHandler.go @@ -104,7 +104,7 @@ func (ssh *shardStorageHandler) SaveDataToStorage(components *ComponentsNeededFo return err } - components.NodesConfig.CurrentEpoch = components.ShardHeader.GetEpoch() + components.NodesConfig.SetCurrentEpoch(components.ShardHeader.GetEpoch()) nodesCoordinatorConfigKey, err := ssh.saveNodesCoordinatorRegistry(components.EpochStartMetaBlock, components.NodesConfig) if err != nil { return err diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index f499db21520..2568e4dc187 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -130,7 +130,7 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat func (s *syncValidatorStatus) NodesConfigFromMetaBlock( currMetaBlock data.HeaderHandler, prevMetaBlock data.HeaderHandler, -) (*sharding.NodesCoordinatorRegistry, uint32, error) { +) (sharding.NodesCoordinatorRegistryHandler, uint32, error) { if currMetaBlock.GetNonce() > 1 && !currMetaBlock.IsStartOfEpochBlock() { return nil, 0, epochStart.ErrNotEpochStartBlock } @@ -154,7 +154,7 @@ func (s *syncValidatorStatus) NodesConfigFromMetaBlock( } nodesConfig := s.nodeCoordinator.NodesCoordinatorToRegistry() - nodesConfig.CurrentEpoch = currMetaBlock.GetEpoch() + nodesConfig.SetCurrentEpoch(currMetaBlock.GetEpoch()) return nodesConfig, selfShardId, nil } @@ -176,7 +176,7 @@ func (s *syncValidatorStatus) processValidatorChangesFor(metaBlock data.HeaderHa func findPeerMiniBlockHeaders(metaBlock data.HeaderHandler) []data.MiniBlockHeaderHandler { shardMBHeaderHandlers := make([]data.MiniBlockHeaderHandler, 0) mbHeaderHandlers := metaBlock.GetMiniBlockHeaderHandlers() - for i, mbHeader := range mbHeaderHandlers{ + for i, mbHeader := range mbHeaderHandlers { if mbHeader.GetTypeInt32() != int32(block.PeerBlock) { continue } diff --git a/epochStart/mock/nodesCoordinatorStub.go b/epochStart/mock/nodesCoordinatorStub.go index 53f503069c9..b3a638fdde3 100644 --- a/epochStart/mock/nodesCoordinatorStub.go +++ b/epochStart/mock/nodesCoordinatorStub.go @@ -19,7 +19,7 @@ type NodesCoordinatorStub struct { } // NodesCoordinatorToRegistry - -func (ncm *NodesCoordinatorStub) NodesCoordinatorToRegistry() *sharding.NodesCoordinatorRegistry { +func (ncm *NodesCoordinatorStub) NodesCoordinatorToRegistry() sharding.NodesCoordinatorRegistryHandler { return nil } @@ -46,7 +46,7 @@ func (ncm *NodesCoordinatorStub) GetAllLeavingValidatorsPublicKeys(_ uint32) (ma } // SetConfig - -func (ncm *NodesCoordinatorStub) SetConfig(_ *sharding.NodesCoordinatorRegistry) error { +func (ncm *NodesCoordinatorStub) SetConfig(_ sharding.NodesCoordinatorRegistryHandler) error { return nil } diff --git a/factory/bootstrapParameters.go b/factory/bootstrapParameters.go index d110a895276..8571e6da4b9 100644 --- a/factory/bootstrapParameters.go +++ b/factory/bootstrapParameters.go @@ -25,7 +25,7 @@ func (bph *bootstrapParams) NumOfShards() uint32 { } // NodesConfig returns the nodes coordinator config after bootstrap -func (bph *bootstrapParams) NodesConfig() *sharding.NodesCoordinatorRegistry { +func (bph *bootstrapParams) NodesConfig() sharding.NodesCoordinatorRegistryHandler { return bph.bootstrapParams.NodesConfig } diff --git a/factory/interface.go b/factory/interface.go index 80acf820f60..04ff86d704b 100644 --- a/factory/interface.go +++ b/factory/interface.go @@ -404,7 +404,7 @@ type BootstrapParamsHolder interface { Epoch() uint32 SelfShardID() uint32 NumOfShards() uint32 - NodesConfig() *sharding.NodesCoordinatorRegistry + NodesConfig() sharding.NodesCoordinatorRegistryHandler IsInterfaceNil() bool } diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index 62ccf37527c..7a05ddce3d0 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -22,12 +22,74 @@ type EpochValidators struct { LeavingValidators map[string][]*SerializableValidator `json:"leavingValidators"` } +func (ev *EpochValidators) GetEligibleValidators() map[string][]*SerializableValidator { + return ev.EligibleValidators +} + +func (ev *EpochValidators) GetWaitingValidators() map[string][]*SerializableValidator { + return ev.WaitingValidators +} + +func (ev *EpochValidators) GetLeavingValidators() map[string][]*SerializableValidator { + return ev.LeavingValidators +} + // NodesCoordinatorRegistry holds the data that can be used to initialize a nodes coordinator type NodesCoordinatorRegistry struct { EpochsConfig map[string]*EpochValidators `json:"epochConfigs"` CurrentEpoch uint32 `json:"currentEpoch"` } +func (ncr *NodesCoordinatorRegistry) GetCurrentEpoch() uint32 { + return ncr.CurrentEpoch +} + +func (ncr *NodesCoordinatorRegistry) GetEpochsConfig() map[string]EpochValidatorsHandler { + ret := make(map[string]EpochValidatorsHandler) + for epoch, config := range ncr.EpochsConfig { + ret[epoch] = config + } + + return ret +} + +func (ncr *NodesCoordinatorRegistry) SetCurrentEpoch(epoch uint32) { + ncr.CurrentEpoch = epoch +} + +func (ncr *NodesCoordinatorRegistry) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { + ncr.EpochsConfig = make(map[string]*EpochValidators) + + for epoch, config := range epochsConfig { + ncr.EpochsConfig[epoch] = &EpochValidators{ + EligibleValidators: config.GetEligibleValidators(), + WaitingValidators: config.GetWaitingValidators(), + LeavingValidators: config.GetLeavingValidators(), + } + } +} + +// EpochValidatorsHandler defines what one epoch configuration for a nodes coordinator should hold +type EpochValidatorsHandler interface { + GetEligibleValidators() map[string][]*SerializableValidator + GetWaitingValidators() map[string][]*SerializableValidator + GetLeavingValidators() map[string][]*SerializableValidator +} + +type EpochValidatorsHandlerWithAuction interface { + EpochValidatorsHandler + GetShuffledOutValidators() map[string][]*SerializableValidator +} + +// NodesCoordinatorRegistryHandler defines that used to initialize nodes coordinator +type NodesCoordinatorRegistryHandler interface { + GetEpochsConfig() map[string]EpochValidatorsHandler + GetCurrentEpoch() uint32 + + SetCurrentEpoch(epoch uint32) + SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) +} + // TODO: add proto marshalizer for these package - replace all json marshalizers // LoadState loads the nodes coordinator state from the used boot storage @@ -103,7 +165,7 @@ func (ihgs *indexHashedNodesCoordinator) saveState(key []byte) error { } // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry -func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistry() *NodesCoordinatorRegistry { +func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistry() NodesCoordinatorRegistryHandler { ihgs.mutNodesConfig.RLock() defer ihgs.mutNodesConfig.RUnlock() diff --git a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go index 86b3a54c901..14538b348cd 100644 --- a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go +++ b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go @@ -5,7 +5,7 @@ import "fmt" // EpochValidatorsWithAuction holds one epoch configuration for a nodes coordinator type EpochValidatorsWithAuction struct { *EpochValidators - AuctionValidators []*SerializableValidator `json:"auctionValidators"` + ShuffledOutValidators map[string][]*SerializableValidator `json:"shuffledOutValidators"` } // NodesCoordinatorRegistryWithAuction holds the data that can be used to initialize a nodes coordinator @@ -23,7 +23,7 @@ func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistryWithAuction() CurrentEpoch: ihgs.currentEpoch, EpochsConfig: make(map[string]*EpochValidatorsWithAuction), } - + // todo: extract this into a common func with NodesCoordinatorToRegistry minEpoch := 0 lastEpoch := ihgs.getLastEpochConfig() if lastEpoch >= nodesCoordinatorStoredEpochs { @@ -49,7 +49,7 @@ func epochNodesConfigToEpochValidatorsWithAuction(config *epochNodesConfig) *Epo WaitingValidators: make(map[string][]*SerializableValidator, len(config.waitingMap)), LeavingValidators: make(map[string][]*SerializableValidator, len(config.leavingMap)), }, - AuctionValidators: make([]*SerializableValidator, len(config.auctionList)), + ShuffledOutValidators: make(map[string][]*SerializableValidator, len(config.shuffledOutMap)), } for k, v := range config.eligibleMap { @@ -64,7 +64,9 @@ func epochNodesConfigToEpochValidatorsWithAuction(config *epochNodesConfig) *Epo result.LeavingValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) } - result.AuctionValidators = ValidatorArrayToSerializableValidatorArray(config.auctionList) + for k, v := range config.leavingMap { + result.ShuffledOutValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) + } return result } diff --git a/testscommon/bootstrapMocks/bootstrapParamsStub.go b/testscommon/bootstrapMocks/bootstrapParamsStub.go index cdc6e6dfd39..9514528b37d 100644 --- a/testscommon/bootstrapMocks/bootstrapParamsStub.go +++ b/testscommon/bootstrapMocks/bootstrapParamsStub.go @@ -7,7 +7,7 @@ type BootstrapParamsHandlerMock struct { EpochCalled func() uint32 SelfShardIDCalled func() uint32 NumOfShardsCalled func() uint32 - NodesConfigCalled func() *sharding.NodesCoordinatorRegistry + NodesConfigCalled func() sharding.NodesCoordinatorRegistryHandler } // Epoch - @@ -36,7 +36,7 @@ func (bphm *BootstrapParamsHandlerMock) NumOfShards() uint32 { } // NodesConfig - -func (bphm *BootstrapParamsHandlerMock) NodesConfig() *sharding.NodesCoordinatorRegistry { +func (bphm *BootstrapParamsHandlerMock) NodesConfig() sharding.NodesCoordinatorRegistryHandler { if bphm.NodesConfigCalled != nil { return bphm.NodesConfigCalled() } From 34b4f0173d2306cedc530166560148f2c95b53c4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 09:06:55 +0200 Subject: [PATCH 085/958] FIX: Build --- factory/shardingFactory.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/factory/shardingFactory.go b/factory/shardingFactory.go index 08c162bfb58..f122e127a33 100644 --- a/factory/shardingFactory.go +++ b/factory/shardingFactory.go @@ -141,15 +141,15 @@ func CreateNodesCoordinator( if bootstrapParameters.NodesConfig() != nil { nodeRegistry := bootstrapParameters.NodesConfig() currentEpoch = bootstrapParameters.Epoch() - epochsConfig, ok := nodeRegistry.EpochsConfig[fmt.Sprintf("%d", currentEpoch)] + epochsConfig, ok := nodeRegistry.GetEpochsConfig()[fmt.Sprintf("%d", currentEpoch)] if ok { - eligibles := epochsConfig.EligibleValidators + eligibles := epochsConfig.GetEligibleValidators() eligibleValidators, err = sharding.SerializableValidatorsToValidators(eligibles) if err != nil { return nil, err } - waitings := epochsConfig.WaitingValidators + waitings := epochsConfig.GetWaitingValidators() waitingValidators, err = sharding.SerializableValidatorsToValidators(waitings) if err != nil { return nil, err From 96640504fd6f21c4e04afc5bd9a153eaf107004a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 09:10:55 +0200 Subject: [PATCH 086/958] FIX: Build 2 --- node/nodeRunner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index e9a1a77a3f7..a7ee2c5dcf2 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -797,7 +797,7 @@ func (nr *nodeRunner) logInformation( log.Info("Bootstrap", "epoch", bootstrapComponents.EpochBootstrapParams().Epoch()) if bootstrapComponents.EpochBootstrapParams().NodesConfig() != nil { log.Info("the epoch from nodesConfig is", - "epoch", bootstrapComponents.EpochBootstrapParams().NodesConfig().CurrentEpoch) + "epoch", bootstrapComponents.EpochBootstrapParams().NodesConfig().GetCurrentEpoch()) } var shardIdString = core.GetShardIDString(bootstrapComponents.ShardCoordinator().SelfId()) From 54087d93faf17797a1b8e8ca0cd499d6dca29bd8 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 11:11:41 +0200 Subject: [PATCH 087/958] FEAT: Refactor LoadState to use interface --- sharding/indexHashedNodesCoordinator.go | 12 ++++ .../indexHashedNodesCoordinatorRegistry.go | 64 ++++++++++++------- ...shedNodesCoordinatorRegistryWithAuction.go | 54 ++++++++++------ ...ndexHashedNodesCoordinatorRegistry_test.go | 18 +++--- 4 files changed, 98 insertions(+), 50 deletions(-) diff --git a/sharding/indexHashedNodesCoordinator.go b/sharding/indexHashedNodesCoordinator.go index 3dde46becd3..4733da87bdc 100644 --- a/sharding/indexHashedNodesCoordinator.go +++ b/sharding/indexHashedNodesCoordinator.go @@ -1029,6 +1029,18 @@ func (ihgs *indexHashedNodesCoordinator) computeShardForSelfPublicKey(nodesConfi return shardId, true } + if ihgs.flagStakingV4.IsSet() { + found, shardId = searchInMap(nodesConfig.shuffledOutMap, pubKey) + if found { + log.Trace("computeShardForSelfPublicKey found validator in shuffled out", + "epoch", ihgs.currentEpoch, + "shard", shardId, + "validator PK", pubKey, + ) + return shardId, true + } + } + log.Trace("computeShardForSelfPublicKey returned default", "shard", selfShard, ) diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index 7a05ddce3d0..723e025f7ed 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -110,18 +110,27 @@ func (ihgs *indexHashedNodesCoordinator) baseLoadState(key []byte) error { return err } - config := &NodesCoordinatorRegistry{} - err = json.Unmarshal(data, config) - if err != nil { - return err + var config NodesCoordinatorRegistryHandler + if ihgs.flagStakingV4.IsSet() { + config = &NodesCoordinatorRegistryWithAuction{} + err = json.Unmarshal(data, config) + if err != nil { + return err + } + } else { + config = &NodesCoordinatorRegistry{} + err = json.Unmarshal(data, config) + if err != nil { + return err + } } ihgs.mutSavedStateKey.Lock() ihgs.savedStateKey = key ihgs.mutSavedStateKey.Unlock() - ihgs.currentEpoch = config.CurrentEpoch - log.Debug("loaded nodes config", "current epoch", config.CurrentEpoch) + ihgs.currentEpoch = config.GetCurrentEpoch() + log.Debug("loaded nodes config", "current epoch", config.GetCurrentEpoch()) nodesConfig, err := ihgs.registryToNodesCoordinator(config) if err != nil { @@ -146,26 +155,29 @@ func displayNodesConfigInfo(config map[uint32]*epochNodesConfig) { } func (ihgs *indexHashedNodesCoordinator) saveState(key []byte) error { - var registry interface{} - if ihgs.flagStakingV4.IsSet() { - registry = ihgs.NodesCoordinatorToRegistryWithAuction() - } else { - registry = ihgs.NodesCoordinatorToRegistry() - } - data, err := json.Marshal(registry) + registry := ihgs.NodesCoordinatorToRegistry() + data, err := json.Marshal(registry) // TODO: Choose different marshaller depending on registry if err != nil { return err } - ncInternalkey := append([]byte(common.NodesCoordinatorRegistryKeyPrefix), key...) + ncInternalKey := append([]byte(common.NodesCoordinatorRegistryKeyPrefix), key...) - log.Debug("saving nodes coordinator config", "key", ncInternalkey) + log.Debug("saving nodes coordinator config", "key", ncInternalKey) - return ihgs.bootStorer.Put(ncInternalkey, data) + return ihgs.bootStorer.Put(ncInternalKey, data) } // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistry() NodesCoordinatorRegistryHandler { + if ihgs.flagStakingV4.IsSet() { + return ihgs.nodesCoordinatorToRegistryWithAuction() + } + + return ihgs.nodesCoordinatorToOldRegistry() +} + +func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToOldRegistry() NodesCoordinatorRegistryHandler { ihgs.mutNodesConfig.RLock() defer ihgs.mutNodesConfig.RUnlock() @@ -204,13 +216,13 @@ func (ihgs *indexHashedNodesCoordinator) getLastEpochConfig() uint32 { } func (ihgs *indexHashedNodesCoordinator) registryToNodesCoordinator( - config *NodesCoordinatorRegistry, + config NodesCoordinatorRegistryHandler, ) (map[uint32]*epochNodesConfig, error) { var err error var epoch int64 result := make(map[uint32]*epochNodesConfig) - for epochStr, epochValidators := range config.EpochsConfig { + for epochStr, epochValidators := range config.GetEpochsConfig() { epoch, err = strconv.ParseInt(epochStr, 10, 64) if err != nil { return nil, err @@ -264,25 +276,33 @@ func epochNodesConfigToEpochValidators(config *epochNodesConfig) *EpochValidator return result } -func epochValidatorsToEpochNodesConfig(config *EpochValidators) (*epochNodesConfig, error) { +func epochValidatorsToEpochNodesConfig(config EpochValidatorsHandler) (*epochNodesConfig, error) { result := &epochNodesConfig{} var err error - result.eligibleMap, err = serializableValidatorsMapToValidatorsMap(config.EligibleValidators) + result.eligibleMap, err = serializableValidatorsMapToValidatorsMap(config.GetEligibleValidators()) if err != nil { return nil, err } - result.waitingMap, err = serializableValidatorsMapToValidatorsMap(config.WaitingValidators) + result.waitingMap, err = serializableValidatorsMapToValidatorsMap(config.GetWaitingValidators()) if err != nil { return nil, err } - result.leavingMap, err = serializableValidatorsMapToValidatorsMap(config.LeavingValidators) + result.leavingMap, err = serializableValidatorsMapToValidatorsMap(config.GetLeavingValidators()) if err != nil { return nil, err } + configWithAuction, castOk := config.(EpochValidatorsHandlerWithAuction) + if castOk { + result.shuffledOutMap, err = serializableValidatorsMapToValidatorsMap(configWithAuction.GetShuffledOutValidators()) + if err != nil { + return nil, err + } + } + return result, nil } diff --git a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go index 14538b348cd..289fb089483 100644 --- a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go +++ b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go @@ -14,8 +14,40 @@ type NodesCoordinatorRegistryWithAuction struct { CurrentEpoch uint32 `json:"currentEpoch"` } -// NodesCoordinatorToRegistryWithAuction will export the nodesCoordinator data to the registry which contains auction list -func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistryWithAuction() *NodesCoordinatorRegistryWithAuction { +func (ncr *NodesCoordinatorRegistryWithAuction) GetCurrentEpoch() uint32 { + return ncr.CurrentEpoch +} + +func (ncr *NodesCoordinatorRegistryWithAuction) GetEpochsConfig() map[string]EpochValidatorsHandler { + ret := make(map[string]EpochValidatorsHandler) + for epoch, config := range ncr.EpochsConfig { + ret[epoch] = config + } + + return ret +} + +func (ncr *NodesCoordinatorRegistryWithAuction) SetCurrentEpoch(epoch uint32) { + ncr.CurrentEpoch = epoch +} + +func (ncr *NodesCoordinatorRegistryWithAuction) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { + ncr.EpochsConfig = make(map[string]*EpochValidatorsWithAuction) + + for epoch, config := range epochsConfig { + ncr.EpochsConfig[epoch] = &EpochValidatorsWithAuction{ + EpochValidators: &EpochValidators{ + EligibleValidators: config.GetEligibleValidators(), + WaitingValidators: config.GetWaitingValidators(), + LeavingValidators: config.GetLeavingValidators(), + }, + ShuffledOutValidators: nil, + } + } +} + +// nodesCoordinatorToRegistryWithAuction will export the nodesCoordinator data to the registry which contains auction list +func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() *NodesCoordinatorRegistryWithAuction { ihgs.mutNodesConfig.RLock() defer ihgs.mutNodesConfig.RUnlock() @@ -44,26 +76,10 @@ func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistryWithAuction() func epochNodesConfigToEpochValidatorsWithAuction(config *epochNodesConfig) *EpochValidatorsWithAuction { result := &EpochValidatorsWithAuction{ - EpochValidators: &EpochValidators{ - EligibleValidators: make(map[string][]*SerializableValidator, len(config.eligibleMap)), - WaitingValidators: make(map[string][]*SerializableValidator, len(config.waitingMap)), - LeavingValidators: make(map[string][]*SerializableValidator, len(config.leavingMap)), - }, + EpochValidators: epochNodesConfigToEpochValidators(config), ShuffledOutValidators: make(map[string][]*SerializableValidator, len(config.shuffledOutMap)), } - for k, v := range config.eligibleMap { - result.EligibleValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) - } - - for k, v := range config.waitingMap { - result.WaitingValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) - } - - for k, v := range config.leavingMap { - result.LeavingValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) - } - for k, v := range config.leavingMap { result.ShuffledOutValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) } diff --git a/sharding/indexHashedNodesCoordinatorRegistry_test.go b/sharding/indexHashedNodesCoordinatorRegistry_test.go index a765e5e0144..b106071ab59 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/indexHashedNodesCoordinatorRegistry_test.go @@ -101,12 +101,12 @@ func TestIndexHashedNodesCooridinator_nodesCoordinatorToRegistry(t *testing.T) { ncr := nodesCoordinator.NodesCoordinatorToRegistry() nc := nodesCoordinator.nodesConfig - assert.Equal(t, nodesCoordinator.currentEpoch, ncr.CurrentEpoch) - assert.Equal(t, len(nodesCoordinator.nodesConfig), len(ncr.EpochsConfig)) + assert.Equal(t, nodesCoordinator.currentEpoch, ncr.GetCurrentEpoch()) + assert.Equal(t, len(nodesCoordinator.nodesConfig), len(ncr.GetEpochsConfig())) for epoch, config := range nc { - assert.True(t, sameValidatorsDifferentMapTypes(config.eligibleMap, ncr.EpochsConfig[fmt.Sprint(epoch)].EligibleValidators)) - assert.True(t, sameValidatorsDifferentMapTypes(config.waitingMap, ncr.EpochsConfig[fmt.Sprint(epoch)].WaitingValidators)) + assert.True(t, sameValidatorsDifferentMapTypes(config.eligibleMap, ncr.GetEpochsConfig()[fmt.Sprint(epoch)].GetEligibleValidators())) + assert.True(t, sameValidatorsDifferentMapTypes(config.waitingMap, ncr.GetEpochsConfig()[fmt.Sprint(epoch)].GetWaitingValidators())) } } @@ -150,14 +150,14 @@ func TestIndexHashedNodesCooridinator_nodesCoordinatorToRegistryLimitNumEpochsIn ncr := nodesCoordinator.NodesCoordinatorToRegistry() nc := nodesCoordinator.nodesConfig - require.Equal(t, nodesCoordinator.currentEpoch, ncr.CurrentEpoch) - require.Equal(t, nodesCoordinatorStoredEpochs, len(ncr.EpochsConfig)) + require.Equal(t, nodesCoordinator.currentEpoch, ncr.GetCurrentEpoch()) + require.Equal(t, nodesCoordinatorStoredEpochs, len(ncr.GetEpochsConfig())) - for epochStr := range ncr.EpochsConfig { + for epochStr := range ncr.GetEpochsConfig() { epoch, err := strconv.Atoi(epochStr) require.Nil(t, err) - require.True(t, sameValidatorsDifferentMapTypes(nc[uint32(epoch)].eligibleMap, ncr.EpochsConfig[epochStr].EligibleValidators)) - require.True(t, sameValidatorsDifferentMapTypes(nc[uint32(epoch)].waitingMap, ncr.EpochsConfig[epochStr].WaitingValidators)) + require.True(t, sameValidatorsDifferentMapTypes(nc[uint32(epoch)].eligibleMap, ncr.GetEpochsConfig()[epochStr].GetEligibleValidators())) + require.True(t, sameValidatorsDifferentMapTypes(nc[uint32(epoch)].waitingMap, ncr.GetEpochsConfig()[epochStr].GetWaitingValidators())) } } From 55e09b3473196ef232aa35f1fae24c2b7b7a9aa1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 14:11:55 +0200 Subject: [PATCH 088/958] FEAT: Use proto structs --- .../indexHashedNodesCoordinatorRegistry.go | 7 -- ...shedNodesCoordinatorRegistryWithAuction.go | 70 ++++++------------- sharding/indexHashedNodesCoordinator_test.go | 2 + .../nodesCoordinatorRegistryWithAuction.go | 70 +++++++++++++++++++ .../nodesCoordinatorRegistryWithAuction.proto | 30 ++++++++ 5 files changed, 122 insertions(+), 57 deletions(-) create mode 100644 sharding/nodesCoordinatorRegistryWithAuction.go create mode 100644 sharding/nodesCoordinatorRegistryWithAuction.proto diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index 723e025f7ed..bf78271369e 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -8,13 +8,6 @@ import ( "github.com/ElrondNetwork/elrond-go/common" ) -// SerializableValidator holds the minimal data required for marshalling and un-marshalling a validator -type SerializableValidator struct { - PubKey []byte `json:"pubKey"` - Chances uint32 `json:"chances"` - Index uint32 `json:"index"` -} - // EpochValidators holds one epoch configuration for a nodes coordinator type EpochValidators struct { EligibleValidators map[string][]*SerializableValidator `json:"eligibleValidators"` diff --git a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go index 289fb089483..070ba003d86 100644 --- a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go +++ b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go @@ -2,58 +2,14 @@ package sharding import "fmt" -// EpochValidatorsWithAuction holds one epoch configuration for a nodes coordinator -type EpochValidatorsWithAuction struct { - *EpochValidators - ShuffledOutValidators map[string][]*SerializableValidator `json:"shuffledOutValidators"` -} - -// NodesCoordinatorRegistryWithAuction holds the data that can be used to initialize a nodes coordinator -type NodesCoordinatorRegistryWithAuction struct { - EpochsConfig map[string]*EpochValidatorsWithAuction `json:"epochConfigs"` - CurrentEpoch uint32 `json:"currentEpoch"` -} - -func (ncr *NodesCoordinatorRegistryWithAuction) GetCurrentEpoch() uint32 { - return ncr.CurrentEpoch -} - -func (ncr *NodesCoordinatorRegistryWithAuction) GetEpochsConfig() map[string]EpochValidatorsHandler { - ret := make(map[string]EpochValidatorsHandler) - for epoch, config := range ncr.EpochsConfig { - ret[epoch] = config - } - - return ret -} - -func (ncr *NodesCoordinatorRegistryWithAuction) SetCurrentEpoch(epoch uint32) { - ncr.CurrentEpoch = epoch -} - -func (ncr *NodesCoordinatorRegistryWithAuction) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { - ncr.EpochsConfig = make(map[string]*EpochValidatorsWithAuction) - - for epoch, config := range epochsConfig { - ncr.EpochsConfig[epoch] = &EpochValidatorsWithAuction{ - EpochValidators: &EpochValidators{ - EligibleValidators: config.GetEligibleValidators(), - WaitingValidators: config.GetWaitingValidators(), - LeavingValidators: config.GetLeavingValidators(), - }, - ShuffledOutValidators: nil, - } - } -} - // nodesCoordinatorToRegistryWithAuction will export the nodesCoordinator data to the registry which contains auction list func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() *NodesCoordinatorRegistryWithAuction { ihgs.mutNodesConfig.RLock() defer ihgs.mutNodesConfig.RUnlock() registry := &NodesCoordinatorRegistryWithAuction{ - CurrentEpoch: ihgs.currentEpoch, - EpochsConfig: make(map[string]*EpochValidatorsWithAuction), + CurrentEpoch: ihgs.currentEpoch, + EpochsConfigWithAuction: make(map[string]*EpochValidatorsWithAuction), } // todo: extract this into a common func with NodesCoordinatorToRegistry minEpoch := 0 @@ -68,7 +24,7 @@ func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() continue } - registry.EpochsConfig[fmt.Sprint(epoch)] = epochNodesConfigToEpochValidatorsWithAuction(epochNodesData) + registry.EpochsConfigWithAuction[fmt.Sprint(epoch)] = epochNodesConfigToEpochValidatorsWithAuction(epochNodesData) } return registry @@ -76,12 +32,26 @@ func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() func epochNodesConfigToEpochValidatorsWithAuction(config *epochNodesConfig) *EpochValidatorsWithAuction { result := &EpochValidatorsWithAuction{ - EpochValidators: epochNodesConfigToEpochValidators(config), - ShuffledOutValidators: make(map[string][]*SerializableValidator, len(config.shuffledOutMap)), + Eligible: make(map[string]Validators, len(config.eligibleMap)), + Waiting: make(map[string]Validators, len(config.waitingMap)), + Leaving: make(map[string]Validators, len(config.leavingMap)), + ShuffledOut: make(map[string]Validators, len(config.shuffledOutMap)), + } + + for k, v := range config.eligibleMap { + result.Eligible[fmt.Sprint(k)] = Validators{Data: ValidatorArrayToSerializableValidatorArray(v)} + } + + for k, v := range config.waitingMap { + result.Waiting[fmt.Sprint(k)] = Validators{Data: ValidatorArrayToSerializableValidatorArray(v)} } for k, v := range config.leavingMap { - result.ShuffledOutValidators[fmt.Sprint(k)] = ValidatorArrayToSerializableValidatorArray(v) + result.Leaving[fmt.Sprint(k)] = Validators{Data: ValidatorArrayToSerializableValidatorArray(v)} + } + + for k, v := range config.shuffledOutMap { + result.ShuffledOut[fmt.Sprint(k)] = Validators{Data: ValidatorArrayToSerializableValidatorArray(v)} } return result diff --git a/sharding/indexHashedNodesCoordinator_test.go b/sharding/indexHashedNodesCoordinator_test.go index f89eea1183b..b2923a0de25 100644 --- a/sharding/indexHashedNodesCoordinator_test.go +++ b/sharding/indexHashedNodesCoordinator_test.go @@ -86,6 +86,7 @@ func createArguments() ArgNodesCoordinator { Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 444, } nodeShuffler, _ := NewHashValidatorsShuffler(shufflerArgs) @@ -110,6 +111,7 @@ func createArguments() ArgNodesCoordinator { IsFullArchive: false, ChanStopNode: make(chan endProcess.ArgEndProcess), NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + StakingV4EnableEpoch: 444, } return arguments } diff --git a/sharding/nodesCoordinatorRegistryWithAuction.go b/sharding/nodesCoordinatorRegistryWithAuction.go new file mode 100644 index 00000000000..ace96fa2aee --- /dev/null +++ b/sharding/nodesCoordinatorRegistryWithAuction.go @@ -0,0 +1,70 @@ +//go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/ElrondNetwork/protobuf/protobuf --gogoslick_out=. nodesCoordinatorRegistryWithAuction.proto +package sharding + +func protoValidatorsMapToSliceMap(validators map[string]Validators) map[string][]*SerializableValidator { + ret := make(map[string][]*SerializableValidator) + + for shardID, val := range validators { + ret[shardID] = val.GetData() + } + + return ret +} + +func sliceMapToProtoMap(validators map[string][]*SerializableValidator) map[string]Validators { + ret := make(map[string]Validators) + + for shardID, val := range validators { + ret[shardID] = Validators{Data: val} + } + + return ret +} + +func (m *EpochValidatorsWithAuction) GetEligibleValidators() map[string][]*SerializableValidator { + return protoValidatorsMapToSliceMap(m.GetEligible()) +} + +func (m *EpochValidatorsWithAuction) GetWaitingValidators() map[string][]*SerializableValidator { + return protoValidatorsMapToSliceMap(m.GetWaiting()) +} + +func (m *EpochValidatorsWithAuction) GetLeavingValidators() map[string][]*SerializableValidator { + return protoValidatorsMapToSliceMap(m.GetLeaving()) +} + +func (m *EpochValidatorsWithAuction) GetShuffledOutValidators() map[string][]*SerializableValidator { + return protoValidatorsMapToSliceMap(m.GetShuffledOut()) +} + +func (m *NodesCoordinatorRegistryWithAuction) GetEpochsConfig() map[string]EpochValidatorsHandler { + ret := make(map[string]EpochValidatorsHandler) + for epoch, config := range m.GetEpochsConfigWithAuction() { + ret[epoch] = config + } + + return ret +} + +func (m *NodesCoordinatorRegistryWithAuction) SetCurrentEpoch(epoch uint32) { + m.CurrentEpoch = epoch +} + +func (m *NodesCoordinatorRegistryWithAuction) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { + m.EpochsConfigWithAuction = make(map[string]*EpochValidatorsWithAuction) + + for epoch, config := range epochsConfig { + shuffledOut := make(map[string]Validators) + configWithAuction, castOk := config.(EpochValidatorsHandlerWithAuction) + if castOk { + shuffledOut = sliceMapToProtoMap(configWithAuction.GetShuffledOutValidators()) + } + + m.EpochsConfigWithAuction[epoch] = &EpochValidatorsWithAuction{ + Eligible: sliceMapToProtoMap(config.GetEligibleValidators()), + Waiting: sliceMapToProtoMap(config.GetWaitingValidators()), + Leaving: sliceMapToProtoMap(config.GetLeavingValidators()), + ShuffledOut: shuffledOut, + } + } +} diff --git a/sharding/nodesCoordinatorRegistryWithAuction.proto b/sharding/nodesCoordinatorRegistryWithAuction.proto new file mode 100644 index 00000000000..a91133586c7 --- /dev/null +++ b/sharding/nodesCoordinatorRegistryWithAuction.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package proto; + +option go_package = "sharding"; +option (gogoproto.stable_marshaler_all) = true; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +message SerializableValidator { + bytes PubKey = 1 [(gogoproto.jsontag) = "pubKey"]; + uint32 Chances = 2 [(gogoproto.jsontag) = "chances"]; + uint32 Index = 3 [(gogoproto.jsontag) = "index"]; +} + +message Validators { + repeated SerializableValidator Data = 1; +} + +message EpochValidatorsWithAuction { + map Eligible = 1 [(gogoproto.nullable) = false]; + map Waiting = 2 [(gogoproto.nullable) = false]; + map Leaving = 3 [(gogoproto.nullable) = false]; + map ShuffledOut = 4 [(gogoproto.nullable) = false]; +} + +message NodesCoordinatorRegistryWithAuction { + uint32 CurrentEpoch = 2; + map EpochsConfigWithAuction = 1; +} From 337a35351c5b84f5ca05af780bc6216251dcc9b0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 14:13:25 +0200 Subject: [PATCH 089/958] FEAT: Add generated proto file --- .../nodesCoordinatorRegistryWithAuction.pb.go | 2128 +++++++++++++++++ 1 file changed, 2128 insertions(+) create mode 100644 sharding/nodesCoordinatorRegistryWithAuction.pb.go diff --git a/sharding/nodesCoordinatorRegistryWithAuction.pb.go b/sharding/nodesCoordinatorRegistryWithAuction.pb.go new file mode 100644 index 00000000000..93c72827258 --- /dev/null +++ b/sharding/nodesCoordinatorRegistryWithAuction.pb.go @@ -0,0 +1,2128 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: nodesCoordinatorRegistryWithAuction.proto + +package sharding + +import ( + bytes "bytes" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + io "io" + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type SerializableValidator struct { + PubKey []byte `protobuf:"bytes,1,opt,name=PubKey,proto3" json:"pubKey"` + Chances uint32 `protobuf:"varint,2,opt,name=Chances,proto3" json:"chances"` + Index uint32 `protobuf:"varint,3,opt,name=Index,proto3" json:"index"` +} + +func (m *SerializableValidator) Reset() { *m = SerializableValidator{} } +func (*SerializableValidator) ProtoMessage() {} +func (*SerializableValidator) Descriptor() ([]byte, []int) { + return fileDescriptor_f04461c784f438d5, []int{0} +} +func (m *SerializableValidator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SerializableValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SerializableValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_SerializableValidator.Merge(m, src) +} +func (m *SerializableValidator) XXX_Size() int { + return m.Size() +} +func (m *SerializableValidator) XXX_DiscardUnknown() { + xxx_messageInfo_SerializableValidator.DiscardUnknown(m) +} + +var xxx_messageInfo_SerializableValidator proto.InternalMessageInfo + +func (m *SerializableValidator) GetPubKey() []byte { + if m != nil { + return m.PubKey + } + return nil +} + +func (m *SerializableValidator) GetChances() uint32 { + if m != nil { + return m.Chances + } + return 0 +} + +func (m *SerializableValidator) GetIndex() uint32 { + if m != nil { + return m.Index + } + return 0 +} + +type Validators struct { + Data []*SerializableValidator `protobuf:"bytes,1,rep,name=Data,proto3" json:"Data,omitempty"` +} + +func (m *Validators) Reset() { *m = Validators{} } +func (*Validators) ProtoMessage() {} +func (*Validators) Descriptor() ([]byte, []int) { + return fileDescriptor_f04461c784f438d5, []int{1} +} +func (m *Validators) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Validators) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Validators) XXX_Merge(src proto.Message) { + xxx_messageInfo_Validators.Merge(m, src) +} +func (m *Validators) XXX_Size() int { + return m.Size() +} +func (m *Validators) XXX_DiscardUnknown() { + xxx_messageInfo_Validators.DiscardUnknown(m) +} + +var xxx_messageInfo_Validators proto.InternalMessageInfo + +func (m *Validators) GetData() []*SerializableValidator { + if m != nil { + return m.Data + } + return nil +} + +type EpochValidatorsWithAuction struct { + Eligible map[string]Validators `protobuf:"bytes,1,rep,name=Eligible,proto3" json:"Eligible" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Waiting map[string]Validators `protobuf:"bytes,2,rep,name=Waiting,proto3" json:"Waiting" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Leaving map[string]Validators `protobuf:"bytes,3,rep,name=Leaving,proto3" json:"Leaving" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + ShuffledOut map[string]Validators `protobuf:"bytes,4,rep,name=ShuffledOut,proto3" json:"ShuffledOut" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *EpochValidatorsWithAuction) Reset() { *m = EpochValidatorsWithAuction{} } +func (*EpochValidatorsWithAuction) ProtoMessage() {} +func (*EpochValidatorsWithAuction) Descriptor() ([]byte, []int) { + return fileDescriptor_f04461c784f438d5, []int{2} +} +func (m *EpochValidatorsWithAuction) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EpochValidatorsWithAuction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EpochValidatorsWithAuction) XXX_Merge(src proto.Message) { + xxx_messageInfo_EpochValidatorsWithAuction.Merge(m, src) +} +func (m *EpochValidatorsWithAuction) XXX_Size() int { + return m.Size() +} +func (m *EpochValidatorsWithAuction) XXX_DiscardUnknown() { + xxx_messageInfo_EpochValidatorsWithAuction.DiscardUnknown(m) +} + +var xxx_messageInfo_EpochValidatorsWithAuction proto.InternalMessageInfo + +func (m *EpochValidatorsWithAuction) GetEligible() map[string]Validators { + if m != nil { + return m.Eligible + } + return nil +} + +func (m *EpochValidatorsWithAuction) GetWaiting() map[string]Validators { + if m != nil { + return m.Waiting + } + return nil +} + +func (m *EpochValidatorsWithAuction) GetLeaving() map[string]Validators { + if m != nil { + return m.Leaving + } + return nil +} + +func (m *EpochValidatorsWithAuction) GetShuffledOut() map[string]Validators { + if m != nil { + return m.ShuffledOut + } + return nil +} + +type NodesCoordinatorRegistryWithAuction struct { + CurrentEpoch uint32 `protobuf:"varint,2,opt,name=CurrentEpoch,proto3" json:"CurrentEpoch,omitempty"` + EpochsConfigWithAuction map[string]*EpochValidatorsWithAuction `protobuf:"bytes,1,rep,name=EpochsConfigWithAuction,proto3" json:"EpochsConfigWithAuction,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *NodesCoordinatorRegistryWithAuction) Reset() { *m = NodesCoordinatorRegistryWithAuction{} } +func (*NodesCoordinatorRegistryWithAuction) ProtoMessage() {} +func (*NodesCoordinatorRegistryWithAuction) Descriptor() ([]byte, []int) { + return fileDescriptor_f04461c784f438d5, []int{3} +} +func (m *NodesCoordinatorRegistryWithAuction) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodesCoordinatorRegistryWithAuction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NodesCoordinatorRegistryWithAuction) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodesCoordinatorRegistryWithAuction.Merge(m, src) +} +func (m *NodesCoordinatorRegistryWithAuction) XXX_Size() int { + return m.Size() +} +func (m *NodesCoordinatorRegistryWithAuction) XXX_DiscardUnknown() { + xxx_messageInfo_NodesCoordinatorRegistryWithAuction.DiscardUnknown(m) +} + +var xxx_messageInfo_NodesCoordinatorRegistryWithAuction proto.InternalMessageInfo + +func (m *NodesCoordinatorRegistryWithAuction) GetCurrentEpoch() uint32 { + if m != nil { + return m.CurrentEpoch + } + return 0 +} + +func (m *NodesCoordinatorRegistryWithAuction) GetEpochsConfigWithAuction() map[string]*EpochValidatorsWithAuction { + if m != nil { + return m.EpochsConfigWithAuction + } + return nil +} + +func init() { + proto.RegisterType((*SerializableValidator)(nil), "proto.SerializableValidator") + proto.RegisterType((*Validators)(nil), "proto.Validators") + proto.RegisterType((*EpochValidatorsWithAuction)(nil), "proto.EpochValidatorsWithAuction") + proto.RegisterMapType((map[string]Validators)(nil), "proto.EpochValidatorsWithAuction.EligibleEntry") + proto.RegisterMapType((map[string]Validators)(nil), "proto.EpochValidatorsWithAuction.LeavingEntry") + proto.RegisterMapType((map[string]Validators)(nil), "proto.EpochValidatorsWithAuction.ShuffledOutEntry") + proto.RegisterMapType((map[string]Validators)(nil), "proto.EpochValidatorsWithAuction.WaitingEntry") + proto.RegisterType((*NodesCoordinatorRegistryWithAuction)(nil), "proto.NodesCoordinatorRegistryWithAuction") + proto.RegisterMapType((map[string]*EpochValidatorsWithAuction)(nil), "proto.NodesCoordinatorRegistryWithAuction.EpochsConfigWithAuctionEntry") +} + +func init() { + proto.RegisterFile("nodesCoordinatorRegistryWithAuction.proto", fileDescriptor_f04461c784f438d5) +} + +var fileDescriptor_f04461c784f438d5 = []byte{ + // 564 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xcd, 0x6e, 0xd3, 0x4e, + 0x14, 0xc5, 0x3d, 0xf9, 0x6c, 0x6f, 0x52, 0xa9, 0xff, 0x91, 0xfe, 0xc2, 0x8a, 0xaa, 0x49, 0x30, + 0x42, 0x84, 0x05, 0x0e, 0x0a, 0x0b, 0x10, 0x0b, 0x24, 0x12, 0x22, 0x84, 0x80, 0x40, 0x5d, 0x89, + 0x4a, 0xdd, 0xd9, 0xc9, 0xc4, 0x1e, 0xe1, 0x7a, 0x22, 0x7f, 0x54, 0x84, 0x15, 0x88, 0x17, 0xe0, + 0x31, 0x58, 0xf0, 0x08, 0x3c, 0x40, 0x97, 0x59, 0x66, 0x15, 0x11, 0x67, 0x83, 0xb2, 0xea, 0x23, + 0x20, 0x8f, 0x9d, 0xd6, 0x41, 0x0d, 0xa9, 0x54, 0x56, 0x9e, 0xb9, 0x33, 0xe7, 0x77, 0x66, 0x8e, + 0xef, 0xc0, 0x5d, 0x87, 0xf7, 0xa9, 0xd7, 0xe6, 0xdc, 0xed, 0x33, 0x47, 0xf7, 0xb9, 0xab, 0x51, + 0x93, 0x79, 0xbe, 0x3b, 0x3a, 0x64, 0xbe, 0xf5, 0x34, 0xe8, 0xf9, 0x8c, 0x3b, 0xea, 0xd0, 0xe5, + 0x3e, 0xc7, 0x79, 0xf1, 0xa9, 0xdc, 0x33, 0x99, 0x6f, 0x05, 0x86, 0xda, 0xe3, 0xc7, 0x0d, 0x93, + 0x9b, 0xbc, 0x21, 0xca, 0x46, 0x30, 0x10, 0x33, 0x31, 0x11, 0xa3, 0x58, 0xa5, 0x7c, 0x41, 0xf0, + 0xff, 0x01, 0x75, 0x99, 0x6e, 0xb3, 0x8f, 0xba, 0x61, 0xd3, 0x77, 0xba, 0xcd, 0xfa, 0x91, 0x11, + 0x56, 0xa0, 0xf0, 0x36, 0x30, 0x5e, 0xd2, 0x91, 0x8c, 0x6a, 0xa8, 0x5e, 0x6e, 0xc1, 0x62, 0x5a, + 0x2d, 0x0c, 0x45, 0x45, 0x4b, 0x56, 0xf0, 0x6d, 0x28, 0xb6, 0x2d, 0xdd, 0xe9, 0x51, 0x4f, 0xce, + 0xd4, 0x50, 0x7d, 0xa7, 0x55, 0x5a, 0x4c, 0xab, 0xc5, 0x5e, 0x5c, 0xd2, 0x96, 0x6b, 0xb8, 0x0a, + 0xf9, 0x17, 0x4e, 0x9f, 0x7e, 0x90, 0xb3, 0x62, 0xd3, 0xf6, 0x62, 0x5a, 0xcd, 0xb3, 0xa8, 0xa0, + 0xc5, 0x75, 0xe5, 0x09, 0xc0, 0xb9, 0xb1, 0x87, 0xef, 0x43, 0xee, 0x99, 0xee, 0xeb, 0x32, 0xaa, + 0x65, 0xeb, 0xa5, 0xe6, 0x5e, 0x7c, 0x52, 0xf5, 0xd2, 0x53, 0x6a, 0x62, 0xa7, 0xf2, 0x3d, 0x0f, + 0x95, 0xce, 0x90, 0xf7, 0xac, 0x0b, 0x4a, 0x2a, 0x20, 0xbc, 0x0f, 0x5b, 0x1d, 0x9b, 0x99, 0xcc, + 0xb0, 0x69, 0x02, 0x6d, 0x24, 0xd0, 0xf5, 0x22, 0x75, 0xa9, 0xe8, 0x38, 0xbe, 0x3b, 0x6a, 0xe5, + 0x4e, 0xa7, 0x55, 0x49, 0x3b, 0xc7, 0xe0, 0x2e, 0x14, 0x0f, 0x75, 0xe6, 0x33, 0xc7, 0x94, 0x33, + 0x82, 0xa8, 0x6e, 0x26, 0x26, 0x82, 0x34, 0x70, 0x09, 0x89, 0x78, 0xaf, 0xa8, 0x7e, 0x12, 0xf1, + 0xb2, 0x57, 0xe5, 0x25, 0x82, 0x15, 0x5e, 0x52, 0xc3, 0x47, 0x50, 0x3a, 0xb0, 0x82, 0xc1, 0xc0, + 0xa6, 0xfd, 0x37, 0x81, 0x2f, 0xe7, 0x04, 0xb3, 0xb9, 0x99, 0x99, 0x12, 0xa5, 0xb9, 0x69, 0x58, + 0xa5, 0x0b, 0x3b, 0x2b, 0xe1, 0xe0, 0x5d, 0xc8, 0xbe, 0x4f, 0xfa, 0x64, 0x5b, 0x8b, 0x86, 0xf8, + 0x0e, 0xe4, 0x4f, 0x74, 0x3b, 0xa0, 0xa2, 0x2d, 0x4a, 0xcd, 0xff, 0x12, 0xe3, 0x0b, 0x4f, 0x2d, + 0x5e, 0x7f, 0x9c, 0x79, 0x84, 0x2a, 0xaf, 0xa1, 0x9c, 0x8e, 0xe6, 0x1f, 0xe0, 0xd2, 0xc9, 0x5c, + 0x17, 0xb7, 0x0f, 0xbb, 0x7f, 0x86, 0x72, 0x4d, 0xa4, 0xf2, 0x23, 0x03, 0xb7, 0xba, 0x9b, 0x1f, + 0x36, 0x56, 0xa0, 0xdc, 0x0e, 0x5c, 0x97, 0x3a, 0xbe, 0xf8, 0x63, 0xf1, 0x1b, 0xd3, 0x56, 0x6a, + 0xf8, 0x33, 0x82, 0x1b, 0x62, 0xe4, 0xb5, 0xb9, 0x33, 0x60, 0x66, 0x4a, 0x9f, 0xf4, 0xfa, 0xf3, + 0xe4, 0x2c, 0x57, 0x70, 0x54, 0xd7, 0x90, 0xc4, 0xad, 0xb5, 0x75, 0x3e, 0x95, 0x63, 0xd8, 0xfb, + 0x9b, 0xf0, 0x92, 0xb8, 0x1e, 0xae, 0xc6, 0x75, 0x73, 0x63, 0x63, 0xa6, 0xe2, 0x6b, 0xb5, 0xc6, + 0x33, 0x22, 0x4d, 0x66, 0x44, 0x3a, 0x9b, 0x11, 0xf4, 0x29, 0x24, 0xe8, 0x5b, 0x48, 0xd0, 0x69, + 0x48, 0xd0, 0x38, 0x24, 0x68, 0x12, 0x12, 0xf4, 0x33, 0x24, 0xe8, 0x57, 0x48, 0xa4, 0xb3, 0x90, + 0xa0, 0xaf, 0x73, 0x22, 0x8d, 0xe7, 0x44, 0x9a, 0xcc, 0x89, 0x74, 0xb4, 0xe5, 0x59, 0x7a, 0x74, + 0x7d, 0xd3, 0x28, 0x08, 0xc3, 0x07, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x76, 0x24, 0xed, 0x37, + 0x61, 0x05, 0x00, 0x00, +} + +func (this *SerializableValidator) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*SerializableValidator) + if !ok { + that2, ok := that.(SerializableValidator) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.PubKey, that1.PubKey) { + return false + } + if this.Chances != that1.Chances { + return false + } + if this.Index != that1.Index { + return false + } + return true +} +func (this *Validators) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Validators) + if !ok { + that2, ok := that.(Validators) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Data) != len(that1.Data) { + return false + } + for i := range this.Data { + if !this.Data[i].Equal(that1.Data[i]) { + return false + } + } + return true +} +func (this *EpochValidatorsWithAuction) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*EpochValidatorsWithAuction) + if !ok { + that2, ok := that.(EpochValidatorsWithAuction) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Eligible) != len(that1.Eligible) { + return false + } + for i := range this.Eligible { + a := this.Eligible[i] + b := that1.Eligible[i] + if !(&a).Equal(&b) { + return false + } + } + if len(this.Waiting) != len(that1.Waiting) { + return false + } + for i := range this.Waiting { + a := this.Waiting[i] + b := that1.Waiting[i] + if !(&a).Equal(&b) { + return false + } + } + if len(this.Leaving) != len(that1.Leaving) { + return false + } + for i := range this.Leaving { + a := this.Leaving[i] + b := that1.Leaving[i] + if !(&a).Equal(&b) { + return false + } + } + if len(this.ShuffledOut) != len(that1.ShuffledOut) { + return false + } + for i := range this.ShuffledOut { + a := this.ShuffledOut[i] + b := that1.ShuffledOut[i] + if !(&a).Equal(&b) { + return false + } + } + return true +} +func (this *NodesCoordinatorRegistryWithAuction) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*NodesCoordinatorRegistryWithAuction) + if !ok { + that2, ok := that.(NodesCoordinatorRegistryWithAuction) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.CurrentEpoch != that1.CurrentEpoch { + return false + } + if len(this.EpochsConfigWithAuction) != len(that1.EpochsConfigWithAuction) { + return false + } + for i := range this.EpochsConfigWithAuction { + if !this.EpochsConfigWithAuction[i].Equal(that1.EpochsConfigWithAuction[i]) { + return false + } + } + return true +} +func (this *SerializableValidator) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&sharding.SerializableValidator{") + s = append(s, "PubKey: "+fmt.Sprintf("%#v", this.PubKey)+",\n") + s = append(s, "Chances: "+fmt.Sprintf("%#v", this.Chances)+",\n") + s = append(s, "Index: "+fmt.Sprintf("%#v", this.Index)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Validators) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&sharding.Validators{") + if this.Data != nil { + s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EpochValidatorsWithAuction) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&sharding.EpochValidatorsWithAuction{") + keysForEligible := make([]string, 0, len(this.Eligible)) + for k, _ := range this.Eligible { + keysForEligible = append(keysForEligible, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForEligible) + mapStringForEligible := "map[string]Validators{" + for _, k := range keysForEligible { + mapStringForEligible += fmt.Sprintf("%#v: %#v,", k, this.Eligible[k]) + } + mapStringForEligible += "}" + if this.Eligible != nil { + s = append(s, "Eligible: "+mapStringForEligible+",\n") + } + keysForWaiting := make([]string, 0, len(this.Waiting)) + for k, _ := range this.Waiting { + keysForWaiting = append(keysForWaiting, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForWaiting) + mapStringForWaiting := "map[string]Validators{" + for _, k := range keysForWaiting { + mapStringForWaiting += fmt.Sprintf("%#v: %#v,", k, this.Waiting[k]) + } + mapStringForWaiting += "}" + if this.Waiting != nil { + s = append(s, "Waiting: "+mapStringForWaiting+",\n") + } + keysForLeaving := make([]string, 0, len(this.Leaving)) + for k, _ := range this.Leaving { + keysForLeaving = append(keysForLeaving, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLeaving) + mapStringForLeaving := "map[string]Validators{" + for _, k := range keysForLeaving { + mapStringForLeaving += fmt.Sprintf("%#v: %#v,", k, this.Leaving[k]) + } + mapStringForLeaving += "}" + if this.Leaving != nil { + s = append(s, "Leaving: "+mapStringForLeaving+",\n") + } + keysForShuffledOut := make([]string, 0, len(this.ShuffledOut)) + for k, _ := range this.ShuffledOut { + keysForShuffledOut = append(keysForShuffledOut, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForShuffledOut) + mapStringForShuffledOut := "map[string]Validators{" + for _, k := range keysForShuffledOut { + mapStringForShuffledOut += fmt.Sprintf("%#v: %#v,", k, this.ShuffledOut[k]) + } + mapStringForShuffledOut += "}" + if this.ShuffledOut != nil { + s = append(s, "ShuffledOut: "+mapStringForShuffledOut+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *NodesCoordinatorRegistryWithAuction) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&sharding.NodesCoordinatorRegistryWithAuction{") + s = append(s, "CurrentEpoch: "+fmt.Sprintf("%#v", this.CurrentEpoch)+",\n") + keysForEpochsConfigWithAuction := make([]string, 0, len(this.EpochsConfigWithAuction)) + for k, _ := range this.EpochsConfigWithAuction { + keysForEpochsConfigWithAuction = append(keysForEpochsConfigWithAuction, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForEpochsConfigWithAuction) + mapStringForEpochsConfigWithAuction := "map[string]*EpochValidatorsWithAuction{" + for _, k := range keysForEpochsConfigWithAuction { + mapStringForEpochsConfigWithAuction += fmt.Sprintf("%#v: %#v,", k, this.EpochsConfigWithAuction[k]) + } + mapStringForEpochsConfigWithAuction += "}" + if this.EpochsConfigWithAuction != nil { + s = append(s, "EpochsConfigWithAuction: "+mapStringForEpochsConfigWithAuction+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringNodesCoordinatorRegistryWithAuction(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} +func (m *SerializableValidator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SerializableValidator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SerializableValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Index != 0 { + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(m.Index)) + i-- + dAtA[i] = 0x18 + } + if m.Chances != 0 { + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(m.Chances)) + i-- + dAtA[i] = 0x10 + } + if len(m.PubKey) > 0 { + i -= len(m.PubKey) + copy(dAtA[i:], m.PubKey) + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(len(m.PubKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Validators) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Validators) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Validators) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Data) > 0 { + for iNdEx := len(m.Data) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Data[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *EpochValidatorsWithAuction) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EpochValidatorsWithAuction) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EpochValidatorsWithAuction) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ShuffledOut) > 0 { + keysForShuffledOut := make([]string, 0, len(m.ShuffledOut)) + for k := range m.ShuffledOut { + keysForShuffledOut = append(keysForShuffledOut, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForShuffledOut) + for iNdEx := len(keysForShuffledOut) - 1; iNdEx >= 0; iNdEx-- { + v := m.ShuffledOut[string(keysForShuffledOut[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForShuffledOut[iNdEx]) + copy(dAtA[i:], keysForShuffledOut[iNdEx]) + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(len(keysForShuffledOut[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x22 + } + } + if len(m.Leaving) > 0 { + keysForLeaving := make([]string, 0, len(m.Leaving)) + for k := range m.Leaving { + keysForLeaving = append(keysForLeaving, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLeaving) + for iNdEx := len(keysForLeaving) - 1; iNdEx >= 0; iNdEx-- { + v := m.Leaving[string(keysForLeaving[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForLeaving[iNdEx]) + copy(dAtA[i:], keysForLeaving[iNdEx]) + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(len(keysForLeaving[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Waiting) > 0 { + keysForWaiting := make([]string, 0, len(m.Waiting)) + for k := range m.Waiting { + keysForWaiting = append(keysForWaiting, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForWaiting) + for iNdEx := len(keysForWaiting) - 1; iNdEx >= 0; iNdEx-- { + v := m.Waiting[string(keysForWaiting[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForWaiting[iNdEx]) + copy(dAtA[i:], keysForWaiting[iNdEx]) + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(len(keysForWaiting[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Eligible) > 0 { + keysForEligible := make([]string, 0, len(m.Eligible)) + for k := range m.Eligible { + keysForEligible = append(keysForEligible, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForEligible) + for iNdEx := len(keysForEligible) - 1; iNdEx >= 0; iNdEx-- { + v := m.Eligible[string(keysForEligible[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForEligible[iNdEx]) + copy(dAtA[i:], keysForEligible[iNdEx]) + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(len(keysForEligible[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *NodesCoordinatorRegistryWithAuction) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodesCoordinatorRegistryWithAuction) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodesCoordinatorRegistryWithAuction) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CurrentEpoch != 0 { + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(m.CurrentEpoch)) + i-- + dAtA[i] = 0x10 + } + if len(m.EpochsConfigWithAuction) > 0 { + keysForEpochsConfigWithAuction := make([]string, 0, len(m.EpochsConfigWithAuction)) + for k := range m.EpochsConfigWithAuction { + keysForEpochsConfigWithAuction = append(keysForEpochsConfigWithAuction, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForEpochsConfigWithAuction) + for iNdEx := len(keysForEpochsConfigWithAuction) - 1; iNdEx >= 0; iNdEx-- { + v := m.EpochsConfigWithAuction[string(keysForEpochsConfigWithAuction[iNdEx])] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(keysForEpochsConfigWithAuction[iNdEx]) + copy(dAtA[i:], keysForEpochsConfigWithAuction[iNdEx]) + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(len(keysForEpochsConfigWithAuction[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintNodesCoordinatorRegistryWithAuction(dAtA []byte, offset int, v uint64) int { + offset -= sovNodesCoordinatorRegistryWithAuction(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SerializableValidator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PubKey) + if l > 0 { + n += 1 + l + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + } + if m.Chances != 0 { + n += 1 + sovNodesCoordinatorRegistryWithAuction(uint64(m.Chances)) + } + if m.Index != 0 { + n += 1 + sovNodesCoordinatorRegistryWithAuction(uint64(m.Index)) + } + return n +} + +func (m *Validators) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Data) > 0 { + for _, e := range m.Data { + l = e.Size() + n += 1 + l + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + } + } + return n +} + +func (m *EpochValidatorsWithAuction) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Eligible) > 0 { + for k, v := range m.Eligible { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovNodesCoordinatorRegistryWithAuction(uint64(len(k))) + 1 + l + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + n += mapEntrySize + 1 + sovNodesCoordinatorRegistryWithAuction(uint64(mapEntrySize)) + } + } + if len(m.Waiting) > 0 { + for k, v := range m.Waiting { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovNodesCoordinatorRegistryWithAuction(uint64(len(k))) + 1 + l + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + n += mapEntrySize + 1 + sovNodesCoordinatorRegistryWithAuction(uint64(mapEntrySize)) + } + } + if len(m.Leaving) > 0 { + for k, v := range m.Leaving { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovNodesCoordinatorRegistryWithAuction(uint64(len(k))) + 1 + l + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + n += mapEntrySize + 1 + sovNodesCoordinatorRegistryWithAuction(uint64(mapEntrySize)) + } + } + if len(m.ShuffledOut) > 0 { + for k, v := range m.ShuffledOut { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovNodesCoordinatorRegistryWithAuction(uint64(len(k))) + 1 + l + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + n += mapEntrySize + 1 + sovNodesCoordinatorRegistryWithAuction(uint64(mapEntrySize)) + } + } + return n +} + +func (m *NodesCoordinatorRegistryWithAuction) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.EpochsConfigWithAuction) > 0 { + for k, v := range m.EpochsConfigWithAuction { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovNodesCoordinatorRegistryWithAuction(uint64(l)) + } + mapEntrySize := 1 + len(k) + sovNodesCoordinatorRegistryWithAuction(uint64(len(k))) + l + n += mapEntrySize + 1 + sovNodesCoordinatorRegistryWithAuction(uint64(mapEntrySize)) + } + } + if m.CurrentEpoch != 0 { + n += 1 + sovNodesCoordinatorRegistryWithAuction(uint64(m.CurrentEpoch)) + } + return n +} + +func sovNodesCoordinatorRegistryWithAuction(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozNodesCoordinatorRegistryWithAuction(x uint64) (n int) { + return sovNodesCoordinatorRegistryWithAuction(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *SerializableValidator) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SerializableValidator{`, + `PubKey:` + fmt.Sprintf("%v", this.PubKey) + `,`, + `Chances:` + fmt.Sprintf("%v", this.Chances) + `,`, + `Index:` + fmt.Sprintf("%v", this.Index) + `,`, + `}`, + }, "") + return s +} +func (this *Validators) String() string { + if this == nil { + return "nil" + } + repeatedStringForData := "[]*SerializableValidator{" + for _, f := range this.Data { + repeatedStringForData += strings.Replace(f.String(), "SerializableValidator", "SerializableValidator", 1) + "," + } + repeatedStringForData += "}" + s := strings.Join([]string{`&Validators{`, + `Data:` + repeatedStringForData + `,`, + `}`, + }, "") + return s +} +func (this *EpochValidatorsWithAuction) String() string { + if this == nil { + return "nil" + } + keysForEligible := make([]string, 0, len(this.Eligible)) + for k, _ := range this.Eligible { + keysForEligible = append(keysForEligible, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForEligible) + mapStringForEligible := "map[string]Validators{" + for _, k := range keysForEligible { + mapStringForEligible += fmt.Sprintf("%v: %v,", k, this.Eligible[k]) + } + mapStringForEligible += "}" + keysForWaiting := make([]string, 0, len(this.Waiting)) + for k, _ := range this.Waiting { + keysForWaiting = append(keysForWaiting, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForWaiting) + mapStringForWaiting := "map[string]Validators{" + for _, k := range keysForWaiting { + mapStringForWaiting += fmt.Sprintf("%v: %v,", k, this.Waiting[k]) + } + mapStringForWaiting += "}" + keysForLeaving := make([]string, 0, len(this.Leaving)) + for k, _ := range this.Leaving { + keysForLeaving = append(keysForLeaving, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLeaving) + mapStringForLeaving := "map[string]Validators{" + for _, k := range keysForLeaving { + mapStringForLeaving += fmt.Sprintf("%v: %v,", k, this.Leaving[k]) + } + mapStringForLeaving += "}" + keysForShuffledOut := make([]string, 0, len(this.ShuffledOut)) + for k, _ := range this.ShuffledOut { + keysForShuffledOut = append(keysForShuffledOut, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForShuffledOut) + mapStringForShuffledOut := "map[string]Validators{" + for _, k := range keysForShuffledOut { + mapStringForShuffledOut += fmt.Sprintf("%v: %v,", k, this.ShuffledOut[k]) + } + mapStringForShuffledOut += "}" + s := strings.Join([]string{`&EpochValidatorsWithAuction{`, + `Eligible:` + mapStringForEligible + `,`, + `Waiting:` + mapStringForWaiting + `,`, + `Leaving:` + mapStringForLeaving + `,`, + `ShuffledOut:` + mapStringForShuffledOut + `,`, + `}`, + }, "") + return s +} +func (this *NodesCoordinatorRegistryWithAuction) String() string { + if this == nil { + return "nil" + } + keysForEpochsConfigWithAuction := make([]string, 0, len(this.EpochsConfigWithAuction)) + for k, _ := range this.EpochsConfigWithAuction { + keysForEpochsConfigWithAuction = append(keysForEpochsConfigWithAuction, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForEpochsConfigWithAuction) + mapStringForEpochsConfigWithAuction := "map[string]*EpochValidatorsWithAuction{" + for _, k := range keysForEpochsConfigWithAuction { + mapStringForEpochsConfigWithAuction += fmt.Sprintf("%v: %v,", k, this.EpochsConfigWithAuction[k]) + } + mapStringForEpochsConfigWithAuction += "}" + s := strings.Join([]string{`&NodesCoordinatorRegistryWithAuction{`, + `EpochsConfigWithAuction:` + mapStringForEpochsConfigWithAuction + `,`, + `CurrentEpoch:` + fmt.Sprintf("%v", this.CurrentEpoch) + `,`, + `}`, + }, "") + return s +} +func valueToStringNodesCoordinatorRegistryWithAuction(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *SerializableValidator) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SerializableValidator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SerializableValidator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PubKey = append(m.PubKey[:0], dAtA[iNdEx:postIndex]...) + if m.PubKey == nil { + m.PubKey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Chances", wireType) + } + m.Chances = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Chances |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Validators) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Validators: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Validators: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data, &SerializableValidator{}) + if err := m.Data[len(m.Data)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EpochValidatorsWithAuction) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EpochValidatorsWithAuction: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EpochValidatorsWithAuction: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Eligible", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Eligible == nil { + m.Eligible = make(map[string]Validators) + } + var mapkey string + mapvalue := &Validators{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &Validators{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Eligible[mapkey] = *mapvalue + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Waiting", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Waiting == nil { + m.Waiting = make(map[string]Validators) + } + var mapkey string + mapvalue := &Validators{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &Validators{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Waiting[mapkey] = *mapvalue + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Leaving", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Leaving == nil { + m.Leaving = make(map[string]Validators) + } + var mapkey string + mapvalue := &Validators{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &Validators{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Leaving[mapkey] = *mapvalue + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShuffledOut", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ShuffledOut == nil { + m.ShuffledOut = make(map[string]Validators) + } + var mapkey string + mapvalue := &Validators{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &Validators{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.ShuffledOut[mapkey] = *mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NodesCoordinatorRegistryWithAuction) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodesCoordinatorRegistryWithAuction: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodesCoordinatorRegistryWithAuction: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochsConfigWithAuction", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.EpochsConfigWithAuction == nil { + m.EpochsConfigWithAuction = make(map[string]*EpochValidatorsWithAuction) + } + var mapkey string + var mapvalue *EpochValidatorsWithAuction + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &EpochValidatorsWithAuction{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.EpochsConfigWithAuction[mapkey] = mapvalue + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType) + } + m.CurrentEpoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentEpoch |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipNodesCoordinatorRegistryWithAuction(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupNodesCoordinatorRegistryWithAuction + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthNodesCoordinatorRegistryWithAuction + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthNodesCoordinatorRegistryWithAuction = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowNodesCoordinatorRegistryWithAuction = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupNodesCoordinatorRegistryWithAuction = fmt.Errorf("proto: unexpected end of group") +) From 6e7b7301e5a258abbb55a76d804bef2cfd5fc120 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 15:15:34 +0200 Subject: [PATCH 090/958] FIX: Refactor code structure --- .../indexHashedNodesCoordinatorRegistry.go | 98 ++++--------------- sharding/interface.go | 22 +++++ sharding/nodesCoordinatorRegistry.go | 62 ++++++++++++ .../nodesCoordinatorRegistryWithAuction.go | 7 ++ .../nodesCoordinatorRegistryWithAuction.proto | 4 +- 5 files changed, 110 insertions(+), 83 deletions(-) create mode 100644 sharding/nodesCoordinatorRegistry.go diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index bf78271369e..6d4d78ed365 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -8,83 +8,6 @@ import ( "github.com/ElrondNetwork/elrond-go/common" ) -// EpochValidators holds one epoch configuration for a nodes coordinator -type EpochValidators struct { - EligibleValidators map[string][]*SerializableValidator `json:"eligibleValidators"` - WaitingValidators map[string][]*SerializableValidator `json:"waitingValidators"` - LeavingValidators map[string][]*SerializableValidator `json:"leavingValidators"` -} - -func (ev *EpochValidators) GetEligibleValidators() map[string][]*SerializableValidator { - return ev.EligibleValidators -} - -func (ev *EpochValidators) GetWaitingValidators() map[string][]*SerializableValidator { - return ev.WaitingValidators -} - -func (ev *EpochValidators) GetLeavingValidators() map[string][]*SerializableValidator { - return ev.LeavingValidators -} - -// NodesCoordinatorRegistry holds the data that can be used to initialize a nodes coordinator -type NodesCoordinatorRegistry struct { - EpochsConfig map[string]*EpochValidators `json:"epochConfigs"` - CurrentEpoch uint32 `json:"currentEpoch"` -} - -func (ncr *NodesCoordinatorRegistry) GetCurrentEpoch() uint32 { - return ncr.CurrentEpoch -} - -func (ncr *NodesCoordinatorRegistry) GetEpochsConfig() map[string]EpochValidatorsHandler { - ret := make(map[string]EpochValidatorsHandler) - for epoch, config := range ncr.EpochsConfig { - ret[epoch] = config - } - - return ret -} - -func (ncr *NodesCoordinatorRegistry) SetCurrentEpoch(epoch uint32) { - ncr.CurrentEpoch = epoch -} - -func (ncr *NodesCoordinatorRegistry) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { - ncr.EpochsConfig = make(map[string]*EpochValidators) - - for epoch, config := range epochsConfig { - ncr.EpochsConfig[epoch] = &EpochValidators{ - EligibleValidators: config.GetEligibleValidators(), - WaitingValidators: config.GetWaitingValidators(), - LeavingValidators: config.GetLeavingValidators(), - } - } -} - -// EpochValidatorsHandler defines what one epoch configuration for a nodes coordinator should hold -type EpochValidatorsHandler interface { - GetEligibleValidators() map[string][]*SerializableValidator - GetWaitingValidators() map[string][]*SerializableValidator - GetLeavingValidators() map[string][]*SerializableValidator -} - -type EpochValidatorsHandlerWithAuction interface { - EpochValidatorsHandler - GetShuffledOutValidators() map[string][]*SerializableValidator -} - -// NodesCoordinatorRegistryHandler defines that used to initialize nodes coordinator -type NodesCoordinatorRegistryHandler interface { - GetEpochsConfig() map[string]EpochValidatorsHandler - GetCurrentEpoch() uint32 - - SetCurrentEpoch(epoch uint32) - SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) -} - -// TODO: add proto marshalizer for these package - replace all json marshalizers - // LoadState loads the nodes coordinator state from the used boot storage func (ihgs *indexHashedNodesCoordinator) LoadState(key []byte) error { return ihgs.baseLoadState(key) @@ -106,7 +29,7 @@ func (ihgs *indexHashedNodesCoordinator) baseLoadState(key []byte) error { var config NodesCoordinatorRegistryHandler if ihgs.flagStakingV4.IsSet() { config = &NodesCoordinatorRegistryWithAuction{} - err = json.Unmarshal(data, config) + err = ihgs.marshalizer.Unmarshal(config, data) if err != nil { return err } @@ -148,19 +71,32 @@ func displayNodesConfigInfo(config map[uint32]*epochNodesConfig) { } func (ihgs *indexHashedNodesCoordinator) saveState(key []byte) error { - registry := ihgs.NodesCoordinatorToRegistry() - data, err := json.Marshal(registry) // TODO: Choose different marshaller depending on registry + data, err := ihgs.getRegistryData() if err != nil { return err } ncInternalKey := append([]byte(common.NodesCoordinatorRegistryKeyPrefix), key...) - log.Debug("saving nodes coordinator config", "key", ncInternalKey) return ihgs.bootStorer.Put(ncInternalKey, data) } +func (ihgs *indexHashedNodesCoordinator) getRegistryData() ([]byte, error) { + var err error + var data []byte + + if ihgs.flagStakingV4.IsSet() { + registry := ihgs.nodesCoordinatorToRegistryWithAuction() + data, err = ihgs.marshalizer.Marshal(registry) + } else { + registry := ihgs.nodesCoordinatorToOldRegistry() + data, err = json.Marshal(registry) + } + + return data, err +} + // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry func (ihgs *indexHashedNodesCoordinator) NodesCoordinatorToRegistry() NodesCoordinatorRegistryHandler { if ihgs.flagStakingV4.IsSet() { diff --git a/sharding/interface.go b/sharding/interface.go index 20a22bea95e..71310806d3a 100644 --- a/sharding/interface.go +++ b/sharding/interface.go @@ -205,3 +205,25 @@ type ValidatorsDistributor interface { DistributeValidators(destination map[uint32][]Validator, source map[uint32][]Validator, rand []byte, balanced bool) error IsInterfaceNil() bool } + +// EpochValidatorsHandler defines what one epoch configuration for a nodes coordinator should hold +type EpochValidatorsHandler interface { + GetEligibleValidators() map[string][]*SerializableValidator + GetWaitingValidators() map[string][]*SerializableValidator + GetLeavingValidators() map[string][]*SerializableValidator +} + +// EpochValidatorsHandlerWithAuction defines what one epoch configuration for a nodes coordinator should hold + shuffled out validators +type EpochValidatorsHandlerWithAuction interface { + EpochValidatorsHandler + GetShuffledOutValidators() map[string][]*SerializableValidator +} + +// NodesCoordinatorRegistryHandler defines what is used to initialize nodes coordinator +type NodesCoordinatorRegistryHandler interface { + GetEpochsConfig() map[string]EpochValidatorsHandler + GetCurrentEpoch() uint32 + + SetCurrentEpoch(epoch uint32) + SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) +} diff --git a/sharding/nodesCoordinatorRegistry.go b/sharding/nodesCoordinatorRegistry.go new file mode 100644 index 00000000000..88123056fe0 --- /dev/null +++ b/sharding/nodesCoordinatorRegistry.go @@ -0,0 +1,62 @@ +package sharding + +// EpochValidators holds one epoch configuration for a nodes coordinator +type EpochValidators struct { + EligibleValidators map[string][]*SerializableValidator `json:"eligibleValidators"` + WaitingValidators map[string][]*SerializableValidator `json:"waitingValidators"` + LeavingValidators map[string][]*SerializableValidator `json:"leavingValidators"` +} + +// GetEligibleValidators returns all eligible validators from all shards +func (ev *EpochValidators) GetEligibleValidators() map[string][]*SerializableValidator { + return ev.EligibleValidators +} + +// GetWaitingValidators returns all waiting validators from all shards +func (ev *EpochValidators) GetWaitingValidators() map[string][]*SerializableValidator { + return ev.WaitingValidators +} + +// GetLeavingValidators returns all leaving validators from all shards +func (ev *EpochValidators) GetLeavingValidators() map[string][]*SerializableValidator { + return ev.LeavingValidators +} + +// NodesCoordinatorRegistry holds the data that can be used to initialize a nodes coordinator +type NodesCoordinatorRegistry struct { + EpochsConfig map[string]*EpochValidators `json:"epochConfigs"` + CurrentEpoch uint32 `json:"currentEpoch"` +} + +// GetCurrentEpoch returns the current epoch +func (ncr *NodesCoordinatorRegistry) GetCurrentEpoch() uint32 { + return ncr.CurrentEpoch +} + +// GetEpochsConfig returns epoch-validators configuration +func (ncr *NodesCoordinatorRegistry) GetEpochsConfig() map[string]EpochValidatorsHandler { + ret := make(map[string]EpochValidatorsHandler) + for epoch, config := range ncr.EpochsConfig { + ret[epoch] = config + } + + return ret +} + +// SetCurrentEpoch sets internally the current epoch +func (ncr *NodesCoordinatorRegistry) SetCurrentEpoch(epoch uint32) { + ncr.CurrentEpoch = epoch +} + +// SetEpochsConfig sets internally epoch-validators configuration +func (ncr *NodesCoordinatorRegistry) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { + ncr.EpochsConfig = make(map[string]*EpochValidators) + + for epoch, config := range epochsConfig { + ncr.EpochsConfig[epoch] = &EpochValidators{ + EligibleValidators: config.GetEligibleValidators(), + WaitingValidators: config.GetWaitingValidators(), + LeavingValidators: config.GetLeavingValidators(), + } + } +} diff --git a/sharding/nodesCoordinatorRegistryWithAuction.go b/sharding/nodesCoordinatorRegistryWithAuction.go index ace96fa2aee..6849e3d5882 100644 --- a/sharding/nodesCoordinatorRegistryWithAuction.go +++ b/sharding/nodesCoordinatorRegistryWithAuction.go @@ -21,22 +21,27 @@ func sliceMapToProtoMap(validators map[string][]*SerializableValidator) map[stri return ret } +// GetEligibleValidators returns all eligible validators from all shards func (m *EpochValidatorsWithAuction) GetEligibleValidators() map[string][]*SerializableValidator { return protoValidatorsMapToSliceMap(m.GetEligible()) } +// GetWaitingValidators returns all waiting validators from all shards func (m *EpochValidatorsWithAuction) GetWaitingValidators() map[string][]*SerializableValidator { return protoValidatorsMapToSliceMap(m.GetWaiting()) } +// GetLeavingValidators returns all leaving validators from all shards func (m *EpochValidatorsWithAuction) GetLeavingValidators() map[string][]*SerializableValidator { return protoValidatorsMapToSliceMap(m.GetLeaving()) } +// GetShuffledOutValidators returns all shuffled out validators from all shards func (m *EpochValidatorsWithAuction) GetShuffledOutValidators() map[string][]*SerializableValidator { return protoValidatorsMapToSliceMap(m.GetShuffledOut()) } +// GetEpochsConfig returns epoch-validators configuration func (m *NodesCoordinatorRegistryWithAuction) GetEpochsConfig() map[string]EpochValidatorsHandler { ret := make(map[string]EpochValidatorsHandler) for epoch, config := range m.GetEpochsConfigWithAuction() { @@ -46,10 +51,12 @@ func (m *NodesCoordinatorRegistryWithAuction) GetEpochsConfig() map[string]Epoch return ret } +// SetCurrentEpoch sets internally the current epoch func (m *NodesCoordinatorRegistryWithAuction) SetCurrentEpoch(epoch uint32) { m.CurrentEpoch = epoch } +// SetEpochsConfig sets internally epoch-validators configuration func (m *NodesCoordinatorRegistryWithAuction) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { m.EpochsConfigWithAuction = make(map[string]*EpochValidatorsWithAuction) diff --git a/sharding/nodesCoordinatorRegistryWithAuction.proto b/sharding/nodesCoordinatorRegistryWithAuction.proto index a91133586c7..8cad9e17d2a 100644 --- a/sharding/nodesCoordinatorRegistryWithAuction.proto +++ b/sharding/nodesCoordinatorRegistryWithAuction.proto @@ -25,6 +25,6 @@ message EpochValidatorsWithAuction { } message NodesCoordinatorRegistryWithAuction { - uint32 CurrentEpoch = 2; - map EpochsConfigWithAuction = 1; + uint32 CurrentEpoch = 1; + map EpochsConfigWithAuction = 2; } From d6cf44591786f58fbb2c396364a9f450f7cb1cdf Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 15:20:07 +0200 Subject: [PATCH 091/958] FIX: Remove SetEpochsConfig interface func --- sharding/interface.go | 2 -- sharding/nodesCoordinatorRegistry.go | 13 -------- .../nodesCoordinatorRegistryWithAuction.go | 30 ------------------- 3 files changed, 45 deletions(-) diff --git a/sharding/interface.go b/sharding/interface.go index 71310806d3a..a15ffe5a3fd 100644 --- a/sharding/interface.go +++ b/sharding/interface.go @@ -223,7 +223,5 @@ type EpochValidatorsHandlerWithAuction interface { type NodesCoordinatorRegistryHandler interface { GetEpochsConfig() map[string]EpochValidatorsHandler GetCurrentEpoch() uint32 - SetCurrentEpoch(epoch uint32) - SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) } diff --git a/sharding/nodesCoordinatorRegistry.go b/sharding/nodesCoordinatorRegistry.go index 88123056fe0..544ce84bab6 100644 --- a/sharding/nodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinatorRegistry.go @@ -47,16 +47,3 @@ func (ncr *NodesCoordinatorRegistry) GetEpochsConfig() map[string]EpochValidator func (ncr *NodesCoordinatorRegistry) SetCurrentEpoch(epoch uint32) { ncr.CurrentEpoch = epoch } - -// SetEpochsConfig sets internally epoch-validators configuration -func (ncr *NodesCoordinatorRegistry) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { - ncr.EpochsConfig = make(map[string]*EpochValidators) - - for epoch, config := range epochsConfig { - ncr.EpochsConfig[epoch] = &EpochValidators{ - EligibleValidators: config.GetEligibleValidators(), - WaitingValidators: config.GetWaitingValidators(), - LeavingValidators: config.GetLeavingValidators(), - } - } -} diff --git a/sharding/nodesCoordinatorRegistryWithAuction.go b/sharding/nodesCoordinatorRegistryWithAuction.go index 6849e3d5882..8edaf4103b0 100644 --- a/sharding/nodesCoordinatorRegistryWithAuction.go +++ b/sharding/nodesCoordinatorRegistryWithAuction.go @@ -11,16 +11,6 @@ func protoValidatorsMapToSliceMap(validators map[string]Validators) map[string][ return ret } -func sliceMapToProtoMap(validators map[string][]*SerializableValidator) map[string]Validators { - ret := make(map[string]Validators) - - for shardID, val := range validators { - ret[shardID] = Validators{Data: val} - } - - return ret -} - // GetEligibleValidators returns all eligible validators from all shards func (m *EpochValidatorsWithAuction) GetEligibleValidators() map[string][]*SerializableValidator { return protoValidatorsMapToSliceMap(m.GetEligible()) @@ -55,23 +45,3 @@ func (m *NodesCoordinatorRegistryWithAuction) GetEpochsConfig() map[string]Epoch func (m *NodesCoordinatorRegistryWithAuction) SetCurrentEpoch(epoch uint32) { m.CurrentEpoch = epoch } - -// SetEpochsConfig sets internally epoch-validators configuration -func (m *NodesCoordinatorRegistryWithAuction) SetEpochsConfig(epochsConfig map[string]EpochValidatorsHandler) { - m.EpochsConfigWithAuction = make(map[string]*EpochValidatorsWithAuction) - - for epoch, config := range epochsConfig { - shuffledOut := make(map[string]Validators) - configWithAuction, castOk := config.(EpochValidatorsHandlerWithAuction) - if castOk { - shuffledOut = sliceMapToProtoMap(configWithAuction.GetShuffledOutValidators()) - } - - m.EpochsConfigWithAuction[epoch] = &EpochValidatorsWithAuction{ - Eligible: sliceMapToProtoMap(config.GetEligibleValidators()), - Waiting: sliceMapToProtoMap(config.GetWaitingValidators()), - Leaving: sliceMapToProtoMap(config.GetLeavingValidators()), - ShuffledOut: shuffledOut, - } - } -} From e63f85bbcc3f837e6cc8b714f96e26f13ea868c9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 15:45:18 +0200 Subject: [PATCH 092/958] FEAT: Extract common code to getMinAndLastEpoch --- .../indexHashedNodesCoordinatorRegistry.go | 19 ++++++++++++------- ...shedNodesCoordinatorRegistryWithAuction.go | 9 ++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index 6d4d78ed365..719cd71a554 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -115,13 +115,8 @@ func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToOldRegistry() NodesCo EpochsConfig: make(map[string]*EpochValidators), } - minEpoch := 0 - lastEpoch := ihgs.getLastEpochConfig() - if lastEpoch >= nodesCoordinatorStoredEpochs { - minEpoch = int(lastEpoch) - nodesCoordinatorStoredEpochs + 1 - } - - for epoch := uint32(minEpoch); epoch <= lastEpoch; epoch++ { + minEpoch, lastEpoch := ihgs.getMinAndLastEpoch() + for epoch := minEpoch; epoch <= lastEpoch; epoch++ { epochNodesData, ok := ihgs.nodesConfig[epoch] if !ok { continue @@ -133,6 +128,16 @@ func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToOldRegistry() NodesCo return registry } +func (ihgs *indexHashedNodesCoordinator) getMinAndLastEpoch() (uint32, uint32) { + minEpoch := 0 + lastEpoch := ihgs.getLastEpochConfig() + if lastEpoch >= nodesCoordinatorStoredEpochs { + minEpoch = int(lastEpoch) - nodesCoordinatorStoredEpochs + 1 + } + + return uint32(minEpoch), lastEpoch +} + func (ihgs *indexHashedNodesCoordinator) getLastEpochConfig() uint32 { lastEpoch := uint32(0) for epoch := range ihgs.nodesConfig { diff --git a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go index 070ba003d86..4d57cac2512 100644 --- a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go +++ b/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go @@ -11,14 +11,9 @@ func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() CurrentEpoch: ihgs.currentEpoch, EpochsConfigWithAuction: make(map[string]*EpochValidatorsWithAuction), } - // todo: extract this into a common func with NodesCoordinatorToRegistry - minEpoch := 0 - lastEpoch := ihgs.getLastEpochConfig() - if lastEpoch >= nodesCoordinatorStoredEpochs { - minEpoch = int(lastEpoch) - nodesCoordinatorStoredEpochs + 1 - } - for epoch := uint32(minEpoch); epoch <= lastEpoch; epoch++ { + minEpoch, lastEpoch := ihgs.getMinAndLastEpoch() + for epoch := minEpoch; epoch <= lastEpoch; epoch++ { epochNodesData, ok := ihgs.nodesConfig[epoch] if !ok { continue From 82bf91ed842dfbf03c7ddef8048fab4943cc6aa0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 8 Mar 2022 16:20:08 +0200 Subject: [PATCH 093/958] FEAT: Add CreateNodesCoordinatorRegistry --- epochStart/bootstrap/fromLocalStorage.go | 4 +-- sharding/common.go | 34 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/epochStart/bootstrap/fromLocalStorage.go b/epochStart/bootstrap/fromLocalStorage.go index 89cf93e7e29..b86079a6005 100644 --- a/epochStart/bootstrap/fromLocalStorage.go +++ b/epochStart/bootstrap/fromLocalStorage.go @@ -2,7 +2,6 @@ package bootstrap import ( "bytes" - "encoding/json" "fmt" "strconv" @@ -263,8 +262,7 @@ func (e *epochStartBootstrap) getLastBootstrapData(storer storage.Storer) (*boot return nil, nil, err } - config := &sharding.NodesCoordinatorRegistry{} - err = json.Unmarshal(d, config) + config, err := sharding.CreateNodesCoordinatorRegistry(e.coreComponentsHolder.InternalMarshalizer(), d) if err != nil { return nil, nil, err } diff --git a/sharding/common.go b/sharding/common.go index 722d5896238..30ada0cbe0f 100644 --- a/sharding/common.go +++ b/sharding/common.go @@ -2,9 +2,11 @@ package sharding import ( "encoding/hex" + "encoding/json" "strconv" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/marshal" logger "github.com/ElrondNetwork/elrond-go-logger" ) @@ -113,3 +115,35 @@ func SerializableShardValidatorListToValidatorList(shardValidators []*Serializab } return newValidators, nil } + +// CreateNodesCoordinatorRegistry creates a NodesCoordinatorRegistryHandler depending on the buffer. Old version uses +// NodesCoordinatorRegistry with a json marshaller; while the new version(from staking v4) uses NodesCoordinatorRegistryWithAuction +// with proto marshaller +func CreateNodesCoordinatorRegistry(marshaller marshal.Marshalizer, buff []byte) (NodesCoordinatorRegistryHandler, error) { + registry, err := createOldRegistry(buff) + if err == nil { + return registry, nil + } + + return createRegistryWithAuction(marshaller, buff) +} + +func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { + registry := &NodesCoordinatorRegistry{} + err := json.Unmarshal(buff, registry) + if err != nil { + return nil, err + } + + return registry, nil +} + +func createRegistryWithAuction(marshaller marshal.Marshalizer, buff []byte) (*NodesCoordinatorRegistryWithAuction, error) { + registry := &NodesCoordinatorRegistryWithAuction{} + err := marshaller.Unmarshal(registry, buff) + if err != nil { + return nil, err + } + + return registry, nil +} From 3ca3f892970f5418114377f5cd848c2ecce8d432 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 10:57:25 +0200 Subject: [PATCH 094/958] FEAT: Use CreateNodesCoordinatorRegistry in nodesCoord --- sharding/indexHashedNodesCoordinatorRegistry.go | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index 719cd71a554..44c8b2c4f7f 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -26,19 +26,9 @@ func (ihgs *indexHashedNodesCoordinator) baseLoadState(key []byte) error { return err } - var config NodesCoordinatorRegistryHandler - if ihgs.flagStakingV4.IsSet() { - config = &NodesCoordinatorRegistryWithAuction{} - err = ihgs.marshalizer.Unmarshal(config, data) - if err != nil { - return err - } - } else { - config = &NodesCoordinatorRegistry{} - err = json.Unmarshal(data, config) - if err != nil { - return err - } + config, err := CreateNodesCoordinatorRegistry(ihgs.marshalizer, data) + if err != nil { + return err } ihgs.mutSavedStateKey.Lock() From 3df6cfb087bd1ddeece009ffdfb87347ba3d5a97 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 12:05:02 +0200 Subject: [PATCH 095/958] FIX: Integration test --- integrationTests/testProcessorNode.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index ca61fb0078e..caa105328bc 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -202,6 +202,9 @@ const stateCheckpointModulus = 100 // StakingV2Epoch defines the epoch for integration tests when stakingV2 is enabled const StakingV2Epoch = 1000 +// StakingV4Epoch defines the epoch for integration tests when stakingV4 is enabled +const StakingV4Epoch = 4444 + // ScheduledMiniBlocksEnableEpoch defines the epoch for integration tests when scheduled nini blocks are enabled const ScheduledMiniBlocksEnableEpoch = 1000 @@ -2207,8 +2210,10 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { ESDTOwnerAddressBytes: vm.EndOfEpochAddress, EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: StakingV2Epoch, - ESDTEnableEpoch: 0, + StakingV2EnableEpoch: StakingV2Epoch, + StakingV4InitEnableEpoch: StakingV4Epoch - 1, + StakingV4EnableEpoch: StakingV4Epoch, + ESDTEnableEpoch: 0, }, }, } From c3abbdb452be9ef6dfcf8702dba71ca9b3e71f59 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 12:20:52 +0200 Subject: [PATCH 096/958] FIX: Broken tests --- process/block/metablock_test.go | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 0cdf20d998b..4ce5c57d706 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3067,7 +3067,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() - header := &block.MetaBlock{ + headerMeta := &block.MetaBlock{ Nonce: 1, Round: 1, PrevHash: []byte("hash1"), @@ -3091,9 +3091,8 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { } arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error { - assert.Equal(t, header.GetEpoch(), epoch) - assert.Equal(t, header.GetNonce(), nonce) + ProcessSystemSmartContractCalled: func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + assert.Equal(t, headerMeta, header) wasCalled = true return nil }, @@ -3101,7 +3100,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { mp, _ := blproc.NewMetaProcessor(arguments) - err := mp.ProcessEpochStartMetaBlock(header, &block.Body{}) + err := mp.ProcessEpochStartMetaBlock(headerMeta, &block.Body{}) assert.Nil(t, err) }) @@ -3123,9 +3122,8 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { } arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorInfos map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error { - assert.Equal(t, header.GetEpoch(), epoch) - assert.Equal(t, header.GetNonce(), nonce) + ProcessSystemSmartContractCalled: func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + assert.Equal(t, headerMeta, header) assert.True(t, wasCalled) return nil }, @@ -3133,7 +3131,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { mp, _ := blproc.NewMetaProcessor(arguments) - err := mp.ProcessEpochStartMetaBlock(header, &block.Body{}) + err := mp.ProcessEpochStartMetaBlock(headerMeta, &block.Body{}) assert.Nil(t, err) }) } @@ -3334,10 +3332,9 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { wasCalled := false arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error { + ProcessSystemSmartContractCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { wasCalled = true - assert.Equal(t, mb.GetNonce(), nonce) - assert.Equal(t, mb.GetEpoch(), epoch) + assert.Equal(t, mb, header) return nil }, } @@ -3427,10 +3424,9 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, nonce uint64, epoch uint32) error { + ProcessSystemSmartContractCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { assert.True(t, wasCalled) - assert.Equal(t, mb.GetNonce(), nonce) - assert.Equal(t, mb.GetEpoch(), epoch) + assert.Equal(t, mb, header) return nil }, } From 47c771241b9b37da91c2fb283ea2b313fd0e7fbf Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 12:55:56 +0200 Subject: [PATCH 097/958] FEAT: Move selected nodes from AuctionList to SelectedFromAuctionList --- common/constants.go | 4 ++++ epochStart/metachain/systemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/common/constants.go b/common/constants.go index 7b2c67bfaa8..67952815d4e 100644 --- a/common/constants.go +++ b/common/constants.go @@ -33,6 +33,10 @@ const NewList PeerType = "new" // based on their top up stake const AuctionList PeerType = "auction" +// SelectedFromAuctionList represents the list of peers which have been selected from AuctionList based on +// their top up to be distributed on the WaitingList in the next epoch +const SelectedFromAuctionList PeerType = "selectedFromAuction" + // CombinedPeerType - represents the combination of two peerTypes const CombinedPeerType = "%s (%s)" diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 94f86a92630..6b44e21fbd1 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -384,7 +384,7 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap map[uin // TODO: Think of a better way of handling these pointers; perhaps use an interface which handles validators for i := uint32(0); i < numOfAvailableNodeSlots; i++ { - auctionList[i].List = string(common.NewList) + auctionList[i].List = string(common.SelectedFromAuctionList) } return nil diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e2c547bf40e..a6d82c0c8d0 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2106,18 +2106,18 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing 0: { createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1), createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1), - createValidatorInfo(owner1StakedKeys[2], common.NewList, owner1), + createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, owner1), }, 1: { createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2), - createValidatorInfo(owner2StakedKeys[1], common.NewList, owner2), + createValidatorInfo(owner2StakedKeys[1], common.SelectedFromAuctionList, owner2), createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2), createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3), createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3), createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4), - createValidatorInfo(owner4StakedKeys[1], common.NewList, owner4), + createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4), }, } require.Equal(t, expectedValidatorsInfo, validatorsInfo) @@ -2196,7 +2196,7 @@ func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, staked // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { rating := uint32(0) - if list == common.NewList || list == common.AuctionList { + if list == common.NewList || list == common.AuctionList || list == common.SelectedFromAuctionList { rating = uint32(5) } From 4fcc03f71defba1c0ac3904bad042c0dde28ea4c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 13:59:57 +0200 Subject: [PATCH 098/958] FIX: Broken test --- integrationTests/testInitializer.go | 4 ++++ integrationTests/testProcessorNode.go | 6 +++++- integrationTests/vm/txsFee/validatorSC_test.go | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 34c91c349ca..d387ee3520b 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -742,6 +742,8 @@ func CreateFullGenesisBlocks( RelayedTransactionsEnableEpoch: 0, PenalizedTooMuchGasEnableEpoch: 0, StakingV2EnableEpoch: StakingV2Epoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4InitEnableEpoch: StakingV4Epoch - 1, StakeEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, DelegationManagerEnableEpoch: 0, @@ -854,6 +856,8 @@ func CreateGenesisMetaBlock( RelayedTransactionsEnableEpoch: 0, PenalizedTooMuchGasEnableEpoch: 0, StakingV2EnableEpoch: StakingV2Epoch, + StakingV4InitEnableEpoch: StakingV4Epoch - 1, + StakingV4EnableEpoch: StakingV4Epoch, StakeEnableEpoch: 0, DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index caa105328bc..d39e8852de3 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -202,7 +202,7 @@ const stateCheckpointModulus = 100 // StakingV2Epoch defines the epoch for integration tests when stakingV2 is enabled const StakingV2Epoch = 1000 -// StakingV4Epoch defines the epoch for integration tests when stakingV4 is enabled +// StakingV4Epoch defines the epoch for integration tests when stakingV4 is enabled; should be greater than StakingV2Epoch const StakingV4Epoch = 4444 // ScheduledMiniBlocksEnableEpoch defines the epoch for integration tests when scheduled nini blocks are enabled @@ -433,6 +433,8 @@ func newBaseTestProcessorNode( tpn.initDataPools() tpn.EnableEpochs = config.EnableEpochs{ OptimizeGasUsedInCrossMiniBlocksEnableEpoch: 10, + StakingV4InitEnableEpoch: StakingV4Epoch - 1, + StakingV4EnableEpoch: StakingV4Epoch, } return tpn @@ -922,6 +924,7 @@ func (tpn *TestProcessorNode) createFullSCQueryService() { EpochConfig: &config.EpochConfig{ EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: 0, + StakingV4EnableEpoch: 444, StakeEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, DelegationManagerEnableEpoch: 0, @@ -1730,6 +1733,7 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors() { ShardCoordinator: tpn.ShardCoordinator, NodesCoordinator: tpn.NodesCoordinator, } + argsVMContainerFactory.EpochConfig.EnableEpochs.StakingV4EnableEpoch = StakingV4Epoch vmFactory, _ := metaProcess.NewVMContainerFactory(argsVMContainerFactory) tpn.VMContainer, _ = vmFactory.Create() diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index 762f71d87c8..d0c1c3ac3d2 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -106,7 +106,7 @@ func checkReturnLog(t *testing.T, testContextMeta *vm.VMTestContext, subStr stri } func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *testing.T) { - testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{}) + testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{StakingV4EnableEpoch: 444}) require.Nil(t, err) defer testContextMeta.Close() From 20535f3ee4a4925cadc813e2ca2213703ffb7ca3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 16:29:00 +0200 Subject: [PATCH 099/958] FIX: Review findings --- epochStart/metachain/systemSCs.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6b44e21fbd1..ed53eb5a015 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -293,14 +293,16 @@ func (s *systemSCProcessor) processWithOldFlags( return err } - numUnStaked, err := s.unStakeNonEligibleNodes(validatorsInfoMap, epoch) + numUnStaked, err := s.unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap, epoch) if err != nil { return err } - err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) - if err != nil { - return err + if s.flagStakingQueueEnabled.IsSet() { + err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) + if err != nil { + return err + } } } @@ -351,7 +353,7 @@ func (s *systemSCProcessor) processWithNewFlags( return err } - _, err = s.unStakeNonEligibleNodes(validatorsInfoMap, header.GetEpoch()) + _, err = s.unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap, header.GetEpoch()) if err != nil { return err } @@ -726,7 +728,7 @@ func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap map[ return s.prepareStakingData(allNodes) } -func (s *systemSCProcessor) unStakeNonEligibleNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32) (uint32, error) { +func (s *systemSCProcessor) unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32) (uint32, error) { err := s.fillStakingDataForNonEligible(validatorsInfoMap) if err != nil { return 0, err From 56b33f5b67ffb0435b50f20cb3ea7e2a7b294a42 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 9 Mar 2022 17:31:08 +0200 Subject: [PATCH 100/958] FIX: Broken tests --- integrationTests/vm/txsFee/validatorSC_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index d0c1c3ac3d2..23fb232e542 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -139,11 +139,13 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes func TestValidatorsSC_DoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *testing.T) { argUnbondTokensV1 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 20000, + StakingV4EnableEpoch: 44444, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV1) argUnbondTokensV2 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 0, + StakingV4EnableEpoch: 44444, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV2) } @@ -177,7 +179,7 @@ func testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *t } func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens(t *testing.T) { - testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{}) + testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{StakingV4EnableEpoch: 4444}) require.Nil(t, err) defer testContextMeta.Close() @@ -224,7 +226,7 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens( } func TestValidatorsSC_ToStakePutInQueueUnStakeNodesAndUnBondNodesShouldRefund(t *testing.T) { - testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{}) + testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{StakingV4EnableEpoch: 444}) require.Nil(t, err) defer testContextMeta.Close() From 18382765388f9c9a20608fff052bf4a7b0b475ca Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 9 Mar 2022 19:27:47 +0200 Subject: [PATCH 101/958] - systemSCs.go code split --- epochStart/metachain/legacySystemSCs.go | 1319 +++++++++++++++++++++ epochStart/metachain/systemSCs.go | 1430 ++--------------------- 2 files changed, 1394 insertions(+), 1355 deletions(-) create mode 100644 epochStart/metachain/legacySystemSCs.go diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go new file mode 100644 index 00000000000..dfc450ac3df --- /dev/null +++ b/epochStart/metachain/legacySystemSCs.go @@ -0,0 +1,1319 @@ +package metachain + +import ( + "bytes" + "encoding/hex" + "fmt" + "math" + "math/big" + "sort" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/atomic" + "github.com/ElrondNetwork/elrond-go-core/core/check" + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/common" + vInfo "github.com/ElrondNetwork/elrond-go/common/validatorInfo" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" +) + +type legacySystemSCProcessor struct { + systemVM vmcommon.VMExecutionHandler + userAccountsDB state.AccountsAdapter + marshalizer marshal.Marshalizer + peerAccountsDB state.AccountsAdapter + chanceComputer sharding.ChanceComputer + shardCoordinator sharding.Coordinator + startRating uint32 + validatorInfoCreator epochStart.ValidatorInfoCreator + genesisNodesConfig sharding.GenesisNodesSetupHandler + nodesConfigProvider epochStart.NodesConfigProvider + stakingDataProvider epochStart.StakingDataProvider + endOfEpochCallerAddress []byte + stakingSCAddress []byte + esdtOwnerAddressBytes []byte + mapNumSwitchedPerShard map[uint32]uint32 + mapNumSwitchablePerShard map[uint32]uint32 + maxNodesEnableConfig []config.MaxNodesChangeConfig + maxNodes uint32 + + switchEnableEpoch uint32 + hystNodesEnableEpoch uint32 + delegationEnableEpoch uint32 + stakingV2EnableEpoch uint32 + correctLastUnJailEpoch uint32 + esdtEnableEpoch uint32 + saveJailedAlwaysEnableEpoch uint32 + stakingV4InitEnableEpoch uint32 + + flagSwitchJailedWaiting atomic.Flag + flagHystNodesEnabled atomic.Flag + flagDelegationEnabled atomic.Flag + flagSetOwnerEnabled atomic.Flag + flagChangeMaxNodesEnabled atomic.Flag + flagStakingV2Enabled atomic.Flag + flagCorrectLastUnjailedEnabled atomic.Flag + flagCorrectNumNodesToStake atomic.Flag + flagESDTEnabled atomic.Flag + flagSaveJailedAlwaysEnabled atomic.Flag + flagStakingQueueEnabled atomic.Flag + flagInitStakingV4Enabled atomic.Flag +} + +func (s *legacySystemSCProcessor) processLegacy( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + nonce uint64, + epoch uint32, +) error { + if s.flagHystNodesEnabled.IsSet() { + err := s.updateSystemSCConfigMinNodes() + if err != nil { + return err + } + } + + if s.flagSetOwnerEnabled.IsSet() { + err := s.updateOwnersForBlsKeys() + if err != nil { + return err + } + } + + if s.flagChangeMaxNodesEnabled.IsSet() { + err := s.updateMaxNodes(validatorsInfoMap, nonce) + if err != nil { + return err + } + } + + if s.flagCorrectLastUnjailedEnabled.IsSet() { + err := s.resetLastUnJailed() + if err != nil { + return err + } + } + + if s.flagDelegationEnabled.IsSet() { + err := s.initDelegationSystemSC() + if err != nil { + return err + } + } + + if s.flagCorrectNumNodesToStake.IsSet() { + err := s.cleanAdditionalQueue() + if err != nil { + return err + } + } + + if s.flagSwitchJailedWaiting.IsSet() { + err := s.computeNumWaitingPerShard(validatorsInfoMap) + if err != nil { + return err + } + + err = s.swapJailedWithWaiting(validatorsInfoMap) + if err != nil { + return err + } + } + + if s.flagStakingV2Enabled.IsSet() { + err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) + if err != nil { + return err + } + + numUnStaked, err := s.unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap, epoch) + if err != nil { + return err + } + + if s.flagStakingQueueEnabled.IsSet() { + err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) + if err != nil { + return err + } + } + } + + if s.flagESDTEnabled.IsSet() { + err := s.initESDT() + if err != nil { + // not a critical error + log.Error("error while initializing ESDT", "err", err) + } + } + + return nil +} + +// ToggleUnStakeUnBond will pause/unPause the unStake/unBond functions on the validator system sc +func (s *legacySystemSCProcessor) ToggleUnStakeUnBond(value bool) error { + if !s.flagStakingV2Enabled.IsSet() { + return nil + } + + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: nil, + CallValue: big.NewInt(0), + }, + RecipientAddr: vm.ValidatorSCAddress, + Function: "unPauseUnStakeUnBond", + } + + if value { + vmInput.Function = "pauseUnStakeUnBond" + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + + if vmOutput.ReturnCode != vmcommon.Ok { + return epochStart.ErrSystemValidatorSCCall + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + epoch uint32, +) (uint32, error) { + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) + if err != nil { + return 0, err + } + + nodesUnStakedFromAdditionalQueue := uint32(0) + + log.Debug("unStake nodes with not enough funds", "num", len(nodesToUnStake)) + for _, blsKey := range nodesToUnStake { + log.Debug("unStake at end of epoch for node", "blsKey", blsKey) + err = s.unStakeOneNode(blsKey, epoch) + if err != nil { + return 0, err + } + + validatorInfo := getValidatorInfoWithBLSKey(validatorsInfoMap, blsKey) + if validatorInfo == nil { + nodesUnStakedFromAdditionalQueue++ + log.Debug("unStaked node which was in additional queue", "blsKey", blsKey) + continue + } + + validatorInfo.List = string(common.LeavingList) + } + + err = s.updateDelegationContracts(mapOwnersKeys) + if err != nil { + return 0, err + } + + nodesToStakeFromQueue := uint32(len(nodesToUnStake)) + if s.flagCorrectNumNodesToStake.IsSet() { + nodesToStakeFromQueue -= nodesUnStakedFromAdditionalQueue + } + + log.Debug("stake nodes from waiting list", "num", nodesToStakeFromQueue) + return nodesToStakeFromQueue, nil +} + +func (s *legacySystemSCProcessor) unStakeOneNode(blsKey []byte, epoch uint32) error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{blsKey}, + CallValue: big.NewInt(0), + }, + RecipientAddr: s.stakingSCAddress, + Function: "unStakeAtEndOfEpoch", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + if vmOutput.ReturnCode != vmcommon.Ok { + log.Debug("unStakeOneNode", "returnMessage", vmOutput.ReturnMessage, "returnCode", vmOutput.ReturnCode.String()) + return epochStart.ErrUnStakeExecuteError + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + account, errExists := s.peerAccountsDB.GetExistingAccount(blsKey) + if errExists != nil { + return nil + } + + peerAccount, ok := account.(state.PeerAccountHandler) + if !ok { + return epochStart.ErrWrongTypeAssertion + } + + peerAccount.SetListAndIndex(peerAccount.GetShardId(), string(common.LeavingList), peerAccount.GetIndexInList()) + peerAccount.SetUnStakedEpoch(epoch) + err = s.peerAccountsDB.SaveAccount(peerAccount) + if err != nil { + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) updateDelegationContracts(mapOwnerKeys map[string][][]byte) error { + sortedDelegationsSCs := make([]string, 0, len(mapOwnerKeys)) + for address := range mapOwnerKeys { + shardId := s.shardCoordinator.ComputeId([]byte(address)) + if shardId != core.MetachainShardId { + continue + } + sortedDelegationsSCs = append(sortedDelegationsSCs, address) + } + + sort.Slice(sortedDelegationsSCs, func(i, j int) bool { + return sortedDelegationsSCs[i] < sortedDelegationsSCs[j] + }) + + for _, address := range sortedDelegationsSCs { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: mapOwnerKeys[address], + CallValue: big.NewInt(0), + }, + RecipientAddr: []byte(address), + Function: "unStakeAtEndOfEpoch", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + if vmOutput.ReturnCode != vmcommon.Ok { + log.Debug("unStakeAtEndOfEpoch", "returnMessage", vmOutput.ReturnMessage, "returnCode", vmOutput.ReturnCode.String()) + return epochStart.ErrUnStakeExecuteError + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + } + + return nil +} + +func getValidatorInfoWithBLSKey(validatorsInfoMap map[uint32][]*state.ValidatorInfo, blsKey []byte) *state.ValidatorInfo { + for _, validatorsInfoSlice := range validatorsInfoMap { + for _, validatorInfo := range validatorsInfoSlice { + if bytes.Equal(validatorInfo.PublicKey, blsKey) { + return validatorInfo + } + } + } + return nil +} + +func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + for shId, validatorsInfoSlice := range validatorsInfoMap { + newList := make([]*state.ValidatorInfo, 0, len(validatorsInfoSlice)) + deleteCalled := false + + for _, validatorInfo := range validatorsInfoSlice { + if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { + newList = append(newList, validatorInfo) + continue + } + + err := s.stakingDataProvider.FillValidatorInfo(validatorInfo.PublicKey) + if err != nil { + deleteCalled = true + + log.Error("fillStakingDataForNonEligible", "error", err) + if len(validatorInfo.List) > 0 { + return err + } + + err = s.peerAccountsDB.RemoveAccount(validatorInfo.PublicKey) + if err != nil { + log.Error("fillStakingDataForNonEligible removeAccount", "error", err) + } + + continue + } + + newList = append(newList, validatorInfo) + } + + if deleteCalled { + validatorsInfoMap[shId] = newList + } + } + + return nil +} + +func (s *legacySystemSCProcessor) prepareStakingDataForEligibleNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + eligibleNodes := s.getEligibleNodeKeys(validatorsInfoMap) + return s.prepareStakingData(eligibleNodes) +} + +func (s *legacySystemSCProcessor) unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32) (uint32, error) { + err := s.fillStakingDataForNonEligible(validatorsInfoMap) + if err != nil { + return 0, err + } + + return s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) +} + +func (s *legacySystemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byte) error { + sw := core.NewStopWatch() + sw.Start("prepareStakingDataForRewards") + defer func() { + sw.Stop("prepareStakingDataForRewards") + log.Debug("systemSCProcessor.prepareStakingDataForRewards time measurements", sw.GetMeasurements()...) + }() + + return s.stakingDataProvider.PrepareStakingData(nodeKeys) +} + +func (s *legacySystemSCProcessor) getEligibleNodeKeys( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, +) map[uint32][][]byte { + eligibleNodesKeys := make(map[uint32][][]byte) + for shardID, validatorsInfoSlice := range validatorsInfoMap { + eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) + for _, validatorInfo := range validatorsInfoSlice { + if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { + eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.PublicKey) + } + } + } + + return eligibleNodesKeys +} + +// ProcessDelegationRewards will process the rewards which are directed towards the delegation system smart contracts +func (s *legacySystemSCProcessor) ProcessDelegationRewards( + miniBlocks block.MiniBlockSlice, + txCache epochStart.TransactionCacher, +) error { + if txCache == nil { + return epochStart.ErrNilLocalTxCache + } + + rwdMb := getRewardsMiniBlockForMeta(miniBlocks) + if rwdMb == nil { + return nil + } + + for _, txHash := range rwdMb.TxHashes { + rwdTx, err := txCache.GetTx(txHash) + if err != nil { + return err + } + + err = s.executeRewardTx(rwdTx) + if err != nil { + return err + } + } + + return nil +} + +func (s *legacySystemSCProcessor) executeRewardTx(rwdTx data.TransactionHandler) error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: nil, + CallValue: rwdTx.GetValue(), + }, + RecipientAddr: rwdTx.GetRcvAddr(), + Function: "updateRewards", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + + if vmOutput.ReturnCode != vmcommon.Ok { + return epochStart.ErrSystemDelegationCall + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + return nil +} + +// updates the configuration of the system SC if the flags permit +func (s *legacySystemSCProcessor) updateSystemSCConfigMinNodes() error { + minNumberOfNodesWithHysteresis := s.genesisNodesConfig.MinNumberOfNodesWithHysteresis() + err := s.setMinNumberOfNodes(minNumberOfNodesWithHysteresis) + + return err +} + +func (s *legacySystemSCProcessor) resetLastUnJailed() error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{}, + CallValue: big.NewInt(0), + }, + RecipientAddr: s.stakingSCAddress, + Function: "resetLastUnJailedFromQueue", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + + if vmOutput.ReturnCode != vmcommon.Ok { + return epochStart.ErrResetLastUnJailedFromQueue + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + return nil +} + +// updates the configuration of the system SC if the flags permit +func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64) error { + sw := core.NewStopWatch() + sw.Start("total") + defer func() { + sw.Stop("total") + log.Debug("systemSCProcessor.updateMaxNodes", sw.GetMeasurements()...) + }() + + maxNumberOfNodes := s.maxNodes + sw.Start("setMaxNumberOfNodes") + prevMaxNumberOfNodes, err := s.setMaxNumberOfNodes(maxNumberOfNodes) + sw.Stop("setMaxNumberOfNodes") + if err != nil { + return err + } + + if maxNumberOfNodes < prevMaxNumberOfNodes { + return epochStart.ErrInvalidMaxNumberOfNodes + } + + if s.flagStakingQueueEnabled.IsSet() { + sw.Start("stakeNodesFromQueue") + err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) + sw.Stop("stakeNodesFromQueue") + if err != nil { + return err + } + } + return nil +} + +func (s *legacySystemSCProcessor) computeNumWaitingPerShard(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + for shardID, validatorInfoList := range validatorsInfoMap { + totalInWaiting := uint32(0) + for _, validatorInfo := range validatorInfoList { + switch validatorInfo.List { + case string(common.WaitingList): + totalInWaiting++ + } + } + s.mapNumSwitchablePerShard[shardID] = totalInWaiting + s.mapNumSwitchedPerShard[shardID] = 0 + } + return nil +} + +func (s *legacySystemSCProcessor) swapJailedWithWaiting(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { + jailedValidators := s.getSortedJailedNodes(validatorsInfoMap) + + log.Debug("number of jailed validators", "num", len(jailedValidators)) + + newValidators := make(map[string]struct{}) + for _, jailedValidator := range jailedValidators { + if _, ok := newValidators[string(jailedValidator.PublicKey)]; ok { + continue + } + if isValidator(jailedValidator) && s.mapNumSwitchablePerShard[jailedValidator.ShardId] <= s.mapNumSwitchedPerShard[jailedValidator.ShardId] { + log.Debug("cannot switch in this epoch anymore for this shard as switched num waiting", + "shardID", jailedValidator.ShardId, + "numSwitched", s.mapNumSwitchedPerShard[jailedValidator.ShardId]) + continue + } + + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{jailedValidator.PublicKey}, + CallValue: big.NewInt(0), + }, + RecipientAddr: s.stakingSCAddress, + Function: "switchJailedWithWaiting", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + + log.Debug("switchJailedWithWaiting called for", + "key", jailedValidator.PublicKey, + "returnMessage", vmOutput.ReturnMessage) + if vmOutput.ReturnCode != vmcommon.Ok { + continue + } + + newValidator, err := s.stakingToValidatorStatistics(validatorsInfoMap, jailedValidator, vmOutput) + if err != nil { + return err + } + + if len(newValidator) != 0 { + newValidators[string(newValidator)] = struct{}{} + } + } + + return nil +} + +func (s *legacySystemSCProcessor) stakingToValidatorStatistics( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + jailedValidator *state.ValidatorInfo, + vmOutput *vmcommon.VMOutput, +) ([]byte, error) { + stakingSCOutput, ok := vmOutput.OutputAccounts[string(s.stakingSCAddress)] + if !ok { + return nil, epochStart.ErrStakingSCOutputAccountNotFound + } + + var activeStorageUpdate *vmcommon.StorageUpdate + for _, storageUpdate := range stakingSCOutput.StorageUpdates { + isNewValidatorKey := len(storageUpdate.Offset) == len(jailedValidator.PublicKey) && + !bytes.Equal(storageUpdate.Offset, jailedValidator.PublicKey) + if isNewValidatorKey { + activeStorageUpdate = storageUpdate + break + } + } + if activeStorageUpdate == nil { + log.Debug("no one in waiting suitable for switch") + if s.flagSaveJailedAlwaysEnabled.IsSet() { + err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return nil, err + } + } + + return nil, nil + } + + err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return nil, err + } + + var stakingData systemSmartContracts.StakedDataV2_0 + err = s.marshalizer.Unmarshal(&stakingData, activeStorageUpdate.Data) + if err != nil { + return nil, err + } + + blsPubKey := activeStorageUpdate.Offset + log.Debug("staking validator key who switches with the jailed one", "blsKey", blsPubKey) + account, err := s.getPeerAccount(blsPubKey) + if err != nil { + return nil, err + } + + if !bytes.Equal(account.GetRewardAddress(), stakingData.RewardAddress) { + err = account.SetRewardAddress(stakingData.RewardAddress) + if err != nil { + return nil, err + } + } + + if !bytes.Equal(account.GetBLSPublicKey(), blsPubKey) { + err = account.SetBLSPublicKey(blsPubKey) + if err != nil { + return nil, err + } + } else { + // old jailed validator getting switched back after unJail with stake - must remove first from exported map + deleteNewValidatorIfExistsFromMap(validatorsInfoMap, blsPubKey, account.GetShardId()) + } + + account.SetListAndIndex(jailedValidator.ShardId, string(common.NewList), uint32(stakingData.StakedNonce)) + account.SetTempRating(s.startRating) + account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) + + err = s.peerAccountsDB.SaveAccount(account) + if err != nil { + return nil, err + } + + jailedAccount, err := s.getPeerAccount(jailedValidator.PublicKey) + if err != nil { + return nil, err + } + + jailedAccount.SetListAndIndex(jailedValidator.ShardId, string(common.JailedList), jailedValidator.Index) + jailedAccount.ResetAtNewEpoch() + err = s.peerAccountsDB.SaveAccount(jailedAccount) + if err != nil { + return nil, err + } + + if isValidator(jailedValidator) { + s.mapNumSwitchedPerShard[jailedValidator.ShardId]++ + } + + newValidatorInfo := s.validatorInfoCreator.PeerAccountToValidatorInfo(account) + switchJailedWithNewValidatorInMap(validatorsInfoMap, jailedValidator, newValidatorInfo) + + return blsPubKey, nil +} + +func isValidator(validator *state.ValidatorInfo) bool { + return validator.List == string(common.WaitingList) || validator.List == string(common.EligibleList) +} + +func deleteNewValidatorIfExistsFromMap( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + blsPubKey []byte, + shardID uint32, +) { + for index, validatorInfo := range validatorsInfoMap[shardID] { + if bytes.Equal(validatorInfo.PublicKey, blsPubKey) { + length := len(validatorsInfoMap[shardID]) + validatorsInfoMap[shardID][index] = validatorsInfoMap[shardID][length-1] + validatorsInfoMap[shardID][length-1] = nil + validatorsInfoMap[shardID] = validatorsInfoMap[shardID][:length-1] + break + } + } +} + +func switchJailedWithNewValidatorInMap( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + jailedValidator *state.ValidatorInfo, + newValidator *state.ValidatorInfo, +) { + for index, validatorInfo := range validatorsInfoMap[jailedValidator.ShardId] { + if bytes.Equal(validatorInfo.PublicKey, jailedValidator.PublicKey) { + validatorsInfoMap[jailedValidator.ShardId][index] = newValidator + break + } + } +} + +func (s *legacySystemSCProcessor) getUserAccount(address []byte) (state.UserAccountHandler, error) { + acnt, err := s.userAccountsDB.LoadAccount(address) + if err != nil { + return nil, err + } + + stAcc, ok := acnt.(state.UserAccountHandler) + if !ok { + return nil, process.ErrWrongTypeAssertion + } + + return stAcc, nil +} + +// save account changes in state from vmOutput - protected by VM - every output can be treated as is. +func (s *legacySystemSCProcessor) processSCOutputAccounts( + vmOutput *vmcommon.VMOutput, +) error { + + outputAccounts := process.SortVMOutputInsideData(vmOutput) + for _, outAcc := range outputAccounts { + acc, err := s.getUserAccount(outAcc.Address) + if err != nil { + return err + } + + storageUpdates := process.GetSortedStorageUpdates(outAcc) + for _, storeUpdate := range storageUpdates { + err = acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) + if err != nil { + return err + } + } + + if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(zero) != 0 { + err = acc.AddToBalance(outAcc.BalanceDelta) + if err != nil { + return err + } + } + + err = s.userAccountsDB.SaveAccount(acc) + if err != nil { + return err + } + } + + return nil +} + +func (s *legacySystemSCProcessor) getSortedJailedNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) []*state.ValidatorInfo { + newJailedValidators := make([]*state.ValidatorInfo, 0) + oldJailedValidators := make([]*state.ValidatorInfo, 0) + + minChance := s.chanceComputer.GetChance(0) + for _, listValidators := range validatorsInfoMap { + for _, validatorInfo := range listValidators { + if validatorInfo.List == string(common.JailedList) { + oldJailedValidators = append(oldJailedValidators, validatorInfo) + } else if s.chanceComputer.GetChance(validatorInfo.TempRating) < minChance { + newJailedValidators = append(newJailedValidators, validatorInfo) + } + } + } + + sort.Sort(validatorList(oldJailedValidators)) + sort.Sort(validatorList(newJailedValidators)) + + return append(oldJailedValidators, newJailedValidators...) +} + +func (s *legacySystemSCProcessor) getPeerAccount(key []byte) (state.PeerAccountHandler, error) { + account, err := s.peerAccountsDB.LoadAccount(key) + if err != nil { + return nil, err + } + + peerAcc, ok := account.(state.PeerAccountHandler) + if !ok { + return nil, epochStart.ErrWrongTypeAssertion + } + + return peerAcc, nil +} + +func (s *legacySystemSCProcessor) setMinNumberOfNodes(minNumNodes uint32) error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{big.NewInt(int64(minNumNodes)).Bytes()}, + CallValue: big.NewInt(0), + }, + RecipientAddr: s.stakingSCAddress, + Function: "updateConfigMinNodes", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + + log.Debug("setMinNumberOfNodes called with", + "minNumNodes", minNumNodes, + "returnMessage", vmOutput.ReturnMessage) + + if vmOutput.ReturnCode != vmcommon.Ok { + return epochStart.ErrInvalidMinNumberOfNodes + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) setMaxNumberOfNodes(maxNumNodes uint32) (uint32, error) { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{big.NewInt(int64(maxNumNodes)).Bytes()}, + CallValue: big.NewInt(0), + }, + RecipientAddr: s.stakingSCAddress, + Function: "updateConfigMaxNodes", + } + + vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return 0, err + } + + log.Debug("setMaxNumberOfNodes called with", + "maxNumNodes", maxNumNodes, + "returnMessage", vmOutput.ReturnMessage) + + if vmOutput.ReturnCode != vmcommon.Ok { + return 0, epochStart.ErrInvalidMaxNumberOfNodes + } + if len(vmOutput.ReturnData) != 1 { + return 0, epochStart.ErrInvalidSystemSCReturn + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return 0, err + } + + prevMaxNumNodes := big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64() + return uint32(prevMaxNumNodes), nil +} + +func (s *legacySystemSCProcessor) updateOwnersForBlsKeys() error { + sw := core.NewStopWatch() + sw.Start("systemSCProcessor") + defer func() { + sw.Stop("systemSCProcessor") + log.Debug("systemSCProcessor.updateOwnersForBlsKeys time measurements", sw.GetMeasurements()...) + }() + + sw.Start("getValidatorSystemAccount") + userValidatorAccount, err := s.getValidatorSystemAccount() + sw.Stop("getValidatorSystemAccount") + if err != nil { + return err + } + + sw.Start("getArgumentsForSetOwnerFunctionality") + arguments, err := s.getArgumentsForSetOwnerFunctionality(userValidatorAccount) + sw.Stop("getArgumentsForSetOwnerFunctionality") + if err != nil { + return err + } + + sw.Start("callSetOwnersOnAddresses") + err = s.callSetOwnersOnAddresses(arguments) + sw.Stop("callSetOwnersOnAddresses") + if err != nil { + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) getValidatorSystemAccount() (state.UserAccountHandler, error) { + validatorAccount, err := s.userAccountsDB.LoadAccount(vm.ValidatorSCAddress) + if err != nil { + return nil, fmt.Errorf("%w when loading validator account", err) + } + + userValidatorAccount, ok := validatorAccount.(state.UserAccountHandler) + if !ok { + return nil, fmt.Errorf("%w when loading validator account", epochStart.ErrWrongTypeAssertion) + } + + if check.IfNil(userValidatorAccount.DataTrie()) { + return nil, epochStart.ErrNilDataTrie + } + + return userValidatorAccount, nil +} + +func (s *legacySystemSCProcessor) getArgumentsForSetOwnerFunctionality(userValidatorAccount state.UserAccountHandler) ([][]byte, error) { + arguments := make([][]byte, 0) + + rootHash, err := userValidatorAccount.DataTrie().RootHash() + if err != nil { + return nil, err + } + + chLeaves, err := userValidatorAccount.DataTrie().GetAllLeavesOnChannel(rootHash) + if err != nil { + return nil, err + } + for leaf := range chLeaves { + validatorData := &systemSmartContracts.ValidatorDataV2{} + value, errTrim := leaf.ValueWithoutSuffix(append(leaf.Key(), vm.ValidatorSCAddress...)) + if errTrim != nil { + return nil, fmt.Errorf("%w for validator key %s", errTrim, hex.EncodeToString(leaf.Key())) + } + + err = s.marshalizer.Unmarshal(validatorData, value) + if err != nil { + continue + } + for _, blsKey := range validatorData.BlsPubKeys { + arguments = append(arguments, blsKey) + arguments = append(arguments, leaf.Key()) + } + } + + return arguments, nil +} + +func (s *legacySystemSCProcessor) callSetOwnersOnAddresses(arguments [][]byte) error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.EndOfEpochAddress, + CallValue: big.NewInt(0), + Arguments: arguments, + }, + RecipientAddr: vm.StakingSCAddress, + Function: "setOwnersOnAddresses", + } + + vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) + if errRun != nil { + return fmt.Errorf("%w when calling setOwnersOnAddresses function", errRun) + } + if vmOutput.ReturnCode != vmcommon.Ok { + return fmt.Errorf("got return code %s when calling setOwnersOnAddresses", vmOutput.ReturnCode) + } + + return s.processSCOutputAccounts(vmOutput) +} + +func (s *legacySystemSCProcessor) initDelegationSystemSC() error { + codeMetaData := &vmcommon.CodeMetadata{ + Upgradeable: false, + Payable: false, + Readable: true, + } + + vmInput := &vmcommon.ContractCreateInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.DelegationManagerSCAddress, + Arguments: [][]byte{}, + CallValue: big.NewInt(0), + }, + ContractCode: vm.DelegationManagerSCAddress, + ContractCodeMetadata: codeMetaData.ToBytes(), + } + + vmOutput, err := s.systemVM.RunSmartContractCreate(vmInput) + if err != nil { + return err + } + if vmOutput.ReturnCode != vmcommon.Ok { + return epochStart.ErrCouldNotInitDelegationSystemSC + } + + err = s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + err = s.updateSystemSCContractsCode(vmInput.ContractCodeMetadata) + if err != nil { + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) updateSystemSCContractsCode(contractMetadata []byte) error { + contractsToUpdate := make([][]byte, 0) + contractsToUpdate = append(contractsToUpdate, vm.StakingSCAddress) + contractsToUpdate = append(contractsToUpdate, vm.ValidatorSCAddress) + contractsToUpdate = append(contractsToUpdate, vm.GovernanceSCAddress) + contractsToUpdate = append(contractsToUpdate, vm.ESDTSCAddress) + contractsToUpdate = append(contractsToUpdate, vm.DelegationManagerSCAddress) + contractsToUpdate = append(contractsToUpdate, vm.FirstDelegationSCAddress) + + for _, address := range contractsToUpdate { + userAcc, err := s.getUserAccount(address) + if err != nil { + return err + } + + userAcc.SetOwnerAddress(address) + userAcc.SetCodeMetadata(contractMetadata) + userAcc.SetCode(address) + + err = s.userAccountsDB.SaveAccount(userAcc) + if err != nil { + return err + } + } + + return nil +} + +func (s *legacySystemSCProcessor) cleanAdditionalQueue() error { + sw := core.NewStopWatch() + sw.Start("systemSCProcessor") + defer func() { + sw.Stop("systemSCProcessor") + log.Debug("systemSCProcessor.cleanAdditionalQueue time measurements", sw.GetMeasurements()...) + }() + + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.EndOfEpochAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{}, + }, + RecipientAddr: vm.StakingSCAddress, + Function: "cleanAdditionalQueue", + } + vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) + if errRun != nil { + return fmt.Errorf("%w when cleaning additional queue", errRun) + } + if vmOutput.ReturnCode != vmcommon.Ok { + return fmt.Errorf("got return code %s, return message %s when cleaning additional queue", vmOutput.ReturnCode, vmOutput.ReturnMessage) + } + + err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + // returnData format is list(address - all blsKeys which were unstaked for that) + addressLength := len(s.endOfEpochCallerAddress) + mapOwnersKeys := make(map[string][][]byte) + currentOwner := "" + for _, returnData := range vmOutput.ReturnData { + if len(returnData) == addressLength { + currentOwner = string(returnData) + continue + } + + mapOwnersKeys[currentOwner] = append(mapOwnersKeys[currentOwner], returnData) + } + + err = s.updateDelegationContracts(mapOwnersKeys) + if err != nil { + log.Error("update delegation contracts failed after cleaning additional queue", "error", err.Error()) + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) stakeNodesFromQueue( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + nodesToStake uint32, + nonce uint64, + list common.PeerType, +) error { + if nodesToStake == 0 { + return nil + } + + nodesToStakeAsBigInt := big.NewInt(0).SetUint64(uint64(nodesToStake)) + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.EndOfEpochAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{nodesToStakeAsBigInt.Bytes()}, + }, + RecipientAddr: vm.StakingSCAddress, + Function: "stakeNodesFromQueue", + } + vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) + if errRun != nil { + return fmt.Errorf("%w when staking nodes from waiting list", errRun) + } + if vmOutput.ReturnCode != vmcommon.Ok { + return fmt.Errorf("got return code %s when staking nodes from waiting list", vmOutput.ReturnCode) + } + if len(vmOutput.ReturnData)%2 != 0 { + return fmt.Errorf("%w return data must be divisible by 2 when staking nodes from waiting list", epochStart.ErrInvalidSystemSCReturn) + } + + err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return err + } + + err = s.addNewlyStakedNodesToValidatorTrie(validatorsInfoMap, vmOutput.ReturnData, nonce, list) + if err != nil { + return err + } + + return nil +} + +func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( + validatorsInfoMap map[uint32][]*state.ValidatorInfo, + returnData [][]byte, + nonce uint64, + list common.PeerType, +) error { + for i := 0; i < len(returnData); i += 2 { + blsKey := returnData[i] + rewardAddress := returnData[i+1] + + peerAcc, err := s.getPeerAccount(blsKey) + if err != nil { + return err + } + + err = peerAcc.SetRewardAddress(rewardAddress) + if err != nil { + return err + } + + err = peerAcc.SetBLSPublicKey(blsKey) + if err != nil { + return err + } + + peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce)) + peerAcc.SetTempRating(s.startRating) + peerAcc.SetUnStakedEpoch(common.DefaultUnstakedEpoch) + + err = s.peerAccountsDB.SaveAccount(peerAcc) + if err != nil { + return err + } + + validatorInfo := &state.ValidatorInfo{ + PublicKey: blsKey, + ShardId: peerAcc.GetShardId(), + List: string(list), + Index: uint32(nonce), + TempRating: s.startRating, + Rating: s.startRating, + RewardAddress: rewardAddress, + AccumulatedFees: big.NewInt(0), + } + validatorsInfoMap[peerAcc.GetShardId()] = append(validatorsInfoMap[peerAcc.GetShardId()], validatorInfo) + } + + return nil +} + +func (s *legacySystemSCProcessor) initESDT() error { + currentConfigValues, err := s.extractConfigFromESDTContract() + if err != nil { + return err + } + + return s.changeESDTOwner(currentConfigValues) +} + +func (s *legacySystemSCProcessor) extractConfigFromESDTContract() ([][]byte, error) { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{}, + CallValue: big.NewInt(0), + GasProvided: math.MaxUint64, + }, + Function: "getContractConfig", + RecipientAddr: vm.ESDTSCAddress, + } + + output, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return nil, err + } + if len(output.ReturnData) != 4 { + return nil, fmt.Errorf("%w getContractConfig should have returned 4 values", epochStart.ErrInvalidSystemSCReturn) + } + + return output.ReturnData, nil +} + +func (s *legacySystemSCProcessor) changeESDTOwner(currentConfigValues [][]byte) error { + baseIssuingCost := currentConfigValues[1] + minTokenNameLength := currentConfigValues[2] + maxTokenNameLength := currentConfigValues[3] + + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: s.endOfEpochCallerAddress, + Arguments: [][]byte{s.esdtOwnerAddressBytes, baseIssuingCost, minTokenNameLength, maxTokenNameLength}, + CallValue: big.NewInt(0), + GasProvided: math.MaxUint64, + }, + Function: "configChange", + RecipientAddr: vm.ESDTSCAddress, + } + + output, err := s.systemVM.RunSmartContractCall(vmInput) + if err != nil { + return err + } + if output.ReturnCode != vmcommon.Ok { + return fmt.Errorf("%w changeESDTOwner should have returned Ok", epochStart.ErrInvalidSystemSCReturn) + } + + return s.processSCOutputAccounts(output) +} + +func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { + s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch) + log.Debug("systemSCProcessor: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) + + // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers + s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) + + s.flagChangeMaxNodesEnabled.SetValue(false) + for _, maxNodesConfig := range s.maxNodesEnableConfig { + if epoch == maxNodesConfig.EpochEnable { + s.flagChangeMaxNodesEnabled.SetValue(true) + s.maxNodes = maxNodesConfig.MaxNumNodes + break + } + } + + log.Debug("systemSCProcessor: consider also (minimum) hysteresis nodes for minimum number of nodes", + "enabled", epoch >= s.hystNodesEnableEpoch) + + // only toggle on exact epoch as init should be called only once + s.flagDelegationEnabled.SetValue(epoch == s.delegationEnableEpoch) + log.Debug("systemSCProcessor: delegation", "enabled", epoch >= s.delegationEnableEpoch) + + s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) + s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch < s.stakingV4InitEnableEpoch) + log.Debug("systemSCProcessor: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) + log.Debug("systemSCProcessor: change of maximum number of nodes and/or shuffling percentage", + "enabled", s.flagChangeMaxNodesEnabled.IsSet(), + "epoch", epoch, + "maxNodes", s.maxNodes, + ) + + s.flagCorrectLastUnjailedEnabled.SetValue(epoch == s.correctLastUnJailEpoch) + log.Debug("systemSCProcessor: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) + + s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch) + log.Debug("systemSCProcessor: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) + + s.flagESDTEnabled.SetValue(epoch == s.esdtEnableEpoch) + log.Debug("systemSCProcessor: ESDT initialization", "enabled", s.flagESDTEnabled.IsSet()) + + s.flagSaveJailedAlwaysEnabled.SetValue(epoch >= s.saveJailedAlwaysEnableEpoch) + log.Debug("systemSCProcessor: save jailed always", "enabled", s.flagSaveJailedAlwaysEnabled.IsSet()) + + s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) + log.Debug("systemProcessor: staking v4 on meta", "enabled", s.flagInitStakingV4Enabled.IsSet()) + + s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) + log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) +} diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index ed53eb5a015..0a8483c9c51 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -17,14 +17,12 @@ import ( "github.com/ElrondNetwork/elrond-go-core/marshal" logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" - vInfo "github.com/ElrondNetwork/elrond-go/common/validatorInfo" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" vmcommon "github.com/ElrondNetwork/elrond-vm-common" ) @@ -52,50 +50,15 @@ type ArgsNewEpochStartSystemSCProcessing struct { } type systemSCProcessor struct { - systemVM vmcommon.VMExecutionHandler - userAccountsDB state.AccountsAdapter - marshalizer marshal.Marshalizer - peerAccountsDB state.AccountsAdapter - chanceComputer sharding.ChanceComputer - shardCoordinator sharding.Coordinator - startRating uint32 - validatorInfoCreator epochStart.ValidatorInfoCreator - genesisNodesConfig sharding.GenesisNodesSetupHandler - nodesConfigProvider epochStart.NodesConfigProvider - stakingDataProvider epochStart.StakingDataProvider - endOfEpochCallerAddress []byte - stakingSCAddress []byte - switchEnableEpoch uint32 - hystNodesEnableEpoch uint32 - delegationEnableEpoch uint32 - stakingV2EnableEpoch uint32 - correctLastUnJailEpoch uint32 - esdtEnableEpoch uint32 - saveJailedAlwaysEnableEpoch uint32 - governanceEnableEpoch uint32 - builtInOnMetaEnableEpoch uint32 - stakingV4InitEnableEpoch uint32 - stakingV4EnableEpoch uint32 - maxNodesEnableConfig []config.MaxNodesChangeConfig - maxNodes uint32 - flagSwitchJailedWaiting atomic.Flag - flagHystNodesEnabled atomic.Flag - flagDelegationEnabled atomic.Flag - flagSetOwnerEnabled atomic.Flag - flagChangeMaxNodesEnabled atomic.Flag - flagStakingV2Enabled atomic.Flag - flagCorrectLastUnjailedEnabled atomic.Flag - flagCorrectNumNodesToStake atomic.Flag - flagESDTEnabled atomic.Flag - flagSaveJailedAlwaysEnabled atomic.Flag - flagGovernanceEnabled atomic.Flag - flagBuiltInOnMetaEnabled atomic.Flag - flagInitStakingV4Enabled atomic.Flag - flagStakingQueueEnabled atomic.Flag - flagStakingV4Enabled atomic.Flag - esdtOwnerAddressBytes []byte - mapNumSwitchedPerShard map[uint32]uint32 - mapNumSwitchablePerShard map[uint32]uint32 + *legacySystemSCProcessor + + governanceEnableEpoch uint32 + builtInOnMetaEnableEpoch uint32 + stakingV4EnableEpoch uint32 + + flagGovernanceEnabled atomic.Flag + flagBuiltInOnMetaEnabled atomic.Flag + flagStakingV4Enabled atomic.Flag } type validatorList []*state.ValidatorInfo @@ -164,33 +127,35 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr } s := &systemSCProcessor{ - systemVM: args.SystemVM, - userAccountsDB: args.UserAccountsDB, - peerAccountsDB: args.PeerAccountsDB, - marshalizer: args.Marshalizer, - startRating: args.StartRating, - validatorInfoCreator: args.ValidatorInfoCreator, - genesisNodesConfig: args.GenesisNodesConfig, - endOfEpochCallerAddress: args.EndOfEpochCallerAddress, - stakingSCAddress: args.StakingSCAddress, - chanceComputer: args.ChanceComputer, - mapNumSwitchedPerShard: make(map[uint32]uint32), - mapNumSwitchablePerShard: make(map[uint32]uint32), - switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, - hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, - delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, - stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, - esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, - stakingDataProvider: args.StakingDataProvider, - nodesConfigProvider: args.NodesConfigProvider, - shardCoordinator: args.ShardCoordinator, - correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, - esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, - saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, - governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, - builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, - stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, - stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + legacySystemSCProcessor: &legacySystemSCProcessor{ + systemVM: args.SystemVM, + userAccountsDB: args.UserAccountsDB, + peerAccountsDB: args.PeerAccountsDB, + marshalizer: args.Marshalizer, + startRating: args.StartRating, + validatorInfoCreator: args.ValidatorInfoCreator, + genesisNodesConfig: args.GenesisNodesConfig, + endOfEpochCallerAddress: args.EndOfEpochCallerAddress, + stakingSCAddress: args.StakingSCAddress, + chanceComputer: args.ChanceComputer, + mapNumSwitchedPerShard: make(map[uint32]uint32), + mapNumSwitchablePerShard: make(map[uint32]uint32), + switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, + hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, + delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, + stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, + esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, + stakingDataProvider: args.StakingDataProvider, + nodesConfigProvider: args.NodesConfigProvider, + shardCoordinator: args.ShardCoordinator, + correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, + esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, + saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, + stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, + }, + governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, + builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, + stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("systemSC: enable epoch for switch jail waiting", "epoch", s.switchEnableEpoch) @@ -220,7 +185,7 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( validatorsInfoMap map[uint32][]*state.ValidatorInfo, header data.HeaderHandler, ) error { - err := s.processWithOldFlags(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) + err := s.processLegacy(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) if err != nil { return err } @@ -228,95 +193,6 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( return s.processWithNewFlags(validatorsInfoMap, header) } -func (s *systemSCProcessor) processWithOldFlags( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - nonce uint64, - epoch uint32, -) error { - if s.flagHystNodesEnabled.IsSet() { - err := s.updateSystemSCConfigMinNodes() - if err != nil { - return err - } - } - - if s.flagSetOwnerEnabled.IsSet() { - err := s.updateOwnersForBlsKeys() - if err != nil { - return err - } - } - - if s.flagChangeMaxNodesEnabled.IsSet() { - err := s.updateMaxNodes(validatorsInfoMap, nonce) - if err != nil { - return err - } - } - - if s.flagCorrectLastUnjailedEnabled.IsSet() { - err := s.resetLastUnJailed() - if err != nil { - return err - } - } - - if s.flagDelegationEnabled.IsSet() { - err := s.initDelegationSystemSC() - if err != nil { - return err - } - } - - if s.flagCorrectNumNodesToStake.IsSet() { - err := s.cleanAdditionalQueue() - if err != nil { - return err - } - } - - if s.flagSwitchJailedWaiting.IsSet() { - err := s.computeNumWaitingPerShard(validatorsInfoMap) - if err != nil { - return err - } - - err = s.swapJailedWithWaiting(validatorsInfoMap) - if err != nil { - return err - } - } - - if s.flagStakingV2Enabled.IsSet() { - err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) - if err != nil { - return err - } - - numUnStaked, err := s.unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap, epoch) - if err != nil { - return err - } - - if s.flagStakingQueueEnabled.IsSet() { - err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) - if err != nil { - return err - } - } - } - - if s.flagESDTEnabled.IsSet() { - err := s.initESDT() - if err != nil { - //not a critical error - log.Error("error while initializing ESDT", "err", err) - } - } - - return nil -} - func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap map[uint32][]*state.ValidatorInfo, header data.HeaderHandler, @@ -500,270 +376,11 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf log.Debug(message) } -// ToggleUnStakeUnBond will pause/unPause the unStake/unBond functions on the validator system sc -func (s *systemSCProcessor) ToggleUnStakeUnBond(value bool) error { - if !s.flagStakingV2Enabled.IsSet() { - return nil - } - - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: nil, - CallValue: big.NewInt(0), - }, - RecipientAddr: vm.ValidatorSCAddress, - Function: "unPauseUnStakeUnBond", - } - - if value { - vmInput.Function = "pauseUnStakeUnBond" - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - - if vmOutput.ReturnCode != vmcommon.Ok { - return epochStart.ErrSystemValidatorSCCall - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) unStakeNodesWithNotEnoughFunds( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - epoch uint32, -) (uint32, error) { - nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) - if err != nil { - return 0, err - } - - nodesUnStakedFromAdditionalQueue := uint32(0) - - log.Debug("unStake nodes with not enough funds", "num", len(nodesToUnStake)) - for _, blsKey := range nodesToUnStake { - log.Debug("unStake at end of epoch for node", "blsKey", blsKey) - err = s.unStakeOneNode(blsKey, epoch) - if err != nil { - return 0, err - } - - validatorInfo := getValidatorInfoWithBLSKey(validatorsInfoMap, blsKey) - if validatorInfo == nil { - nodesUnStakedFromAdditionalQueue++ - log.Debug("unStaked node which was in additional queue", "blsKey", blsKey) - continue - } - - validatorInfo.List = string(common.LeavingList) - } - - err = s.updateDelegationContracts(mapOwnersKeys) - if err != nil { - return 0, err - } - - nodesToStakeFromQueue := uint32(len(nodesToUnStake)) - if s.flagCorrectNumNodesToStake.IsSet() { - nodesToStakeFromQueue -= nodesUnStakedFromAdditionalQueue - } - - log.Debug("stake nodes from waiting list", "num", nodesToStakeFromQueue) - return nodesToStakeFromQueue, nil -} - -func (s *systemSCProcessor) unStakeOneNode(blsKey []byte, epoch uint32) error { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{blsKey}, - CallValue: big.NewInt(0), - }, - RecipientAddr: s.stakingSCAddress, - Function: "unStakeAtEndOfEpoch", - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - if vmOutput.ReturnCode != vmcommon.Ok { - log.Debug("unStakeOneNode", "returnMessage", vmOutput.ReturnMessage, "returnCode", vmOutput.ReturnCode.String()) - return epochStart.ErrUnStakeExecuteError - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - account, errExists := s.peerAccountsDB.GetExistingAccount(blsKey) - if errExists != nil { - return nil - } - - peerAccount, ok := account.(state.PeerAccountHandler) - if !ok { - return epochStart.ErrWrongTypeAssertion - } - - peerAccount.SetListAndIndex(peerAccount.GetShardId(), string(common.LeavingList), peerAccount.GetIndexInList()) - peerAccount.SetUnStakedEpoch(epoch) - err = s.peerAccountsDB.SaveAccount(peerAccount) - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) updateDelegationContracts(mapOwnerKeys map[string][][]byte) error { - sortedDelegationsSCs := make([]string, 0, len(mapOwnerKeys)) - for address := range mapOwnerKeys { - shardId := s.shardCoordinator.ComputeId([]byte(address)) - if shardId != core.MetachainShardId { - continue - } - sortedDelegationsSCs = append(sortedDelegationsSCs, address) - } - - sort.Slice(sortedDelegationsSCs, func(i, j int) bool { - return sortedDelegationsSCs[i] < sortedDelegationsSCs[j] - }) - - for _, address := range sortedDelegationsSCs { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: mapOwnerKeys[address], - CallValue: big.NewInt(0), - }, - RecipientAddr: []byte(address), - Function: "unStakeAtEndOfEpoch", - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - if vmOutput.ReturnCode != vmcommon.Ok { - log.Debug("unStakeAtEndOfEpoch", "returnMessage", vmOutput.ReturnMessage, "returnCode", vmOutput.ReturnCode.String()) - return epochStart.ErrUnStakeExecuteError - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - } - - return nil -} - -func getValidatorInfoWithBLSKey(validatorsInfoMap map[uint32][]*state.ValidatorInfo, blsKey []byte) *state.ValidatorInfo { - for _, validatorsInfoSlice := range validatorsInfoMap { - for _, validatorInfo := range validatorsInfoSlice { - if bytes.Equal(validatorInfo.PublicKey, blsKey) { - return validatorInfo - } - } - } - return nil -} - -func (s *systemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - for shId, validatorsInfoSlice := range validatorsInfoMap { - newList := make([]*state.ValidatorInfo, 0, len(validatorsInfoSlice)) - deleteCalled := false - - for _, validatorInfo := range validatorsInfoSlice { - if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { - newList = append(newList, validatorInfo) - continue - } - - err := s.stakingDataProvider.FillValidatorInfo(validatorInfo.PublicKey) - if err != nil { - deleteCalled = true - - log.Error("fillStakingDataForNonEligible", "error", err) - if len(validatorInfo.List) > 0 { - return err - } - - err = s.peerAccountsDB.RemoveAccount(validatorInfo.PublicKey) - if err != nil { - log.Error("fillStakingDataForNonEligible removeAccount", "error", err) - } - - continue - } - - newList = append(newList, validatorInfo) - } - - if deleteCalled { - validatorsInfoMap[shId] = newList - } - } - - return nil -} - -func (s *systemSCProcessor) prepareStakingDataForEligibleNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - eligibleNodes := s.getEligibleNodeKeys(validatorsInfoMap) - return s.prepareStakingData(eligibleNodes) -} - func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { allNodes := s.getAllNodeKeys(validatorsInfoMap) return s.prepareStakingData(allNodes) } -func (s *systemSCProcessor) unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32) (uint32, error) { - err := s.fillStakingDataForNonEligible(validatorsInfoMap) - if err != nil { - return 0, err - } - - return s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) -} - -func (s *systemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byte) error { - sw := core.NewStopWatch() - sw.Start("prepareStakingDataForRewards") - defer func() { - sw.Stop("prepareStakingDataForRewards") - log.Debug("systemSCProcessor.prepareStakingDataForRewards time measurements", sw.GetMeasurements()...) - }() - - return s.stakingDataProvider.PrepareStakingData(nodeKeys) -} - -func (s *systemSCProcessor) getEligibleNodeKeys( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, -) map[uint32][][]byte { - eligibleNodesKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfoMap { - eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) - for _, validatorInfo := range validatorsInfoSlice { - if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { - eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.PublicKey) - } - } - } - - return eligibleNodesKeys -} - func (s *systemSCProcessor) getAllNodeKeys( validatorsInfo map[uint32][]*state.ValidatorInfo, ) map[uint32][][]byte { @@ -791,567 +408,60 @@ func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBloc return nil } -// ProcessDelegationRewards will process the rewards which are directed towards the delegation system smart contracts -func (s *systemSCProcessor) ProcessDelegationRewards( - miniBlocks block.MiniBlockSlice, - txCache epochStart.TransactionCacher, -) error { - if txCache == nil { - return epochStart.ErrNilLocalTxCache +func (s *systemSCProcessor) updateToGovernanceV2() error { + vmInput := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.GovernanceSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{}, + }, + RecipientAddr: vm.GovernanceSCAddress, + Function: "initV2", } - - rwdMb := getRewardsMiniBlockForMeta(miniBlocks) - if rwdMb == nil { - return nil + vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) + if errRun != nil { + return fmt.Errorf("%w when updating to governanceV2", errRun) + } + if vmOutput.ReturnCode != vmcommon.Ok { + return fmt.Errorf("got return code %s when updating to governanceV2", vmOutput.ReturnCode) } - for _, txHash := range rwdMb.TxHashes { - rwdTx, err := txCache.GetTx(txHash) - if err != nil { - return err - } - - err = s.executeRewardTx(rwdTx) - if err != nil { - return err - } + err := s.processSCOutputAccounts(vmOutput) + if err != nil { + return err } return nil } -func (s *systemSCProcessor) executeRewardTx(rwdTx data.TransactionHandler) error { +func (s *systemSCProcessor) initTokenOnMeta() ([]byte, error) { vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: nil, - CallValue: rwdTx.GetValue(), + CallerAddr: vm.ESDTSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{}, + GasProvided: math.MaxUint64, }, - RecipientAddr: rwdTx.GetRcvAddr(), - Function: "updateRewards", + RecipientAddr: vm.ESDTSCAddress, + Function: "initDelegationESDTOnMeta", } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err + vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) + if errRun != nil { + return nil, fmt.Errorf("%w when setting up NFTs on metachain", errRun) } - if vmOutput.ReturnCode != vmcommon.Ok { - return epochStart.ErrSystemDelegationCall + return nil, fmt.Errorf("got return code %s, return message %s when setting up NFTs on metachain", vmOutput.ReturnCode, vmOutput.ReturnMessage) + } + if len(vmOutput.ReturnData) != 1 { + return nil, fmt.Errorf("invalid return data on initDelegationESDTOnMeta") } - err = s.processSCOutputAccounts(vmOutput) + err := s.processSCOutputAccounts(vmOutput) if err != nil { - return err + return nil, err } - return nil -} - -// updates the configuration of the system SC if the flags permit -func (s *systemSCProcessor) updateSystemSCConfigMinNodes() error { - minNumberOfNodesWithHysteresis := s.genesisNodesConfig.MinNumberOfNodesWithHysteresis() - err := s.setMinNumberOfNodes(minNumberOfNodesWithHysteresis) - - return err -} - -func (s *systemSCProcessor) resetLastUnJailed() error { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{}, - CallValue: big.NewInt(0), - }, - RecipientAddr: s.stakingSCAddress, - Function: "resetLastUnJailedFromQueue", - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - - if vmOutput.ReturnCode != vmcommon.Ok { - return epochStart.ErrResetLastUnJailedFromQueue - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - return nil -} - -// updates the configuration of the system SC if the flags permit -func (s *systemSCProcessor) updateMaxNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64) error { - sw := core.NewStopWatch() - sw.Start("total") - defer func() { - sw.Stop("total") - log.Debug("systemSCProcessor.updateMaxNodes", sw.GetMeasurements()...) - }() - - maxNumberOfNodes := s.maxNodes - sw.Start("setMaxNumberOfNodes") - prevMaxNumberOfNodes, err := s.setMaxNumberOfNodes(maxNumberOfNodes) - sw.Stop("setMaxNumberOfNodes") - if err != nil { - return err - } - - if maxNumberOfNodes < prevMaxNumberOfNodes { - return epochStart.ErrInvalidMaxNumberOfNodes - } - - if s.flagStakingQueueEnabled.IsSet() { - sw.Start("stakeNodesFromQueue") - err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) - sw.Stop("stakeNodesFromQueue") - if err != nil { - return err - } - } - return nil -} - -func (s *systemSCProcessor) computeNumWaitingPerShard(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - for shardID, validatorInfoList := range validatorsInfoMap { - totalInWaiting := uint32(0) - for _, validatorInfo := range validatorInfoList { - switch validatorInfo.List { - case string(common.WaitingList): - totalInWaiting++ - } - } - s.mapNumSwitchablePerShard[shardID] = totalInWaiting - s.mapNumSwitchedPerShard[shardID] = 0 - } - return nil -} - -func (s *systemSCProcessor) swapJailedWithWaiting(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - jailedValidators := s.getSortedJailedNodes(validatorsInfoMap) - - log.Debug("number of jailed validators", "num", len(jailedValidators)) - - newValidators := make(map[string]struct{}) - for _, jailedValidator := range jailedValidators { - if _, ok := newValidators[string(jailedValidator.PublicKey)]; ok { - continue - } - if isValidator(jailedValidator) && s.mapNumSwitchablePerShard[jailedValidator.ShardId] <= s.mapNumSwitchedPerShard[jailedValidator.ShardId] { - log.Debug("cannot switch in this epoch anymore for this shard as switched num waiting", - "shardID", jailedValidator.ShardId, - "numSwitched", s.mapNumSwitchedPerShard[jailedValidator.ShardId]) - continue - } - - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{jailedValidator.PublicKey}, - CallValue: big.NewInt(0), - }, - RecipientAddr: s.stakingSCAddress, - Function: "switchJailedWithWaiting", - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - - log.Debug("switchJailedWithWaiting called for", - "key", jailedValidator.PublicKey, - "returnMessage", vmOutput.ReturnMessage) - if vmOutput.ReturnCode != vmcommon.Ok { - continue - } - - newValidator, err := s.stakingToValidatorStatistics(validatorsInfoMap, jailedValidator, vmOutput) - if err != nil { - return err - } - - if len(newValidator) != 0 { - newValidators[string(newValidator)] = struct{}{} - } - } - - return nil -} - -func (s *systemSCProcessor) stakingToValidatorStatistics( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - jailedValidator *state.ValidatorInfo, - vmOutput *vmcommon.VMOutput, -) ([]byte, error) { - stakingSCOutput, ok := vmOutput.OutputAccounts[string(s.stakingSCAddress)] - if !ok { - return nil, epochStart.ErrStakingSCOutputAccountNotFound - } - - var activeStorageUpdate *vmcommon.StorageUpdate - for _, storageUpdate := range stakingSCOutput.StorageUpdates { - isNewValidatorKey := len(storageUpdate.Offset) == len(jailedValidator.PublicKey) && - !bytes.Equal(storageUpdate.Offset, jailedValidator.PublicKey) - if isNewValidatorKey { - activeStorageUpdate = storageUpdate - break - } - } - if activeStorageUpdate == nil { - log.Debug("no one in waiting suitable for switch") - if s.flagSaveJailedAlwaysEnabled.IsSet() { - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return nil, err - } - } - - return nil, nil - } - - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return nil, err - } - - var stakingData systemSmartContracts.StakedDataV2_0 - err = s.marshalizer.Unmarshal(&stakingData, activeStorageUpdate.Data) - if err != nil { - return nil, err - } - - blsPubKey := activeStorageUpdate.Offset - log.Debug("staking validator key who switches with the jailed one", "blsKey", blsPubKey) - account, err := s.getPeerAccount(blsPubKey) - if err != nil { - return nil, err - } - - if !bytes.Equal(account.GetRewardAddress(), stakingData.RewardAddress) { - err = account.SetRewardAddress(stakingData.RewardAddress) - if err != nil { - return nil, err - } - } - - if !bytes.Equal(account.GetBLSPublicKey(), blsPubKey) { - err = account.SetBLSPublicKey(blsPubKey) - if err != nil { - return nil, err - } - } else { - // old jailed validator getting switched back after unJail with stake - must remove first from exported map - deleteNewValidatorIfExistsFromMap(validatorsInfoMap, blsPubKey, account.GetShardId()) - } - - account.SetListAndIndex(jailedValidator.ShardId, string(common.NewList), uint32(stakingData.StakedNonce)) - account.SetTempRating(s.startRating) - account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) - - err = s.peerAccountsDB.SaveAccount(account) - if err != nil { - return nil, err - } - - jailedAccount, err := s.getPeerAccount(jailedValidator.PublicKey) - if err != nil { - return nil, err - } - - jailedAccount.SetListAndIndex(jailedValidator.ShardId, string(common.JailedList), jailedValidator.Index) - jailedAccount.ResetAtNewEpoch() - err = s.peerAccountsDB.SaveAccount(jailedAccount) - if err != nil { - return nil, err - } - - if isValidator(jailedValidator) { - s.mapNumSwitchedPerShard[jailedValidator.ShardId]++ - } - - newValidatorInfo := s.validatorInfoCreator.PeerAccountToValidatorInfo(account) - switchJailedWithNewValidatorInMap(validatorsInfoMap, jailedValidator, newValidatorInfo) - - return blsPubKey, nil -} - -func isValidator(validator *state.ValidatorInfo) bool { - return validator.List == string(common.WaitingList) || validator.List == string(common.EligibleList) -} - -func deleteNewValidatorIfExistsFromMap( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - blsPubKey []byte, - shardID uint32, -) { - for index, validatorInfo := range validatorsInfoMap[shardID] { - if bytes.Equal(validatorInfo.PublicKey, blsPubKey) { - length := len(validatorsInfoMap[shardID]) - validatorsInfoMap[shardID][index] = validatorsInfoMap[shardID][length-1] - validatorsInfoMap[shardID][length-1] = nil - validatorsInfoMap[shardID] = validatorsInfoMap[shardID][:length-1] - break - } - } -} - -func switchJailedWithNewValidatorInMap( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - jailedValidator *state.ValidatorInfo, - newValidator *state.ValidatorInfo, -) { - for index, validatorInfo := range validatorsInfoMap[jailedValidator.ShardId] { - if bytes.Equal(validatorInfo.PublicKey, jailedValidator.PublicKey) { - validatorsInfoMap[jailedValidator.ShardId][index] = newValidator - break - } - } -} - -func (s *systemSCProcessor) getUserAccount(address []byte) (state.UserAccountHandler, error) { - acnt, err := s.userAccountsDB.LoadAccount(address) - if err != nil { - return nil, err - } - - stAcc, ok := acnt.(state.UserAccountHandler) - if !ok { - return nil, process.ErrWrongTypeAssertion - } - - return stAcc, nil -} - -// save account changes in state from vmOutput - protected by VM - every output can be treated as is. -func (s *systemSCProcessor) processSCOutputAccounts( - vmOutput *vmcommon.VMOutput, -) error { - - outputAccounts := process.SortVMOutputInsideData(vmOutput) - for _, outAcc := range outputAccounts { - acc, err := s.getUserAccount(outAcc.Address) - if err != nil { - return err - } - - storageUpdates := process.GetSortedStorageUpdates(outAcc) - for _, storeUpdate := range storageUpdates { - err = acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) - if err != nil { - return err - } - } - - if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(zero) != 0 { - err = acc.AddToBalance(outAcc.BalanceDelta) - if err != nil { - return err - } - } - - err = s.userAccountsDB.SaveAccount(acc) - if err != nil { - return err - } - } - - return nil -} - -func (s *systemSCProcessor) getSortedJailedNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) []*state.ValidatorInfo { - newJailedValidators := make([]*state.ValidatorInfo, 0) - oldJailedValidators := make([]*state.ValidatorInfo, 0) - - minChance := s.chanceComputer.GetChance(0) - for _, listValidators := range validatorsInfoMap { - for _, validatorInfo := range listValidators { - if validatorInfo.List == string(common.JailedList) { - oldJailedValidators = append(oldJailedValidators, validatorInfo) - } else if s.chanceComputer.GetChance(validatorInfo.TempRating) < minChance { - newJailedValidators = append(newJailedValidators, validatorInfo) - } - } - } - - sort.Sort(validatorList(oldJailedValidators)) - sort.Sort(validatorList(newJailedValidators)) - - return append(oldJailedValidators, newJailedValidators...) -} - -func (s *systemSCProcessor) getPeerAccount(key []byte) (state.PeerAccountHandler, error) { - account, err := s.peerAccountsDB.LoadAccount(key) - if err != nil { - return nil, err - } - - peerAcc, ok := account.(state.PeerAccountHandler) - if !ok { - return nil, epochStart.ErrWrongTypeAssertion - } - - return peerAcc, nil -} - -func (s *systemSCProcessor) setMinNumberOfNodes(minNumNodes uint32) error { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{big.NewInt(int64(minNumNodes)).Bytes()}, - CallValue: big.NewInt(0), - }, - RecipientAddr: s.stakingSCAddress, - Function: "updateConfigMinNodes", - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - - log.Debug("setMinNumberOfNodes called with", - "minNumNodes", minNumNodes, - "returnMessage", vmOutput.ReturnMessage) - - if vmOutput.ReturnCode != vmcommon.Ok { - return epochStart.ErrInvalidMinNumberOfNodes - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) setMaxNumberOfNodes(maxNumNodes uint32) (uint32, error) { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{big.NewInt(int64(maxNumNodes)).Bytes()}, - CallValue: big.NewInt(0), - }, - RecipientAddr: s.stakingSCAddress, - Function: "updateConfigMaxNodes", - } - - vmOutput, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return 0, err - } - - log.Debug("setMaxNumberOfNodes called with", - "maxNumNodes", maxNumNodes, - "returnMessage", vmOutput.ReturnMessage) - - if vmOutput.ReturnCode != vmcommon.Ok { - return 0, epochStart.ErrInvalidMaxNumberOfNodes - } - if len(vmOutput.ReturnData) != 1 { - return 0, epochStart.ErrInvalidSystemSCReturn - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return 0, err - } - - prevMaxNumNodes := big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64() - return uint32(prevMaxNumNodes), nil -} - -func (s *systemSCProcessor) updateOwnersForBlsKeys() error { - sw := core.NewStopWatch() - sw.Start("systemSCProcessor") - defer func() { - sw.Stop("systemSCProcessor") - log.Debug("systemSCProcessor.updateOwnersForBlsKeys time measurements", sw.GetMeasurements()...) - }() - - sw.Start("getValidatorSystemAccount") - userValidatorAccount, err := s.getValidatorSystemAccount() - sw.Stop("getValidatorSystemAccount") - if err != nil { - return err - } - - sw.Start("getArgumentsForSetOwnerFunctionality") - arguments, err := s.getArgumentsForSetOwnerFunctionality(userValidatorAccount) - sw.Stop("getArgumentsForSetOwnerFunctionality") - if err != nil { - return err - } - - sw.Start("callSetOwnersOnAddresses") - err = s.callSetOwnersOnAddresses(arguments) - sw.Stop("callSetOwnersOnAddresses") - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) updateToGovernanceV2() error { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.GovernanceSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{}, - }, - RecipientAddr: vm.GovernanceSCAddress, - Function: "initV2", - } - vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) - if errRun != nil { - return fmt.Errorf("%w when updating to governanceV2", errRun) - } - if vmOutput.ReturnCode != vmcommon.Ok { - return fmt.Errorf("got return code %s when updating to governanceV2", vmOutput.ReturnCode) - } - - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) initTokenOnMeta() ([]byte, error) { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.ESDTSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{}, - GasProvided: math.MaxUint64, - }, - RecipientAddr: vm.ESDTSCAddress, - Function: "initDelegationESDTOnMeta", - } - vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) - if errRun != nil { - return nil, fmt.Errorf("%w when setting up NFTs on metachain", errRun) - } - if vmOutput.ReturnCode != vmcommon.Ok { - return nil, fmt.Errorf("got return code %s, return message %s when setting up NFTs on metachain", vmOutput.ReturnCode, vmOutput.ReturnMessage) - } - if len(vmOutput.ReturnData) != 1 { - return nil, fmt.Errorf("invalid return data on initDelegationESDTOnMeta") - } - - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return nil, err - } - - return vmOutput.ReturnData[0], nil + return vmOutput.ReturnData[0], nil } func (s *systemSCProcessor) initLiquidStakingSC(tokenID []byte) error { @@ -1392,349 +502,6 @@ func (s *systemSCProcessor) initLiquidStakingSC(tokenID []byte) error { return nil } -func (s *systemSCProcessor) getValidatorSystemAccount() (state.UserAccountHandler, error) { - validatorAccount, err := s.userAccountsDB.LoadAccount(vm.ValidatorSCAddress) - if err != nil { - return nil, fmt.Errorf("%w when loading validator account", err) - } - - userValidatorAccount, ok := validatorAccount.(state.UserAccountHandler) - if !ok { - return nil, fmt.Errorf("%w when loading validator account", epochStart.ErrWrongTypeAssertion) - } - - if check.IfNil(userValidatorAccount.DataTrie()) { - return nil, epochStart.ErrNilDataTrie - } - - return userValidatorAccount, nil -} - -func (s *systemSCProcessor) getArgumentsForSetOwnerFunctionality(userValidatorAccount state.UserAccountHandler) ([][]byte, error) { - arguments := make([][]byte, 0) - - rootHash, err := userValidatorAccount.DataTrie().RootHash() - if err != nil { - return nil, err - } - - chLeaves, err := userValidatorAccount.DataTrie().GetAllLeavesOnChannel(rootHash) - if err != nil { - return nil, err - } - for leaf := range chLeaves { - validatorData := &systemSmartContracts.ValidatorDataV2{} - value, errTrim := leaf.ValueWithoutSuffix(append(leaf.Key(), vm.ValidatorSCAddress...)) - if errTrim != nil { - return nil, fmt.Errorf("%w for validator key %s", errTrim, hex.EncodeToString(leaf.Key())) - } - - err = s.marshalizer.Unmarshal(validatorData, value) - if err != nil { - continue - } - for _, blsKey := range validatorData.BlsPubKeys { - arguments = append(arguments, blsKey) - arguments = append(arguments, leaf.Key()) - } - } - - return arguments, nil -} - -func (s *systemSCProcessor) callSetOwnersOnAddresses(arguments [][]byte) error { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.EndOfEpochAddress, - CallValue: big.NewInt(0), - Arguments: arguments, - }, - RecipientAddr: vm.StakingSCAddress, - Function: "setOwnersOnAddresses", - } - - vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) - if errRun != nil { - return fmt.Errorf("%w when calling setOwnersOnAddresses function", errRun) - } - if vmOutput.ReturnCode != vmcommon.Ok { - return fmt.Errorf("got return code %s when calling setOwnersOnAddresses", vmOutput.ReturnCode) - } - - return s.processSCOutputAccounts(vmOutput) -} - -func (s *systemSCProcessor) initDelegationSystemSC() error { - codeMetaData := &vmcommon.CodeMetadata{ - Upgradeable: false, - Payable: false, - Readable: true, - } - - vmInput := &vmcommon.ContractCreateInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.DelegationManagerSCAddress, - Arguments: [][]byte{}, - CallValue: big.NewInt(0), - }, - ContractCode: vm.DelegationManagerSCAddress, - ContractCodeMetadata: codeMetaData.ToBytes(), - } - - vmOutput, err := s.systemVM.RunSmartContractCreate(vmInput) - if err != nil { - return err - } - if vmOutput.ReturnCode != vmcommon.Ok { - return epochStart.ErrCouldNotInitDelegationSystemSC - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - err = s.updateSystemSCContractsCode(vmInput.ContractCodeMetadata) - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) updateSystemSCContractsCode(contractMetadata []byte) error { - contractsToUpdate := make([][]byte, 0) - contractsToUpdate = append(contractsToUpdate, vm.StakingSCAddress) - contractsToUpdate = append(contractsToUpdate, vm.ValidatorSCAddress) - contractsToUpdate = append(contractsToUpdate, vm.GovernanceSCAddress) - contractsToUpdate = append(contractsToUpdate, vm.ESDTSCAddress) - contractsToUpdate = append(contractsToUpdate, vm.DelegationManagerSCAddress) - contractsToUpdate = append(contractsToUpdate, vm.FirstDelegationSCAddress) - - for _, address := range contractsToUpdate { - userAcc, err := s.getUserAccount(address) - if err != nil { - return err - } - - userAcc.SetOwnerAddress(address) - userAcc.SetCodeMetadata(contractMetadata) - userAcc.SetCode(address) - - err = s.userAccountsDB.SaveAccount(userAcc) - if err != nil { - return err - } - } - - return nil -} - -func (s *systemSCProcessor) cleanAdditionalQueue() error { - sw := core.NewStopWatch() - sw.Start("systemSCProcessor") - defer func() { - sw.Stop("systemSCProcessor") - log.Debug("systemSCProcessor.cleanAdditionalQueue time measurements", sw.GetMeasurements()...) - }() - - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.EndOfEpochAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{}, - }, - RecipientAddr: vm.StakingSCAddress, - Function: "cleanAdditionalQueue", - } - vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) - if errRun != nil { - return fmt.Errorf("%w when cleaning additional queue", errRun) - } - if vmOutput.ReturnCode != vmcommon.Ok { - return fmt.Errorf("got return code %s, return message %s when cleaning additional queue", vmOutput.ReturnCode, vmOutput.ReturnMessage) - } - - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - // returnData format is list(address - all blsKeys which were unstaked for that) - addressLength := len(s.endOfEpochCallerAddress) - mapOwnersKeys := make(map[string][][]byte) - currentOwner := "" - for _, returnData := range vmOutput.ReturnData { - if len(returnData) == addressLength { - currentOwner = string(returnData) - continue - } - - mapOwnersKeys[currentOwner] = append(mapOwnersKeys[currentOwner], returnData) - } - - err = s.updateDelegationContracts(mapOwnersKeys) - if err != nil { - log.Error("update delegation contracts failed after cleaning additional queue", "error", err.Error()) - return err - } - - return nil -} - -func (s *systemSCProcessor) stakeNodesFromQueue( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - nodesToStake uint32, - nonce uint64, - list common.PeerType, -) error { - if nodesToStake == 0 { - return nil - } - - nodesToStakeAsBigInt := big.NewInt(0).SetUint64(uint64(nodesToStake)) - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.EndOfEpochAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{nodesToStakeAsBigInt.Bytes()}, - }, - RecipientAddr: vm.StakingSCAddress, - Function: "stakeNodesFromQueue", - } - vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) - if errRun != nil { - return fmt.Errorf("%w when staking nodes from waiting list", errRun) - } - if vmOutput.ReturnCode != vmcommon.Ok { - return fmt.Errorf("got return code %s when staking nodes from waiting list", vmOutput.ReturnCode) - } - if len(vmOutput.ReturnData)%2 != 0 { - return fmt.Errorf("%w return data must be divisible by 2 when staking nodes from waiting list", epochStart.ErrInvalidSystemSCReturn) - } - - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - err = s.addNewlyStakedNodesToValidatorTrie(validatorsInfoMap, vmOutput.ReturnData, nonce, list) - if err != nil { - return err - } - - return nil -} - -func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - returnData [][]byte, - nonce uint64, - list common.PeerType, -) error { - for i := 0; i < len(returnData); i += 2 { - blsKey := returnData[i] - rewardAddress := returnData[i+1] - - peerAcc, err := s.getPeerAccount(blsKey) - if err != nil { - return err - } - - err = peerAcc.SetRewardAddress(rewardAddress) - if err != nil { - return err - } - - err = peerAcc.SetBLSPublicKey(blsKey) - if err != nil { - return err - } - - peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce)) - peerAcc.SetTempRating(s.startRating) - peerAcc.SetUnStakedEpoch(common.DefaultUnstakedEpoch) - - err = s.peerAccountsDB.SaveAccount(peerAcc) - if err != nil { - return err - } - - validatorInfo := &state.ValidatorInfo{ - PublicKey: blsKey, - ShardId: peerAcc.GetShardId(), - List: string(list), - Index: uint32(nonce), - TempRating: s.startRating, - Rating: s.startRating, - RewardAddress: rewardAddress, - AccumulatedFees: big.NewInt(0), - } - validatorsInfoMap[peerAcc.GetShardId()] = append(validatorsInfoMap[peerAcc.GetShardId()], validatorInfo) - } - - return nil -} - -func (s *systemSCProcessor) initESDT() error { - currentConfigValues, err := s.extractConfigFromESDTContract() - if err != nil { - return err - } - - return s.changeESDTOwner(currentConfigValues) -} - -func (s *systemSCProcessor) extractConfigFromESDTContract() ([][]byte, error) { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{}, - CallValue: big.NewInt(0), - GasProvided: math.MaxUint64, - }, - Function: "getContractConfig", - RecipientAddr: vm.ESDTSCAddress, - } - - output, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return nil, err - } - if len(output.ReturnData) != 4 { - return nil, fmt.Errorf("%w getContractConfig should have returned 4 values", epochStart.ErrInvalidSystemSCReturn) - } - - return output.ReturnData, nil -} - -func (s *systemSCProcessor) changeESDTOwner(currentConfigValues [][]byte) error { - baseIssuingCost := currentConfigValues[1] - minTokenNameLength := currentConfigValues[2] - maxTokenNameLength := currentConfigValues[3] - - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{s.esdtOwnerAddressBytes, baseIssuingCost, minTokenNameLength, maxTokenNameLength}, - CallValue: big.NewInt(0), - GasProvided: math.MaxUint64, - }, - Function: "configChange", - RecipientAddr: vm.ESDTSCAddress, - } - - output, err := s.systemVM.RunSmartContractCall(vmInput) - if err != nil { - return err - } - if output.ReturnCode != vmcommon.Ok { - return fmt.Errorf("%w changeESDTOwner should have returned Ok", epochStart.ErrInvalidSystemSCReturn) - } - - return s.processSCOutputAccounts(output) -} - // IsInterfaceNil returns true if underlying object is nil func (s *systemSCProcessor) IsInterfaceNil() bool { return s == nil @@ -1742,48 +509,7 @@ func (s *systemSCProcessor) IsInterfaceNil() bool { // EpochConfirmed is called whenever a new epoch is confirmed func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { - s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch) - log.Debug("systemSCProcessor: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) - - // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers - s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) - - s.flagChangeMaxNodesEnabled.SetValue(false) - for _, maxNodesConfig := range s.maxNodesEnableConfig { - if epoch == maxNodesConfig.EpochEnable { - s.flagChangeMaxNodesEnabled.SetValue(true) - s.maxNodes = maxNodesConfig.MaxNumNodes - break - } - } - - log.Debug("systemSCProcessor: consider also (minimum) hysteresis nodes for minimum number of nodes", - "enabled", epoch >= s.hystNodesEnableEpoch) - - // only toggle on exact epoch as init should be called only once - s.flagDelegationEnabled.SetValue(epoch == s.delegationEnableEpoch) - log.Debug("systemSCProcessor: delegation", "enabled", epoch >= s.delegationEnableEpoch) - - s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) - s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch < s.stakingV4InitEnableEpoch) - log.Debug("systemSCProcessor: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) - log.Debug("systemSCProcessor: change of maximum number of nodes and/or shuffling percentage", - "enabled", s.flagChangeMaxNodesEnabled.IsSet(), - "epoch", epoch, - "maxNodes", s.maxNodes, - ) - - s.flagCorrectLastUnjailedEnabled.SetValue(epoch == s.correctLastUnJailEpoch) - log.Debug("systemSCProcessor: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) - - s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch) - log.Debug("systemSCProcessor: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) - - s.flagESDTEnabled.SetValue(epoch == s.esdtEnableEpoch) - log.Debug("systemSCProcessor: ESDT initialization", "enabled", s.flagESDTEnabled.IsSet()) - - s.flagSaveJailedAlwaysEnabled.SetValue(epoch >= s.saveJailedAlwaysEnableEpoch) - log.Debug("systemSCProcessor: save jailed always", "enabled", s.flagSaveJailedAlwaysEnabled.IsSet()) + s.legacyEpochConfirmed(epoch) s.flagGovernanceEnabled.SetValue(epoch == s.governanceEnableEpoch) log.Debug("systemProcessor: governanceV2", "enabled", s.flagGovernanceEnabled.IsSet()) @@ -1791,12 +517,6 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagBuiltInOnMetaEnabled.SetValue(epoch == s.builtInOnMetaEnableEpoch) log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) - s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) - log.Debug("systemProcessor: staking v4 on meta", "enabled", s.flagInitStakingV4Enabled.IsSet()) - - s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) - log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) - s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingV4Enabled.IsSet()) } From b4993df148996c41a8893eacd924f6c24323ea34 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 10 Mar 2022 11:01:06 +0200 Subject: [PATCH 102/958] FIX: Use SelectedFromAuctionList instead of AuctionList --- sharding/indexHashedNodesCoordinator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/indexHashedNodesCoordinator.go b/sharding/indexHashedNodesCoordinator.go index 4733da87bdc..f8685ea726e 100644 --- a/sharding/indexHashedNodesCoordinator.go +++ b/sharding/indexHashedNodesCoordinator.go @@ -751,7 +751,7 @@ func (ihgs *indexHashedNodesCoordinator) computeNodesConfigFromList( log.Debug("inactive validator", "pk", validatorInfo.PublicKey) case string(common.JailedList): log.Debug("jailed validator", "pk", validatorInfo.PublicKey) - case string(common.AuctionList): + case string(common.SelectedFromAuctionList): auctionList = append(auctionList, currentValidator) } } From 6e116efc7da0e122ae5c0906ac2e01d2ce0032cc Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 10 Mar 2022 11:47:22 +0200 Subject: [PATCH 103/958] - more code separation --- epochStart/metachain/legacySystemSCs.go | 108 ++++++++++++++++++++++ epochStart/metachain/systemSCs.go | 117 +----------------------- epochStart/metachain/validatorList.go | 27 ++++++ 3 files changed, 140 insertions(+), 112 deletions(-) create mode 100644 epochStart/metachain/validatorList.go diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index dfc450ac3df..6ae628b0c71 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -69,6 +69,101 @@ type legacySystemSCProcessor struct { flagInitStakingV4Enabled atomic.Flag } +func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*legacySystemSCProcessor, error) { + err := checkLegacyArgs(args) + if err != nil { + return nil, err + } + + legacy := &legacySystemSCProcessor{ + systemVM: args.SystemVM, + userAccountsDB: args.UserAccountsDB, + peerAccountsDB: args.PeerAccountsDB, + marshalizer: args.Marshalizer, + startRating: args.StartRating, + validatorInfoCreator: args.ValidatorInfoCreator, + genesisNodesConfig: args.GenesisNodesConfig, + endOfEpochCallerAddress: args.EndOfEpochCallerAddress, + stakingSCAddress: args.StakingSCAddress, + chanceComputer: args.ChanceComputer, + mapNumSwitchedPerShard: make(map[uint32]uint32), + mapNumSwitchablePerShard: make(map[uint32]uint32), + switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, + hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, + delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, + stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, + esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, + stakingDataProvider: args.StakingDataProvider, + nodesConfigProvider: args.NodesConfigProvider, + shardCoordinator: args.ShardCoordinator, + correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, + esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, + saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, + stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, + } + + log.Debug("legacySystemSC: enable epoch for switch jail waiting", "epoch", legacy.switchEnableEpoch) + log.Debug("legacySystemSC: enable epoch for switch hysteresis for min nodes", "epoch", legacy.hystNodesEnableEpoch) + log.Debug("legacySystemSC: enable epoch for delegation manager", "epoch", legacy.delegationEnableEpoch) + log.Debug("legacySystemSC: enable epoch for staking v2", "epoch", legacy.stakingV2EnableEpoch) + log.Debug("legacySystemSC: enable epoch for ESDT", "epoch", legacy.esdtEnableEpoch) + log.Debug("legacySystemSC: enable epoch for correct last unjailed", "epoch", legacy.correctLastUnJailEpoch) + log.Debug("legacySystemSC: enable epoch for save jailed always", "epoch", legacy.saveJailedAlwaysEnableEpoch) + log.Debug("legacySystemSC: enable epoch for initializing staking v4", "epoch", legacy.stakingV4InitEnableEpoch) + + legacy.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) + copy(legacy.maxNodesEnableConfig, args.MaxNodesEnableConfig) + sort.Slice(legacy.maxNodesEnableConfig, func(i, j int) bool { + return legacy.maxNodesEnableConfig[i].EpochEnable < legacy.maxNodesEnableConfig[j].EpochEnable + }) + + return legacy, nil +} + +func checkLegacyArgs(args ArgsNewEpochStartSystemSCProcessing) error { + if check.IfNilReflect(args.SystemVM) { + return epochStart.ErrNilSystemVM + } + if check.IfNil(args.UserAccountsDB) { + return epochStart.ErrNilAccountsDB + } + if check.IfNil(args.PeerAccountsDB) { + return epochStart.ErrNilAccountsDB + } + if check.IfNil(args.Marshalizer) { + return epochStart.ErrNilMarshalizer + } + if check.IfNil(args.ValidatorInfoCreator) { + return epochStart.ErrNilValidatorInfoProcessor + } + if len(args.EndOfEpochCallerAddress) == 0 { + return epochStart.ErrNilEndOfEpochCallerAddress + } + if len(args.StakingSCAddress) == 0 { + return epochStart.ErrNilStakingSCAddress + } + if check.IfNil(args.ChanceComputer) { + return epochStart.ErrNilChanceComputer + } + if check.IfNil(args.GenesisNodesConfig) { + return epochStart.ErrNilGenesisNodesConfig + } + if check.IfNil(args.NodesConfigProvider) { + return epochStart.ErrNilNodesConfigProvider + } + if check.IfNil(args.StakingDataProvider) { + return epochStart.ErrNilStakingDataProvider + } + if check.IfNil(args.ShardCoordinator) { + return epochStart.ErrNilShardCoordinator + } + if len(args.ESDTOwnerAddressBytes) == 0 { + return epochStart.ErrEmptyESDTOwnerAddress + } + + return nil +} + func (s *legacySystemSCProcessor) processLegacy( validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64, @@ -1267,6 +1362,19 @@ func (s *legacySystemSCProcessor) changeESDTOwner(currentConfigValues [][]byte) return s.processSCOutputAccounts(output) } +func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBlock { + for _, miniBlock := range miniBlocks { + if miniBlock.Type != block.RewardsBlock { + continue + } + if miniBlock.ReceiverShardID != core.MetachainShardId { + continue + } + return miniBlock + } + return nil +} + func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch) log.Debug("systemSCProcessor: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 0a8483c9c51..45f212136f5 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -12,7 +12,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" logger "github.com/ElrondNetwork/elrond-go-logger" @@ -61,121 +60,28 @@ type systemSCProcessor struct { flagStakingV4Enabled atomic.Flag } -type validatorList []*state.ValidatorInfo - -// Len will return the length of the validatorList -func (v validatorList) Len() int { return len(v) } - -// Swap will interchange the objects on input indexes -func (v validatorList) Swap(i, j int) { v[i], v[j] = v[j], v[i] } - -// Less will return true if object on index i should appear before object in index j -// Sorting of validators should be by index and public key -func (v validatorList) Less(i, j int) bool { - if v[i].TempRating == v[j].TempRating { - if v[i].Index == v[j].Index { - return bytes.Compare(v[i].PublicKey, v[j].PublicKey) < 0 - } - return v[i].Index < v[j].Index - } - return v[i].TempRating < v[j].TempRating -} - // NewSystemSCProcessor creates the end of epoch system smart contract processor func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCProcessor, error) { - if check.IfNilReflect(args.SystemVM) { - return nil, epochStart.ErrNilSystemVM - } - if check.IfNil(args.UserAccountsDB) { - return nil, epochStart.ErrNilAccountsDB - } - if check.IfNil(args.PeerAccountsDB) { - return nil, epochStart.ErrNilAccountsDB - } - if check.IfNil(args.Marshalizer) { - return nil, epochStart.ErrNilMarshalizer - } - if check.IfNil(args.ValidatorInfoCreator) { - return nil, epochStart.ErrNilValidatorInfoProcessor - } - if len(args.EndOfEpochCallerAddress) == 0 { - return nil, epochStart.ErrNilEndOfEpochCallerAddress - } - if len(args.StakingSCAddress) == 0 { - return nil, epochStart.ErrNilStakingSCAddress - } - if check.IfNil(args.ChanceComputer) { - return nil, epochStart.ErrNilChanceComputer - } if check.IfNil(args.EpochNotifier) { return nil, epochStart.ErrNilEpochStartNotifier } - if check.IfNil(args.GenesisNodesConfig) { - return nil, epochStart.ErrNilGenesisNodesConfig - } - if check.IfNil(args.NodesConfigProvider) { - return nil, epochStart.ErrNilNodesConfigProvider - } - if check.IfNil(args.StakingDataProvider) { - return nil, epochStart.ErrNilStakingDataProvider - } - if check.IfNil(args.ShardCoordinator) { - return nil, epochStart.ErrNilShardCoordinator - } - if len(args.ESDTOwnerAddressBytes) == 0 { - return nil, epochStart.ErrEmptyESDTOwnerAddress + + legacy, err := newLegacySystemSCProcessor(args) + if err != nil { + return nil, err } s := &systemSCProcessor{ - legacySystemSCProcessor: &legacySystemSCProcessor{ - systemVM: args.SystemVM, - userAccountsDB: args.UserAccountsDB, - peerAccountsDB: args.PeerAccountsDB, - marshalizer: args.Marshalizer, - startRating: args.StartRating, - validatorInfoCreator: args.ValidatorInfoCreator, - genesisNodesConfig: args.GenesisNodesConfig, - endOfEpochCallerAddress: args.EndOfEpochCallerAddress, - stakingSCAddress: args.StakingSCAddress, - chanceComputer: args.ChanceComputer, - mapNumSwitchedPerShard: make(map[uint32]uint32), - mapNumSwitchablePerShard: make(map[uint32]uint32), - switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, - hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, - delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, - stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, - esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, - stakingDataProvider: args.StakingDataProvider, - nodesConfigProvider: args.NodesConfigProvider, - shardCoordinator: args.ShardCoordinator, - correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, - esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, - saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, - stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, - }, + legacySystemSCProcessor: legacy, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } - log.Debug("systemSC: enable epoch for switch jail waiting", "epoch", s.switchEnableEpoch) - log.Debug("systemSC: enable epoch for switch hysteresis for min nodes", "epoch", s.hystNodesEnableEpoch) - log.Debug("systemSC: enable epoch for delegation manager", "epoch", s.delegationEnableEpoch) - log.Debug("systemSC: enable epoch for staking v2", "epoch", s.stakingV2EnableEpoch) - log.Debug("systemSC: enable epoch for ESDT", "epoch", s.esdtEnableEpoch) - log.Debug("systemSC: enable epoch for correct last unjailed", "epoch", s.correctLastUnJailEpoch) - log.Debug("systemSC: enable epoch for save jailed always", "epoch", s.saveJailedAlwaysEnableEpoch) log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) log.Debug("systemSC: enable epoch for create NFT on meta", "epoch", s.builtInOnMetaEnableEpoch) - log.Debug("systemSC: enable epoch for initializing staking v4", "epoch", s.stakingV4InitEnableEpoch) log.Debug("systemSC: enable epoch for staking v4", "epoch", s.stakingV4EnableEpoch) - s.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) - copy(s.maxNodesEnableConfig, args.MaxNodesEnableConfig) - sort.Slice(s.maxNodesEnableConfig, func(i, j int) bool { - return s.maxNodesEnableConfig[i].EpochEnable < s.maxNodesEnableConfig[j].EpochEnable - }) - args.EpochNotifier.RegisterNotifyHandler(s) return s, nil } @@ -395,19 +301,6 @@ func (s *systemSCProcessor) getAllNodeKeys( return nodeKeys } -func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBlock { - for _, miniBlock := range miniBlocks { - if miniBlock.Type != block.RewardsBlock { - continue - } - if miniBlock.ReceiverShardID != core.MetachainShardId { - continue - } - return miniBlock - } - return nil -} - func (s *systemSCProcessor) updateToGovernanceV2() error { vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ diff --git a/epochStart/metachain/validatorList.go b/epochStart/metachain/validatorList.go new file mode 100644 index 00000000000..3d080cc1a4c --- /dev/null +++ b/epochStart/metachain/validatorList.go @@ -0,0 +1,27 @@ +package metachain + +import ( + "bytes" + + "github.com/ElrondNetwork/elrond-go/state" +) + +type validatorList []*state.ValidatorInfo + +// Len will return the length of the validatorList +func (v validatorList) Len() int { return len(v) } + +// Swap will interchange the objects on input indexes +func (v validatorList) Swap(i, j int) { v[i], v[j] = v[j], v[i] } + +// Less will return true if object on index i should appear before object in index j +// Sorting of validators should be by index and public key +func (v validatorList) Less(i, j int) bool { + if v[i].TempRating == v[j].TempRating { + if v[i].Index == v[j].Index { + return bytes.Compare(v[i].PublicKey, v[j].PublicKey) < 0 + } + return v[i].Index < v[j].Index + } + return v[i].TempRating < v[j].TempRating +} From e306d99818620a88040eaf8ddde446d5651a579b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 10 Mar 2022 12:15:41 +0200 Subject: [PATCH 104/958] FEAT: Add tmp test --- sharding/indexHashedNodesCoordinator_test.go | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/sharding/indexHashedNodesCoordinator_test.go b/sharding/indexHashedNodesCoordinator_test.go index b2923a0de25..099850dee1d 100644 --- a/sharding/indexHashedNodesCoordinator_test.go +++ b/sharding/indexHashedNodesCoordinator_test.go @@ -1105,6 +1105,18 @@ func createBlockBodyFromNodesCoordinator(ihgs *indexHashedNodesCoordinator, epoc return body } +func createBlockBodyWithAuctionFromNodesCoordinator(ihgs *indexHashedNodesCoordinator, epoch uint32) *block.Body { + body := &block.Body{MiniBlocks: make([]*block.MiniBlock, 0)} + + mbs := createBlockBodyFromNodesCoordinator(ihgs, epoch).MiniBlocks + body.MiniBlocks = append(body.MiniBlocks, mbs...) + + mbs = createMiniBlocksForNodesMap(ihgs.nodesConfig[epoch].leavingMap, string(common.SelectedFromAuctionList), ihgs.marshalizer) + body.MiniBlocks = append(body.MiniBlocks, mbs...) + + return body +} + func createMiniBlocksForNodesMap(nodesMap map[uint32][]Validator, list string, marshalizer marshal.Marshalizer) []*block.MiniBlock { miniBlocks := make([]*block.MiniBlock, 0) for shId, eligibleList := range nodesMap { @@ -1272,6 +1284,42 @@ func TestIndexHashedNodesCoordinator_setNodesPerShardsShouldSetNodeTypeObserver( require.Equal(t, core.NodeTypeObserver, nodeTypeResult) } +func TestIndexHashedNodesCoordinator_EpochStartPrepareWithAuction(t *testing.T) { + t.Parallel() + + arguments := createArguments() + pk := []byte("pk") + arguments.SelfPublicKey = pk + ihgs, _ := NewIndexHashedNodesCoordinator(arguments) + + ihgs.updateEpochFlags(arguments.StakingV4EnableEpoch) + epoch := uint32(2) + + header := &block.MetaBlock{ + PrevRandSeed: []byte("rand seed"), + EpochStart: block.EpochStart{LastFinalizedHeaders: []block.EpochStartShardData{{}}}, + Epoch: epoch, + } + + validatorShard := core.MetachainShardId + ihgs.nodesConfig = map[uint32]*epochNodesConfig{ + epoch: { + shardID: validatorShard, + eligibleMap: map[uint32][]Validator{ + validatorShard: {mock.NewValidatorMock(pk, 1, 1)}, + }, + }, + } + body := createBlockBodyWithAuctionFromNodesCoordinator(ihgs, epoch) + ihgs.EpochStartPrepare(header, body) + ihgs.EpochStartAction(header) + + computedShardId, isValidator := ihgs.computeShardForSelfPublicKey(ihgs.nodesConfig[epoch]) + + require.Equal(t, validatorShard, computedShardId) + require.True(t, isValidator) +} + func TestIndexHashedNodesCoordinator_EpochStartInEligible(t *testing.T) { t.Parallel() From 77a475558f95740d4e6eae4620b4f32fe8558385 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 10 Mar 2022 12:20:36 +0200 Subject: [PATCH 105/958] - minor fixes: moved a flag where it should belong --- epochStart/metachain/legacySystemSCs.go | 22 +++++++++------------- epochStart/metachain/systemSCs.go | 6 +++++- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 6ae628b0c71..d1fe6e03849 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -66,7 +66,6 @@ type legacySystemSCProcessor struct { flagESDTEnabled atomic.Flag flagSaveJailedAlwaysEnabled atomic.Flag flagStakingQueueEnabled atomic.Flag - flagInitStakingV4Enabled atomic.Flag } func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*legacySystemSCProcessor, error) { @@ -1377,7 +1376,7 @@ func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBloc func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch) - log.Debug("systemSCProcessor: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) + log.Debug("legacySystemSC: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) @@ -1391,7 +1390,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { } } - log.Debug("systemSCProcessor: consider also (minimum) hysteresis nodes for minimum number of nodes", + log.Debug("legacySystemSC: consider also (minimum) hysteresis nodes for minimum number of nodes", "enabled", epoch >= s.hystNodesEnableEpoch) // only toggle on exact epoch as init should be called only once @@ -1400,28 +1399,25 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch < s.stakingV4InitEnableEpoch) - log.Debug("systemSCProcessor: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) - log.Debug("systemSCProcessor: change of maximum number of nodes and/or shuffling percentage", + log.Debug("legacySystemSC: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) + log.Debug("legacySystemSC: change of maximum number of nodes and/or shuffling percentage", "enabled", s.flagChangeMaxNodesEnabled.IsSet(), "epoch", epoch, "maxNodes", s.maxNodes, ) s.flagCorrectLastUnjailedEnabled.SetValue(epoch == s.correctLastUnJailEpoch) - log.Debug("systemSCProcessor: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) + log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch) - log.Debug("systemSCProcessor: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) + log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) s.flagESDTEnabled.SetValue(epoch == s.esdtEnableEpoch) - log.Debug("systemSCProcessor: ESDT initialization", "enabled", s.flagESDTEnabled.IsSet()) + log.Debug("legacySystemSC: ESDT initialization", "enabled", s.flagESDTEnabled.IsSet()) s.flagSaveJailedAlwaysEnabled.SetValue(epoch >= s.saveJailedAlwaysEnableEpoch) - log.Debug("systemSCProcessor: save jailed always", "enabled", s.flagSaveJailedAlwaysEnabled.IsSet()) - - s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) - log.Debug("systemProcessor: staking v4 on meta", "enabled", s.flagInitStakingV4Enabled.IsSet()) + log.Debug("legacySystemSC: save jailed always", "enabled", s.flagSaveJailedAlwaysEnabled.IsSet()) s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) - log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) + log.Debug("legacySystemSC: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 45f212136f5..aba15dc0f0d 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -58,6 +58,7 @@ type systemSCProcessor struct { flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag flagStakingV4Enabled atomic.Flag + flagInitStakingV4Enabled atomic.Flag } // NewSystemSCProcessor creates the end of epoch system smart contract processor @@ -411,5 +412,8 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) - log.Debug("systemProcessor: staking queue on meta", "enabled", s.flagStakingV4Enabled.IsSet()) + log.Debug("systemProcessor: staking v4", "enabled", s.flagStakingV4Enabled.IsSet()) + + s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) + log.Debug("systemProcessor: init staking v4", "enabled", s.flagInitStakingV4Enabled.IsSet()) } From 0c6ae5e8f7d7eb9f39a0e4bb9e2d1d52bd49709f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 11 Mar 2022 12:17:11 +0200 Subject: [PATCH 106/958] FEAT: Add nodes coord tests --- sharding/indexHashedNodesCoordinator.go | 5 +- .../indexHashedNodesCoordinatorRegistry.go | 3 +- ...ndexHashedNodesCoordinatorRegistry_test.go | 58 +++++++++- sharding/indexHashedNodesCoordinator_test.go | 109 ++++++++++++------ 4 files changed, 135 insertions(+), 40 deletions(-) diff --git a/sharding/indexHashedNodesCoordinator.go b/sharding/indexHashedNodesCoordinator.go index f8685ea726e..1a6744800e4 100644 --- a/sharding/indexHashedNodesCoordinator.go +++ b/sharding/indexHashedNodesCoordinator.go @@ -752,11 +752,14 @@ func (ihgs *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.JailedList): log.Debug("jailed validator", "pk", validatorInfo.PublicKey) case string(common.SelectedFromAuctionList): - auctionList = append(auctionList, currentValidator) + if ihgs.flagStakingV4.IsSet() { + auctionList = append(auctionList, currentValidator) + } } } sort.Sort(validatorList(newNodesList)) + sort.Sort(validatorList(auctionList)) for _, eligibleList := range eligibleMap { sort.Sort(validatorList(eligibleList)) } diff --git a/sharding/indexHashedNodesCoordinatorRegistry.go b/sharding/indexHashedNodesCoordinatorRegistry.go index 44c8b2c4f7f..a28a77dbd35 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/indexHashedNodesCoordinatorRegistry.go @@ -76,11 +76,10 @@ func (ihgs *indexHashedNodesCoordinator) getRegistryData() ([]byte, error) { var err error var data []byte + registry := ihgs.NodesCoordinatorToRegistry() if ihgs.flagStakingV4.IsSet() { - registry := ihgs.nodesCoordinatorToRegistryWithAuction() data, err = ihgs.marshalizer.Marshal(registry) } else { - registry := ihgs.nodesCoordinatorToOldRegistry() data, err = json.Marshal(registry) } diff --git a/sharding/indexHashedNodesCoordinatorRegistry_test.go b/sharding/indexHashedNodesCoordinatorRegistry_test.go index b106071ab59..3dc5a8fc469 100644 --- a/sharding/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/indexHashedNodesCoordinatorRegistry_test.go @@ -6,6 +6,8 @@ import ( "strconv" "testing" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -73,6 +75,8 @@ func validatorsEqualSerializableValidators(validators []Validator, sValidators [ } func TestIndexHashedNodesCoordinator_LoadStateAfterSave(t *testing.T) { + t.Parallel() + args := createArguments() nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) @@ -94,7 +98,59 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSave(t *testing.T) { assert.True(t, sameValidatorsMaps(expectedConfig.waitingMap, actualConfig.waitingMap)) } -func TestIndexHashedNodesCooridinator_nodesCoordinatorToRegistry(t *testing.T) { +func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing.T) { + t.Parallel() + + args := createArguments() + args.Marshalizer = &marshal.GogoProtoMarshalizer{} + nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) + nodesCoordinator.flagStakingV4.SetValue(true) + + nodesCoordinator.nodesConfig[0].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) + nodesCoordinator.nodesConfig[0].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) + expectedConfig := nodesCoordinator.nodesConfig[0] + + key := []byte("config") + err := nodesCoordinator.saveState(key) + assert.Nil(t, err) + + delete(nodesCoordinator.nodesConfig, 0) + err = nodesCoordinator.LoadState(key) + assert.Nil(t, err) + + actualConfig := nodesCoordinator.nodesConfig[0] + assert.Equal(t, expectedConfig.shardID, actualConfig.shardID) + assert.Equal(t, expectedConfig.nbShards, actualConfig.nbShards) + assert.True(t, sameValidatorsMaps(expectedConfig.eligibleMap, actualConfig.eligibleMap)) + assert.True(t, sameValidatorsMaps(expectedConfig.waitingMap, actualConfig.waitingMap)) + assert.True(t, sameValidatorsMaps(expectedConfig.shuffledOutMap, actualConfig.shuffledOutMap)) + assert.True(t, sameValidatorsMaps(expectedConfig.leavingMap, actualConfig.leavingMap)) +} + +func TestIndexHashedNodesCoordinator_nodesCoordinatorToRegistryWithStakingV4(t *testing.T) { + args := createArguments() + nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) + + nodesCoordinator.flagStakingV4.SetValue(true) + nodesCoordinator.nodesConfig[0].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) + nodesCoordinator.nodesConfig[0].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) + + ncr := nodesCoordinator.NodesCoordinatorToRegistry() + nc := nodesCoordinator.nodesConfig + + assert.Equal(t, nodesCoordinator.currentEpoch, ncr.GetCurrentEpoch()) + assert.Equal(t, len(nodesCoordinator.nodesConfig), len(ncr.GetEpochsConfig())) + + for epoch, config := range nc { + ncrWithAuction := ncr.GetEpochsConfig()[fmt.Sprint(epoch)].(EpochValidatorsHandlerWithAuction) + assert.True(t, sameValidatorsDifferentMapTypes(config.waitingMap, ncrWithAuction.GetWaitingValidators())) + assert.True(t, sameValidatorsDifferentMapTypes(config.leavingMap, ncrWithAuction.GetLeavingValidators())) + assert.True(t, sameValidatorsDifferentMapTypes(config.eligibleMap, ncrWithAuction.GetEligibleValidators())) + assert.True(t, sameValidatorsDifferentMapTypes(config.shuffledOutMap, ncrWithAuction.GetShuffledOutValidators())) + } +} + +func TestIndexHashedNodesCoordinator_nodesCoordinatorToRegistry(t *testing.T) { args := createArguments() nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) diff --git a/sharding/indexHashedNodesCoordinator_test.go b/sharding/indexHashedNodesCoordinator_test.go index 099850dee1d..99edf7480da 100644 --- a/sharding/indexHashedNodesCoordinator_test.go +++ b/sharding/indexHashedNodesCoordinator_test.go @@ -1105,18 +1105,6 @@ func createBlockBodyFromNodesCoordinator(ihgs *indexHashedNodesCoordinator, epoc return body } -func createBlockBodyWithAuctionFromNodesCoordinator(ihgs *indexHashedNodesCoordinator, epoch uint32) *block.Body { - body := &block.Body{MiniBlocks: make([]*block.MiniBlock, 0)} - - mbs := createBlockBodyFromNodesCoordinator(ihgs, epoch).MiniBlocks - body.MiniBlocks = append(body.MiniBlocks, mbs...) - - mbs = createMiniBlocksForNodesMap(ihgs.nodesConfig[epoch].leavingMap, string(common.SelectedFromAuctionList), ihgs.marshalizer) - body.MiniBlocks = append(body.MiniBlocks, mbs...) - - return body -} - func createMiniBlocksForNodesMap(nodesMap map[uint32][]Validator, list string, marshalizer marshal.Marshalizer) []*block.MiniBlock { miniBlocks := make([]*block.MiniBlock, 0) for shId, eligibleList := range nodesMap { @@ -1284,15 +1272,14 @@ func TestIndexHashedNodesCoordinator_setNodesPerShardsShouldSetNodeTypeObserver( require.Equal(t, core.NodeTypeObserver, nodeTypeResult) } -func TestIndexHashedNodesCoordinator_EpochStartPrepareWithAuction(t *testing.T) { +func TestIndexHashedNodesCoordinator_EpochStartInEligible(t *testing.T) { t.Parallel() arguments := createArguments() pk := []byte("pk") arguments.SelfPublicKey = pk - ihgs, _ := NewIndexHashedNodesCoordinator(arguments) - - ihgs.updateEpochFlags(arguments.StakingV4EnableEpoch) + ihgs, err := NewIndexHashedNodesCoordinator(arguments) + require.Nil(t, err) epoch := uint32(2) header := &block.MetaBlock{ @@ -1310,7 +1297,7 @@ func TestIndexHashedNodesCoordinator_EpochStartPrepareWithAuction(t *testing.T) }, }, } - body := createBlockBodyWithAuctionFromNodesCoordinator(ihgs, epoch) + body := createBlockBodyFromNodesCoordinator(ihgs, epoch) ihgs.EpochStartPrepare(header, body) ihgs.EpochStartAction(header) @@ -1320,38 +1307,33 @@ func TestIndexHashedNodesCoordinator_EpochStartPrepareWithAuction(t *testing.T) require.True(t, isValidator) } -func TestIndexHashedNodesCoordinator_EpochStartInEligible(t *testing.T) { +func TestIndexHashedNodesCoordinator_computeShardForSelfPublicKeyWithStakingV4(t *testing.T) { t.Parallel() arguments := createArguments() pk := []byte("pk") arguments.SelfPublicKey = pk - ihgs, err := NewIndexHashedNodesCoordinator(arguments) - require.Nil(t, err) + nc, _ := NewIndexHashedNodesCoordinator(arguments) epoch := uint32(2) - header := &block.MetaBlock{ - PrevRandSeed: []byte("rand seed"), - EpochStart: block.EpochStart{LastFinalizedHeaders: []block.EpochStartShardData{{}}}, - Epoch: epoch, - } - - validatorShard := core.MetachainShardId - ihgs.nodesConfig = map[uint32]*epochNodesConfig{ + metaShard := core.MetachainShardId + nc.nodesConfig = map[uint32]*epochNodesConfig{ epoch: { - shardID: validatorShard, - eligibleMap: map[uint32][]Validator{ - validatorShard: {mock.NewValidatorMock(pk, 1, 1)}, + shardID: metaShard, + shuffledOutMap: map[uint32][]Validator{ + metaShard: {mock.NewValidatorMock(pk, 1, 1)}, }, }, } - body := createBlockBodyFromNodesCoordinator(ihgs, epoch) - ihgs.EpochStartPrepare(header, body) - ihgs.EpochStartAction(header) - computedShardId, isValidator := ihgs.computeShardForSelfPublicKey(ihgs.nodesConfig[epoch]) + computedShardId, isValidator := nc.computeShardForSelfPublicKey(nc.nodesConfig[epoch]) + require.Equal(t, nc.shardIDAsObserver, computedShardId) + require.False(t, isValidator) - require.Equal(t, validatorShard, computedShardId) + nc.flagStakingV4.SetReturningPrevious() + + computedShardId, isValidator = nc.computeShardForSelfPublicKey(nc.nodesConfig[epoch]) + require.Equal(t, metaShard, computedShardId) require.True(t, isValidator) } @@ -2063,6 +2045,61 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNilPk(t *testing. assert.Equal(t, ErrNilPubKey, err) } +func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t *testing.T) { + t.Parallel() + arguments := createArguments() + nc, _ := NewIndexHashedNodesCoordinator(arguments) + + shard0Eligible := &state.ShardValidatorInfo{ + PublicKey: []byte("pk0"), + List: string(common.EligibleList), + Index: 1, + TempRating: 2, + ShardId: 0, + } + shard0Auction := &state.ShardValidatorInfo{ + PublicKey: []byte("pk1"), + List: string(common.SelectedFromAuctionList), + Index: 3, + TempRating: 2, + ShardId: 0, + } + shard1Auction := &state.ShardValidatorInfo{ + PublicKey: []byte("pk2"), + List: string(common.SelectedFromAuctionList), + Index: 2, + TempRating: 2, + ShardId: 1, + } + + validatorInfos := + []*state.ShardValidatorInfo{ + shard0Eligible, + shard0Auction, + shard1Auction, + } + + previousConfig := &epochNodesConfig{ + eligibleMap: map[uint32][]Validator{ + 0: { + mock.NewValidatorMock(shard0Eligible.PublicKey, 0, 0), + }, + }, + } + + newNodesConfig, err := nc.computeNodesConfigFromList(previousConfig, validatorInfos) + require.Nil(t, err) + require.Empty(t, newNodesConfig.auctionList) + + nc.flagStakingV4.SetReturningPrevious() + + newNodesConfig, err = nc.computeNodesConfigFromList(previousConfig, validatorInfos) + require.Nil(t, err) + v1, _ := NewValidator([]byte("pk2"), 1, 2) + v2, _ := NewValidator([]byte("pk1"), 1, 3) + require.Equal(t, []Validator{v1, v2}, newNodesConfig.auctionList) +} + func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix(t *testing.T) { t.Parallel() From 9815093d59b9504d58c32cbe9efd9d8b88bfac9e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 11 Mar 2022 13:45:56 +0200 Subject: [PATCH 107/958] FEAT: Add node shuffler tests --- sharding/hashValidatorShuffler_test.go | 55 ++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/sharding/hashValidatorShuffler_test.go b/sharding/hashValidatorShuffler_test.go index f86b5177039..5367a5be026 100644 --- a/sharding/hashValidatorShuffler_test.go +++ b/sharding/hashValidatorShuffler_test.go @@ -2618,6 +2618,61 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting(t *testing.T) assert.Equal(t, previousNumberOfNodes, currentNumberOfNodes) } +func TestRandHashShuffler_UpdateNodeLists_WithStakingV4(t *testing.T) { + t.Parallel() + + numEligiblePerShard := 100 + numNewNodesPerShard := 100 + numWaitingPerShard := 30 + numAuction := 40 + nbShards := uint32(2) + + eligibleMap := generateValidatorMap(numEligiblePerShard, nbShards) + waitingMap := generateValidatorMap(numWaitingPerShard, nbShards) + newNodes := generateValidatorList(numNewNodesPerShard * (int(nbShards) + 1)) + auctionList := generateValidatorList(numAuction) + + args := ArgsUpdateNodes{ + Eligible: eligibleMap, + Waiting: waitingMap, + NewNodes: newNodes, + UnStakeLeaving: make([]Validator, 0), + AdditionalLeaving: make([]Validator, 0), + Rand: generateRandomByteArray(32), + Auction: auctionList, + NbShards: nbShards, + Epoch: 444, + } + + shuffler, _ := createHashShufflerIntraShards() + resUpdateNodeList, err := shuffler.UpdateNodeLists(args) + require.Nil(t, err) + + for _, newNode := range args.NewNodes { + found, _ := searchInMap(resUpdateNodeList.Waiting, newNode.PubKey()) + assert.True(t, found) + } + + for _, auctionNode := range args.Auction { + found, _ := searchInMap(resUpdateNodeList.Waiting, auctionNode.PubKey()) + assert.True(t, found) + } + + allShuffledOut := getValidatorsInMap(resUpdateNodeList.ShuffledOut) + for _, shuffledOut := range allShuffledOut { + found, _ := searchInMap(args.Eligible, shuffledOut.PubKey()) + assert.True(t, found) + } + + allNewEligible := getValidatorsInMap(resUpdateNodeList.Eligible) + allNewWaiting := getValidatorsInMap(resUpdateNodeList.Waiting) + + previousNumberOfNodes := (numEligiblePerShard+numWaitingPerShard+numNewNodesPerShard)*(int(nbShards)+1) + numAuction + currentNumberOfNodes := len(allNewEligible) + len(allNewWaiting) + len(allShuffledOut) + assert.Equal(t, previousNumberOfNodes, currentNumberOfNodes) + +} + func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t *testing.T) { t.Parallel() From 08073413e2eae370fc8935b353e32d79da3f0db2 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 11 Mar 2022 13:52:33 +0200 Subject: [PATCH 108/958] FIX: Small test refactor --- sharding/indexHashedNodesCoordinator_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sharding/indexHashedNodesCoordinator_test.go b/sharding/indexHashedNodesCoordinator_test.go index 99edf7480da..10144af1e07 100644 --- a/sharding/indexHashedNodesCoordinator_test.go +++ b/sharding/indexHashedNodesCoordinator_test.go @@ -2071,13 +2071,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * TempRating: 2, ShardId: 1, } - - validatorInfos := - []*state.ShardValidatorInfo{ - shard0Eligible, - shard0Auction, - shard1Auction, - } + validatorInfos := []*state.ShardValidatorInfo{shard0Eligible, shard0Auction, shard1Auction} previousConfig := &epochNodesConfig{ eligibleMap: map[uint32][]Validator{ From 4d27010be453e93de87c67661b8903c3f5171445 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 11 Mar 2022 15:47:35 +0200 Subject: [PATCH 109/958] FIX: Merge conflict --- epochStart/metachain/legacySystemSCs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index d1fe6e03849..b6a874d9266 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -1375,7 +1375,7 @@ func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBloc } func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { - s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch) + s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch && epoch < s.stakingV4InitEnableEpoch) log.Debug("legacySystemSC: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers From a8ee7065cf1d93f53ef9adc29f51ab1a2376103f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 11:24:24 +0200 Subject: [PATCH 110/958] FEAT: Add files --- state/interface.go | 62 +++++++ state/validatorInfo.go | 102 ++++++++++++ state/validatorsInfoMap.go | 183 +++++++++++++++++++++ state/validatorsInfoMap_test.go | 280 ++++++++++++++++++++++++++++++++ 4 files changed, 627 insertions(+) create mode 100644 state/validatorsInfoMap.go create mode 100644 state/validatorsInfoMap_test.go diff --git a/state/interface.go b/state/interface.go index df013c5f85a..ce6b95e7960 100644 --- a/state/interface.go +++ b/state/interface.go @@ -182,3 +182,65 @@ type StoragePruningManager interface { Close() error IsInterfaceNil() bool } + +// ShardValidatorsInfoMapHandler shall be used to manage operations inside +// a map in a concurrent-safe way. +type ShardValidatorsInfoMapHandler interface { + GetShardValidatorsInfoMap() map[uint32][]ValidatorInfoHandler + GetAllValidatorsInfo() []ValidatorInfoHandler + GetValidator(blsKey []byte) ValidatorInfoHandler + + Add(validator ValidatorInfoHandler) + Delete(validator ValidatorInfoHandler) + Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) + SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) + + GetValInfoPointerMap() map[uint32][]*ValidatorInfo +} + +//ValidatorInfoHandler defines which data shall a validator info hold. +type ValidatorInfoHandler interface { + IsInterfaceNil() bool + + GetPublicKey() []byte + GetShardId() uint32 + GetList() string + GetIndex() uint32 + GetTempRating() uint32 + GetRating() uint32 + GetRatingModifier() float32 + GetRewardAddress() []byte + GetLeaderSuccess() uint32 + GetLeaderFailure() uint32 + GetValidatorSuccess() uint32 + GetValidatorFailure() uint32 + GetValidatorIgnoredSignatures() uint32 + GetNumSelectedInSuccessBlocks() uint32 + GetAccumulatedFees() *big.Int + GetTotalLeaderSuccess() uint32 + GetTotalLeaderFailure() uint32 + GetTotalValidatorSuccess() uint32 + GetTotalValidatorFailure() uint32 + GetTotalValidatorIgnoredSignatures() uint32 + + SetPublicKey(publicKey []byte) + SetShardId(shardID uint32) + SetList(list string) + SetIndex(index uint32) + SetTempRating(tempRating uint32) + SetRating(rating uint32) + SetRatingModifier(ratingModifier float32) + SetRewardAddress(rewardAddress []byte) + SetLeaderSuccess(leaderSuccess uint32) + SetLeaderFailure(leaderFailure uint32) + SetValidatorSuccess(validatorSuccess uint32) + SetValidatorFailure(validatorFailure uint32) + SetValidatorIgnoredSignatures(validatorIgnoredSignatures uint32) + SetNumSelectedInSuccessBlocks(numSelectedInSuccessBlock uint32) + SetAccumulatedFees(accumulatedFees *big.Int) + SetTotalLeaderSuccess(totalLeaderSuccess uint32) + SetTotalLeaderFailure(totalLeaderFailure uint32) + SetTotalValidatorSuccess(totalValidatorSuccess uint32) + SetTotalValidatorFailure(totalValidatorFailure uint32) + SetTotalValidatorIgnoredSignatures(totalValidatorIgnoredSignatures uint32) +} diff --git a/state/validatorInfo.go b/state/validatorInfo.go index 90c21e0e9b9..93980510347 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -2,11 +2,113 @@ package state +import mathbig "math/big" + // IsInterfaceNil returns true if there is no value under the interface func (vi *ValidatorInfo) IsInterfaceNil() bool { return vi == nil } +// SetPublicKey sets validator's public key +func (vi *ValidatorInfo) SetPublicKey(publicKey []byte) { + vi.PublicKey = publicKey +} + +// SetList sets validator's list +func (vi *ValidatorInfo) SetList(list string) { + vi.List = list +} + +// SetShardId sets validator's public shard id +func (vi *ValidatorInfo) SetShardId(shardID uint32) { + vi.ShardId = shardID +} + +// SetIndex sets validator's index +func (vi *ValidatorInfo) SetIndex(index uint32) { + vi.Index = index +} + +// SetTempRating sets validator's temp rating +func (vi *ValidatorInfo) SetTempRating(tempRating uint32) { + vi.TempRating = tempRating +} + +// SetRating sets validator's rating +func (vi *ValidatorInfo) SetRating(rating uint32) { + vi.Rating = rating +} + +// SetRatingModifier sets validator's rating modifier +func (vi *ValidatorInfo) SetRatingModifier(ratingModifier float32) { + vi.RatingModifier = ratingModifier +} + +// SetRewardAddress sets validator's reward address +func (vi *ValidatorInfo) SetRewardAddress(rewardAddress []byte) { + vi.RewardAddress = rewardAddress +} + +// SetLeaderSuccess sets leader success +func (vi *ValidatorInfo) SetLeaderSuccess(leaderSuccess uint32) { + vi.LeaderSuccess = leaderSuccess +} + +// SetLeaderFailure sets validator's leader failure +func (vi *ValidatorInfo) SetLeaderFailure(leaderFailure uint32) { + vi.LeaderFailure = leaderFailure +} + +// SetValidatorSuccess sets validator's success +func (vi *ValidatorInfo) SetValidatorSuccess(validatorSuccess uint32) { + vi.ValidatorSuccess = validatorSuccess +} + +// SetValidatorFailure sets validator's failure +func (vi *ValidatorInfo) SetValidatorFailure(validatorFailure uint32) { + vi.ValidatorFailure = validatorFailure +} + +// SetValidatorIgnoredSignatures sets validator's ignored signatures +func (vi *ValidatorInfo) SetValidatorIgnoredSignatures(validatorIgnoredSignatures uint32) { + vi.ValidatorIgnoredSignatures = validatorIgnoredSignatures +} + +// SetNumSelectedInSuccessBlocks sets validator's num of selected in success block +func (vi *ValidatorInfo) SetNumSelectedInSuccessBlocks(numSelectedInSuccessBlock uint32) { + vi.NumSelectedInSuccessBlocks = numSelectedInSuccessBlock +} + +// SetAccumulatedFees sets validator's accumulated fees +func (vi *ValidatorInfo) SetAccumulatedFees(accumulatedFees *mathbig.Int) { + vi.AccumulatedFees = mathbig.NewInt(0).Set(accumulatedFees) +} + +// SetTotalLeaderSuccess sets validator's total leader success +func (vi *ValidatorInfo) SetTotalLeaderSuccess(totalLeaderSuccess uint32) { + vi.TotalLeaderSuccess = totalLeaderSuccess +} + +// SetTotalLeaderFailure sets validator's total leader failure +func (vi *ValidatorInfo) SetTotalLeaderFailure(totalLeaderFailure uint32) { + vi.TotalLeaderFailure = totalLeaderFailure +} + +// SetTotalValidatorSuccess sets validator's total success +func (vi *ValidatorInfo) SetTotalValidatorSuccess(totalValidatorSuccess uint32) { + vi.TotalValidatorSuccess = totalValidatorSuccess +} + +// SetTotalValidatorFailure sets validator's total failure +func (vi *ValidatorInfo) SetTotalValidatorFailure(totalValidatorFailure uint32) { + vi.TotalValidatorFailure = totalValidatorFailure +} + +// SetTotalValidatorIgnoredSignatures sets validator's total ignored signatures +func (vi *ValidatorInfo) SetTotalValidatorIgnoredSignatures(totalValidatorIgnoredSignatures uint32) { + vi.TotalValidatorIgnoredSignatures = totalValidatorIgnoredSignatures +} + // IsInterfaceNil returns true if there is no value under the interface func (svi *ShardValidatorInfo) IsInterfaceNil() bool { return svi == nil diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go new file mode 100644 index 00000000000..59255d7a2c4 --- /dev/null +++ b/state/validatorsInfoMap.go @@ -0,0 +1,183 @@ +package state + +import ( + "bytes" + "sync" +) + +type shardValidatorsInfoMap struct { + mutex sync.RWMutex + valInfoMap map[uint32][]ValidatorInfoHandler +} + +// NewShardValidatorsInfoMap creates an instance of shardValidatorsInfoMap which manages a +// map internally +func NewShardValidatorsInfoMap(numOfShards uint32) *shardValidatorsInfoMap { + return &shardValidatorsInfoMap{ + mutex: sync.RWMutex{}, + valInfoMap: make(map[uint32][]ValidatorInfoHandler, numOfShards), + } +} + +// TODO: Delete this 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 +} + +// GetAllValidatorsInfo returns a ValidatorInfoHandler copy slice with validators from all shards. +func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler { + ret := make([]ValidatorInfoHandler, 0) + + vi.mutex.RLock() + validatorsMapCopy := vi.valInfoMap + vi.mutex.RUnlock() + + for _, validatorsInShard := range validatorsMapCopy { + validatorsCopy := make([]ValidatorInfoHandler, len(validatorsInShard)) + copy(validatorsCopy, validatorsInShard) + ret = append(ret, validatorsCopy...) + } + + return ret +} + +// GetShardValidatorsInfoMap returns a copy map of internally stored data +func (vi *shardValidatorsInfoMap) GetShardValidatorsInfoMap() map[uint32][]ValidatorInfoHandler { + ret := make(map[uint32][]ValidatorInfoHandler, 0) + + vi.mutex.RLock() + validatorsMapCopy := vi.valInfoMap + vi.mutex.RUnlock() + + for shardID, valInShard := range validatorsMapCopy { + validatorsCopy := make([]ValidatorInfoHandler, len(valInShard)) + copy(validatorsCopy, valInShard) + ret[shardID] = validatorsCopy + } + + return ret +} + +// Add adds a new ValidatorInfoHandler in its corresponding shardID, if it doesn't already exists +func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) { + if vi.GetValidator(validator.GetPublicKey()) != nil { + return + } + + shardID := validator.GetShardId() + + vi.mutex.Lock() + vi.valInfoMap[shardID] = append(vi.valInfoMap[shardID], validator) + vi.mutex.Unlock() +} + +// GetValidator returns a ValidatorInfoHandler with the provided blsKey, if it is present in the map +func (vi *shardValidatorsInfoMap) GetValidator(blsKey []byte) ValidatorInfoHandler { + for _, validator := range vi.GetAllValidatorsInfo() { + if bytes.Equal(validator.GetPublicKey(), blsKey) { + return validator + } + } + + return nil +} + +// Replace will replace an existing ValidatorInfoHandler with a new one. The old and new validator +// shall be in the same shard and have the same public key. +func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) { + if old.GetShardId() != new.GetShardId() { + return + } + + shardID := old.GetShardId() + + vi.mutex.Lock() + defer vi.mutex.Unlock() + + for idx, validator := range vi.valInfoMap[shardID] { + if bytes.Equal(validator.GetPublicKey(), old.GetPublicKey()) { + vi.valInfoMap[shardID][idx] = new + break + } + } +} + +// SetValidatorsInShard resets all validators saved in a specific shard with the provided []ValidatorInfoHandler. +// Before setting them, it checks that provided validators have the same shardID as the one provided. +func (vi *shardValidatorsInfoMap) SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) { + sameShardValidators := make([]ValidatorInfoHandler, 0, len(validators)) + for _, validator := range validators { + if validator.GetShardId() == shardID { + sameShardValidators = append(sameShardValidators, validator) + } + } + + vi.mutex.Lock() + vi.valInfoMap[shardID] = sameShardValidators + vi.mutex.Unlock() +} + +// Delete will delete the provided validator from the internally stored map. The validators slice at the +// corresponding shardID key will be re-sliced, without reordering +func (vi *shardValidatorsInfoMap) Delete(validator ValidatorInfoHandler) { + shardID := validator.GetShardId() + + vi.mutex.Lock() + defer vi.mutex.Unlock() + + for index, validatorInfo := range vi.valInfoMap[shardID] { + if bytes.Equal(validatorInfo.GetPublicKey(), validator.GetPublicKey()) { + length := len(vi.valInfoMap[shardID]) + vi.valInfoMap[shardID][index] = vi.valInfoMap[shardID][length-1] + vi.valInfoMap[shardID][length-1] = nil + vi.valInfoMap[shardID] = vi.valInfoMap[shardID][:length-1] + break + } + } +} + +// 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 new file mode 100644 index 00000000000..e36834fbca2 --- /dev/null +++ b/state/validatorsInfoMap_test.go @@ -0,0 +1,280 @@ +package state + +import ( + "strconv" + "sync" + "testing" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/stretchr/testify/require" +) + +func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsInfo(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(3) + + v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} + v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} + v2 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk2")} + v3 := &ValidatorInfo{ShardId: core.MetachainShardId, PublicKey: []byte("pk3")} + + vi.Add(v0) + vi.Add(v1) + vi.Add(v2) + vi.Add(v3) + vi.Add(v3) + + allValidators := vi.GetAllValidatorsInfo() + require.Len(t, allValidators, 4) + require.Contains(t, allValidators, v0) + require.Contains(t, allValidators, v1) + require.Contains(t, allValidators, v2) + require.Contains(t, allValidators, v3) + + validatorsMap := vi.GetShardValidatorsInfoMap() + expectedValidatorsMap := map[uint32][]ValidatorInfoHandler{ + 0: {v0, v1}, + 1: {v2}, + 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_GetValidatorWithBLSKey(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(1) + + pubKey0 := []byte("pk0") + pubKey1 := []byte("pk1") + v0 := &ValidatorInfo{ShardId: 0, PublicKey: pubKey0} + v1 := &ValidatorInfo{ShardId: 1, PublicKey: pubKey1} + + vi.Add(v0) + vi.Add(v1) + + require.Equal(t, v0, vi.GetValidator(pubKey0)) + require.Equal(t, v1, vi.GetValidator(pubKey1)) + require.Nil(t, vi.GetValidator([]byte("pk2"))) +} + +func TestShardValidatorsInfoMap_Delete(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(2) + + v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} + v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} + v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} + v3 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk3")} + + vi.Add(v0) + vi.Add(v1) + vi.Add(v2) + vi.Add(v3) + + vi.Delete(&ValidatorInfo{ShardId: 0, PublicKey: []byte("pk3")}) + vi.Delete(&ValidatorInfo{ShardId: 1, PublicKey: []byte("pk0")}) + require.Len(t, vi.GetAllValidatorsInfo(), 4) + + vi.Delete(&ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")}) + require.Len(t, vi.GetAllValidatorsInfo(), 3) + require.Equal(t, []ValidatorInfoHandler{v0, v2}, vi.GetShardValidatorsInfoMap()[0]) +} + +func TestShardValidatorsInfoMap_Replace(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(2) + + v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} + v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} + + vi.Add(v0) + vi.Add(v1) + + vi.Replace(v0, &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk2")}) + require.Equal(t, []ValidatorInfoHandler{v0, v1}, vi.GetShardValidatorsInfoMap()[0]) + + v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} + vi.Replace(v0, v2) + require.Equal(t, []ValidatorInfoHandler{v2, v1}, vi.GetShardValidatorsInfoMap()[0]) +} + +func TestShardValidatorsInfoMap_SetValidatorsInShard(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(2) + + v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} + vi.Add(v0) + + v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} + v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} + v3 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk3")} + shard0Validators := []ValidatorInfoHandler{v1, v2} + shard1Validators := []ValidatorInfoHandler{v3} + + vi.SetValidatorsInShard(1, shard0Validators) + require.Equal(t, []ValidatorInfoHandler{v0}, vi.GetShardValidatorsInfoMap()[0]) + + vi.SetValidatorsInShard(0, []ValidatorInfoHandler{v1, v2, v3}) + require.Equal(t, shard0Validators, vi.GetShardValidatorsInfoMap()[0]) + + vi.SetValidatorsInShard(1, shard1Validators) + require.Equal(t, shard0Validators, vi.GetShardValidatorsInfoMap()[0]) + require.Equal(t, shard1Validators, vi.GetShardValidatorsInfoMap()[1]) +} + +func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(2) + + v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} + v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} + v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} + + vi.Add(v0) + vi.Add(v1) + vi.Add(v2) + + validatorsMap := vi.GetShardValidatorsInfoMap() + delete(validatorsMap, 0) + + validatorPointersMap := vi.GetValInfoPointerMap() + delete(validatorPointersMap, 0) + + validators := vi.GetAllValidatorsInfo() + validators = append(validators, &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk3")}) + + validator := vi.GetValidator([]byte("pk0")) + validator.SetShardId(1) + + require.Equal(t, []ValidatorInfoHandler{v0, v1, v2}, vi.GetAllValidatorsInfo()) +} + +func TestShardValidatorsInfoMap_Concurrency(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(2) + + numValidatorsShard0 := 100 + numValidatorsShard1 := 50 + numValidators := numValidatorsShard0 + numValidatorsShard1 + + shard0Validators := createValidatorsInfo(0, numValidatorsShard0) + shard1Validators := createValidatorsInfo(1, numValidatorsShard1) + + firstHalfShard0 := shard0Validators[:numValidatorsShard0/2] + secondHalfShard0 := shard0Validators[numValidatorsShard0/2:] + + firstHalfShard1 := shard1Validators[:numValidatorsShard1/2] + secondHalfShard1 := shard1Validators[numValidatorsShard1/2:] + + wg := &sync.WaitGroup{} + + wg.Add(numValidators) + go addValidatorsInShardConcurrently(vi, shard0Validators, wg) + go addValidatorsInShardConcurrently(vi, shard1Validators, wg) + wg.Wait() + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[0], shard0Validators) + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[1], shard1Validators) + + wg.Add(numValidators / 2) + go deleteValidatorsConcurrently(vi, firstHalfShard0, wg) + go deleteValidatorsConcurrently(vi, firstHalfShard1, wg) + wg.Wait() + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[0], secondHalfShard0) + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[1], secondHalfShard1) + + wg.Add(numValidators / 2) + go replaceValidatorsConcurrently(vi, vi.GetShardValidatorsInfoMap()[0], firstHalfShard0, wg) + go replaceValidatorsConcurrently(vi, vi.GetShardValidatorsInfoMap()[1], firstHalfShard1, wg) + wg.Wait() + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[0], firstHalfShard0) + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[1], firstHalfShard1) + + wg.Add(2) + go func() { + vi.SetValidatorsInShard(0, shard0Validators) + wg.Done() + }() + go func() { + vi.SetValidatorsInShard(1, shard1Validators) + wg.Done() + }() + wg.Wait() + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[0], shard0Validators) + requireSameValidatorsDifferentOrder(t, vi.GetShardValidatorsInfoMap()[1], shard1Validators) +} + +func requireSameValidatorsDifferentOrder(t *testing.T, dest []ValidatorInfoHandler, src []ValidatorInfoHandler) { + require.Equal(t, len(dest), len(src)) + + for _, v := range src { + require.Contains(t, dest, v) + } +} + +func createValidatorsInfo(shardID uint32, numOfValidators int) []ValidatorInfoHandler { + ret := make([]ValidatorInfoHandler, 0, numOfValidators) + + for i := 0; i < numOfValidators; i++ { + ret = append(ret, &ValidatorInfo{ + ShardId: shardID, + PublicKey: []byte(strconv.Itoa(int(shardID)) + "pubKey" + strconv.Itoa(i)), + }) + } + + return ret +} + +func addValidatorsInShardConcurrently( + vi ShardValidatorsInfoMapHandler, + validators []ValidatorInfoHandler, + wg *sync.WaitGroup, +) { + for _, validator := range validators { + go func(val ValidatorInfoHandler) { + vi.Add(val) + wg.Done() + }(validator) + } +} + +func deleteValidatorsConcurrently( + vi ShardValidatorsInfoMapHandler, + validators []ValidatorInfoHandler, + wg *sync.WaitGroup, +) { + for _, validator := range validators { + go func(val ValidatorInfoHandler) { + vi.Delete(val) + wg.Done() + }(validator) + } +} + +func replaceValidatorsConcurrently( + vi ShardValidatorsInfoMapHandler, + oldValidators []ValidatorInfoHandler, + newValidators []ValidatorInfoHandler, + wg *sync.WaitGroup, +) { + for idx := range oldValidators { + go func(old ValidatorInfoHandler, new ValidatorInfoHandler) { + vi.Replace(old, new) + wg.Done() + }(oldValidators[idx], newValidators[idx]) + } +} From 4f0c39305b8c8e3b8f95f3010b414ebf95e6d677 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 11:27:38 +0200 Subject: [PATCH 111/958] FEAT: Add files --- common/validatorInfo/validatorInfoUtils.go | 16 +-- epochStart/metachain/legacySystemSCs.go | 145 ++++++++------------- epochStart/metachain/systemSCs.go | 66 ++++++---- epochStart/metachain/validatorList.go | 12 +- 4 files changed, 105 insertions(+), 134 deletions(-) diff --git a/common/validatorInfo/validatorInfoUtils.go b/common/validatorInfo/validatorInfoUtils.go index ca4a22e7204..83454f7f4bd 100644 --- a/common/validatorInfo/validatorInfoUtils.go +++ b/common/validatorInfo/validatorInfoUtils.go @@ -6,33 +6,33 @@ import ( ) // WasActiveInCurrentEpoch returns true if the node was active in current epoch -func WasActiveInCurrentEpoch(valInfo *state.ValidatorInfo) bool { - active := valInfo.LeaderFailure > 0 || valInfo.LeaderSuccess > 0 || valInfo.ValidatorSuccess > 0 || valInfo.ValidatorFailure > 0 +func WasActiveInCurrentEpoch(valInfo state.ValidatorInfoHandler) bool { + active := valInfo.GetLeaderFailure() > 0 || valInfo.GetLeaderSuccess() > 0 || valInfo.GetValidatorSuccess() > 0 || valInfo.GetValidatorFailure() > 0 return active } // WasLeavingEligibleInCurrentEpoch returns true if the validator was eligible in the epoch but has done an unstake. -func WasLeavingEligibleInCurrentEpoch(valInfo *state.ValidatorInfo) bool { +func WasLeavingEligibleInCurrentEpoch(valInfo state.ValidatorInfoHandler) bool { if valInfo == nil { return false } - return valInfo.List == string(common.LeavingList) && WasActiveInCurrentEpoch(valInfo) + return valInfo.GetList() == string(common.LeavingList) && WasActiveInCurrentEpoch(valInfo) } // WasJailedEligibleInCurrentEpoch returns true if the validator was jailed in the epoch but also active/eligible due to not enough //nodes in shard. -func WasJailedEligibleInCurrentEpoch(valInfo *state.ValidatorInfo) bool { +func WasJailedEligibleInCurrentEpoch(valInfo state.ValidatorInfoHandler) bool { if valInfo == nil { return false } - return valInfo.List == string(common.JailedList) && WasActiveInCurrentEpoch(valInfo) + return valInfo.GetList() == string(common.JailedList) && WasActiveInCurrentEpoch(valInfo) } // WasEligibleInCurrentEpoch returns true if the validator was eligible for consensus in current epoch -func WasEligibleInCurrentEpoch(valInfo *state.ValidatorInfo) bool { - wasEligibleInShard := valInfo.List == string(common.EligibleList) || +func WasEligibleInCurrentEpoch(valInfo state.ValidatorInfoHandler) bool { + wasEligibleInShard := valInfo.GetList() == string(common.EligibleList) || WasLeavingEligibleInCurrentEpoch(valInfo) || WasJailedEligibleInCurrentEpoch(valInfo) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index b6a874d9266..40b4a70f8e6 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -164,7 +164,7 @@ func checkLegacyArgs(args ArgsNewEpochStartSystemSCProcessing) error { } func (s *legacySystemSCProcessor) processLegacy( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, nonce uint64, epoch uint32, ) error { @@ -290,10 +290,10 @@ func (s *legacySystemSCProcessor) ToggleUnStakeUnBond(value bool) error { } func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, epoch uint32, ) (uint32, error) { - nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap.GetValInfoPointerMap()) if err != nil { return 0, err } @@ -308,14 +308,14 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( return 0, err } - validatorInfo := getValidatorInfoWithBLSKey(validatorsInfoMap, blsKey) + validatorInfo := validatorsInfoMap.GetValidator(blsKey) if validatorInfo == nil { nodesUnStakedFromAdditionalQueue++ log.Debug("unStaked node which was in additional queue", "blsKey", blsKey) continue } - validatorInfo.List = string(common.LeavingList) + validatorInfo.SetList(string(common.LeavingList)) } err = s.updateDelegationContracts(mapOwnersKeys) @@ -420,20 +420,9 @@ func (s *legacySystemSCProcessor) updateDelegationContracts(mapOwnerKeys map[str return nil } -func getValidatorInfoWithBLSKey(validatorsInfoMap map[uint32][]*state.ValidatorInfo, blsKey []byte) *state.ValidatorInfo { - for _, validatorsInfoSlice := range validatorsInfoMap { - for _, validatorInfo := range validatorsInfoSlice { - if bytes.Equal(validatorInfo.PublicKey, blsKey) { - return validatorInfo - } - } - } - return nil -} - -func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - for shId, validatorsInfoSlice := range validatorsInfoMap { - newList := make([]*state.ValidatorInfo, 0, len(validatorsInfoSlice)) +func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { + for shId, validatorsInfoSlice := range validatorsInfoMap.GetShardValidatorsInfoMap() { + newList := make([]state.ValidatorInfoHandler, 0, len(validatorsInfoSlice)) deleteCalled := false for _, validatorInfo := range validatorsInfoSlice { @@ -442,16 +431,16 @@ func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMa continue } - err := s.stakingDataProvider.FillValidatorInfo(validatorInfo.PublicKey) + err := s.stakingDataProvider.FillValidatorInfo(validatorInfo.GetPublicKey()) if err != nil { deleteCalled = true log.Error("fillStakingDataForNonEligible", "error", err) - if len(validatorInfo.List) > 0 { + if len(validatorInfo.GetList()) > 0 { return err } - err = s.peerAccountsDB.RemoveAccount(validatorInfo.PublicKey) + err = s.peerAccountsDB.RemoveAccount(validatorInfo.GetPublicKey()) if err != nil { log.Error("fillStakingDataForNonEligible removeAccount", "error", err) } @@ -463,19 +452,19 @@ func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMa } if deleteCalled { - validatorsInfoMap[shId] = newList + validatorsInfoMap.SetValidatorsInShard(shId, newList) } } return nil } -func (s *legacySystemSCProcessor) prepareStakingDataForEligibleNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { +func (s *legacySystemSCProcessor) prepareStakingDataForEligibleNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { eligibleNodes := s.getEligibleNodeKeys(validatorsInfoMap) return s.prepareStakingData(eligibleNodes) } -func (s *legacySystemSCProcessor) unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap map[uint32][]*state.ValidatorInfo, epoch uint32) (uint32, error) { +func (s *legacySystemSCProcessor) unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap state.ShardValidatorsInfoMapHandler, epoch uint32) (uint32, error) { err := s.fillStakingDataForNonEligible(validatorsInfoMap) if err != nil { return 0, err @@ -496,14 +485,14 @@ func (s *legacySystemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byt } func (s *legacySystemSCProcessor) getEligibleNodeKeys( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, ) map[uint32][][]byte { eligibleNodesKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfoMap { + for shardID, validatorsInfoSlice := range validatorsInfoMap.GetShardValidatorsInfoMap() { eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) for _, validatorInfo := range validatorsInfoSlice { if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { - eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.PublicKey) + eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.GetPublicKey()) } } } @@ -605,7 +594,7 @@ func (s *legacySystemSCProcessor) resetLastUnJailed() error { } // updates the configuration of the system SC if the flags permit -func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo, nonce uint64) error { +func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler, nonce uint64) error { sw := core.NewStopWatch() sw.Start("total") defer func() { @@ -636,11 +625,11 @@ func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap map[uint32][] return nil } -func (s *legacySystemSCProcessor) computeNumWaitingPerShard(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { - for shardID, validatorInfoList := range validatorsInfoMap { +func (s *legacySystemSCProcessor) computeNumWaitingPerShard(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { + for shardID, validatorInfoList := range validatorsInfoMap.GetShardValidatorsInfoMap() { totalInWaiting := uint32(0) for _, validatorInfo := range validatorInfoList { - switch validatorInfo.List { + switch validatorInfo.GetList() { case string(common.WaitingList): totalInWaiting++ } @@ -651,27 +640,27 @@ func (s *legacySystemSCProcessor) computeNumWaitingPerShard(validatorsInfoMap ma return nil } -func (s *legacySystemSCProcessor) swapJailedWithWaiting(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { +func (s *legacySystemSCProcessor) swapJailedWithWaiting(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { jailedValidators := s.getSortedJailedNodes(validatorsInfoMap) log.Debug("number of jailed validators", "num", len(jailedValidators)) newValidators := make(map[string]struct{}) for _, jailedValidator := range jailedValidators { - if _, ok := newValidators[string(jailedValidator.PublicKey)]; ok { + if _, ok := newValidators[string(jailedValidator.GetPublicKey())]; ok { continue } - if isValidator(jailedValidator) && s.mapNumSwitchablePerShard[jailedValidator.ShardId] <= s.mapNumSwitchedPerShard[jailedValidator.ShardId] { + if isValidator(jailedValidator) && s.mapNumSwitchablePerShard[jailedValidator.GetShardId()] <= s.mapNumSwitchedPerShard[jailedValidator.GetShardId()] { log.Debug("cannot switch in this epoch anymore for this shard as switched num waiting", - "shardID", jailedValidator.ShardId, - "numSwitched", s.mapNumSwitchedPerShard[jailedValidator.ShardId]) + "shardID", jailedValidator.GetShardId(), + "numSwitched", s.mapNumSwitchedPerShard[jailedValidator.GetShardId()]) continue } vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ CallerAddr: s.endOfEpochCallerAddress, - Arguments: [][]byte{jailedValidator.PublicKey}, + Arguments: [][]byte{jailedValidator.GetPublicKey()}, CallValue: big.NewInt(0), }, RecipientAddr: s.stakingSCAddress, @@ -684,7 +673,7 @@ func (s *legacySystemSCProcessor) swapJailedWithWaiting(validatorsInfoMap map[ui } log.Debug("switchJailedWithWaiting called for", - "key", jailedValidator.PublicKey, + "key", jailedValidator.GetPublicKey(), "returnMessage", vmOutput.ReturnMessage) if vmOutput.ReturnCode != vmcommon.Ok { continue @@ -704,8 +693,8 @@ func (s *legacySystemSCProcessor) swapJailedWithWaiting(validatorsInfoMap map[ui } func (s *legacySystemSCProcessor) stakingToValidatorStatistics( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - jailedValidator *state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + jailedValidator state.ValidatorInfoHandler, vmOutput *vmcommon.VMOutput, ) ([]byte, error) { stakingSCOutput, ok := vmOutput.OutputAccounts[string(s.stakingSCAddress)] @@ -715,8 +704,8 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( var activeStorageUpdate *vmcommon.StorageUpdate for _, storageUpdate := range stakingSCOutput.StorageUpdates { - isNewValidatorKey := len(storageUpdate.Offset) == len(jailedValidator.PublicKey) && - !bytes.Equal(storageUpdate.Offset, jailedValidator.PublicKey) + isNewValidatorKey := len(storageUpdate.Offset) == len(jailedValidator.GetPublicKey()) && + !bytes.Equal(storageUpdate.Offset, jailedValidator.GetPublicKey()) if isNewValidatorKey { activeStorageUpdate = storageUpdate break @@ -766,10 +755,10 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } } else { // old jailed validator getting switched back after unJail with stake - must remove first from exported map - deleteNewValidatorIfExistsFromMap(validatorsInfoMap, blsPubKey, account.GetShardId()) + validatorsInfoMap.Delete(jailedValidator) } - account.SetListAndIndex(jailedValidator.ShardId, string(common.NewList), uint32(stakingData.StakedNonce)) + account.SetListAndIndex(jailedValidator.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce)) account.SetTempRating(s.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) @@ -778,12 +767,12 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( return nil, err } - jailedAccount, err := s.getPeerAccount(jailedValidator.PublicKey) + jailedAccount, err := s.getPeerAccount(jailedValidator.GetPublicKey()) if err != nil { return nil, err } - jailedAccount.SetListAndIndex(jailedValidator.ShardId, string(common.JailedList), jailedValidator.Index) + jailedAccount.SetListAndIndex(jailedValidator.GetShardId(), string(common.JailedList), jailedValidator.GetIndex()) jailedAccount.ResetAtNewEpoch() err = s.peerAccountsDB.SaveAccount(jailedAccount) if err != nil { @@ -791,46 +780,17 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } if isValidator(jailedValidator) { - s.mapNumSwitchedPerShard[jailedValidator.ShardId]++ + s.mapNumSwitchedPerShard[jailedValidator.GetShardId()]++ } newValidatorInfo := s.validatorInfoCreator.PeerAccountToValidatorInfo(account) - switchJailedWithNewValidatorInMap(validatorsInfoMap, jailedValidator, newValidatorInfo) + validatorsInfoMap.Replace(jailedValidator, newValidatorInfo) return blsPubKey, nil } -func isValidator(validator *state.ValidatorInfo) bool { - return validator.List == string(common.WaitingList) || validator.List == string(common.EligibleList) -} - -func deleteNewValidatorIfExistsFromMap( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - blsPubKey []byte, - shardID uint32, -) { - for index, validatorInfo := range validatorsInfoMap[shardID] { - if bytes.Equal(validatorInfo.PublicKey, blsPubKey) { - length := len(validatorsInfoMap[shardID]) - validatorsInfoMap[shardID][index] = validatorsInfoMap[shardID][length-1] - validatorsInfoMap[shardID][length-1] = nil - validatorsInfoMap[shardID] = validatorsInfoMap[shardID][:length-1] - break - } - } -} - -func switchJailedWithNewValidatorInMap( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, - jailedValidator *state.ValidatorInfo, - newValidator *state.ValidatorInfo, -) { - for index, validatorInfo := range validatorsInfoMap[jailedValidator.ShardId] { - if bytes.Equal(validatorInfo.PublicKey, jailedValidator.PublicKey) { - validatorsInfoMap[jailedValidator.ShardId][index] = newValidator - break - } - } +func isValidator(validator state.ValidatorInfoHandler) bool { + return validator.GetList() == string(common.WaitingList) || validator.GetList() == string(common.EligibleList) } func (s *legacySystemSCProcessor) getUserAccount(address []byte) (state.UserAccountHandler, error) { @@ -883,19 +843,18 @@ func (s *legacySystemSCProcessor) processSCOutputAccounts( return nil } -func (s *legacySystemSCProcessor) getSortedJailedNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) []*state.ValidatorInfo { - newJailedValidators := make([]*state.ValidatorInfo, 0) - oldJailedValidators := make([]*state.ValidatorInfo, 0) +func (s *legacySystemSCProcessor) getSortedJailedNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) []state.ValidatorInfoHandler { + newJailedValidators := make([]state.ValidatorInfoHandler, 0) + oldJailedValidators := make([]state.ValidatorInfoHandler, 0) minChance := s.chanceComputer.GetChance(0) - for _, listValidators := range validatorsInfoMap { - for _, validatorInfo := range listValidators { - if validatorInfo.List == string(common.JailedList) { - oldJailedValidators = append(oldJailedValidators, validatorInfo) - } else if s.chanceComputer.GetChance(validatorInfo.TempRating) < minChance { - newJailedValidators = append(newJailedValidators, validatorInfo) - } + for _, validatorInfo := range validatorsInfoMap.GetAllValidatorsInfo() { + if validatorInfo.GetList() == string(common.JailedList) { + oldJailedValidators = append(oldJailedValidators, validatorInfo) + } else if s.chanceComputer.GetChance(validatorInfo.GetTempRating()) < minChance { + newJailedValidators = append(newJailedValidators, validatorInfo) } + } sort.Sort(validatorList(oldJailedValidators)) @@ -1209,7 +1168,7 @@ func (s *legacySystemSCProcessor) cleanAdditionalQueue() error { } func (s *legacySystemSCProcessor) stakeNodesFromQueue( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, nodesToStake uint32, nonce uint64, list common.PeerType, @@ -1253,7 +1212,7 @@ func (s *legacySystemSCProcessor) stakeNodesFromQueue( } func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, returnData [][]byte, nonce uint64, list common.PeerType, @@ -1296,7 +1255,7 @@ func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( RewardAddress: rewardAddress, AccumulatedFees: big.NewInt(0), } - validatorsInfoMap[peerAcc.GetShardId()] = append(validatorsInfoMap[peerAcc.GetShardId()], validatorInfo) + validatorsInfoMap.Add(validatorInfo) } return nil diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index aba15dc0f0d..621eced5215 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -92,16 +92,29 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( validatorsInfoMap map[uint32][]*state.ValidatorInfo, header data.HeaderHandler, ) error { - err := s.processLegacy(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) + validatorsInfoHandler := state.CreateShardValidatorsMap(validatorsInfoMap) + + err := s.processLegacy(validatorsInfoHandler, header.GetNonce(), header.GetEpoch()) + if err != nil { + return err + } + err = s.processWithNewFlags(validatorsInfoHandler, header) if err != nil { return err } - return s.processWithNewFlags(validatorsInfoMap, header) + for shardID := range validatorsInfoMap { + delete(validatorsInfoMap, shardID) + } + for shardID, validators := range validatorsInfoHandler.GetValInfoPointerMap() { + validatorsInfoMap[shardID] = validators + } + + return nil } func (s *systemSCProcessor) processWithNewFlags( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { if s.flagGovernanceEnabled.IsSet() { @@ -150,7 +163,7 @@ func (s *systemSCProcessor) processWithNewFlags( return nil } -func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap map[uint32][]*state.ValidatorInfo, randomness []byte) error { +func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) availableSlots := s.maxNodes - numOfValidators if availableSlots <= 0 { @@ -167,42 +180,41 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap map[uin numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) s.displayAuctionList(auctionList, numOfAvailableNodeSlots) - // TODO: Think of a better way of handling these pointers; perhaps use an interface which handles validators for i := uint32(0); i < numOfAvailableNodeSlots; i++ { - auctionList[i].List = string(common.SelectedFromAuctionList) + newNode := auctionList[i] + newNode.SetList(string(common.SelectedFromAuctionList)) + validatorsInfoMap.Replace(auctionList[i], newNode) } return nil } -func getAuctionListAndNumOfValidators(validatorsInfoMap map[uint32][]*state.ValidatorInfo) ([]*state.ValidatorInfo, uint32) { - auctionList := make([]*state.ValidatorInfo, 0) +func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, uint32) { + auctionList := make([]state.ValidatorInfoHandler, 0) numOfValidators := uint32(0) - for _, validatorsInShard := range validatorsInfoMap { - for _, validator := range validatorsInShard { - if validator.List == string(common.AuctionList) { - auctionList = append(auctionList, validator) - continue - } - if isValidator(validator) { - numOfValidators++ - } + for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { + if validator.GetList() == string(common.AuctionList) { + auctionList = append(auctionList, validator) + continue + } + if isValidator(validator) { + numOfValidators++ } } return auctionList, numOfValidators } -func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, randomness []byte) error { +func (s *systemSCProcessor) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { validatorTopUpMap, err := s.getValidatorTopUpMap(auctionList) if err != nil { return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) } sort.SliceStable(auctionList, func(i, j int) bool { - pubKey1 := auctionList[i].PublicKey - pubKey2 := auctionList[j].PublicKey + pubKey1 := auctionList[i].GetPublicKey() + pubKey2 := auctionList[j].GetPublicKey() nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] @@ -217,11 +229,11 @@ func (s *systemSCProcessor) sortAuctionList(auctionList []*state.ValidatorInfo, return nil } -func (s *systemSCProcessor) getValidatorTopUpMap(validators []*state.ValidatorInfo) (map[string]*big.Int, error) { +func (s *systemSCProcessor) getValidatorTopUpMap(validators []state.ValidatorInfoHandler) (map[string]*big.Int, error) { ret := make(map[string]*big.Int, len(validators)) for _, validator := range validators { - pubKey := validator.PublicKey + pubKey := validator.GetPublicKey() topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) if err != nil { return nil, fmt.Errorf("%w when trying to get top up per node for %s", err, hex.EncodeToString(pubKey)) @@ -247,7 +259,7 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { return bytes.Compare(key1Xor, key2Xor) == 1 } -func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInfo, numOfSelectedNodes uint32) { +func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { if log.GetLevel() > logger.LogDebug { return } @@ -283,19 +295,19 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []*state.ValidatorInf log.Debug(message) } -func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap map[uint32][]*state.ValidatorInfo) error { +func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { allNodes := s.getAllNodeKeys(validatorsInfoMap) return s.prepareStakingData(allNodes) } func (s *systemSCProcessor) getAllNodeKeys( - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, ) map[uint32][][]byte { nodeKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfo { + for shardID, validatorsInfoSlice := range validatorsInfo.GetShardValidatorsInfoMap() { nodeKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) for _, validatorInfo := range validatorsInfoSlice { - nodeKeys[shardID] = append(nodeKeys[shardID], validatorInfo.PublicKey) + nodeKeys[shardID] = append(nodeKeys[shardID], validatorInfo.GetPublicKey()) } } diff --git a/epochStart/metachain/validatorList.go b/epochStart/metachain/validatorList.go index 3d080cc1a4c..b703ddd3018 100644 --- a/epochStart/metachain/validatorList.go +++ b/epochStart/metachain/validatorList.go @@ -6,7 +6,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" ) -type validatorList []*state.ValidatorInfo +type validatorList []state.ValidatorInfoHandler // Len will return the length of the validatorList func (v validatorList) Len() int { return len(v) } @@ -17,11 +17,11 @@ func (v validatorList) Swap(i, j int) { v[i], v[j] = v[j], v[i] } // Less will return true if object on index i should appear before object in index j // Sorting of validators should be by index and public key func (v validatorList) Less(i, j int) bool { - if v[i].TempRating == v[j].TempRating { - if v[i].Index == v[j].Index { - return bytes.Compare(v[i].PublicKey, v[j].PublicKey) < 0 + if v[i].GetTempRating() == v[j].GetTempRating() { + if v[i].GetIndex() == v[j].GetIndex() { + return bytes.Compare(v[i].GetPublicKey(), v[j].GetPublicKey()) < 0 } - return v[i].Index < v[j].Index + return v[i].GetIndex() < v[j].GetIndex() } - return v[i].TempRating < v[j].TempRating + return v[i].GetTempRating() < v[j].GetTempRating() } From f3525e47d1d49c17e192fcaf94e9fbec9e7888dd Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 12:13:37 +0200 Subject: [PATCH 112/958] FIX: Race condition in tests --- state/validatorsInfoMap.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 59255d7a2c4..14fab8c1cc9 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -40,10 +40,9 @@ func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler ret := make([]ValidatorInfoHandler, 0) vi.mutex.RLock() - validatorsMapCopy := vi.valInfoMap - vi.mutex.RUnlock() + defer vi.mutex.RUnlock() - for _, validatorsInShard := range validatorsMapCopy { + for _, validatorsInShard := range vi.valInfoMap { validatorsCopy := make([]ValidatorInfoHandler, len(validatorsInShard)) copy(validatorsCopy, validatorsInShard) ret = append(ret, validatorsCopy...) @@ -54,15 +53,14 @@ func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler // GetShardValidatorsInfoMap returns a copy map of internally stored data func (vi *shardValidatorsInfoMap) GetShardValidatorsInfoMap() map[uint32][]ValidatorInfoHandler { - ret := make(map[uint32][]ValidatorInfoHandler, 0) + ret := make(map[uint32][]ValidatorInfoHandler, len(vi.valInfoMap)) vi.mutex.RLock() - validatorsMapCopy := vi.valInfoMap - vi.mutex.RUnlock() + defer vi.mutex.RUnlock() - for shardID, valInShard := range validatorsMapCopy { - validatorsCopy := make([]ValidatorInfoHandler, len(valInShard)) - copy(validatorsCopy, valInShard) + for shardID, validatorsInShard := range vi.valInfoMap { + validatorsCopy := make([]ValidatorInfoHandler, len(validatorsInShard)) + copy(validatorsCopy, validatorsInShard) ret[shardID] = validatorsCopy } From b992d8ca25c4c03651ceb2f36d45cbecd8580c37 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 14:48:17 +0200 Subject: [PATCH 113/958] FEAT: Refactor all unit tests to use interface --- epochStart/metachain/systemSCs.go | 20 +- epochStart/metachain/systemSCs_test.go | 293 +++++++++--------- .../mock/epochStartSystemSCStub.go | 6 +- process/block/metablock.go | 18 +- process/block/metablock_test.go | 8 +- process/interface.go | 2 +- process/mock/epochStartSystemSCStub.go | 6 +- state/validatorsInfoMap.go | 14 +- 8 files changed, 182 insertions(+), 185 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 621eced5215..ebc38c54af2 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -89,28 +89,14 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr // ProcessSystemSmartContract does all the processing at end of epoch in case of system smart contract func (s *systemSCProcessor) ProcessSystemSmartContract( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - validatorsInfoHandler := state.CreateShardValidatorsMap(validatorsInfoMap) - - err := s.processLegacy(validatorsInfoHandler, header.GetNonce(), header.GetEpoch()) - if err != nil { - return err - } - err = s.processWithNewFlags(validatorsInfoHandler, header) + err := s.processLegacy(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) if err != nil { return err } - - for shardID := range validatorsInfoMap { - delete(validatorsInfoMap, shardID) - } - for shardID, validators := range validatorsInfoHandler.GetValInfoPointerMap() { - validatorsInfoMap[shardID] = validators - } - - return nil + return s.processWithNewFlags(validatorsInfoMap, header) } func (s *systemSCProcessor) processWithNewFlags( diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index a6d82c0c8d0..dc7b6c4d206 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -174,7 +174,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { jailedAcc, _ := args.PeerAccountsDB.LoadAccount([]byte("jailedPubKey0")) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo := state.NewShardValidatorsInfoMap(1) vInfo := &state.ValidatorInfo{ PublicKey: []byte("jailedPubKey0"), ShardId: 0, @@ -183,13 +183,13 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { RewardAddress: []byte("address"), AccumulatedFees: big.NewInt(0), } - validatorInfos[0] = append(validatorInfos[0], vInfo) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + validatorsInfo.Add(vInfo) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - assert.Equal(t, len(validatorInfos[0]), 1) - newValidatorInfo := validatorInfos[0][0] - assert.Equal(t, newValidatorInfo.List, string(common.NewList)) + assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 1) + newValidatorInfo := validatorsInfo.GetShardValidatorsInfoMap()[0][0] + assert.Equal(t, newValidatorInfo.GetList(), string(common.NewList)) } func TestSystemSCProcessor_JailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T) { @@ -227,23 +227,23 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s addValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) - validatorsInfo[0] = append(validatorsInfo[0], jailed...) + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.SetValidatorsInShard(0, jailed) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) for i := 0; i < numWaiting; i++ { - assert.Equal(t, string(common.NewList), validatorsInfo[0][i].List) + assert.Equal(t, string(common.NewList), validatorsInfo.GetShardValidatorsInfoMap()[0][i].GetList()) } for i := numWaiting; i < numJailed; i++ { - assert.Equal(t, string(common.JailedList), validatorsInfo[0][i].List) + assert.Equal(t, string(common.JailedList), validatorsInfo.GetShardValidatorsInfoMap()[0][i].GetList()) } newJailedNodes := jailed[numWaiting:numJailed] checkNodesStatusInSystemSCDataTrie(t, newJailedNodes, args.UserAccountsDB, args.Marshalizer, saveJailedAlwaysEnableEpoch == 0) } -func checkNodesStatusInSystemSCDataTrie(t *testing.T, nodes []*state.ValidatorInfo, accounts state.AccountsAdapter, marshalizer marshal.Marshalizer, jailed bool) { +func checkNodesStatusInSystemSCDataTrie(t *testing.T, nodes []state.ValidatorInfoHandler, accounts state.AccountsAdapter, marshalizer marshal.Marshalizer, jailed bool) { account, err := accounts.LoadAccount(vm.StakingSCAddress) require.Nil(t, err) @@ -251,7 +251,7 @@ func checkNodesStatusInSystemSCDataTrie(t *testing.T, nodes []*state.ValidatorIn systemScAccount, ok := account.(state.UserAccountHandler) require.True(t, ok) for _, nodeInfo := range nodes { - buff, err = systemScAccount.DataTrieTracker().RetrieveValue(nodeInfo.PublicKey) + buff, err = systemScAccount.DataTrieTracker().RetrieveValue(nodeInfo.GetPublicKey()) require.Nil(t, err) require.True(t, len(buff) > 0) @@ -290,7 +290,7 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { _ = s.initDelegationSystemSC() doStake(t, s.systemVM, s.userAccountsDB, owner1, big.NewInt(1000), blsKeys...) doUnStake(t, s.systemVM, s.userAccountsDB, owner1, blsKeys[:3]...) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo := state.NewShardValidatorsInfoMap(1) jailed := &state.ValidatorInfo{ PublicKey: blsKeys[0], ShardId: 0, @@ -299,16 +299,16 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { RewardAddress: []byte("owner1"), AccumulatedFees: big.NewInt(0), } - validatorsInfo[0] = append(validatorsInfo[0], jailed) + validatorsInfo.Add(jailed) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - for _, vInfo := range validatorsInfo[0] { - assert.Equal(t, string(common.JailedList), vInfo.List) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + assert.Equal(t, string(common.JailedList), vInfo.GetList()) } - nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfo) + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfo.GetValInfoPointerMap()) assert.Nil(t, err) assert.Equal(t, 0, len(nodesToUnStake)) assert.Equal(t, 0, len(mapOwnersKeys)) @@ -536,8 +536,8 @@ func createEligibleNodes(numNodes int, stakingSCAcc state.UserAccountHandler, ma } } -func createJailedNodes(numNodes int, stakingSCAcc state.UserAccountHandler, userAccounts state.AccountsAdapter, peerAccounts state.AccountsAdapter, marshalizer marshal.Marshalizer) []*state.ValidatorInfo { - validatorInfos := make([]*state.ValidatorInfo, 0) +func createJailedNodes(numNodes int, stakingSCAcc state.UserAccountHandler, userAccounts state.AccountsAdapter, peerAccounts state.AccountsAdapter, marshalizer marshal.Marshalizer) []state.ValidatorInfoHandler { + validatorInfos := make([]state.ValidatorInfoHandler, 0) for i := 0; i < numNodes; i++ { stakedData := &systemSmartContracts.StakedDataV2_0{ @@ -1053,8 +1053,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin s, _ := NewSystemSCProcessor(args) _ = s.flagDelegationEnabled.SetReturningPrevious() - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + validatorsInfo := state.NewShardValidatorsInfoMap(1) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) @@ -1196,8 +1196,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueue(t * []byte("rewardAddress"), ) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + validatorsInfo := state.NewShardValidatorsInfoMap(1) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1248,8 +1248,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwne args.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: 10, }) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{Epoch: 10}) + validatorsInfo := state.NewShardValidatorsInfoMap(1) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{Epoch: 10}) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1312,38 +1312,38 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t args.Marshalizer, ) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - for _, vInfo := range validatorInfos[0] { - jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.PublicKey) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.GetPublicKey()) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) peerAcc, err := s.getPeerAccount([]byte("waitingPubKey")) @@ -1354,10 +1354,10 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t peerAcc, _ = s.getPeerAccount([]byte("stakedPubKey1")) assert.Equal(t, peerAcc.GetList(), string(common.LeavingList)) - assert.Equal(t, string(common.LeavingList), validatorInfos[0][1].List) + assert.Equal(t, string(common.LeavingList), validatorsInfo.GetShardValidatorsInfoMap()[0][1].GetList()) - assert.Equal(t, 5, len(validatorInfos[0])) - assert.Equal(t, string(common.NewList), validatorInfos[0][4].List) + assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 5) + assert.Equal(t, string(common.NewList), validatorsInfo.GetShardValidatorsInfoMap()[0][4].GetList()) } func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWork(t *testing.T) { @@ -1380,14 +1380,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor addValidatorDataWithUnStakedKey(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, big.NewInt(1000), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), @@ -1396,7 +1396,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) } @@ -1457,47 +1457,47 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.WaitingList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.WaitingList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - for _, vInfo := range validatorInfos[0] { - jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.PublicKey) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.GetPublicKey()) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - for _, vInfo := range validatorInfos[0] { - assert.NotEqual(t, string(common.NewList), vInfo.List) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + assert.NotEqual(t, string(common.NewList), vInfo.GetList()) } peerAcc, _ := s.getPeerAccount([]byte("stakedPubKey2")) assert.Equal(t, peerAcc.GetList(), string(common.LeavingList)) - assert.Equal(t, 4, len(validatorInfos[0])) + assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 4) delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) @@ -1546,42 +1546,42 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional addDelegationData(args.UserAccountsDB, delegationAddr, allStakedKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - for _, vInfo := range validatorInfos[0] { - jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.PublicKey) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.GetPublicKey()) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - for _, vInfo := range validatorInfos[0] { - assert.Equal(t, string(common.EligibleList), vInfo.List) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + assert.Equal(t, string(common.EligibleList), vInfo.GetList()) } delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr) @@ -1644,37 +1644,37 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( addDelegationData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - for _, vInfo := range validatorInfos[0] { - peerAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.PublicKey) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + peerAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.GetPublicKey()) _ = args.PeerAccountsDB.SaveAccount(peerAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr2) @@ -1716,42 +1716,42 @@ func TestSystemSCProcessor_ProcessSystemSmartContractWrongValidatorInfoShouldBeC []byte("oneAddress1"), ) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("oneAddress1"), List: string(common.EligibleList), RewardAddress: []byte("oneAddress1"), AccumulatedFees: big.NewInt(0), }) - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - assert.Equal(t, len(validatorInfos[0]), 1) + assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 1) } func TestSystemSCProcessor_TogglePauseUnPause(t *testing.T) { @@ -1814,48 +1814,48 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T addValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - validatorInfos[0] = append(validatorInfos[0], &state.ValidatorInfo{ + validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - for _, vInfo := range validatorInfos[0] { - jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.PublicKey) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + jailedAcc, _ := args.PeerAccountsDB.LoadAccount(vInfo.GetPublicKey()) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) } s.flagSetOwnerEnabled.Reset() - err := s.ProcessSystemSmartContract(validatorInfos, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) _, err = s.peerAccountsDB.GetExistingAccount([]byte("waitingPubKey")) assert.NotNil(t, err) - assert.Equal(t, 4, len(validatorInfos[0])) - for _, vInfo := range validatorInfos[0] { - assert.Equal(t, vInfo.List, string(common.LeavingList)) - peerAcc, _ := s.getPeerAccount(vInfo.PublicKey) + assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 4) + for _, vInfo := range validatorsInfo.GetShardValidatorsInfoMap()[0] { + assert.Equal(t, vInfo.GetList(), string(common.LeavingList)) + peerAcc, _ := s.getPeerAccount(vInfo.GetPublicKey()) assert.Equal(t, peerAcc.GetList(), string(common.LeavingList)) } } @@ -1904,32 +1904,29 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) addKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1)) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2)) + validatorsInfo := state.NewShardValidatorsInfoMap(2) + validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) + validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) + validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) - expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ - 0: { - createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1), - createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1), - createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1), - createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1), - createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1), + expectedValidatorsInfo := state.NewShardValidatorsInfoMap(2) + expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1, 0)) - createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2), + expectedValidatorsInfo.Add(createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2, 0)) + + expectedValidatorsInfo.Add(createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3, 0)) + + expectedValidatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) - createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3), - createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3), - }, - 1: { - createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2), - }, - } require.Equal(t, expectedValidatorsInfo, validatorsInfo) } @@ -1949,9 +1946,9 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) + validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) @@ -1983,9 +1980,9 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner)) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner)) + validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) + validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) @@ -2011,22 +2008,19 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1)) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2)) + validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) - expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ - 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1), - createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2), - }, - } + expectedValidatorsInfo := state.NewShardValidatorsInfoMap(1) + expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) require.Equal(t, expectedValidatorsInfo, validatorsInfo) } @@ -2051,20 +2045,20 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1)) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1)) - validatorsInfo[0] = append(validatorsInfo[0], createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1)) + validatorsInfo := state.NewShardValidatorsInfoMap(2) + validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) + validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1, 0)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2)) + validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1)) + validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2, 1)) + validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3)) + validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1)) + validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4)) - validatorsInfo[1] = append(validatorsInfo[1], createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4)) + validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) + validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) @@ -2102,24 +2096,20 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(0)) requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(500)) - expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ - 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1), - createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1), - createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, owner1), - }, - 1: { - createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2), - createValidatorInfo(owner2StakedKeys[1], common.SelectedFromAuctionList, owner2), - createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2), + expectedValidatorsInfo := state.NewShardValidatorsInfoMap(2) + expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) + expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, owner1, 0)) - createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3), - createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3), + expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1)) + expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.SelectedFromAuctionList, owner2, 1)) + expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1)) - createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4), - createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4), - }, - } + expectedValidatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1)) + expectedValidatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1)) + + expectedValidatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) + expectedValidatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4, 1)) require.Equal(t, expectedValidatorsInfo, validatorsInfo) } @@ -2194,7 +2184,7 @@ func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, staked } // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing -func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *state.ValidatorInfo { +func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte, shardID uint32) *state.ValidatorInfo { rating := uint32(0) if list == common.NewList || list == common.AuctionList || list == common.SelectedFromAuctionList { rating = uint32(5) @@ -2203,6 +2193,7 @@ func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte) *sta return &state.ValidatorInfo{ PublicKey: pubKey, List: string(list), + ShardId: shardID, RewardAddress: owner, AccumulatedFees: zero, Rating: rating, diff --git a/integrationTests/mock/epochStartSystemSCStub.go b/integrationTests/mock/epochStartSystemSCStub.go index 9ec174c0b46..27c500495dd 100644 --- a/integrationTests/mock/epochStartSystemSCStub.go +++ b/integrationTests/mock/epochStartSystemSCStub.go @@ -9,7 +9,7 @@ import ( // EpochStartSystemSCStub - type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error + ProcessSystemSmartContractCalled func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error ToggleUnStakeUnBondCalled func(value bool) error } @@ -24,11 +24,11 @@ func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { // ProcessSystemSmartContract - func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorInfos, header) + return e.ProcessSystemSmartContractCalled(validatorsInfo, header) } return nil } diff --git a/process/block/metablock.go b/process/block/metablock.go index 02c8ef98dcd..739d3597d40 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -418,12 +418,14 @@ func (mp *metaProcessor) processEpochStartMetaBlock( } if mp.isRewardsV2Enabled(header) { - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header) + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) if err != nil { return err } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) - err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, allValidatorsInfo, computedEconomics) + err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, validatorsInfoMap.GetValInfoPointerMap(), computedEconomics) if err != nil { return err } @@ -433,10 +435,12 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header) + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) if err != nil { return err } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) } err = mp.epochSystemSCProcessor.ProcessDelegationRewards(body.MiniBlocks, mp.epochRewardsCreator.GetLocalTxCache()) @@ -886,10 +890,12 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. var rewardMiniBlocks block.MiniBlockSlice if mp.isRewardsV2Enabled(metaBlock) { - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock) + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, metaBlock) if err != nil { return nil, err } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, allValidatorsInfo, &metaBlock.EpochStart.Economics) if err != nil { @@ -901,10 +907,12 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock) + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, metaBlock) if err != nil { return nil, err } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) } metaBlock.EpochStart.Economics.RewardsForProtocolSustainability.Set(mp.epochRewardsCreator.GetProtocolSustainabilityRewards()) diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 4ce5c57d706..5a828bf8cf9 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3091,7 +3091,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { } arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + ProcessSystemSmartContractCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { assert.Equal(t, headerMeta, header) wasCalled = true return nil @@ -3122,7 +3122,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { } arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + ProcessSystemSmartContractCalled: func(validatorInfos state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { assert.Equal(t, headerMeta, header) assert.True(t, wasCalled) return nil @@ -3332,7 +3332,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { wasCalled := false arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + ProcessSystemSmartContractCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { wasCalled = true assert.Equal(t, mb, header) return nil @@ -3424,7 +3424,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ - ProcessSystemSmartContractCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + ProcessSystemSmartContractCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { assert.True(t, wasCalled) assert.Equal(t, mb, header) return nil diff --git a/process/interface.go b/process/interface.go index e3c929b7112..4fa07244b43 100644 --- a/process/interface.go +++ b/process/interface.go @@ -906,7 +906,7 @@ type EpochStartValidatorInfoCreator interface { // EpochStartSystemSCProcessor defines the functionality for the metachain to process system smart contract and end of epoch type EpochStartSystemSCProcessor interface { ProcessSystemSmartContract( - validatorsInfoMap map[uint32][]*state.ValidatorInfo, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error ProcessDelegationRewards( diff --git a/process/mock/epochStartSystemSCStub.go b/process/mock/epochStartSystemSCStub.go index 9ec174c0b46..27c500495dd 100644 --- a/process/mock/epochStartSystemSCStub.go +++ b/process/mock/epochStartSystemSCStub.go @@ -9,7 +9,7 @@ import ( // EpochStartSystemSCStub - type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error + ProcessSystemSmartContractCalled func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error ToggleUnStakeUnBondCalled func(value bool) error } @@ -24,11 +24,11 @@ func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { // ProcessSystemSmartContract - func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorInfos, header) + return e.ProcessSystemSmartContractCalled(validatorsInfo, header) } return nil } diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 14fab8c1cc9..e3ac9137aba 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -19,7 +19,7 @@ func NewShardValidatorsInfoMap(numOfShards uint32) *shardValidatorsInfoMap { } } -// TODO: Delete this once map[uint32][]*ValidatorInfo is completely replaced with new interface +// 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. @@ -35,6 +35,18 @@ func CreateShardValidatorsMap(input map[uint32][]*ValidatorInfo) *shardValidator return ret } +// Replace will replace src with dst map +func Replace(src, dest map[uint32][]*ValidatorInfo) { + for shardID := range src { + delete(src, shardID) + } + + for shardID, validatorsInShard := range src { + dest[shardID] = validatorsInShard + } + +} + // GetAllValidatorsInfo returns a ValidatorInfoHandler copy slice with validators from all shards. func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler { ret := make([]ValidatorInfoHandler, 0) From 6462ea175fb7772a771662440c7ede7d7191f83f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 15:21:57 +0200 Subject: [PATCH 114/958] FIX: Replace + add processSystemSCsWithNewValidatorsInfo func --- process/block/metablock.go | 29 ++++++++++++++++------------- state/validatorsInfoMap.go | 10 +++++----- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/process/block/metablock.go b/process/block/metablock.go index 739d3597d40..836e0797f71 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -418,14 +418,12 @@ func (mp *metaProcessor) processEpochStartMetaBlock( } if mp.isRewardsV2Enabled(header) { - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) + err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, header) if err != nil { return err } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) - err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, validatorsInfoMap.GetValInfoPointerMap(), computedEconomics) + err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, allValidatorsInfo, computedEconomics) if err != nil { return err } @@ -435,12 +433,10 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) + err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, header) if err != nil { return err } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) } err = mp.epochSystemSCProcessor.ProcessDelegationRewards(body.MiniBlocks, mp.epochRewardsCreator.GetLocalTxCache()) @@ -890,12 +886,10 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. var rewardMiniBlocks block.MiniBlockSlice if mp.isRewardsV2Enabled(metaBlock) { - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, metaBlock) + err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, metaBlock) if err != nil { return nil, err } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, allValidatorsInfo, &metaBlock.EpochStart.Economics) if err != nil { @@ -907,12 +901,10 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, metaBlock) + err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, metaBlock) if err != nil { return nil, err } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) } metaBlock.EpochStart.Economics.RewardsForProtocolSustainability.Set(mp.epochRewardsCreator.GetProtocolSustainabilityRewards()) @@ -2507,3 +2499,14 @@ func (mp *metaProcessor) DecodeBlockHeader(dta []byte) data.HeaderHandler { return metaBlock } + +// TODO: StakingV4 delete this once map[uint32][]*ValidatorInfo is replaced with interface +func (mp *metaProcessor) processSystemSCsWithNewValidatorsInfo(allValidatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + err := mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) + if err != nil { + return err + } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) + return nil +} diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index e3ac9137aba..653682b7198 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -36,13 +36,13 @@ func CreateShardValidatorsMap(input map[uint32][]*ValidatorInfo) *shardValidator } // Replace will replace src with dst map -func Replace(src, dest map[uint32][]*ValidatorInfo) { - for shardID := range src { - delete(src, shardID) +func Replace(oldMap, newMap map[uint32][]*ValidatorInfo) { + for shardID := range oldMap { + delete(oldMap, shardID) } - for shardID, validatorsInShard := range src { - dest[shardID] = validatorsInShard + for shardID, validatorsInShard := range newMap { + oldMap[shardID] = validatorsInShard } } From e9c113d01f2926b48fb7eeaa0c49f7c7d3ca82d0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 15:46:56 +0200 Subject: [PATCH 115/958] FIX: Merge conflicts --- epochStart/metachain/legacySystemSCs.go | 7 ++++++- epochStart/metachain/systemSCs.go | 3 ++- epochStart/metachain/systemSCs_test.go | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index d1fe6e03849..6da6c01d11c 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -20,6 +20,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" @@ -31,7 +32,7 @@ type legacySystemSCProcessor struct { userAccountsDB state.AccountsAdapter marshalizer marshal.Marshalizer peerAccountsDB state.AccountsAdapter - chanceComputer sharding.ChanceComputer + chanceComputer nodesCoordinator.ChanceComputer shardCoordinator sharding.Coordinator startRating uint32 validatorInfoCreator epochStart.ValidatorInfoCreator @@ -1196,6 +1197,10 @@ func (s *legacySystemSCProcessor) cleanAdditionalQueue() error { continue } + if len(currentOwner) != addressLength { + continue + } + mapOwnersKeys[currentOwner] = append(mapOwnersKeys[currentOwner], returnData) } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index aba15dc0f0d..b88d340983c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -20,6 +20,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -33,7 +34,7 @@ type ArgsNewEpochStartSystemSCProcessing struct { Marshalizer marshal.Marshalizer StartRating uint32 ValidatorInfoCreator epochStart.ValidatorInfoCreator - ChanceComputer sharding.ChanceComputer + ChanceComputer nodesCoordinator.ChanceComputer ShardCoordinator sharding.Coordinator EpochConfig config.EpochConfig diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index b55ee4c1c98..c2192ef6cf4 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -949,7 +949,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, - NodesCoordinator: &mock.NodesCoordinatorStub{}, + NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) From 779733d60542b41940287bec626fe89352919d14 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 16:06:41 +0200 Subject: [PATCH 116/958] FIX: Finding --- vm/systemSmartContracts/staking_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 87927073bf1..6e5de5dac74 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -3350,7 +3350,6 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) arguments := CreateVmContractCallInput() - arguments.Arguments = [][]byte{} arguments.Function = "getQueueIndex" retCode := stakingSmartContract.Execute(arguments) require.Equal(t, vmcommon.UserError, retCode) From df421cf9b60699bfc70fe5a12e6d9ba906bd6383 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 16:13:43 +0200 Subject: [PATCH 117/958] FIX: Another merge conflict --- integrationTests/vm/testInitializer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 0eb61f4dea0..69024da7244 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -673,7 +673,7 @@ func CreateVMAndBlockchainHookMeta( EpochNotifier: &epochNotifier.EpochNotifierStub{}, EpochConfig: createEpochConfig(enableEpochs), ShardCoordinator: mock.NewMultiShardsCoordinatorMock(1), - NodesCoordinator: &mock.NodesCoordinatorMock{}, + NodesCoordinator: &shardingMocks.NodesCoordinatorMock{}, } vmFactory, err := metachain.NewVMContainerFactory(argVMContainer) if err != nil { From 7ad2ba9b954424be28a9943fa32ce27b6d359842 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 16 Mar 2022 16:36:39 +0200 Subject: [PATCH 118/958] FIX: Another merge conflict --- process/factory/metachain/vmContainerFactory_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 1886d5e1960..039fe5bd750 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -17,6 +17,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/vm" "github.com/stretchr/testify/assert" @@ -72,7 +73,7 @@ func createVmContainerMockArgument(gasSchedule core.GasScheduleNotifier) ArgsNew }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, - NodesCoordinator: &mock.NodesCoordinatorMock{GetNumTotalEligibleCalled: func() uint64 { + NodesCoordinator: &shardingMocks.NodesCoordinatorMock{GetNumTotalEligibleCalled: func() uint64 { return 1000 }}, } @@ -355,7 +356,7 @@ func TestVmContainerFactory_Create(t *testing.T) { }, }, ShardCoordinator: mock.NewMultiShardsCoordinatorMock(1), - NodesCoordinator: &mock.NodesCoordinatorMock{GetNumTotalEligibleCalled: func() uint64 { + NodesCoordinator: &shardingMocks.NodesCoordinatorMock{GetNumTotalEligibleCalled: func() uint64 { return 1000 }}, } From 8dbcf970170e5b73f2dd54d5fc19d35996230e1d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 17 Mar 2022 12:45:18 +0200 Subject: [PATCH 119/958] FIX: Merge conflicts --- sharding/interface.go | 20 --- sharding/nodesCoordinator/dtos.go | 2 + .../indexHashedNodesCoordinator.go | 6 +- .../indexHashedNodesCoordinatorRegistry.go | 3 +- ...shedNodesCoordinatorRegistryWithAuction.go | 18 ++- .../indexHashedNodesCoordinator_test.go | 4 +- sharding/nodesCoordinator/interface.go | 20 +++ .../nodesCoordinatorRegistry.go | 2 +- .../nodesCoordinatorRegistryWithAuction.go | 2 +- .../nodesCoordinatorRegistryWithAuction.pb.go | 146 +++++++++--------- .../nodesCoordinatorRegistryWithAuction.proto | 2 +- 11 files changed, 114 insertions(+), 111 deletions(-) rename sharding/{ => nodesCoordinator}/indexHashedNodesCoordinatorRegistryWithAuction.go (83%) rename sharding/{ => nodesCoordinator}/nodesCoordinatorRegistry.go (98%) rename sharding/{ => nodesCoordinator}/nodesCoordinatorRegistryWithAuction.go (98%) rename sharding/{ => nodesCoordinator}/nodesCoordinatorRegistryWithAuction.pb.go (93%) rename sharding/{ => nodesCoordinator}/nodesCoordinatorRegistryWithAuction.proto (95%) diff --git a/sharding/interface.go b/sharding/interface.go index 3a9e9cd3e4e..4452d6ecaa5 100644 --- a/sharding/interface.go +++ b/sharding/interface.go @@ -61,23 +61,3 @@ type GenesisNodesSetupHandler interface { MinNumberOfNodesWithHysteresis() uint32 IsInterfaceNil() bool } - -// EpochValidatorsHandler defines what one epoch configuration for a nodes coordinator should hold -type EpochValidatorsHandler interface { - GetEligibleValidators() map[string][]*SerializableValidator - GetWaitingValidators() map[string][]*SerializableValidator - GetLeavingValidators() map[string][]*SerializableValidator -} - -// EpochValidatorsHandlerWithAuction defines what one epoch configuration for a nodes coordinator should hold + shuffled out validators -type EpochValidatorsHandlerWithAuction interface { - EpochValidatorsHandler - GetShuffledOutValidators() map[string][]*SerializableValidator -} - -// NodesCoordinatorRegistryHandler defines what is used to initialize nodes coordinator -type NodesCoordinatorRegistryHandler interface { - GetEpochsConfig() map[string]EpochValidatorsHandler - GetCurrentEpoch() uint32 - SetCurrentEpoch(epoch uint32) -} \ No newline at end of file diff --git a/sharding/nodesCoordinator/dtos.go b/sharding/nodesCoordinator/dtos.go index 854dd931d8d..ab54bdeb4fa 100644 --- a/sharding/nodesCoordinator/dtos.go +++ b/sharding/nodesCoordinator/dtos.go @@ -7,6 +7,7 @@ type ArgsUpdateNodes struct { NewNodes []Validator UnStakeLeaving []Validator AdditionalLeaving []Validator + Auction []Validator Rand []byte NbShards uint32 Epoch uint32 @@ -16,6 +17,7 @@ type ArgsUpdateNodes struct { type ResUpdateNodes struct { Eligible map[uint32][]Validator Waiting map[uint32][]Validator + ShuffledOut map[uint32][]Validator Leaving []Validator StillRemaining []Validator } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index ce477724725..12a7ceed950 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -752,7 +752,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.JailedList): log.Debug("jailed validator", "pk", validatorInfo.PublicKey) case string(common.SelectedFromAuctionList): - if ihgs.flagStakingV4.IsSet() { + if ihnc.flagStakingV4.IsSet() { auctionList = append(auctionList, currentValidator) } } @@ -1032,11 +1032,11 @@ func (ihnc *indexHashedNodesCoordinator) computeShardForSelfPublicKey(nodesConfi return shardId, true } - if ihgs.flagStakingV4.IsSet() { + if ihnc.flagStakingV4.IsSet() { found, shardId = searchInMap(nodesConfig.shuffledOutMap, pubKey) if found { log.Trace("computeShardForSelfPublicKey found validator in shuffled out", - "epoch", ihgs.currentEpoch, + "epoch", ihnc.currentEpoch, "shard", shardId, "validator PK", pubKey, ) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go index f5f278ea1aa..0714bff74ea 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go @@ -26,7 +26,7 @@ func (ihnc *indexHashedNodesCoordinator) baseLoadState(key []byte) error { return err } - config, err := CreateNodesCoordinatorRegistry(ihgs.marshalizer, data) + config, err := CreateNodesCoordinatorRegistry(ihnc.marshalizer, data) if err != nil { return err } @@ -76,7 +76,6 @@ func (ihnc *indexHashedNodesCoordinator) getRegistryData() ([]byte, error) { var err error var data []byte - return ihnc.bootStorer.Put(ncInternalkey, data) registry := ihnc.NodesCoordinatorToRegistry() if ihnc.flagStakingV4.IsSet() { data, err = ihnc.marshalizer.Marshal(registry) diff --git a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistryWithAuction.go similarity index 83% rename from sharding/indexHashedNodesCoordinatorRegistryWithAuction.go rename to sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistryWithAuction.go index 4d57cac2512..261aa60aefc 100644 --- a/sharding/indexHashedNodesCoordinatorRegistryWithAuction.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistryWithAuction.go @@ -1,20 +1,22 @@ -package sharding +package nodesCoordinator -import "fmt" +import ( + "fmt" +) // nodesCoordinatorToRegistryWithAuction will export the nodesCoordinator data to the registry which contains auction list -func (ihgs *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() *NodesCoordinatorRegistryWithAuction { - ihgs.mutNodesConfig.RLock() - defer ihgs.mutNodesConfig.RUnlock() +func (ihnc *indexHashedNodesCoordinator) nodesCoordinatorToRegistryWithAuction() *NodesCoordinatorRegistryWithAuction { + ihnc.mutNodesConfig.RLock() + defer ihnc.mutNodesConfig.RUnlock() registry := &NodesCoordinatorRegistryWithAuction{ - CurrentEpoch: ihgs.currentEpoch, + CurrentEpoch: ihnc.currentEpoch, EpochsConfigWithAuction: make(map[string]*EpochValidatorsWithAuction), } - minEpoch, lastEpoch := ihgs.getMinAndLastEpoch() + minEpoch, lastEpoch := ihnc.getMinAndLastEpoch() for epoch := minEpoch; epoch <= lastEpoch; epoch++ { - epochNodesData, ok := ihgs.nodesConfig[epoch] + epochNodesData, ok := ihnc.nodesConfig[epoch] if !ok { continue } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 4d9992940cc..d6c10a20110 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -1321,7 +1321,7 @@ func TestIndexHashedNodesCoordinator_computeShardForSelfPublicKeyWithStakingV4(t epoch: { shardID: metaShard, shuffledOutMap: map[uint32][]Validator{ - metaShard: {mock.NewValidatorMock(pk, 1, 1)}, + metaShard: {newValidatorMock(pk, 1, 1)}, }, }, } @@ -2076,7 +2076,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * previousConfig := &epochNodesConfig{ eligibleMap: map[uint32][]Validator{ 0: { - mock.NewValidatorMock(shard0Eligible.PublicKey, 0, 0), + newValidatorMock(shard0Eligible.PublicKey, 0, 0), }, }, } diff --git a/sharding/nodesCoordinator/interface.go b/sharding/nodesCoordinator/interface.go index b53506fc473..acd343d5664 100644 --- a/sharding/nodesCoordinator/interface.go +++ b/sharding/nodesCoordinator/interface.go @@ -130,3 +130,23 @@ type EpochsConfigUpdateHandler interface { SetNodesConfigFromValidatorsInfo(epoch uint32, randomness []byte, validatorsInfo []*state.ShardValidatorInfo) error IsEpochInConfig(epoch uint32) bool } + +// EpochValidatorsHandler defines what one epoch configuration for a nodes coordinator should hold +type EpochValidatorsHandler interface { + GetEligibleValidators() map[string][]*SerializableValidator + GetWaitingValidators() map[string][]*SerializableValidator + GetLeavingValidators() map[string][]*SerializableValidator +} + +// EpochValidatorsHandlerWithAuction defines what one epoch configuration for a nodes coordinator should hold + shuffled out validators +type EpochValidatorsHandlerWithAuction interface { + EpochValidatorsHandler + GetShuffledOutValidators() map[string][]*SerializableValidator +} + +// NodesCoordinatorRegistryHandler defines what is used to initialize nodes coordinator +type NodesCoordinatorRegistryHandler interface { + GetEpochsConfig() map[string]EpochValidatorsHandler + GetCurrentEpoch() uint32 + SetCurrentEpoch(epoch uint32) +} diff --git a/sharding/nodesCoordinatorRegistry.go b/sharding/nodesCoordinator/nodesCoordinatorRegistry.go similarity index 98% rename from sharding/nodesCoordinatorRegistry.go rename to sharding/nodesCoordinator/nodesCoordinatorRegistry.go index 544ce84bab6..fbf84919d7a 100644 --- a/sharding/nodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistry.go @@ -1,4 +1,4 @@ -package sharding +package nodesCoordinator // EpochValidators holds one epoch configuration for a nodes coordinator type EpochValidators struct { diff --git a/sharding/nodesCoordinatorRegistryWithAuction.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go similarity index 98% rename from sharding/nodesCoordinatorRegistryWithAuction.go rename to sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go index 8edaf4103b0..21a41afd033 100644 --- a/sharding/nodesCoordinatorRegistryWithAuction.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go @@ -1,5 +1,5 @@ //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/ElrondNetwork/protobuf/protobuf --gogoslick_out=. nodesCoordinatorRegistryWithAuction.proto -package sharding +package nodesCoordinator func protoValidatorsMapToSliceMap(validators map[string]Validators) map[string][]*SerializableValidator { ret := make(map[string][]*SerializableValidator) diff --git a/sharding/nodesCoordinatorRegistryWithAuction.pb.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.pb.go similarity index 93% rename from sharding/nodesCoordinatorRegistryWithAuction.pb.go rename to sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.pb.go index 93c72827258..3c69dc78080 100644 --- a/sharding/nodesCoordinatorRegistryWithAuction.pb.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: nodesCoordinatorRegistryWithAuction.proto -package sharding +package nodesCoordinator import ( bytes "bytes" @@ -185,8 +185,8 @@ func (m *EpochValidatorsWithAuction) GetShuffledOut() map[string]Validators { } type NodesCoordinatorRegistryWithAuction struct { - CurrentEpoch uint32 `protobuf:"varint,2,opt,name=CurrentEpoch,proto3" json:"CurrentEpoch,omitempty"` - EpochsConfigWithAuction map[string]*EpochValidatorsWithAuction `protobuf:"bytes,1,rep,name=EpochsConfigWithAuction,proto3" json:"EpochsConfigWithAuction,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + CurrentEpoch uint32 `protobuf:"varint,1,opt,name=CurrentEpoch,proto3" json:"CurrentEpoch,omitempty"` + EpochsConfigWithAuction map[string]*EpochValidatorsWithAuction `protobuf:"bytes,2,rep,name=EpochsConfigWithAuction,proto3" json:"EpochsConfigWithAuction,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (m *NodesCoordinatorRegistryWithAuction) Reset() { *m = NodesCoordinatorRegistryWithAuction{} } @@ -248,43 +248,43 @@ func init() { } var fileDescriptor_f04461c784f438d5 = []byte{ - // 564 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xcd, 0x6e, 0xd3, 0x4e, - 0x14, 0xc5, 0x3d, 0xf9, 0x6c, 0x6f, 0x52, 0xa9, 0xff, 0x91, 0xfe, 0xc2, 0x8a, 0xaa, 0x49, 0x30, - 0x42, 0x84, 0x05, 0x0e, 0x0a, 0x0b, 0x10, 0x0b, 0x24, 0x12, 0x22, 0x84, 0x80, 0x40, 0x5d, 0x89, - 0x4a, 0xdd, 0xd9, 0xc9, 0xc4, 0x1e, 0xe1, 0x7a, 0x22, 0x7f, 0x54, 0x84, 0x15, 0x88, 0x17, 0xe0, - 0x31, 0x58, 0xf0, 0x08, 0x3c, 0x40, 0x97, 0x59, 0x66, 0x15, 0x11, 0x67, 0x83, 0xb2, 0xea, 0x23, - 0x20, 0x8f, 0x9d, 0xd6, 0x41, 0x0d, 0xa9, 0x54, 0x56, 0x9e, 0xb9, 0x33, 0xe7, 0x77, 0x66, 0x8e, - 0xef, 0xc0, 0x5d, 0x87, 0xf7, 0xa9, 0xd7, 0xe6, 0xdc, 0xed, 0x33, 0x47, 0xf7, 0xb9, 0xab, 0x51, - 0x93, 0x79, 0xbe, 0x3b, 0x3a, 0x64, 0xbe, 0xf5, 0x34, 0xe8, 0xf9, 0x8c, 0x3b, 0xea, 0xd0, 0xe5, - 0x3e, 0xc7, 0x79, 0xf1, 0xa9, 0xdc, 0x33, 0x99, 0x6f, 0x05, 0x86, 0xda, 0xe3, 0xc7, 0x0d, 0x93, - 0x9b, 0xbc, 0x21, 0xca, 0x46, 0x30, 0x10, 0x33, 0x31, 0x11, 0xa3, 0x58, 0xa5, 0x7c, 0x41, 0xf0, - 0xff, 0x01, 0x75, 0x99, 0x6e, 0xb3, 0x8f, 0xba, 0x61, 0xd3, 0x77, 0xba, 0xcd, 0xfa, 0x91, 0x11, - 0x56, 0xa0, 0xf0, 0x36, 0x30, 0x5e, 0xd2, 0x91, 0x8c, 0x6a, 0xa8, 0x5e, 0x6e, 0xc1, 0x62, 0x5a, - 0x2d, 0x0c, 0x45, 0x45, 0x4b, 0x56, 0xf0, 0x6d, 0x28, 0xb6, 0x2d, 0xdd, 0xe9, 0x51, 0x4f, 0xce, - 0xd4, 0x50, 0x7d, 0xa7, 0x55, 0x5a, 0x4c, 0xab, 0xc5, 0x5e, 0x5c, 0xd2, 0x96, 0x6b, 0xb8, 0x0a, - 0xf9, 0x17, 0x4e, 0x9f, 0x7e, 0x90, 0xb3, 0x62, 0xd3, 0xf6, 0x62, 0x5a, 0xcd, 0xb3, 0xa8, 0xa0, - 0xc5, 0x75, 0xe5, 0x09, 0xc0, 0xb9, 0xb1, 0x87, 0xef, 0x43, 0xee, 0x99, 0xee, 0xeb, 0x32, 0xaa, - 0x65, 0xeb, 0xa5, 0xe6, 0x5e, 0x7c, 0x52, 0xf5, 0xd2, 0x53, 0x6a, 0x62, 0xa7, 0xf2, 0x3d, 0x0f, - 0x95, 0xce, 0x90, 0xf7, 0xac, 0x0b, 0x4a, 0x2a, 0x20, 0xbc, 0x0f, 0x5b, 0x1d, 0x9b, 0x99, 0xcc, - 0xb0, 0x69, 0x02, 0x6d, 0x24, 0xd0, 0xf5, 0x22, 0x75, 0xa9, 0xe8, 0x38, 0xbe, 0x3b, 0x6a, 0xe5, - 0x4e, 0xa7, 0x55, 0x49, 0x3b, 0xc7, 0xe0, 0x2e, 0x14, 0x0f, 0x75, 0xe6, 0x33, 0xc7, 0x94, 0x33, - 0x82, 0xa8, 0x6e, 0x26, 0x26, 0x82, 0x34, 0x70, 0x09, 0x89, 0x78, 0xaf, 0xa8, 0x7e, 0x12, 0xf1, - 0xb2, 0x57, 0xe5, 0x25, 0x82, 0x15, 0x5e, 0x52, 0xc3, 0x47, 0x50, 0x3a, 0xb0, 0x82, 0xc1, 0xc0, - 0xa6, 0xfd, 0x37, 0x81, 0x2f, 0xe7, 0x04, 0xb3, 0xb9, 0x99, 0x99, 0x12, 0xa5, 0xb9, 0x69, 0x58, - 0xa5, 0x0b, 0x3b, 0x2b, 0xe1, 0xe0, 0x5d, 0xc8, 0xbe, 0x4f, 0xfa, 0x64, 0x5b, 0x8b, 0x86, 0xf8, - 0x0e, 0xe4, 0x4f, 0x74, 0x3b, 0xa0, 0xa2, 0x2d, 0x4a, 0xcd, 0xff, 0x12, 0xe3, 0x0b, 0x4f, 0x2d, - 0x5e, 0x7f, 0x9c, 0x79, 0x84, 0x2a, 0xaf, 0xa1, 0x9c, 0x8e, 0xe6, 0x1f, 0xe0, 0xd2, 0xc9, 0x5c, - 0x17, 0xb7, 0x0f, 0xbb, 0x7f, 0x86, 0x72, 0x4d, 0xa4, 0xf2, 0x23, 0x03, 0xb7, 0xba, 0x9b, 0x1f, - 0x36, 0x56, 0xa0, 0xdc, 0x0e, 0x5c, 0x97, 0x3a, 0xbe, 0xf8, 0x63, 0xf1, 0x1b, 0xd3, 0x56, 0x6a, - 0xf8, 0x33, 0x82, 0x1b, 0x62, 0xe4, 0xb5, 0xb9, 0x33, 0x60, 0x66, 0x4a, 0x9f, 0xf4, 0xfa, 0xf3, - 0xe4, 0x2c, 0x57, 0x70, 0x54, 0xd7, 0x90, 0xc4, 0xad, 0xb5, 0x75, 0x3e, 0x95, 0x63, 0xd8, 0xfb, - 0x9b, 0xf0, 0x92, 0xb8, 0x1e, 0xae, 0xc6, 0x75, 0x73, 0x63, 0x63, 0xa6, 0xe2, 0x6b, 0xb5, 0xc6, - 0x33, 0x22, 0x4d, 0x66, 0x44, 0x3a, 0x9b, 0x11, 0xf4, 0x29, 0x24, 0xe8, 0x5b, 0x48, 0xd0, 0x69, - 0x48, 0xd0, 0x38, 0x24, 0x68, 0x12, 0x12, 0xf4, 0x33, 0x24, 0xe8, 0x57, 0x48, 0xa4, 0xb3, 0x90, - 0xa0, 0xaf, 0x73, 0x22, 0x8d, 0xe7, 0x44, 0x9a, 0xcc, 0x89, 0x74, 0xb4, 0xe5, 0x59, 0x7a, 0x74, - 0x7d, 0xd3, 0x28, 0x08, 0xc3, 0x07, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x76, 0x24, 0xed, 0x37, - 0x61, 0x05, 0x00, 0x00, + // 561 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x4f, 0x8f, 0xd2, 0x40, + 0x18, 0xc6, 0x3b, 0xb0, 0x80, 0xfb, 0x02, 0x09, 0x4e, 0x62, 0x6c, 0xc8, 0x66, 0xc0, 0x1a, 0x23, + 0x1e, 0x2c, 0x06, 0x0f, 0x1a, 0x0f, 0x26, 0x82, 0xc4, 0xf8, 0x0f, 0xdd, 0x6e, 0xe2, 0x26, 0x7b, + 0x6b, 0x61, 0x28, 0x13, 0xbb, 0x1d, 0x52, 0xa6, 0x1b, 0xf1, 0xa4, 0xf1, 0x0b, 0xf8, 0x31, 0x3c, + 0xf8, 0x11, 0xfc, 0x00, 0x7b, 0xe4, 0xc8, 0x89, 0x48, 0xb9, 0x18, 0x4e, 0xfb, 0x11, 0x0c, 0xd3, + 0xb2, 0x5b, 0x36, 0x8b, 0x6c, 0xb2, 0x9e, 0x98, 0x3e, 0x33, 0xcf, 0xef, 0x19, 0x1e, 0x5e, 0x0a, + 0xf7, 0x5c, 0xde, 0xa1, 0x83, 0x06, 0xe7, 0x5e, 0x87, 0xb9, 0xa6, 0xe0, 0x9e, 0x41, 0x6d, 0x36, + 0x10, 0xde, 0x70, 0x9f, 0x89, 0xde, 0x33, 0xbf, 0x2d, 0x18, 0x77, 0xf5, 0xbe, 0xc7, 0x05, 0xc7, + 0x29, 0xf9, 0x51, 0xbc, 0x6f, 0x33, 0xd1, 0xf3, 0x2d, 0xbd, 0xcd, 0x0f, 0xab, 0x36, 0xb7, 0x79, + 0x55, 0xca, 0x96, 0xdf, 0x95, 0x4f, 0xf2, 0x41, 0xae, 0x42, 0x97, 0xf6, 0x0d, 0xc1, 0x8d, 0x3d, + 0xea, 0x31, 0xd3, 0x61, 0x9f, 0x4d, 0xcb, 0xa1, 0x1f, 0x4c, 0x87, 0x75, 0x16, 0x41, 0x58, 0x83, + 0xf4, 0x7b, 0xdf, 0x7a, 0x4d, 0x87, 0x2a, 0x2a, 0xa3, 0x4a, 0xae, 0x0e, 0xf3, 0x49, 0x29, 0xdd, + 0x97, 0x8a, 0x11, 0xed, 0xe0, 0x3b, 0x90, 0x69, 0xf4, 0x4c, 0xb7, 0x4d, 0x07, 0x6a, 0xa2, 0x8c, + 0x2a, 0xf9, 0x7a, 0x76, 0x3e, 0x29, 0x65, 0xda, 0xa1, 0x64, 0x2c, 0xf7, 0x70, 0x09, 0x52, 0x2f, + 0xdd, 0x0e, 0xfd, 0xa4, 0x26, 0xe5, 0xa1, 0xed, 0xf9, 0xa4, 0x94, 0x62, 0x0b, 0xc1, 0x08, 0x75, + 0xed, 0x29, 0xc0, 0x69, 0xf0, 0x00, 0x3f, 0x80, 0xad, 0xe7, 0xa6, 0x30, 0x55, 0x54, 0x4e, 0x56, + 0xb2, 0xb5, 0x9d, 0xf0, 0xa6, 0xfa, 0x85, 0xb7, 0x34, 0xe4, 0x49, 0xed, 0x67, 0x0a, 0x8a, 0xcd, + 0x3e, 0x6f, 0xf7, 0xce, 0x28, 0xb1, 0x82, 0xf0, 0x2e, 0x5c, 0x6b, 0x3a, 0xcc, 0x66, 0x96, 0x43, + 0x23, 0x68, 0x35, 0x82, 0xae, 0x37, 0xe9, 0x4b, 0x47, 0xd3, 0x15, 0xde, 0xb0, 0xbe, 0x75, 0x3c, + 0x29, 0x29, 0xc6, 0x29, 0x06, 0xb7, 0x20, 0xb3, 0x6f, 0x32, 0xc1, 0x5c, 0x5b, 0x4d, 0x48, 0xa2, + 0xbe, 0x99, 0x18, 0x19, 0xe2, 0xc0, 0x25, 0x64, 0xc1, 0x7b, 0x43, 0xcd, 0xa3, 0x05, 0x2f, 0x79, + 0x59, 0x5e, 0x64, 0x58, 0xe1, 0x45, 0x1a, 0x3e, 0x80, 0xec, 0x5e, 0xcf, 0xef, 0x76, 0x1d, 0xda, + 0x79, 0xe7, 0x0b, 0x75, 0x4b, 0x32, 0x6b, 0x9b, 0x99, 0x31, 0x53, 0x9c, 0x1b, 0x87, 0x15, 0x5b, + 0x90, 0x5f, 0x29, 0x07, 0x17, 0x20, 0xf9, 0x31, 0x9a, 0x93, 0x6d, 0x63, 0xb1, 0xc4, 0x77, 0x21, + 0x75, 0x64, 0x3a, 0x3e, 0x95, 0x63, 0x91, 0xad, 0x5d, 0x8f, 0x82, 0xcf, 0x32, 0x8d, 0x70, 0xff, + 0x49, 0xe2, 0x31, 0x2a, 0xbe, 0x85, 0x5c, 0xbc, 0x9a, 0xff, 0x80, 0x8b, 0x37, 0x73, 0x55, 0xdc, + 0x2e, 0x14, 0xce, 0x97, 0x72, 0x45, 0xa4, 0xf6, 0x2b, 0x01, 0xb7, 0x5b, 0x9b, 0xff, 0xd8, 0x58, + 0x83, 0x5c, 0xc3, 0xf7, 0x3c, 0xea, 0x0a, 0xf9, 0x8b, 0xc9, 0xbc, 0xbc, 0xb1, 0xa2, 0xe1, 0xaf, + 0x08, 0x6e, 0xca, 0xd5, 0xa0, 0xc1, 0xdd, 0x2e, 0xb3, 0x63, 0xfe, 0x68, 0x32, 0x5f, 0x44, 0x77, + 0xb9, 0x44, 0xa2, 0xbe, 0x86, 0x24, 0xbf, 0xb5, 0xb1, 0x2e, 0xa7, 0x78, 0x08, 0x3b, 0xff, 0x32, + 0x5e, 0x50, 0xd7, 0xa3, 0xd5, 0xba, 0x6e, 0x6d, 0x1c, 0xcc, 0x58, 0x7d, 0xf5, 0x57, 0xa3, 0x29, + 0x51, 0xc6, 0x53, 0xa2, 0x9c, 0x4c, 0x09, 0xfa, 0x12, 0x10, 0xf4, 0x23, 0x20, 0xe8, 0x38, 0x20, + 0x68, 0x14, 0x10, 0x34, 0x0e, 0x08, 0xfa, 0x1d, 0x10, 0xf4, 0x27, 0x20, 0xca, 0x49, 0x40, 0xd0, + 0xf7, 0x19, 0x51, 0x46, 0x33, 0xa2, 0x8c, 0x67, 0x44, 0x39, 0x28, 0x9c, 0x7f, 0x9d, 0x5a, 0x69, + 0x19, 0xfc, 0xf0, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0x19, 0xc5, 0xc4, 0x69, 0x05, 0x00, + 0x00, } func (this *SerializableValidator) Equal(that interface{}) bool { @@ -444,7 +444,7 @@ func (this *SerializableValidator) GoString() string { return "nil" } s := make([]string, 0, 7) - s = append(s, "&sharding.SerializableValidator{") + s = append(s, "&nodesCoordinator.SerializableValidator{") s = append(s, "PubKey: "+fmt.Sprintf("%#v", this.PubKey)+",\n") s = append(s, "Chances: "+fmt.Sprintf("%#v", this.Chances)+",\n") s = append(s, "Index: "+fmt.Sprintf("%#v", this.Index)+",\n") @@ -456,7 +456,7 @@ func (this *Validators) GoString() string { return "nil" } s := make([]string, 0, 5) - s = append(s, "&sharding.Validators{") + s = append(s, "&nodesCoordinator.Validators{") if this.Data != nil { s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n") } @@ -468,7 +468,7 @@ func (this *EpochValidatorsWithAuction) GoString() string { return "nil" } s := make([]string, 0, 8) - s = append(s, "&sharding.EpochValidatorsWithAuction{") + s = append(s, "&nodesCoordinator.EpochValidatorsWithAuction{") keysForEligible := make([]string, 0, len(this.Eligible)) for k, _ := range this.Eligible { keysForEligible = append(keysForEligible, k) @@ -529,7 +529,7 @@ func (this *NodesCoordinatorRegistryWithAuction) GoString() string { return "nil" } s := make([]string, 0, 6) - s = append(s, "&sharding.NodesCoordinatorRegistryWithAuction{") + s = append(s, "&nodesCoordinator.NodesCoordinatorRegistryWithAuction{") s = append(s, "CurrentEpoch: "+fmt.Sprintf("%#v", this.CurrentEpoch)+",\n") keysForEpochsConfigWithAuction := make([]string, 0, len(this.EpochsConfigWithAuction)) for k, _ := range this.EpochsConfigWithAuction { @@ -791,11 +791,6 @@ func (m *NodesCoordinatorRegistryWithAuction) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l - if m.CurrentEpoch != 0 { - i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(m.CurrentEpoch)) - i-- - dAtA[i] = 0x10 - } if len(m.EpochsConfigWithAuction) > 0 { keysForEpochsConfigWithAuction := make([]string, 0, len(m.EpochsConfigWithAuction)) for k := range m.EpochsConfigWithAuction { @@ -824,9 +819,14 @@ func (m *NodesCoordinatorRegistryWithAuction) MarshalToSizedBuffer(dAtA []byte) dAtA[i] = 0xa i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(baseI-i)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 } } + if m.CurrentEpoch != 0 { + i = encodeVarintNodesCoordinatorRegistryWithAuction(dAtA, i, uint64(m.CurrentEpoch)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -926,6 +926,9 @@ func (m *NodesCoordinatorRegistryWithAuction) Size() (n int) { } var l int _ = l + if m.CurrentEpoch != 0 { + n += 1 + sovNodesCoordinatorRegistryWithAuction(uint64(m.CurrentEpoch)) + } if len(m.EpochsConfigWithAuction) > 0 { for k, v := range m.EpochsConfigWithAuction { _ = k @@ -939,9 +942,6 @@ func (m *NodesCoordinatorRegistryWithAuction) Size() (n int) { n += mapEntrySize + 1 + sovNodesCoordinatorRegistryWithAuction(uint64(mapEntrySize)) } } - if m.CurrentEpoch != 0 { - n += 1 + sovNodesCoordinatorRegistryWithAuction(uint64(m.CurrentEpoch)) - } return n } @@ -1046,8 +1046,8 @@ func (this *NodesCoordinatorRegistryWithAuction) String() string { } mapStringForEpochsConfigWithAuction += "}" s := strings.Join([]string{`&NodesCoordinatorRegistryWithAuction{`, - `EpochsConfigWithAuction:` + mapStringForEpochsConfigWithAuction + `,`, `CurrentEpoch:` + fmt.Sprintf("%v", this.CurrentEpoch) + `,`, + `EpochsConfigWithAuction:` + mapStringForEpochsConfigWithAuction + `,`, `}`, }, "") return s @@ -1871,6 +1871,25 @@ func (m *NodesCoordinatorRegistryWithAuction) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType) + } + m.CurrentEpoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNodesCoordinatorRegistryWithAuction + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentEpoch |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field EpochsConfigWithAuction", wireType) } @@ -1999,25 +2018,6 @@ func (m *NodesCoordinatorRegistryWithAuction) Unmarshal(dAtA []byte) error { } m.EpochsConfigWithAuction[mapkey] = mapvalue iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType) - } - m.CurrentEpoch = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowNodesCoordinatorRegistryWithAuction - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CurrentEpoch |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipNodesCoordinatorRegistryWithAuction(dAtA[iNdEx:]) diff --git a/sharding/nodesCoordinatorRegistryWithAuction.proto b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.proto similarity index 95% rename from sharding/nodesCoordinatorRegistryWithAuction.proto rename to sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.proto index 8cad9e17d2a..3ff1c90acb1 100644 --- a/sharding/nodesCoordinatorRegistryWithAuction.proto +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package proto; -option go_package = "sharding"; +option go_package = "nodesCoordinator"; option (gogoproto.stable_marshaler_all) = true; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; From b974a7de6460f1bd47a01b2f1176325bf254cec2 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 17 Mar 2022 17:34:14 +0200 Subject: [PATCH 120/958] FIX: Add return error --- state/errors.go | 6 ++ state/interface.go | 8 +- state/validatorsInfoMap.go | 66 +++++++++++---- state/validatorsInfoMap_test.go | 144 ++++++++++++++++++++++++-------- 4 files changed, 169 insertions(+), 55 deletions(-) diff --git a/state/errors.go b/state/errors.go index 966de871029..f68755564a0 100644 --- a/state/errors.go +++ b/state/errors.go @@ -121,3 +121,9 @@ var ErrNilRootHash = errors.New("nil root hash") // ErrNilChainHandler signals that a nil chain handler was provided var ErrNilChainHandler = errors.New("nil chain handler") + +// ErrNilValidatorInfo signals that a nil value for the validator info has been provided +var ErrNilValidatorInfo = errors.New("validator info is nil") + +// ErrValidatorsDifferentShards signals that validators are not in the same shard +var ErrValidatorsDifferentShards = errors.New("validators are not in the same shard") diff --git a/state/interface.go b/state/interface.go index ce6b95e7960..dd8c6633b12 100644 --- a/state/interface.go +++ b/state/interface.go @@ -190,10 +190,10 @@ type ShardValidatorsInfoMapHandler interface { GetAllValidatorsInfo() []ValidatorInfoHandler GetValidator(blsKey []byte) ValidatorInfoHandler - Add(validator ValidatorInfoHandler) - Delete(validator ValidatorInfoHandler) - Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) - SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) + Add(validator ValidatorInfoHandler) error + Delete(validator ValidatorInfoHandler) error + Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) error + SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) error GetValInfoPointerMap() map[uint32][]*ValidatorInfo } diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 14fab8c1cc9..66ff6c5c39c 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -2,7 +2,11 @@ package state import ( "bytes" + "encoding/hex" + "fmt" "sync" + + "github.com/ElrondNetwork/elrond-go-core/core/check" ) type shardValidatorsInfoMap struct { @@ -68,16 +72,17 @@ func (vi *shardValidatorsInfoMap) GetShardValidatorsInfoMap() map[uint32][]Valid } // Add adds a new ValidatorInfoHandler in its corresponding shardID, if it doesn't already exists -func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) { - if vi.GetValidator(validator.GetPublicKey()) != nil { - return +func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) error { + if check.IfNil(validator) { + return ErrNilValidatorInfo } shardID := validator.GetShardId() - vi.mutex.Lock() vi.valInfoMap[shardID] = append(vi.valInfoMap[shardID], validator) vi.mutex.Unlock() + + return nil } // GetValidator returns a ValidatorInfoHandler with the provided blsKey, if it is present in the map @@ -93,9 +98,21 @@ func (vi *shardValidatorsInfoMap) GetValidator(blsKey []byte) ValidatorInfoHandl // Replace will replace an existing ValidatorInfoHandler with a new one. The old and new validator // shall be in the same shard and have the same public key. -func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) { +func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) error { + if check.IfNil(old) { + return fmt.Errorf("%w for old validator in shardValidatorsInfoMap.Replace", ErrNilValidatorInfo) + } + if check.IfNil(new) { + return fmt.Errorf("%w for new validator in shardValidatorsInfoMap.Replace", ErrNilValidatorInfo) + } if old.GetShardId() != new.GetShardId() { - return + return fmt.Errorf("%w when trying to replace %s from shard %v with %s from shard %v", + ErrValidatorsDifferentShards, + hex.EncodeToString(old.GetPublicKey()), + old.GetShardId(), + hex.EncodeToString(new.GetPublicKey()), + new.GetShardId(), + ) } shardID := old.GetShardId() @@ -109,28 +126,47 @@ func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new Validato break } } + + return nil } // SetValidatorsInShard resets all validators saved in a specific shard with the provided []ValidatorInfoHandler. // Before setting them, it checks that provided validators have the same shardID as the one provided. -func (vi *shardValidatorsInfoMap) SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) { +func (vi *shardValidatorsInfoMap) SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) error { sameShardValidators := make([]ValidatorInfoHandler, 0, len(validators)) - for _, validator := range validators { - if validator.GetShardId() == shardID { - sameShardValidators = append(sameShardValidators, validator) + for idx, validator := range validators { + if check.IfNil(validator) { + return fmt.Errorf("%w in shardValidatorsInfoMap.SetValidatorsInShard at index %d", + ErrNilValidatorInfo, + idx, + ) } + if validator.GetShardId() != shardID { + return fmt.Errorf("%w, %s is in shard %d, but should be set in shard %d in shardValidatorsInfoMap.SetValidatorsInShard", + ErrValidatorsDifferentShards, + hex.EncodeToString(validator.GetPublicKey()), + validator.GetShardId(), + shardID, + ) + } + sameShardValidators = append(sameShardValidators, validator) } vi.mutex.Lock() vi.valInfoMap[shardID] = sameShardValidators vi.mutex.Unlock() + + return nil } -// Delete will delete the provided validator from the internally stored map. The validators slice at the -// corresponding shardID key will be re-sliced, without reordering -func (vi *shardValidatorsInfoMap) Delete(validator ValidatorInfoHandler) { - shardID := validator.GetShardId() +// Delete will delete the provided validator from the internally stored map, if found. +// The validators slice at the corresponding shardID key will be re-sliced, without reordering +func (vi *shardValidatorsInfoMap) Delete(validator ValidatorInfoHandler) error { + if check.IfNil(validator) { + return ErrNilValidatorInfo + } + shardID := validator.GetShardId() vi.mutex.Lock() defer vi.mutex.Unlock() @@ -143,6 +179,8 @@ func (vi *shardValidatorsInfoMap) Delete(validator ValidatorInfoHandler) { break } } + + return nil } // TODO: Delete this once map[uint32][]*ValidatorInfo is completely replaced with new interface diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index e36834fbca2..c056c9b7a32 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -1,7 +1,9 @@ package state import ( + "encoding/hex" "strconv" + "strings" "sync" "testing" @@ -9,7 +11,55 @@ import ( "github.com/stretchr/testify/require" ) -func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsInfo(t *testing.T) { +func TestShardValidatorsInfoMap_Add_Delete_Replace_SetValidatorsInShard_NilValidators(t *testing.T) { + t.Parallel() + + vi := NewShardValidatorsInfoMap(1) + + err := vi.Add(nil) + require.Equal(t, ErrNilValidatorInfo, err) + + err = vi.Delete(nil) + require.Equal(t, ErrNilValidatorInfo, err) + + err = vi.Replace(nil, &ValidatorInfo{}) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) + require.True(t, strings.Contains(err.Error(), "old")) + + err = vi.Replace(&ValidatorInfo{}, nil) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) + require.True(t, strings.Contains(err.Error(), "new")) + + v := &ValidatorInfo{ShardId: 3, PublicKey: []byte("pk")} + err = vi.SetValidatorsInShard(3, []ValidatorInfoHandler{v, nil}) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) + require.True(t, strings.Contains(err.Error(), "index 1")) +} + +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() vi := NewShardValidatorsInfoMap(3) @@ -19,11 +69,10 @@ func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsIn v2 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk2")} v3 := &ValidatorInfo{ShardId: core.MetachainShardId, PublicKey: []byte("pk3")} - vi.Add(v0) - vi.Add(v1) - vi.Add(v2) - vi.Add(v3) - vi.Add(v3) + _ = vi.Add(v0) + _ = vi.Add(v1) + _ = vi.Add(v2) + _ = vi.Add(v3) allValidators := vi.GetAllValidatorsInfo() require.Len(t, allValidators, 4) @@ -49,7 +98,7 @@ func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsIn require.Equal(t, expectedValidatorPointersMap, validatorPointersMap) } -func TestShardValidatorsInfoMap_GetValidatorWithBLSKey(t *testing.T) { +func TestShardValidatorsInfoMap_GetValidator(t *testing.T) { t.Parallel() vi := NewShardValidatorsInfoMap(1) @@ -59,8 +108,8 @@ func TestShardValidatorsInfoMap_GetValidatorWithBLSKey(t *testing.T) { v0 := &ValidatorInfo{ShardId: 0, PublicKey: pubKey0} v1 := &ValidatorInfo{ShardId: 1, PublicKey: pubKey1} - vi.Add(v0) - vi.Add(v1) + _ = vi.Add(v0) + _ = vi.Add(v1) require.Equal(t, v0, vi.GetValidator(pubKey0)) require.Equal(t, v1, vi.GetValidator(pubKey1)) @@ -77,18 +126,23 @@ func TestShardValidatorsInfoMap_Delete(t *testing.T) { v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} v3 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk3")} - vi.Add(v0) - vi.Add(v1) - vi.Add(v2) - vi.Add(v3) + _ = vi.Add(v0) + _ = vi.Add(v1) + _ = vi.Add(v2) + _ = vi.Add(v3) - vi.Delete(&ValidatorInfo{ShardId: 0, PublicKey: []byte("pk3")}) - vi.Delete(&ValidatorInfo{ShardId: 1, PublicKey: []byte("pk0")}) + _ = vi.Delete(&ValidatorInfo{ShardId: 0, PublicKey: []byte("pk3")}) + _ = vi.Delete(&ValidatorInfo{ShardId: 1, PublicKey: []byte("pk0")}) require.Len(t, vi.GetAllValidatorsInfo(), 4) - vi.Delete(&ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")}) + _ = vi.Delete(v1) require.Len(t, vi.GetAllValidatorsInfo(), 3) require.Equal(t, []ValidatorInfoHandler{v0, v2}, vi.GetShardValidatorsInfoMap()[0]) + require.Equal(t, []ValidatorInfoHandler{v3}, vi.GetShardValidatorsInfoMap()[1]) + + _ = vi.Delete(v3) + require.Len(t, vi.GetAllValidatorsInfo(), 2) + require.Equal(t, []ValidatorInfoHandler{v0, v2}, vi.GetShardValidatorsInfoMap()[0]) } func TestShardValidatorsInfoMap_Replace(t *testing.T) { @@ -99,14 +153,17 @@ func TestShardValidatorsInfoMap_Replace(t *testing.T) { v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} - vi.Add(v0) - vi.Add(v1) + _ = vi.Add(v0) + _ = vi.Add(v1) - vi.Replace(v0, &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk2")}) + err := vi.Replace(v0, &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk2")}) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrValidatorsDifferentShards.Error())) require.Equal(t, []ValidatorInfoHandler{v0, v1}, vi.GetShardValidatorsInfoMap()[0]) v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} - vi.Replace(v0, v2) + err = vi.Replace(v0, v2) + require.Nil(t, err) require.Equal(t, []ValidatorInfoHandler{v2, v1}, vi.GetShardValidatorsInfoMap()[0]) } @@ -116,7 +173,7 @@ func TestShardValidatorsInfoMap_SetValidatorsInShard(t *testing.T) { vi := NewShardValidatorsInfoMap(2) v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} - vi.Add(v0) + _ = vi.Add(v0) v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} @@ -124,14 +181,26 @@ func TestShardValidatorsInfoMap_SetValidatorsInShard(t *testing.T) { shard0Validators := []ValidatorInfoHandler{v1, v2} shard1Validators := []ValidatorInfoHandler{v3} - vi.SetValidatorsInShard(1, shard0Validators) + err := vi.SetValidatorsInShard(1, shard0Validators) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrValidatorsDifferentShards.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(v1.PublicKey))) require.Equal(t, []ValidatorInfoHandler{v0}, vi.GetShardValidatorsInfoMap()[0]) + require.Empty(t, vi.GetShardValidatorsInfoMap()[1]) - vi.SetValidatorsInShard(0, []ValidatorInfoHandler{v1, v2, v3}) - require.Equal(t, shard0Validators, vi.GetShardValidatorsInfoMap()[0]) + err = vi.SetValidatorsInShard(0, []ValidatorInfoHandler{v1, v2, v3}) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrValidatorsDifferentShards.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(v3.PublicKey))) + require.Equal(t, []ValidatorInfoHandler{v0}, vi.GetShardValidatorsInfoMap()[0]) + require.Empty(t, vi.GetShardValidatorsInfoMap()[1]) - vi.SetValidatorsInShard(1, shard1Validators) + err = vi.SetValidatorsInShard(0, shard0Validators) + require.Nil(t, err) require.Equal(t, shard0Validators, vi.GetShardValidatorsInfoMap()[0]) + + err = vi.SetValidatorsInShard(1, shard1Validators) + require.Nil(t, err) require.Equal(t, shard1Validators, vi.GetShardValidatorsInfoMap()[1]) } @@ -141,26 +210,27 @@ func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testi vi := NewShardValidatorsInfoMap(2) v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} - v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} - v2 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk2")} + v1 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk1")} - vi.Add(v0) - vi.Add(v1) - vi.Add(v2) + _ = vi.Add(v0) + _ = vi.Add(v1) validatorsMap := vi.GetShardValidatorsInfoMap() 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")}) validator := vi.GetValidator([]byte("pk0")) - validator.SetShardId(1) + validator.SetShardId(2) - require.Equal(t, []ValidatorInfoHandler{v0, v1, v2}, vi.GetAllValidatorsInfo()) + require.Equal(t, []ValidatorInfoHandler{v0}, vi.GetShardValidatorsInfoMap()[0]) + require.Equal(t, []ValidatorInfoHandler{v1}, vi.GetShardValidatorsInfoMap()[1]) } func TestShardValidatorsInfoMap_Concurrency(t *testing.T) { @@ -206,11 +276,11 @@ func TestShardValidatorsInfoMap_Concurrency(t *testing.T) { wg.Add(2) go func() { - vi.SetValidatorsInShard(0, shard0Validators) + _ = vi.SetValidatorsInShard(0, shard0Validators) wg.Done() }() go func() { - vi.SetValidatorsInShard(1, shard1Validators) + _ = vi.SetValidatorsInShard(1, shard1Validators) wg.Done() }() wg.Wait() @@ -246,7 +316,7 @@ func addValidatorsInShardConcurrently( ) { for _, validator := range validators { go func(val ValidatorInfoHandler) { - vi.Add(val) + _ = vi.Add(val) wg.Done() }(validator) } @@ -259,7 +329,7 @@ func deleteValidatorsConcurrently( ) { for _, validator := range validators { go func(val ValidatorInfoHandler) { - vi.Delete(val) + _ = vi.Delete(val) wg.Done() }(validator) } @@ -273,7 +343,7 @@ func replaceValidatorsConcurrently( ) { for idx := range oldValidators { go func(old ValidatorInfoHandler, new ValidatorInfoHandler) { - vi.Replace(old, new) + _ = vi.Replace(old, new) wg.Done() }(oldValidators[idx], newValidators[idx]) } From fee72390bde352519d2614882161e03862ccce2d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 17 Mar 2022 18:12:31 +0200 Subject: [PATCH 121/958] FIX: Func description + return error on Replace when old val not found --- state/errors.go | 3 +++ state/validatorsInfoMap.go | 21 +++++++++++++-------- state/validatorsInfoMap_test.go | 8 ++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/state/errors.go b/state/errors.go index f68755564a0..5344bbd8060 100644 --- a/state/errors.go +++ b/state/errors.go @@ -127,3 +127,6 @@ var ErrNilValidatorInfo = errors.New("validator info is nil") // ErrValidatorsDifferentShards signals that validators are not in the same shard var ErrValidatorsDifferentShards = errors.New("validators are not in the same shard") + +// ErrValidatorNotFound signals that a validator was not found +var ErrValidatorNotFound = errors.New("validator not found") diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 66ff6c5c39c..75611e3ffd6 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -39,7 +39,7 @@ func CreateShardValidatorsMap(input map[uint32][]*ValidatorInfo) *shardValidator return ret } -// GetAllValidatorsInfo returns a ValidatorInfoHandler copy slice with validators from all shards. +// GetAllValidatorsInfo returns a []ValidatorInfoHandler copy with validators from all shards. func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler { ret := make([]ValidatorInfoHandler, 0) @@ -55,7 +55,7 @@ func (vi *shardValidatorsInfoMap) GetAllValidatorsInfo() []ValidatorInfoHandler return ret } -// GetShardValidatorsInfoMap returns a copy map of internally stored data +// GetShardValidatorsInfoMap returns a map copy of internally stored data func (vi *shardValidatorsInfoMap) GetShardValidatorsInfoMap() map[uint32][]ValidatorInfoHandler { ret := make(map[uint32][]ValidatorInfoHandler, len(vi.valInfoMap)) @@ -71,7 +71,7 @@ func (vi *shardValidatorsInfoMap) GetShardValidatorsInfoMap() map[uint32][]Valid return ret } -// Add adds a new ValidatorInfoHandler in its corresponding shardID, if it doesn't already exists +// Add adds a ValidatorInfoHandler in its corresponding shardID func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) error { if check.IfNil(validator) { return ErrNilValidatorInfo @@ -85,7 +85,8 @@ func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) error { return nil } -// GetValidator returns a ValidatorInfoHandler with the provided blsKey, if it is present in the map +// GetValidator returns a ValidatorInfoHandler copy with the provided blsKey, +// if it is present in the map, otherwise returns nil func (vi *shardValidatorsInfoMap) GetValidator(blsKey []byte) ValidatorInfoHandler { for _, validator := range vi.GetAllValidatorsInfo() { if bytes.Equal(validator.GetPublicKey(), blsKey) { @@ -97,7 +98,7 @@ func (vi *shardValidatorsInfoMap) GetValidator(blsKey []byte) ValidatorInfoHandl } // Replace will replace an existing ValidatorInfoHandler with a new one. The old and new validator -// shall be in the same shard and have the same public key. +// shall be in the same shard. If the old validator is not found in the map, an error is returned func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new ValidatorInfoHandler) error { if check.IfNil(old) { return fmt.Errorf("%w for old validator in shardValidatorsInfoMap.Replace", ErrNilValidatorInfo) @@ -123,11 +124,15 @@ func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new Validato for idx, validator := range vi.valInfoMap[shardID] { if bytes.Equal(validator.GetPublicKey(), old.GetPublicKey()) { vi.valInfoMap[shardID][idx] = new - break + return nil } } - return nil + return fmt.Errorf("old %w: %s when trying to replace it with %s", + ErrValidatorNotFound, + hex.EncodeToString(old.GetPublicKey()), + hex.EncodeToString(new.GetPublicKey()), + ) } // SetValidatorsInShard resets all validators saved in a specific shard with the provided []ValidatorInfoHandler. @@ -185,7 +190,7 @@ func (vi *shardValidatorsInfoMap) Delete(validator ValidatorInfoHandler) error { // TODO: Delete this once map[uint32][]*ValidatorInfo is completely replaced with new interface -// GetValInfoPointerMap returns a from internally stored data +// GetValInfoPointerMap returns a from internally stored data func (vi *shardValidatorsInfoMap) GetValInfoPointerMap() map[uint32][]*ValidatorInfo { ret := make(map[uint32][]*ValidatorInfo, 0) diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index c056c9b7a32..111b76820ad 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -165,6 +165,14 @@ func TestShardValidatorsInfoMap_Replace(t *testing.T) { err = vi.Replace(v0, v2) require.Nil(t, err) require.Equal(t, []ValidatorInfoHandler{v2, v1}, vi.GetShardValidatorsInfoMap()[0]) + + v3 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk3")} + v4 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk4")} + err = vi.Replace(v3, v4) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrValidatorNotFound.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(v3.PublicKey))) + require.Equal(t, []ValidatorInfoHandler{v2, v1}, vi.GetShardValidatorsInfoMap()[0]) } func TestShardValidatorsInfoMap_SetValidatorsInShard(t *testing.T) { From d4081b6a8010b0ff159b19a04f831ff4ee772603 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 11:40:55 +0200 Subject: [PATCH 122/958] FIX: Refactor to use new interface --- epochStart/metachain/legacySystemSCs.go | 20 ++- epochStart/metachain/systemSCs.go | 5 +- epochStart/metachain/systemSCs_test.go | 167 +++++++++++++----------- 3 files changed, 109 insertions(+), 83 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 7f15705c327..d01c787f492 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -453,7 +453,10 @@ func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMa } if deleteCalled { - validatorsInfoMap.SetValidatorsInShard(shId, newList) + err := validatorsInfoMap.SetValidatorsInShard(shId, newList) + if err != nil { + return err + } } } @@ -756,7 +759,10 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } } else { // old jailed validator getting switched back after unJail with stake - must remove first from exported map - validatorsInfoMap.Delete(jailedValidator) + err = validatorsInfoMap.Delete(jailedValidator) + if err != nil { + return nil, err + } } account.SetListAndIndex(jailedValidator.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce)) @@ -785,7 +791,10 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } newValidatorInfo := s.validatorInfoCreator.PeerAccountToValidatorInfo(account) - validatorsInfoMap.Replace(jailedValidator, newValidatorInfo) + err = validatorsInfoMap.Replace(jailedValidator, newValidatorInfo) + if err != nil { + return nil, err + } return blsPubKey, nil } @@ -1260,7 +1269,10 @@ func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( RewardAddress: rewardAddress, AccumulatedFees: big.NewInt(0), } - validatorsInfoMap.Add(validatorInfo) + err = validatorsInfoMap.Add(validatorInfo) + if err != nil { + return err + } } return nil diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index ddb1bab6f44..6ceacc241a6 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -170,7 +170,10 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S for i := uint32(0); i < numOfAvailableNodeSlots; i++ { newNode := auctionList[i] newNode.SetList(string(common.SelectedFromAuctionList)) - validatorsInfoMap.Replace(auctionList[i], newNode) + err = validatorsInfoMap.Replace(auctionList[i], newNode) + if err != nil { + return err + } } return nil diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f22713a6ce0..749dcc1916b 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -184,7 +184,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { RewardAddress: []byte("address"), AccumulatedFees: big.NewInt(0), } - validatorsInfo.Add(vInfo) + _ = validatorsInfo.Add(vInfo) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) @@ -229,7 +229,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s addValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.SetValidatorsInShard(0, jailed) + _ = validatorsInfo.SetValidatorsInShard(0, jailed) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) @@ -300,7 +300,7 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { RewardAddress: []byte("owner1"), AccumulatedFees: big.NewInt(0), } - validatorsInfo.Add(jailed) + _ = validatorsInfo.Add(jailed) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) @@ -1314,25 +1314,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t ) validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), @@ -1382,13 +1382,13 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: []byte("rewardAddress"), @@ -1459,25 +1459,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.WaitingList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.WaitingList), RewardAddress: delegationAddr, @@ -1548,25 +1548,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: delegationAddr, @@ -1646,25 +1646,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: delegationAddr, AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: delegationAddr, @@ -1718,31 +1718,31 @@ func TestSystemSCProcessor_ProcessSystemSmartContractWrongValidatorInfoShouldBeC ) validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: "", RewardAddress: []byte("stakedPubKey0"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("oneAddress1"), List: string(common.EligibleList), RewardAddress: []byte("oneAddress1"), @@ -1816,25 +1816,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey1"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey2"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), AccumulatedFees: big.NewInt(0), }) - validatorsInfo.Add(&state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey3"), List: string(common.EligibleList), RewardAddress: []byte("ownerKey"), @@ -1906,29 +1906,33 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap(2) - validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) - validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) - validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) - expectedValidatorsInfo := state.NewShardValidatorsInfoMap(2) - expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1, 0)) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0), + createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1, 0), + createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1, 0), + createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1, 0), - expectedValidatorsInfo.Add(createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2, 0)) + createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2, 0), - expectedValidatorsInfo.Add(createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3, 0)) - - expectedValidatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) + createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3, 0), + createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3, 0), + }, + 1: { + createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1), + }, + } - require.Equal(t, expectedValidatorsInfo, validatorsInfo) + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepareStakingData(t *testing.T) { @@ -1948,8 +1952,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) - validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) @@ -1982,8 +1986,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) - validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) @@ -2011,18 +2015,21 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA validatorsInfo := state.NewShardValidatorsInfoMap(1) - validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) - expectedValidatorsInfo := state.NewShardValidatorsInfoMap(1) - expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) - require.Equal(t, expectedValidatorsInfo, validatorsInfo) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { @@ -2047,19 +2054,19 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap(2) - validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) - validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1, 0)) - validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1)) - validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2, 1)) - validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1)) - validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1)) - validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1)) - validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) - validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) @@ -2097,21 +2104,25 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(0)) requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(500)) - expectedValidatorsInfo := state.NewShardValidatorsInfoMap(2) - expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) - expectedValidatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, owner1, 0)) - - expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1)) - expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.SelectedFromAuctionList, owner2, 1)) - expectedValidatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1)) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0), + createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, owner1, 0), + }, + 1: { + createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1), + createValidatorInfo(owner2StakedKeys[1], common.SelectedFromAuctionList, owner2, 1), + createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1), - expectedValidatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1)) - expectedValidatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1)) + createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1), + createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1), - expectedValidatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) - expectedValidatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4, 1)) - require.Equal(t, expectedValidatorsInfo, validatorsInfo) + createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1), + createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4, 1), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } func registerValidatorKeys( From 9496271f32ef7c91f148688a64d4848d00852051 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 11:43:52 +0200 Subject: [PATCH 123/958] FIX: Remove empty line --- state/validatorsInfoMap.go | 1 - 1 file changed, 1 deletion(-) diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 3b2fd89983c..3c487420f9e 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -48,7 +48,6 @@ func Replace(oldMap, newMap map[uint32][]*ValidatorInfo) { for shardID, validatorsInShard := range newMap { oldMap[shardID] = validatorsInShard } - } // GetAllValidatorsInfo returns a []ValidatorInfoHandler copy with validators from all shards. From 003d563dd11e855ac9f23a3dbd5948d236fc1ebb Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 12:10:00 +0200 Subject: [PATCH 124/958] FEAT: Remove all duplicated validator statistics stubs --- factory/blockProcessorCreator_test.go | 4 +- factory/consensusComponents_test.go | 2 +- .../mock/validatorStatisticsProcessorStub.go | 130 ----------------- .../mock/validatorStatisticsProcessorStub.go | 130 ----------------- integrationTests/testP2PNode.go | 2 +- integrationTests/testProcessorNode.go | 6 +- integrationTests/testSyncNode.go | 2 +- node/mock/peerProcessorMock.go | 133 ------------------ node/mock/validatorStatisticsProcessorStub.go | 130 ----------------- node/node_test.go | 6 +- process/block/metablock_test.go | 20 +-- process/peer/validatorsProvider_test.go | 17 +-- .../validatorStatisticsProcessorStub.go | 58 ++++---- 13 files changed, 59 insertions(+), 581 deletions(-) delete mode 100644 factory/mock/validatorStatisticsProcessorStub.go delete mode 100644 integrationTests/mock/validatorStatisticsProcessorStub.go delete mode 100644 node/mock/peerProcessorMock.go delete mode 100644 node/mock/validatorStatisticsProcessorStub.go rename {process/mock => testscommon}/validatorStatisticsProcessorStub.go (96%) diff --git a/factory/blockProcessorCreator_test.go b/factory/blockProcessorCreator_test.go index 6a9b22dc997..c2cf298898d 100644 --- a/factory/blockProcessorCreator_test.go +++ b/factory/blockProcessorCreator_test.go @@ -39,7 +39,7 @@ func Test_newBlockProcessorCreatorForShard(t *testing.T) { &mock.ForkDetectorStub{}, &mock.EpochStartTriggerStub{}, &mock.BoostrapStorerStub{}, - &mock.ValidatorStatisticsProcessorStub{}, + &testscommon.ValidatorStatisticsProcessorStub{}, &mock.HeaderValidatorStub{}, &mock.BlockTrackerStub{}, &mock.PendingMiniBlocksHandlerStub{}, @@ -147,7 +147,7 @@ func Test_newBlockProcessorCreatorForMeta(t *testing.T) { &mock.ForkDetectorStub{}, &mock.EpochStartTriggerStub{}, &mock.BoostrapStorerStub{}, - &mock.ValidatorStatisticsProcessorStub{}, + &testscommon.ValidatorStatisticsProcessorStub{}, &mock.HeaderValidatorStub{}, &mock.BlockTrackerStub{}, &mock.PendingMiniBlocksHandlerStub{}, diff --git a/factory/consensusComponents_test.go b/factory/consensusComponents_test.go index 2334c9941ef..34b721fa4c1 100644 --- a/factory/consensusComponents_test.go +++ b/factory/consensusComponents_test.go @@ -456,7 +456,7 @@ func getDefaultProcessComponents(shardCoordinator sharding.Coordinator) *mock.Pr BootSore: &mock.BootstrapStorerMock{}, HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, - ValidatorStatistics: &mock.ValidatorStatisticsProcessorStub{}, + ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, ValidatorProvider: &mock.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, diff --git a/factory/mock/validatorStatisticsProcessorStub.go b/factory/mock/validatorStatisticsProcessorStub.go deleted file mode 100644 index 2f842c388b9..00000000000 --- a/factory/mock/validatorStatisticsProcessorStub.go +++ /dev/null @@ -1,130 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go/state" -) - -// ValidatorStatisticsProcessorStub - -type ValidatorStatisticsProcessorStub struct { - UpdatePeerStateCalled func(header data.MetaHeaderHandler) ([]byte, error) - RevertPeerStateCalled func(header data.MetaHeaderHandler) error - GetPeerAccountCalled func(address []byte) (state.PeerAccountHandler, error) - RootHashCalled func() ([]byte, error) - ResetValidatorStatisticsAtNewEpochCalled func(vInfos map[uint32][]*state.ValidatorInfo) error - GetValidatorInfoForRootHashCalled func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - ProcessRatingsEndOfEpochCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error - ProcessCalled func(validatorInfo data.ShardValidatorInfoHandler) error - CommitCalled func() ([]byte, error) - PeerAccountToValidatorInfoCalled func(peerAccount state.PeerAccountHandler) *state.ValidatorInfo - SaveNodesCoordinatorUpdatesCalled func(epoch uint32) (bool, error) -} - -// PeerAccountToValidatorInfo - -func (vsp *ValidatorStatisticsProcessorStub) PeerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.ValidatorInfo { - if vsp.PeerAccountToValidatorInfoCalled != nil { - return vsp.PeerAccountToValidatorInfoCalled(peerAccount) - } - return nil -} - -// Process - -func (vsp *ValidatorStatisticsProcessorStub) Process(validatorInfo data.ShardValidatorInfoHandler) error { - if vsp.ProcessCalled != nil { - return vsp.ProcessCalled(validatorInfo) - } - - return nil -} - -// Commit - -func (vsp *ValidatorStatisticsProcessorStub) Commit() ([]byte, error) { - if vsp.CommitCalled != nil { - return vsp.CommitCalled() - } - - return nil, nil -} - -// ResetValidatorStatisticsAtNewEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error { - if vsp.ResetValidatorStatisticsAtNewEpochCalled != nil { - return vsp.ResetValidatorStatisticsAtNewEpochCalled(vInfos) - } - return nil -} - -// GetValidatorInfoForRootHash - -func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { - if vsp.GetValidatorInfoForRootHashCalled != nil { - return vsp.GetValidatorInfoForRootHashCalled(rootHash) - } - return nil, nil -} - -// UpdatePeerState - -func (vsp *ValidatorStatisticsProcessorStub) UpdatePeerState(header data.MetaHeaderHandler, _ map[string]data.HeaderHandler) ([]byte, error) { - if vsp.UpdatePeerStateCalled != nil { - return vsp.UpdatePeerStateCalled(header) - } - return nil, nil -} - -// ProcessRatingsEndOfEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { - if vsp.ProcessRatingsEndOfEpochCalled != nil { - return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) - } - return nil -} - -// RevertPeerState - -func (vsp *ValidatorStatisticsProcessorStub) RevertPeerState(header data.MetaHeaderHandler) error { - if vsp.RevertPeerStateCalled != nil { - return vsp.RevertPeerStateCalled(header) - } - return nil -} - -// RootHash - -func (vsp *ValidatorStatisticsProcessorStub) RootHash() ([]byte, error) { - if vsp.RootHashCalled != nil { - return vsp.RootHashCalled() - } - return nil, nil -} - -// SetLastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) SetLastFinalizedRootHash(_ []byte) { -} - -// LastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) LastFinalizedRootHash() []byte { - return nil -} - -// GetPeerAccount - -func (vsp *ValidatorStatisticsProcessorStub) GetPeerAccount(address []byte) (state.PeerAccountHandler, error) { - if vsp.GetPeerAccountCalled != nil { - return vsp.GetPeerAccountCalled(address) - } - - return nil, nil -} - -// DisplayRatings - -func (vsp *ValidatorStatisticsProcessorStub) DisplayRatings(_ uint32) { -} - -// SaveNodesCoordinatorUpdates - -func (vsp *ValidatorStatisticsProcessorStub) SaveNodesCoordinatorUpdates(epoch uint32) (bool, error) { - if vsp.SaveNodesCoordinatorUpdatesCalled != nil { - return vsp.SaveNodesCoordinatorUpdatesCalled(epoch) - } - return false, nil -} - -// IsInterfaceNil - -func (vsp *ValidatorStatisticsProcessorStub) IsInterfaceNil() bool { - return false -} diff --git a/integrationTests/mock/validatorStatisticsProcessorStub.go b/integrationTests/mock/validatorStatisticsProcessorStub.go deleted file mode 100644 index 2870f9d1d7e..00000000000 --- a/integrationTests/mock/validatorStatisticsProcessorStub.go +++ /dev/null @@ -1,130 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go/state" -) - -// ValidatorStatisticsProcessorStub - -type ValidatorStatisticsProcessorStub struct { - UpdatePeerStateCalled func(header data.MetaHeaderHandler) ([]byte, error) - RevertPeerStateCalled func(header data.MetaHeaderHandler) error - GetPeerAccountCalled func(address []byte) (state.PeerAccountHandler, error) - RootHashCalled func() ([]byte, error) - ResetValidatorStatisticsAtNewEpochCalled func(vInfos map[uint32][]*state.ValidatorInfo) error - GetValidatorInfoForRootHashCalled func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - ProcessRatingsEndOfEpochCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error - ProcessCalled func(validatorInfo data.ShardValidatorInfoHandler) error - CommitCalled func() ([]byte, error) - PeerAccountToValidatorInfoCalled func(peerAccount state.PeerAccountHandler) *state.ValidatorInfo - SaveNodesCoordinatorUpdatesCalled func(epoch uint32) (bool, error) -} - -// SaveNodesCoordinatorUpdates - -func (vsp *ValidatorStatisticsProcessorStub) SaveNodesCoordinatorUpdates(epoch uint32) (bool, error) { - if vsp.SaveNodesCoordinatorUpdatesCalled != nil { - return vsp.SaveNodesCoordinatorUpdatesCalled(epoch) - } - return false, nil -} - -// PeerAccountToValidatorInfo - -func (vsp *ValidatorStatisticsProcessorStub) PeerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.ValidatorInfo { - if vsp.PeerAccountToValidatorInfoCalled != nil { - return vsp.PeerAccountToValidatorInfoCalled(peerAccount) - } - return nil -} - -// Process - -func (vsp *ValidatorStatisticsProcessorStub) Process(validatorInfo data.ShardValidatorInfoHandler) error { - if vsp.ProcessCalled != nil { - return vsp.ProcessCalled(validatorInfo) - } - - return nil -} - -// Commit - -func (vsp *ValidatorStatisticsProcessorStub) Commit() ([]byte, error) { - if vsp.CommitCalled != nil { - return vsp.CommitCalled() - } - - return nil, nil -} - -// ProcessRatingsEndOfEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { - if vsp.ProcessRatingsEndOfEpochCalled != nil { - return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) - } - return nil -} - -// ResetValidatorStatisticsAtNewEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error { - if vsp.ResetValidatorStatisticsAtNewEpochCalled != nil { - return vsp.ResetValidatorStatisticsAtNewEpochCalled(vInfos) - } - return nil -} - -// GetValidatorInfoForRootHash - -func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { - if vsp.GetValidatorInfoForRootHashCalled != nil { - return vsp.GetValidatorInfoForRootHashCalled(rootHash) - } - return nil, nil -} - -// UpdatePeerState - -func (vsp *ValidatorStatisticsProcessorStub) UpdatePeerState(header data.MetaHeaderHandler, _ map[string]data.HeaderHandler) ([]byte, error) { - if vsp.UpdatePeerStateCalled != nil { - return vsp.UpdatePeerStateCalled(header) - } - return nil, nil -} - -// RevertPeerState - -func (vsp *ValidatorStatisticsProcessorStub) RevertPeerState(header data.MetaHeaderHandler) error { - if vsp.RevertPeerStateCalled != nil { - return vsp.RevertPeerStateCalled(header) - } - return nil -} - -// RootHash - -func (vsp *ValidatorStatisticsProcessorStub) RootHash() ([]byte, error) { - if vsp.RootHashCalled != nil { - return vsp.RootHashCalled() - } - return nil, nil -} - -// GetExistingPeerAccount - -func (vsp *ValidatorStatisticsProcessorStub) GetExistingPeerAccount(address []byte) (state.PeerAccountHandler, error) { - if vsp.GetPeerAccountCalled != nil { - return vsp.GetPeerAccountCalled(address) - } - - return nil, nil -} - -// DisplayRatings - -func (vsp *ValidatorStatisticsProcessorStub) DisplayRatings(_ uint32) { -} - -// SetLastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) SetLastFinalizedRootHash(_ []byte) { -} - -// LastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) LastFinalizedRootHash() []byte { - return nil -} - -// IsInterfaceNil - -func (vsp *ValidatorStatisticsProcessorStub) IsInterfaceNil() bool { - return false -} diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index db8f6765b95..233ca7239bb 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -170,7 +170,7 @@ func (tP2pNode *TestP2PNode) initNode() { processComponents.ShardCoord = tP2pNode.ShardCoordinator processComponents.NodesCoord = tP2pNode.NodesCoordinator processComponents.ValidatorProvider = &mock.ValidatorsProviderStub{} - processComponents.ValidatorStatistics = &mock.ValidatorStatisticsProcessorStub{ + processComponents.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ GetValidatorInfoForRootHashCalled: func(_ []byte) (map[uint32][]*state.ValidatorInfo, error) { return map[uint32][]*state.ValidatorInfo{ 0: {{PublicKey: []byte("pk0")}}, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 746b5c11adf..27f3515ecc2 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1386,7 +1386,7 @@ func (tpn *TestProcessorNode) initInnerProcessors(gasMap map[string]map[string]u } if tpn.ValidatorStatisticsProcessor == nil { - tpn.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{} + tpn.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{} } interimProcFactory, _ := shard.NewIntermediateProcessorsContainerFactory( @@ -2922,7 +2922,7 @@ func (tpn *TestProcessorNode) createHeartbeatWithHardforkTrigger(heartbeatPk str processComponents.NodesCoord = tpn.NodesCoordinator processComponents.ShardCoord = tpn.ShardCoordinator processComponents.IntContainer = tpn.InterceptorsContainer - processComponents.ValidatorStatistics = &mock.ValidatorStatisticsProcessorStub{ + processComponents.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ GetValidatorInfoForRootHashCalled: func(_ []byte) (map[uint32][]*state.ValidatorInfo, error) { return map[uint32][]*state.ValidatorInfo{ 0: {{PublicKey: []byte("pk0")}}, @@ -3038,7 +3038,7 @@ func GetDefaultProcessComponents() *mock.ProcessComponentsStub { BootSore: &mock.BoostrapStorerMock{}, HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, - ValidatorStatistics: &mock.ValidatorStatisticsProcessorStub{}, + ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, ValidatorProvider: &mock.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index af1518ca462..120b11b322e 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -240,7 +240,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, EpochValidatorInfoCreator: &mock.EpochValidatorInfoCreatorStub{}, - ValidatorStatisticsProcessor: &mock.ValidatorStatisticsProcessorStub{}, + ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, EpochSystemSCProcessor: &mock.EpochStartSystemSCStub{}, } diff --git a/node/mock/peerProcessorMock.go b/node/mock/peerProcessorMock.go deleted file mode 100644 index ec5867fea66..00000000000 --- a/node/mock/peerProcessorMock.go +++ /dev/null @@ -1,133 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go/state" -) - -// ValidatorStatisticsProcessorMock - -type ValidatorStatisticsProcessorMock struct { - UpdatePeerStateCalled func(header data.MetaHeaderHandler) ([]byte, error) - RevertPeerStateCalled func(header data.MetaHeaderHandler) error - IsInterfaceNilCalled func() bool - - GetPeerAccountCalled func(address []byte) (state.PeerAccountHandler, error) - RootHashCalled func() ([]byte, error) - ResetValidatorStatisticsAtNewEpochCalled func(vInfos map[uint32][]*state.ValidatorInfo) error - GetValidatorInfoForRootHashCalled func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - ProcessCalled func(validatorInfo data.ShardValidatorInfoHandler) error - CommitCalled func() ([]byte, error) - ProcessRatingsEndOfEpochCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error - PeerAccountToValidatorInfoCalled func(peerAccount state.PeerAccountHandler) *state.ValidatorInfo - SaveNodesCoordinatorUpdatesCalled func(epoch uint32) (bool, error) -} - -// SaveNodesCoordinatorUpdates - -func (vsp *ValidatorStatisticsProcessorMock) SaveNodesCoordinatorUpdates(epoch uint32) (bool, error) { - if vsp.SaveNodesCoordinatorUpdatesCalled != nil { - return vsp.SaveNodesCoordinatorUpdatesCalled(epoch) - } - return false, nil -} - -// PeerAccountToValidatorInfo - -func (vsp *ValidatorStatisticsProcessorMock) PeerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.ValidatorInfo { - if vsp.PeerAccountToValidatorInfoCalled != nil { - return vsp.PeerAccountToValidatorInfoCalled(peerAccount) - } - return nil -} - -// UpdatePeerState - -func (vsp *ValidatorStatisticsProcessorMock) UpdatePeerState(header data.MetaHeaderHandler, _ map[string]data.HeaderHandler) ([]byte, error) { - if vsp.UpdatePeerStateCalled != nil { - return vsp.UpdatePeerStateCalled(header) - } - return nil, nil -} - -// Process - -func (vsp *ValidatorStatisticsProcessorMock) Process(validatorInfo data.ShardValidatorInfoHandler) error { - if vsp.ProcessCalled != nil { - return vsp.ProcessCalled(validatorInfo) - } - - return nil -} - -// Commit - -func (vsp *ValidatorStatisticsProcessorMock) Commit() ([]byte, error) { - if vsp.CommitCalled != nil { - return vsp.CommitCalled() - } - - return nil, nil -} - -// ProcessRatingsEndOfEpoch - -func (vsp *ValidatorStatisticsProcessorMock) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { - if vsp.ProcessRatingsEndOfEpochCalled != nil { - return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) - } - - return nil -} - -// ResetValidatorStatisticsAtNewEpoch - -func (vsp *ValidatorStatisticsProcessorMock) ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error { - if vsp.ResetValidatorStatisticsAtNewEpochCalled != nil { - return vsp.ResetValidatorStatisticsAtNewEpochCalled(vInfos) - } - return nil -} - -// GetValidatorInfoForRootHash - -func (vsp *ValidatorStatisticsProcessorMock) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { - if vsp.GetValidatorInfoForRootHashCalled != nil { - return vsp.GetValidatorInfoForRootHashCalled(rootHash) - } - return nil, nil -} - -// RevertPeerState - -func (vsp *ValidatorStatisticsProcessorMock) RevertPeerState(header data.MetaHeaderHandler) error { - if vsp.RevertPeerStateCalled != nil { - return vsp.RevertPeerStateCalled(header) - } - return nil -} - -// RootHash - -func (vsp *ValidatorStatisticsProcessorMock) RootHash() ([]byte, error) { - if vsp.RootHashCalled != nil { - return vsp.RootHashCalled() - } - return nil, nil -} - -// GetExistingPeerAccount - -func (vsp *ValidatorStatisticsProcessorMock) GetExistingPeerAccount(address []byte) (state.PeerAccountHandler, error) { - if vsp.GetPeerAccountCalled != nil { - return vsp.GetPeerAccountCalled(address) - } - - return nil, nil -} - -// DisplayRatings - -func (vsp *ValidatorStatisticsProcessorMock) DisplayRatings(_ uint32) { -} - -// SetLastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorMock) SetLastFinalizedRootHash(_ []byte) { -} - -// LastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorMock) LastFinalizedRootHash() []byte { - return nil -} - -// IsInterfaceNil - -func (vsp *ValidatorStatisticsProcessorMock) IsInterfaceNil() bool { - return false -} diff --git a/node/mock/validatorStatisticsProcessorStub.go b/node/mock/validatorStatisticsProcessorStub.go deleted file mode 100644 index 0953a2a90a7..00000000000 --- a/node/mock/validatorStatisticsProcessorStub.go +++ /dev/null @@ -1,130 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go/state" -) - -// ValidatorStatisticsProcessorStub - -type ValidatorStatisticsProcessorStub struct { - UpdatePeerStateCalled func(header data.MetaHeaderHandler) ([]byte, error) - RevertPeerStateCalled func(header data.MetaHeaderHandler) error - GetPeerAccountCalled func(address []byte) (state.PeerAccountHandler, error) - RootHashCalled func() ([]byte, error) - ResetValidatorStatisticsAtNewEpochCalled func(vInfos map[uint32][]*state.ValidatorInfo) error - GetValidatorInfoForRootHashCalled func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - ProcessRatingsEndOfEpochCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error - ProcessCalled func(validatorInfo data.ShardValidatorInfoHandler) error - CommitCalled func() ([]byte, error) - PeerAccountToValidatorInfoCalled func(peerAccount state.PeerAccountHandler) *state.ValidatorInfo - SaveNodesCoordinatorUpdatesCalled func(epoch uint32) (bool, error) -} - -// SaveNodesCoordinatorUpdates - -func (vsp *ValidatorStatisticsProcessorStub) SaveNodesCoordinatorUpdates(epoch uint32) (bool, error) { - if vsp.SaveNodesCoordinatorUpdatesCalled != nil { - return vsp.SaveNodesCoordinatorUpdatesCalled(epoch) - } - return false, nil -} - -// PeerAccountToValidatorInfo - -func (vsp *ValidatorStatisticsProcessorStub) PeerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.ValidatorInfo { - if vsp.PeerAccountToValidatorInfoCalled != nil { - return vsp.PeerAccountToValidatorInfoCalled(peerAccount) - } - return nil -} - -// Process - -func (vsp *ValidatorStatisticsProcessorStub) Process(validatorInfo data.ShardValidatorInfoHandler) error { - if vsp.ProcessCalled != nil { - return vsp.ProcessCalled(validatorInfo) - } - - return nil -} - -// Commit - -func (vsp *ValidatorStatisticsProcessorStub) Commit() ([]byte, error) { - if vsp.CommitCalled != nil { - return vsp.CommitCalled() - } - - return nil, nil -} - -// ResetValidatorStatisticsAtNewEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error { - if vsp.ResetValidatorStatisticsAtNewEpochCalled != nil { - return vsp.ResetValidatorStatisticsAtNewEpochCalled(vInfos) - } - return nil -} - -// GetValidatorInfoForRootHash - -func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { - if vsp.GetValidatorInfoForRootHashCalled != nil { - return vsp.GetValidatorInfoForRootHashCalled(rootHash) - } - return nil, nil -} - -// UpdatePeerState - -func (vsp *ValidatorStatisticsProcessorStub) UpdatePeerState(header data.MetaHeaderHandler, _ map[string]data.HeaderHandler) ([]byte, error) { - if vsp.UpdatePeerStateCalled != nil { - return vsp.UpdatePeerStateCalled(header) - } - return nil, nil -} - -// ProcessRatingsEndOfEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { - if vsp.ProcessRatingsEndOfEpochCalled != nil { - return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) - } - return nil -} - -// RevertPeerState - -func (vsp *ValidatorStatisticsProcessorStub) RevertPeerState(header data.MetaHeaderHandler) error { - if vsp.RevertPeerStateCalled != nil { - return vsp.RevertPeerStateCalled(header) - } - return nil -} - -// RootHash - -func (vsp *ValidatorStatisticsProcessorStub) RootHash() ([]byte, error) { - if vsp.RootHashCalled != nil { - return vsp.RootHashCalled() - } - return nil, nil -} - -// SetLastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) SetLastFinalizedRootHash(_ []byte) { -} - -// LastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) LastFinalizedRootHash() []byte { - return nil -} - -// GetExistingPeerAccount - -func (vsp *ValidatorStatisticsProcessorStub) GetExistingPeerAccount(address []byte) (state.PeerAccountHandler, error) { - if vsp.GetPeerAccountCalled != nil { - return vsp.GetPeerAccountCalled(address) - } - - return nil, nil -} - -// DisplayRatings - -func (vsp *ValidatorStatisticsProcessorStub) DisplayRatings(_ uint32) { -} - -// IsInterfaceNil - -func (vsp *ValidatorStatisticsProcessorStub) IsInterfaceNil() bool { - return false -} diff --git a/node/node_test.go b/node/node_test.go index 741ea141cf1..293008e84de 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -50,7 +50,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" trieMock "github.com/ElrondNetwork/elrond-go/testscommon/trie" - txsSenderMock "github.com/ElrondNetwork/elrond-go/testscommon/txsSenderMock" + "github.com/ElrondNetwork/elrond-go/testscommon/txsSenderMock" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/assert" @@ -2443,7 +2443,7 @@ func TestNode_ValidatorStatisticsApi(t *testing.T) { } } - vsp := &mock.ValidatorStatisticsProcessorStub{ + vsp := &testscommon.ValidatorStatisticsProcessorStub{ RootHashCalled: func() (i []byte, err error) { return []byte("hash"), nil }, @@ -3537,7 +3537,7 @@ func getDefaultProcessComponents() *factoryMock.ProcessComponentsMock { BootSore: &mock.BootstrapStorerMock{}, HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, - ValidatorStatistics: &mock.ValidatorStatisticsProcessorMock{}, + ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, ValidatorProvider: &mock.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index f10cf29faa1..39021125352 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -140,7 +140,7 @@ func createMockMetaArguments( EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, EpochValidatorInfoCreator: &mock.EpochValidatorInfoCreatorStub{}, - ValidatorStatisticsProcessor: &mock.ValidatorStatisticsProcessorStub{}, + ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, EpochSystemSCProcessor: &mock.EpochStartSystemSCStub{}, } return arguments @@ -1130,7 +1130,7 @@ func TestMetaProcessor_RevertStateRevertPeerStateFailsShouldErr(t *testing.T) { return nil }, } - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ RevertPeerStateCalled: func(header data.MetaHeaderHandler) error { return expectedErr }, @@ -1159,7 +1159,7 @@ func TestMetaProcessor_RevertStateShouldWork(t *testing.T) { return nil }, } - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ RevertPeerStateCalled: func(header data.MetaHeaderHandler) error { revertePeerStateWasCalled = true return nil @@ -2934,7 +2934,7 @@ func TestMetaProcessor_CreateAndProcessBlockCallsProcessAfterFirstEpoch(t *testi dataComponents.DataPool = dPool dataComponents.BlockChain = blkc calledSaveNodesCoordinator := false - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ SaveNodesCoordinatorUpdatesCalled: func(epoch uint32) (bool, error) { calledSaveNodesCoordinator = true return true, nil @@ -3110,7 +3110,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) arguments.RewardsV2EnableEpoch = 10 - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{} + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{} wasCalled := false arguments.EpochRewardsCreator = &mock.EpochRewardsCreatorStub{ @@ -3221,7 +3221,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldFail(t *testing.T) { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) expectedErr := errors.New("expected error") - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ RootHashCalled: func() ([]byte, error) { return nil, expectedErr }, @@ -3239,7 +3239,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldFail(t *testing.T) { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) expectedErr := errors.New("expected error") - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ GetValidatorInfoForRootHashCalled: func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { return nil, expectedErr }, @@ -3257,7 +3257,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldFail(t *testing.T) { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) expectedErr := errors.New("expected error") - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ ProcessRatingsEndOfEpochCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, epoch uint32) error { return expectedErr }, @@ -3320,7 +3320,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } expectedRootHash := []byte("root hash") - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ RootHashCalled: func() ([]byte, error) { return expectedRootHash, nil }, @@ -3391,7 +3391,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } expectedRootHash := []byte("root hash") - arguments.ValidatorStatisticsProcessor = &mock.ValidatorStatisticsProcessorStub{ + arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ RootHashCalled: func() ([]byte, error) { return expectedRootHash, nil }, diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index d23b3fa282a..742a2ce7ce7 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -19,6 +19,7 @@ import ( "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" "github.com/pkg/errors" "github.com/stretchr/testify/assert" @@ -88,7 +89,7 @@ func TestValidatorsProvider_GetLatestValidatorsSecondHashDoesNotExist(t *testing gotOk := false gotNil := false - vs := &mock.ValidatorStatisticsProcessorStub{ + vs := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() (bytes []byte) { mut.Lock() defer mut.Unlock() @@ -165,7 +166,7 @@ func TestValidatorsProvider_CallsPopulateAndRegister(t *testing.T) { }, } - arg.ValidatorStatistics = &mock.ValidatorStatisticsProcessorStub{ + arg.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ GetValidatorInfoForRootHashCalled: func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { atomic.AddInt32(&numPopulateCacheCalled, 1) return nil, nil @@ -187,7 +188,7 @@ func TestValidatorsProvider_UpdateCache_WithError(t *testing.T) { expectedErr := errors.New("expectedError") arg := createDefaultValidatorsProviderArg() - validatorProc := &mock.ValidatorStatisticsProcessorStub{ + validatorProc := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, @@ -271,7 +272,7 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { }, } arg := createDefaultValidatorsProviderArg() - validatorProc := &mock.ValidatorStatisticsProcessorStub{ + validatorProc := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, @@ -507,7 +508,7 @@ func TestValidatorsProvider_CallsPopulateOnlyAfterTimeout(t *testing.T) { arg := createDefaultValidatorsProviderArg() arg.CacheRefreshIntervalDurationInSec = time.Millisecond * 10 - validatorStatisticsProcessor := &mock.ValidatorStatisticsProcessorStub{ + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, @@ -548,7 +549,7 @@ func TestValidatorsProvider_CallsUpdateCacheOnEpochChange(t *testing.T) { arg.CacheRefreshIntervalDurationInSec = 5 * time.Millisecond pkEligibleInTrie := []byte("pk1") - validatorStatisticsProcessor := &mock.ValidatorStatisticsProcessorStub{ + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, @@ -587,7 +588,7 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin arg.CacheRefreshIntervalDurationInSec = 5 * time.Millisecond pkEligibleInTrie := []byte("pk1") - validatorStatisticsProcessor := &mock.ValidatorStatisticsProcessorStub{ + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, @@ -651,7 +652,7 @@ func createDefaultValidatorsProviderArg() ArgValidatorsProvider { StartEpoch: 1, EpochStartEventNotifier: &mock.EpochStartNotifierStub{}, CacheRefreshIntervalDurationInSec: 1 * time.Millisecond, - ValidatorStatistics: &mock.ValidatorStatisticsProcessorStub{ + ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, diff --git a/process/mock/validatorStatisticsProcessorStub.go b/testscommon/validatorStatisticsProcessorStub.go similarity index 96% rename from process/mock/validatorStatisticsProcessorStub.go rename to testscommon/validatorStatisticsProcessorStub.go index 7cef27444ab..cf5086d9f7c 100644 --- a/process/mock/validatorStatisticsProcessorStub.go +++ b/testscommon/validatorStatisticsProcessorStub.go @@ -1,4 +1,4 @@ -package mock +package testscommon import ( "github.com/ElrondNetwork/elrond-go-core/data" @@ -21,14 +21,6 @@ type ValidatorStatisticsProcessorStub struct { SaveNodesCoordinatorUpdatesCalled func(epoch uint32) (bool, error) } -// SaveNodesCoordinatorUpdates - -func (vsp *ValidatorStatisticsProcessorStub) SaveNodesCoordinatorUpdates(epoch uint32) (bool, error) { - if vsp.SaveNodesCoordinatorUpdatesCalled != nil { - return vsp.SaveNodesCoordinatorUpdatesCalled(epoch) - } - return false, nil -} - // PeerAccountToValidatorInfo - func (vsp *ValidatorStatisticsProcessorStub) PeerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.ValidatorInfo { if vsp.PeerAccountToValidatorInfoCalled != nil { @@ -71,14 +63,6 @@ func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHas return nil, nil } -// ProcessRatingsEndOfEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { - if vsp.ProcessRatingsEndOfEpochCalled != nil { - return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) - } - return nil -} - // UpdatePeerState - func (vsp *ValidatorStatisticsProcessorStub) UpdatePeerState(header data.MetaHeaderHandler, _ map[string]data.HeaderHandler) ([]byte, error) { if vsp.UpdatePeerStateCalled != nil { @@ -87,6 +71,14 @@ func (vsp *ValidatorStatisticsProcessorStub) UpdatePeerState(header data.MetaHea return nil, nil } +// ProcessRatingsEndOfEpoch - +func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { + if vsp.ProcessRatingsEndOfEpochCalled != nil { + return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) + } + return nil +} + // RevertPeerState - func (vsp *ValidatorStatisticsProcessorStub) RevertPeerState(header data.MetaHeaderHandler) error { if vsp.RevertPeerStateCalled != nil { @@ -103,8 +95,20 @@ func (vsp *ValidatorStatisticsProcessorStub) RootHash() ([]byte, error) { return nil, nil } -// GetExistingPeerAccount - -func (vsp *ValidatorStatisticsProcessorStub) GetExistingPeerAccount(address []byte) (state.PeerAccountHandler, error) { +// SetLastFinalizedRootHash - +func (vsp *ValidatorStatisticsProcessorStub) SetLastFinalizedRootHash(_ []byte) { +} + +// LastFinalizedRootHash - +func (vsp *ValidatorStatisticsProcessorStub) LastFinalizedRootHash() []byte { + if vsp.LastFinalizedRootHashCalled != nil { + return vsp.LastFinalizedRootHashCalled() + } + return nil +} + +// GetPeerAccount - +func (vsp *ValidatorStatisticsProcessorStub) GetPeerAccount(address []byte) (state.PeerAccountHandler, error) { if vsp.GetPeerAccountCalled != nil { return vsp.GetPeerAccountCalled(address) } @@ -116,19 +120,15 @@ func (vsp *ValidatorStatisticsProcessorStub) GetExistingPeerAccount(address []by func (vsp *ValidatorStatisticsProcessorStub) DisplayRatings(_ uint32) { } -// SetLastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) SetLastFinalizedRootHash(_ []byte) { -} - -// LastFinalizedRootHash - -func (vsp *ValidatorStatisticsProcessorStub) LastFinalizedRootHash() []byte { - if vsp.LastFinalizedRootHashCalled != nil { - return vsp.LastFinalizedRootHashCalled() +// SaveNodesCoordinatorUpdates - +func (vsp *ValidatorStatisticsProcessorStub) SaveNodesCoordinatorUpdates(epoch uint32) (bool, error) { + if vsp.SaveNodesCoordinatorUpdatesCalled != nil { + return vsp.SaveNodesCoordinatorUpdatesCalled(epoch) } - return nil + return false, nil } // IsInterfaceNil - func (vsp *ValidatorStatisticsProcessorStub) IsInterfaceNil() bool { - return false + return vsp == nil } From 696e7fc19d135631da4995f97d93f2bc5b550814 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 12:25:36 +0200 Subject: [PATCH 125/958] FEAT: Remove all duplicated epochStartSystemSCStub.go --- integrationTests/testSyncNode.go | 2 +- process/block/metablock_test.go | 12 ++--- process/mock/epochStartSystemSCStub.go | 50 ------------------- .../epochStartSystemSCStub.go | 2 +- 4 files changed, 8 insertions(+), 58 deletions(-) delete mode 100644 process/mock/epochStartSystemSCStub.go rename {integrationTests/mock => testscommon}/epochStartSystemSCStub.go (98%) diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index af1518ca462..4fd43c9804c 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -241,7 +241,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, EpochValidatorInfoCreator: &mock.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &mock.ValidatorStatisticsProcessorStub{}, - EpochSystemSCProcessor: &mock.EpochStartSystemSCStub{}, + EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, } tpn.BlockProcessor, err = block.NewMetaProcessor(arguments) diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index f10cf29faa1..ced19cdd889 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -141,7 +141,7 @@ func createMockMetaArguments( EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, EpochValidatorInfoCreator: &mock.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &mock.ValidatorStatisticsProcessorStub{}, - EpochSystemSCProcessor: &mock.EpochStartSystemSCStub{}, + EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, } return arguments } @@ -2942,7 +2942,7 @@ func TestMetaProcessor_CreateAndProcessBlockCallsProcessAfterFirstEpoch(t *testi } toggleCalled := false - arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ + arguments.EpochSystemSCProcessor = &testscommon.EpochStartSystemSCStub{ ToggleUnStakeUnBondCalled: func(value bool) error { toggleCalled = true assert.Equal(t, value, true) @@ -3091,7 +3091,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { }, } - arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ + arguments.EpochSystemSCProcessor = &testscommon.EpochStartSystemSCStub{ ProcessSystemSmartContractCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { assert.Equal(t, headerMeta, header) wasCalled = true @@ -3122,7 +3122,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { }, } - arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ + arguments.EpochSystemSCProcessor = &testscommon.EpochStartSystemSCStub{ ProcessSystemSmartContractCalled: func(validatorInfos state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { assert.Equal(t, headerMeta, header) assert.True(t, wasCalled) @@ -3332,7 +3332,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } wasCalled := false - arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ + arguments.EpochSystemSCProcessor = &testscommon.EpochStartSystemSCStub{ ProcessSystemSmartContractCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { wasCalled = true assert.Equal(t, mb, header) @@ -3424,7 +3424,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { }, } - arguments.EpochSystemSCProcessor = &mock.EpochStartSystemSCStub{ + arguments.EpochSystemSCProcessor = &testscommon.EpochStartSystemSCStub{ ProcessSystemSmartContractCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { assert.True(t, wasCalled) assert.Equal(t, mb, header) diff --git a/process/mock/epochStartSystemSCStub.go b/process/mock/epochStartSystemSCStub.go deleted file mode 100644 index 27c500495dd..00000000000 --- a/process/mock/epochStartSystemSCStub.go +++ /dev/null @@ -1,50 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/state" -) - -// EpochStartSystemSCStub - -type EpochStartSystemSCStub struct { - ProcessSystemSmartContractCalled func(validatorsInfo state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error - ProcessDelegationRewardsCalled func(miniBlocks block.MiniBlockSlice, txCache epochStart.TransactionCacher) error - ToggleUnStakeUnBondCalled func(value bool) error -} - -// ToggleUnStakeUnBond - -func (e *EpochStartSystemSCStub) ToggleUnStakeUnBond(value bool) error { - if e.ToggleUnStakeUnBondCalled != nil { - return e.ToggleUnStakeUnBondCalled(value) - } - return nil -} - -// ProcessSystemSmartContract - -func (e *EpochStartSystemSCStub) ProcessSystemSmartContract( - validatorsInfo state.ShardValidatorsInfoMapHandler, - header data.HeaderHandler, -) error { - if e.ProcessSystemSmartContractCalled != nil { - return e.ProcessSystemSmartContractCalled(validatorsInfo, header) - } - return nil -} - -// ProcessDelegationRewards - -func (e *EpochStartSystemSCStub) ProcessDelegationRewards( - miniBlocks block.MiniBlockSlice, - txCache epochStart.TransactionCacher, -) error { - if e.ProcessDelegationRewardsCalled != nil { - return e.ProcessDelegationRewardsCalled(miniBlocks, txCache) - } - return nil -} - -// IsInterfaceNil - -func (e *EpochStartSystemSCStub) IsInterfaceNil() bool { - return e == nil -} diff --git a/integrationTests/mock/epochStartSystemSCStub.go b/testscommon/epochStartSystemSCStub.go similarity index 98% rename from integrationTests/mock/epochStartSystemSCStub.go rename to testscommon/epochStartSystemSCStub.go index 27c500495dd..91b816dc1e7 100644 --- a/integrationTests/mock/epochStartSystemSCStub.go +++ b/testscommon/epochStartSystemSCStub.go @@ -1,4 +1,4 @@ -package mock +package testscommon import ( "github.com/ElrondNetwork/elrond-go-core/data" From df9c095547c35d79d5d4393b5d303af6a51dc3c4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 12:35:10 +0200 Subject: [PATCH 126/958] FEAT: Remove unused code --- heartbeat/interface.go | 7 ----- heartbeat/mock/validatorStatisticsStub.go | 32 ----------------------- 2 files changed, 39 deletions(-) delete mode 100644 heartbeat/mock/validatorStatisticsStub.go diff --git a/heartbeat/interface.go b/heartbeat/interface.go index 63ab5b2fb9e..c6a612eb175 100644 --- a/heartbeat/interface.go +++ b/heartbeat/interface.go @@ -100,13 +100,6 @@ type PeerBlackListHandler interface { IsInterfaceNil() bool } -// ValidatorStatisticsProcessor is the interface for consensus participation statistics -type ValidatorStatisticsProcessor interface { - RootHash() ([]byte, error) - GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - IsInterfaceNil() bool -} - // CurrentBlockProvider can provide the current block that the node was able to commit type CurrentBlockProvider interface { GetCurrentBlockHeader() data.HeaderHandler diff --git a/heartbeat/mock/validatorStatisticsStub.go b/heartbeat/mock/validatorStatisticsStub.go deleted file mode 100644 index da8560cd85a..00000000000 --- a/heartbeat/mock/validatorStatisticsStub.go +++ /dev/null @@ -1,32 +0,0 @@ -package mock - -import "github.com/ElrondNetwork/elrond-go/state" - -// ValidatorStatisticsStub - -type ValidatorStatisticsStub struct { - RootHashCalled func() ([]byte, error) - GetValidatorInfoForRootHashCalled func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) -} - -// RootHash - -func (vss *ValidatorStatisticsStub) RootHash() ([]byte, error) { - if vss.RootHashCalled != nil { - return vss.RootHashCalled() - } - - return make([]byte, 0), nil -} - -// GetValidatorInfoForRootHash - -func (vss *ValidatorStatisticsStub) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { - if vss.GetValidatorInfoForRootHashCalled != nil { - return vss.GetValidatorInfoForRootHashCalled(rootHash) - } - - return make(map[uint32][]*state.ValidatorInfo), nil -} - -// IsInterfaceNil - -func (vss *ValidatorStatisticsStub) IsInterfaceNil() bool { - return vss == nil -} From b840374c62a3b6b71ece196dfba71d2f28cf509e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 12:38:43 +0200 Subject: [PATCH 127/958] FEAT: Remove more unused code --- epochStart/interface.go | 8 ---- .../mock/validatorStatisticsProcessorStub.go | 38 ------------------- 2 files changed, 46 deletions(-) delete mode 100644 epochStart/mock/validatorStatisticsProcessorStub.go diff --git a/epochStart/interface.go b/epochStart/interface.go index fa2dcaba7dd..44387393337 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -83,14 +83,6 @@ type Notifier interface { IsInterfaceNil() bool } -// ValidatorStatisticsProcessorHandler defines the actions for processing validator statistics -// needed in the epoch events -type ValidatorStatisticsProcessorHandler interface { - Process(info data.ShardValidatorInfoHandler) error - Commit() ([]byte, error) - IsInterfaceNil() bool -} - // ValidatorInfoCreator defines the methods to create a validator info type ValidatorInfoCreator interface { PeerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.ValidatorInfo diff --git a/epochStart/mock/validatorStatisticsProcessorStub.go b/epochStart/mock/validatorStatisticsProcessorStub.go deleted file mode 100644 index e8f9ee75846..00000000000 --- a/epochStart/mock/validatorStatisticsProcessorStub.go +++ /dev/null @@ -1,38 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" -) - -// ValidatorStatisticsProcessorStub - -type ValidatorStatisticsProcessorStub struct { - ProcessCalled func(validatorInfo data.ShardValidatorInfoHandler) error - CommitCalled func() ([]byte, error) - IsInterfaceNilCalled func() bool -} - -// Process - -func (pm *ValidatorStatisticsProcessorStub) Process(validatorInfo data.ShardValidatorInfoHandler) error { - if pm.ProcessCalled != nil { - return pm.ProcessCalled(validatorInfo) - } - - return nil -} - -// Commit - -func (pm *ValidatorStatisticsProcessorStub) Commit() ([]byte, error) { - if pm.CommitCalled != nil { - return pm.CommitCalled() - } - - return nil, nil -} - -// IsInterfaceNil - -func (pm *ValidatorStatisticsProcessorStub) IsInterfaceNil() bool { - if pm.IsInterfaceNilCalled != nil { - return pm.IsInterfaceNilCalled() - } - return false -} From df001ea29a5c8a19081dfe16104249c4df091ce0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 18 Mar 2022 17:54:04 +0200 Subject: [PATCH 128/958] FEAT: Refactor code to use new interface --- factory/heartbeatComponents.go | 6 +- process/block/metablock.go | 28 +-- process/block/metablock_test.go | 32 ++-- process/block/metrics.go | 6 +- process/interface.go | 10 +- process/peer/process.go | 95 +++++----- process/peer/process_test.go | 130 +++++++------- process/peer/validatorsProvider.go | 47 ++--- process/peer/validatorsProvider_test.go | 170 ++++++++---------- state/interface.go | 2 + .../validatorStatisticsProcessorStub.go | 14 +- 11 files changed, 258 insertions(+), 282 deletions(-) diff --git a/factory/heartbeatComponents.go b/factory/heartbeatComponents.go index e1f22d8f0bc..41c1d459652 100644 --- a/factory/heartbeatComponents.go +++ b/factory/heartbeatComponents.go @@ -184,9 +184,9 @@ func (hcf *heartbeatComponentsFactory) Create() (*heartbeatComponents, error) { allValidators, _, _ := hcf.getLatestValidators() pubKeysMap := make(map[uint32][]string) - for shardID, valsInShard := range allValidators { + for shardID, valsInShard := range allValidators.GetShardValidatorsInfoMap() { for _, val := range valsInShard { - pubKeysMap[shardID] = append(pubKeysMap[shardID], string(val.PublicKey)) + pubKeysMap[shardID] = append(pubKeysMap[shardID], string(val.GetPublicKey())) } } @@ -228,7 +228,7 @@ func (hcf *heartbeatComponentsFactory) Create() (*heartbeatComponents, error) { return hbc, nil } -func (hcf *heartbeatComponentsFactory) getLatestValidators() (map[uint32][]*state.ValidatorInfo, map[string]*state.ValidatorApiResponse, error) { +func (hcf *heartbeatComponentsFactory) getLatestValidators() (state.ShardValidatorsInfoMapHandler, map[string]*state.ValidatorApiResponse, error) { latestHash, err := hcf.processComponents.ValidatorsStatistics().RootHash() if err != nil { return nil, nil, err diff --git a/process/block/metablock.go b/process/block/metablock.go index 0fa698a35dc..e61695bc7d9 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -417,23 +417,25 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } + oldValidatorsInfoMap := make(map[uint32][]*state.ValidatorInfo) + state.Replace(oldValidatorsInfoMap, allValidatorsInfo.GetValInfoPointerMap()) if mp.isRewardsV2Enabled(header) { - err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, header) + err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, header) if err != nil { return err } - err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, allValidatorsInfo, computedEconomics) + err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, oldValidatorsInfoMap, computedEconomics) if err != nil { return err } } else { - err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, allValidatorsInfo, computedEconomics) + err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, oldValidatorsInfoMap, computedEconomics) if err != nil { return err } - err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, header) + err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, header) if err != nil { return err } @@ -444,12 +446,12 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - err = mp.validatorInfoCreator.VerifyValidatorInfoMiniBlocks(body.MiniBlocks, allValidatorsInfo) + err = mp.validatorInfoCreator.VerifyValidatorInfoMiniBlocks(body.MiniBlocks, oldValidatorsInfoMap) if err != nil { return err } - err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(allValidatorsInfo) + err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(state.CreateShardValidatorsMap(oldValidatorsInfoMap)) if err != nil { return err } @@ -885,23 +887,25 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. } var rewardMiniBlocks block.MiniBlockSlice + oldValidatorsInfoMap := make(map[uint32][]*state.ValidatorInfo) + state.Replace(oldValidatorsInfoMap, allValidatorsInfo.GetValInfoPointerMap()) if mp.isRewardsV2Enabled(metaBlock) { - err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, metaBlock) + err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, metaBlock) if err != nil { return nil, err } - rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, allValidatorsInfo, &metaBlock.EpochStart.Economics) + rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, oldValidatorsInfoMap, &metaBlock.EpochStart.Economics) if err != nil { return nil, err } } else { - rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, allValidatorsInfo, &metaBlock.EpochStart.Economics) + rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, oldValidatorsInfoMap, &metaBlock.EpochStart.Economics) if err != nil { return nil, err } - err = mp.processSystemSCsWithNewValidatorsInfo(allValidatorsInfo, metaBlock) + err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, metaBlock) if err != nil { return nil, err } @@ -914,12 +918,12 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - validatorMiniBlocks, err := mp.validatorInfoCreator.CreateValidatorInfoMiniBlocks(allValidatorsInfo) + validatorMiniBlocks, err := mp.validatorInfoCreator.CreateValidatorInfoMiniBlocks(oldValidatorsInfoMap) if err != nil { return nil, err } - err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(allValidatorsInfo) + err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(state.CreateShardValidatorsMap(oldValidatorsInfoMap)) if err != nil { return nil, err } diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 51285277077..1d543340837 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3240,7 +3240,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldFail(t *testing.T) { expectedErr := errors.New("expected error") arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ - GetValidatorInfoForRootHashCalled: func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { return nil, expectedErr }, } @@ -3258,7 +3258,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldFail(t *testing.T) { expectedErr := errors.New("expected error") arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{ - ProcessRatingsEndOfEpochCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo, epoch uint32) error { + ProcessRatingsEndOfEpochCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler, epoch uint32) error { return expectedErr }, } @@ -3276,15 +3276,13 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() - expectedValidatorsInfo := map[uint32][]*state.ValidatorInfo{ - 0: { - &state.ValidatorInfo{ - ShardId: 1, - RewardAddress: []byte("rewardAddr1"), - AccumulatedFees: big.NewInt(10), - }, - }, - } + expectedValidatorsInfo := state.NewShardValidatorsInfoMap(1) + _ = expectedValidatorsInfo.Add( + &state.ValidatorInfo{ + ShardId: 1, + RewardAddress: []byte("rewardAddr1"), + AccumulatedFees: big.NewInt(10), + }) rewardMiniBlocks := block.MiniBlockSlice{ &block.MiniBlock{ @@ -3324,7 +3322,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { RootHashCalled: func() ([]byte, error) { return expectedRootHash, nil }, - GetValidatorInfoForRootHashCalled: func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { assert.Equal(t, expectedRootHash, rootHash) return expectedValidatorsInfo, nil @@ -3345,7 +3343,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { - assert.Equal(t, expectedValidatorsInfo, validatorsInfo) + assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) assert.Equal(t, mb, metaBlock) assert.True(t, wasCalled) return rewardMiniBlocks, nil @@ -3357,7 +3355,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { arguments.EpochValidatorInfoCreator = &mock.EpochValidatorInfoCreatorStub{ CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { - assert.Equal(t, expectedValidatorsInfo, validatorsInfo) + assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) return validatorInfoMiniBlocks, nil }, } @@ -3395,7 +3393,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { RootHashCalled: func() ([]byte, error) { return expectedRootHash, nil }, - GetValidatorInfoForRootHashCalled: func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { assert.Equal(t, expectedRootHash, rootHash) return expectedValidatorsInfo, nil }, @@ -3408,7 +3406,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { wasCalled = true - assert.Equal(t, expectedValidatorsInfo, validatorsInfo) + assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) assert.Equal(t, mb, metaBlock) return rewardMiniBlocks, nil }, @@ -3419,7 +3417,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { arguments.EpochValidatorInfoCreator = &mock.EpochValidatorInfoCreatorStub{ CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { - assert.Equal(t, expectedValidatorsInfo, validatorsInfo) + assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) return validatorInfoMiniBlocks, nil }, } diff --git a/process/block/metrics.go b/process/block/metrics.go index 9bca60c2912..a47c415ce5e 100644 --- a/process/block/metrics.go +++ b/process/block/metrics.go @@ -269,12 +269,12 @@ func indexValidatorsRating( } shardValidatorsRating := make(map[string][]*indexer.ValidatorRatingInfo) - for shardID, validatorInfosInShard := range validators { + for shardID, validatorInfosInShard := range validators.GetShardValidatorsInfoMap() { validatorsInfos := make([]*indexer.ValidatorRatingInfo, 0) for _, validatorInfo := range validatorInfosInShard { validatorsInfos = append(validatorsInfos, &indexer.ValidatorRatingInfo{ - PublicKey: hex.EncodeToString(validatorInfo.PublicKey), - Rating: float32(validatorInfo.Rating) * 100 / 10000000, + PublicKey: hex.EncodeToString(validatorInfo.GetPublicKey()), + Rating: float32(validatorInfo.GetRating()) * 100 / 10000000, }) } diff --git a/process/interface.go b/process/interface.go index 33ce5376e5a..2f4c8192d95 100644 --- a/process/interface.go +++ b/process/interface.go @@ -151,7 +151,7 @@ type TransactionCoordinator interface { AddIntermediateTransactions(mapSCRs map[block.Type][]data.TransactionHandler) error GetAllIntermediateTxs() map[block.Type]map[string]data.TransactionHandler AddTxsFromMiniBlocks(miniBlocks block.MiniBlockSlice) - AddTransactions (txHandlers []data.TransactionHandler, blockType block.Type) + AddTransactions(txHandlers []data.TransactionHandler, blockType block.Type) IsInterfaceNil() bool } @@ -219,7 +219,7 @@ type PreProcessor interface { GetAllCurrentUsedTxs() map[string]data.TransactionHandler AddTxsFromMiniBlocks(miniBlocks block.MiniBlockSlice) - AddTransactions (txHandlers []data.TransactionHandler) + AddTransactions(txHandlers []data.TransactionHandler) IsInterfaceNil() bool } @@ -257,9 +257,9 @@ type ValidatorStatisticsProcessor interface { Process(shardValidatorInfo data.ShardValidatorInfoHandler) error IsInterfaceNil() bool RootHash() ([]byte, error) - ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error - GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error + ResetValidatorStatisticsAtNewEpoch(vInfos state.ShardValidatorsInfoMapHandler) error + GetValidatorInfoForRootHash(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) + ProcessRatingsEndOfEpoch(validatorInfos state.ShardValidatorsInfoMapHandler, epoch uint32) error Commit() ([]byte, error) DisplayRatings(epoch uint32) SetLastFinalizedRootHash([]byte) diff --git a/process/peer/process.go b/process/peer/process.go index 32c7d10ea12..32f4e1e9be0 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -445,13 +445,8 @@ func (vs *validatorStatistics) RootHash() ([]byte, error) { func (vs *validatorStatistics) getValidatorDataFromLeaves( leavesChannel chan core.KeyValueHolder, -) (map[uint32][]*state.ValidatorInfo, error) { - - validators := make(map[uint32][]*state.ValidatorInfo, vs.shardCoordinator.NumberOfShards()+1) - for i := uint32(0); i < vs.shardCoordinator.NumberOfShards(); i++ { - validators[i] = make([]*state.ValidatorInfo, 0) - } - validators[core.MetachainShardId] = make([]*state.ValidatorInfo, 0) +) (state.ShardValidatorsInfoMapHandler, error) { + validators := state.NewShardValidatorsInfoMap(vs.shardCoordinator.NumberOfShards() + 1) for pa := range leavesChannel { peerAccount, err := vs.unmarshalPeer(pa.Value()) @@ -459,9 +454,11 @@ func (vs *validatorStatistics) getValidatorDataFromLeaves( return nil, err } - currentShardId := peerAccount.GetShardId() validatorInfoData := vs.PeerAccountToValidatorInfo(peerAccount) - validators[currentShardId] = append(validators[currentShardId], validatorInfoData) + err = validators.Add(validatorInfoData) + if err != nil { + return nil, err + } } return validators, nil @@ -564,7 +561,7 @@ func (vs *validatorStatistics) unmarshalPeer(pa []byte) (state.PeerAccountHandle } // GetValidatorInfoForRootHash returns all the peer accounts from the trie with the given rootHash -func (vs *validatorStatistics) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { +func (vs *validatorStatistics) GetValidatorInfoForRootHash(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { sw := core.NewStopWatch() sw.Start("GetValidatorInfoForRootHash") defer func() { @@ -587,10 +584,10 @@ func (vs *validatorStatistics) GetValidatorInfoForRootHash(rootHash []byte) (map // ProcessRatingsEndOfEpoch makes end of epoch process on the rating func (vs *validatorStatistics) ProcessRatingsEndOfEpoch( - validatorInfos map[uint32][]*state.ValidatorInfo, + validatorInfos state.ShardValidatorsInfoMapHandler, epoch uint32, ) error { - if len(validatorInfos) == 0 { + if validatorInfos == nil || len(validatorInfos.GetAllValidatorsInfo()) == 0 { return process.ErrNilValidatorInfos } @@ -599,14 +596,14 @@ func (vs *validatorStatistics) ProcessRatingsEndOfEpoch( } signedThreshold := vs.rater.GetSignedBlocksThreshold() - for shardId, validators := range validatorInfos { + for shardId, validators := range validatorInfos.GetShardValidatorsInfoMap() { for _, validator := range validators { if !vs.flagStakingV2Enabled.IsSet() { - if validator.List != string(common.EligibleList) { + if validator.GetList() != string(common.EligibleList) { continue } } else { - if validator.List != string(common.EligibleList) && !validatorInfo.WasLeavingEligibleInCurrentEpoch(validator) { + if validator.GetList() != string(common.EligibleList) && !validatorInfo.WasLeavingEligibleInCurrentEpoch(validator) { continue } } @@ -622,7 +619,7 @@ func (vs *validatorStatistics) ProcessRatingsEndOfEpoch( } func (vs *validatorStatistics) verifySignaturesBelowSignedThreshold( - validator *state.ValidatorInfo, + validator state.ValidatorInfoHandler, signedThreshold float32, shardId uint32, epoch uint32, @@ -631,19 +628,19 @@ func (vs *validatorStatistics) verifySignaturesBelowSignedThreshold( return nil } - validatorOccurrences := core.MaxUint32(1, validator.ValidatorSuccess+validator.ValidatorFailure+validator.ValidatorIgnoredSignatures) - computedThreshold := float32(validator.ValidatorSuccess) / float32(validatorOccurrences) + validatorOccurrences := core.MaxUint32(1, validator.GetValidatorSuccess()+validator.GetValidatorFailure()+validator.GetValidatorIgnoredSignatures()) + computedThreshold := float32(validator.GetValidatorSuccess()) / float32(validatorOccurrences) if computedThreshold <= signedThreshold { increasedRatingTimes := uint32(0) if epoch < vs.belowSignedThresholdEnableEpoch { - increasedRatingTimes = validator.ValidatorFailure + increasedRatingTimes = validator.GetValidatorFailure() } else { - increasedRatingTimes = validator.ValidatorSuccess + validator.ValidatorIgnoredSignatures + increasedRatingTimes = validator.GetValidatorSuccess() + validator.GetValidatorIgnoredSignatures() } - newTempRating := vs.rater.RevertIncreaseValidator(shardId, validator.TempRating, increasedRatingTimes) - pa, err := vs.loadPeerAccount(validator.PublicKey) + newTempRating := vs.rater.RevertIncreaseValidator(shardId, validator.GetTempRating(), increasedRatingTimes) + pa, err := vs.loadPeerAccount(validator.GetPublicKey()) if err != nil { return err } @@ -656,23 +653,23 @@ func (vs *validatorStatistics) verifySignaturesBelowSignedThreshold( } log.Debug("below signed blocks threshold", - "pk", validator.PublicKey, + "pk", validator.GetPublicKey(), "signed %", computedThreshold, - "validatorSuccess", validator.ValidatorSuccess, - "validatorFailure", validator.ValidatorFailure, - "validatorIgnored", validator.ValidatorIgnoredSignatures, + "validatorSuccess", validator.GetValidatorSuccess(), + "validatorFailure", validator.GetValidatorFailure(), + "validatorIgnored", validator.GetValidatorIgnoredSignatures(), "new tempRating", newTempRating, - "old tempRating", validator.TempRating, + "old tempRating", validator.GetTempRating(), ) - validator.TempRating = newTempRating + validator.SetTempRating(newTempRating) } return nil } // ResetValidatorStatisticsAtNewEpoch resets the validator info at the start of a new epoch -func (vs *validatorStatistics) ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error { +func (vs *validatorStatistics) ResetValidatorStatisticsAtNewEpoch(vInfos state.ShardValidatorsInfoMapHandler) error { sw := core.NewStopWatch() sw.Start("ResetValidatorStatisticsAtNewEpoch") defer func() { @@ -680,24 +677,22 @@ func (vs *validatorStatistics) ResetValidatorStatisticsAtNewEpoch(vInfos map[uin log.Debug("ResetValidatorStatisticsAtNewEpoch", sw.GetMeasurements()...) }() - for _, validators := range vInfos { - for _, validator := range validators { - account, err := vs.peerAdapter.LoadAccount(validator.GetPublicKey()) - if err != nil { - return err - } + for _, validator := range vInfos.GetAllValidatorsInfo() { + account, err := vs.peerAdapter.LoadAccount(validator.GetPublicKey()) + if err != nil { + return err + } - peerAccount, ok := account.(state.PeerAccountHandler) - if !ok { - return process.ErrWrongTypeAssertion - } - peerAccount.ResetAtNewEpoch() - vs.setToJailedIfNeeded(peerAccount, validator) + peerAccount, ok := account.(state.PeerAccountHandler) + if !ok { + return process.ErrWrongTypeAssertion + } + peerAccount.ResetAtNewEpoch() + vs.setToJailedIfNeeded(peerAccount, validator) - err = vs.peerAdapter.SaveAccount(peerAccount) - if err != nil { - return err - } + err = vs.peerAdapter.SaveAccount(peerAccount) + if err != nil { + return err } } @@ -706,23 +701,23 @@ func (vs *validatorStatistics) ResetValidatorStatisticsAtNewEpoch(vInfos map[uin func (vs *validatorStatistics) setToJailedIfNeeded( peerAccount state.PeerAccountHandler, - validator *state.ValidatorInfo, + validator state.ValidatorInfoHandler, ) { if !vs.flagJailedEnabled.IsSet() { return } - if validator.List == string(common.WaitingList) || validator.List == string(common.EligibleList) { + if validator.GetList() == string(common.WaitingList) || validator.GetList() == string(common.EligibleList) { return } - if validator.List == string(common.JailedList) && peerAccount.GetList() != string(common.JailedList) { - peerAccount.SetListAndIndex(validator.ShardId, string(common.JailedList), validator.Index) + if validator.GetList() == string(common.JailedList) && peerAccount.GetList() != string(common.JailedList) { + peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex()) return } if vs.isValidatorWithLowRating(peerAccount) { - peerAccount.SetListAndIndex(validator.ShardId, string(common.JailedList), validator.Index) + peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex()) } } diff --git a/process/peer/process_test.go b/process/peer/process_test.go index e1fb128e6a4..342f593f350 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2032,9 +2032,9 @@ func TestValidatorStatistics_Process(t *testing.T) { validatorStatistics, _ := peer.NewValidatorStatisticsProcessor(arguments) validatorInfos, _ := validatorStatistics.GetValidatorInfoForRootHash(hash) - vi0 := validatorInfos[0][0] + vi0 := validatorInfos.GetShardValidatorsInfoMap()[0][0] newTempRating := uint32(25) - vi0.TempRating = newTempRating + vi0.SetTempRating(newTempRating) assert.NotEqual(t, newTempRating, pa0.GetRating()) @@ -2078,10 +2078,10 @@ func TestValidatorStatistics_GetValidatorInfoForRootHash(t *testing.T) { validatorInfos, err := validatorStatistics.GetValidatorInfoForRootHash(hash) assert.NotNil(t, validatorInfos) assert.Nil(t, err) - assert.Equal(t, uint32(0), validatorInfos[0][0].ShardId) - compare(t, pa0, validatorInfos[0][0]) - assert.Equal(t, core.MetachainShardId, validatorInfos[core.MetachainShardId][0].ShardId) - compare(t, paMeta, validatorInfos[core.MetachainShardId][0]) + assert.Equal(t, uint32(0), validatorInfos.GetShardValidatorsInfoMap()[0][0].GetShardId()) + compare(t, pa0, validatorInfos.GetShardValidatorsInfoMap()[0][0]) + assert.Equal(t, core.MetachainShardId, validatorInfos.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetShardId()) + compare(t, paMeta, validatorInfos.GetShardValidatorsInfoMap()[core.MetachainShardId][0]) } func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNilMapShouldErr(t *testing.T) { @@ -2091,7 +2091,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNilMapShouldErr( err := validatorStatistics.ProcessRatingsEndOfEpoch(nil, 1) assert.Equal(t, process.ErrNilValidatorInfos, err) - vi := make(map[uint32][]*state.ValidatorInfo) + vi := state.NewShardValidatorsInfoMap(1) err = validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Equal(t, process.ErrNilValidatorInfos, err) } @@ -2109,9 +2109,8 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNoValidatorFailu tempRating1 := uint32(75) tempRating2 := uint32(80) - vi := make(map[uint32][]*state.ValidatorInfo) - vi[core.MetachainShardId] = make([]*state.ValidatorInfo, 1) - vi[core.MetachainShardId][0] = &state.ValidatorInfo{ + vi := state.NewShardValidatorsInfoMap(2) + _ = vi.Add(&state.ValidatorInfo{ PublicKey: nil, ShardId: core.MetachainShardId, List: "", @@ -2125,12 +2124,10 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNoValidatorFailu ValidatorFailure: 0, NumSelectedInSuccessBlocks: 20, AccumulatedFees: nil, - } - - vi[0] = make([]*state.ValidatorInfo, 1) - vi[0][0] = &state.ValidatorInfo{ + }) + _ = vi.Add(&state.ValidatorInfo{ PublicKey: nil, - ShardId: core.MetachainShardId, + ShardId: 0, List: "", Index: 0, TempRating: tempRating2, @@ -2142,12 +2139,12 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNoValidatorFailu ValidatorFailure: 0, NumSelectedInSuccessBlocks: 20, AccumulatedFees: nil, - } + }) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Nil(t, err) - assert.Equal(t, tempRating1, vi[core.MetachainShardId][0].TempRating) - assert.Equal(t, tempRating2, vi[0][0].TempRating) + assert.Equal(t, tempRating1, vi.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetTempRating()) + assert.Equal(t, tempRating2, vi.GetShardValidatorsInfoMap()[0][0].GetTempRating()) } func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithSmallValidatorFailureShouldWork(t *testing.T) { @@ -2174,18 +2171,16 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithSmallValidatorFa validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := make(map[uint32][]*state.ValidatorInfo) - vi[core.MetachainShardId] = make([]*state.ValidatorInfo, 1) - vi[core.MetachainShardId][0] = createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) - vi[0] = make([]*state.ValidatorInfo, 1) - vi[0][0] = createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) + vi := state.NewShardValidatorsInfoMap(2) + _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) + _ = vi.Add(createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2)) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Nil(t, err) expectedTempRating1 := tempRating1 - uint32(rater.MetaIncreaseValidator)*(validatorSuccess1+validatorIgnored1) - assert.Equal(t, expectedTempRating1, vi[core.MetachainShardId][0].TempRating) + assert.Equal(t, expectedTempRating1, vi.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetTempRating()) expectedTempRating2 := tempRating2 - uint32(rater.IncreaseValidator)*(validatorSuccess2+validatorIgnored2) - assert.Equal(t, expectedTempRating2, vi[0][0].TempRating) + assert.Equal(t, expectedTempRating2, vi.GetShardValidatorsInfoMap()[0][0].GetTempRating()) } func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochComputesJustEligible(t *testing.T) { @@ -2213,20 +2208,19 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochComputesJustEligible validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := make(map[uint32][]*state.ValidatorInfo) - vi[core.MetachainShardId] = make([]*state.ValidatorInfo, 1) - vi[core.MetachainShardId][0] = createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) + vi := state.NewShardValidatorsInfoMap(2) + _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) - vi[0] = make([]*state.ValidatorInfo, 1) - vi[0][0] = createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) - vi[0][0].List = string(common.WaitingList) + validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) + validatorWaiting.SetList(string(common.WaitingList)) + _ = vi.Add(validatorWaiting) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Nil(t, err) expectedTempRating1 := tempRating1 - uint32(rater.MetaIncreaseValidator)*(validatorSuccess1+validatorIgnored1) - assert.Equal(t, expectedTempRating1, vi[core.MetachainShardId][0].TempRating) + assert.Equal(t, expectedTempRating1, vi.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetTempRating()) - assert.Equal(t, tempRating2, vi[0][0].TempRating) + assert.Equal(t, tempRating2, vi.GetShardValidatorsInfoMap()[0][0].GetTempRating()) } func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochV2ComputesEligibleLeaving(t *testing.T) { @@ -2255,21 +2249,21 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochV2ComputesEligibleLe validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := make(map[uint32][]*state.ValidatorInfo) - vi[core.MetachainShardId] = make([]*state.ValidatorInfo, 1) - vi[core.MetachainShardId][0] = createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) - vi[core.MetachainShardId][0].List = string(common.LeavingList) + vi := state.NewShardValidatorsInfoMap(2) + validatorLeaving := createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) + validatorLeaving.SetList(string(common.LeavingList)) + _ = vi.Add(validatorLeaving) - vi[0] = make([]*state.ValidatorInfo, 1) - vi[0][0] = createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) - vi[0][0].List = string(common.WaitingList) + validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) + validatorWaiting.SetList(string(common.WaitingList)) + _ = vi.Add(validatorWaiting) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Nil(t, err) expectedTempRating1 := tempRating1 - uint32(rater.MetaIncreaseValidator)*(validatorSuccess1+validatorIgnored1) - assert.Equal(t, expectedTempRating1, vi[core.MetachainShardId][0].TempRating) + assert.Equal(t, expectedTempRating1, vi.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetTempRating()) - assert.Equal(t, tempRating2, vi[0][0].TempRating) + assert.Equal(t, tempRating2, vi.GetShardValidatorsInfoMap()[0][0].GetTempRating()) } func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithLargeValidatorFailureBelowMinRatingShouldWork(t *testing.T) { @@ -2295,18 +2289,16 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithLargeValidatorFa validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := make(map[uint32][]*state.ValidatorInfo) - vi[core.MetachainShardId] = make([]*state.ValidatorInfo, 1) - vi[core.MetachainShardId][0] = createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) - vi[0] = make([]*state.ValidatorInfo, 1) - vi[0][0] = createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) + vi := state.NewShardValidatorsInfoMap(2) + _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) + _ = vi.Add(createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2)) validatorStatistics, _ := peer.NewValidatorStatisticsProcessor(arguments) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Nil(t, err) - assert.Equal(t, rater.MinRating, vi[core.MetachainShardId][0].TempRating) - assert.Equal(t, rater.MinRating, vi[0][0].TempRating) + assert.Equal(t, rater.MinRating, vi.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetTempRating()) + assert.Equal(t, rater.MinRating, vi.GetShardValidatorsInfoMap()[0][0].GetTempRating()) } func TestValidatorsProvider_PeerAccoutToValidatorInfo(t *testing.T) { @@ -2405,26 +2397,26 @@ func createMockValidatorInfo(shardId uint32, tempRating uint32, validatorSuccess } } -func compare(t *testing.T, peerAccount state.PeerAccountHandler, validatorInfo *state.ValidatorInfo) { - assert.Equal(t, peerAccount.GetShardId(), validatorInfo.ShardId) - assert.Equal(t, peerAccount.GetRating(), validatorInfo.Rating) - assert.Equal(t, peerAccount.GetTempRating(), validatorInfo.TempRating) - assert.Equal(t, peerAccount.GetBLSPublicKey(), validatorInfo.PublicKey) - assert.Equal(t, peerAccount.GetValidatorSuccessRate().NumFailure, validatorInfo.ValidatorFailure) - assert.Equal(t, peerAccount.GetValidatorSuccessRate().NumSuccess, validatorInfo.ValidatorSuccess) - assert.Equal(t, peerAccount.GetValidatorIgnoredSignaturesRate(), validatorInfo.ValidatorIgnoredSignatures) - assert.Equal(t, peerAccount.GetLeaderSuccessRate().NumFailure, validatorInfo.LeaderFailure) - assert.Equal(t, peerAccount.GetLeaderSuccessRate().NumSuccess, validatorInfo.LeaderSuccess) - assert.Equal(t, peerAccount.GetTotalValidatorSuccessRate().NumFailure, validatorInfo.TotalValidatorFailure) - assert.Equal(t, peerAccount.GetTotalValidatorSuccessRate().NumSuccess, validatorInfo.TotalValidatorSuccess) - assert.Equal(t, peerAccount.GetTotalValidatorIgnoredSignaturesRate(), validatorInfo.TotalValidatorIgnoredSignatures) - assert.Equal(t, peerAccount.GetTotalLeaderSuccessRate().NumFailure, validatorInfo.TotalLeaderFailure) - assert.Equal(t, peerAccount.GetTotalLeaderSuccessRate().NumSuccess, validatorInfo.TotalLeaderSuccess) - assert.Equal(t, peerAccount.GetList(), validatorInfo.List) - assert.Equal(t, peerAccount.GetIndexInList(), validatorInfo.Index) - assert.Equal(t, peerAccount.GetRewardAddress(), validatorInfo.RewardAddress) - assert.Equal(t, peerAccount.GetAccumulatedFees(), validatorInfo.AccumulatedFees) - assert.Equal(t, peerAccount.GetNumSelectedInSuccessBlocks(), validatorInfo.NumSelectedInSuccessBlocks) +func compare(t *testing.T, peerAccount state.PeerAccountHandler, validatorInfo state.ValidatorInfoHandler) { + assert.Equal(t, peerAccount.GetShardId(), validatorInfo.GetShardId()) + assert.Equal(t, peerAccount.GetRating(), validatorInfo.GetRating()) + assert.Equal(t, peerAccount.GetTempRating(), validatorInfo.GetTempRating()) + assert.Equal(t, peerAccount.GetBLSPublicKey(), validatorInfo.GetPublicKey()) + assert.Equal(t, peerAccount.GetValidatorSuccessRate().NumFailure, validatorInfo.GetValidatorFailure()) + assert.Equal(t, peerAccount.GetValidatorSuccessRate().NumSuccess, validatorInfo.GetValidatorSuccess()) + assert.Equal(t, peerAccount.GetValidatorIgnoredSignaturesRate(), validatorInfo.GetValidatorIgnoredSignatures()) + assert.Equal(t, peerAccount.GetLeaderSuccessRate().NumFailure, validatorInfo.GetLeaderFailure()) + assert.Equal(t, peerAccount.GetLeaderSuccessRate().NumSuccess, validatorInfo.GetLeaderSuccess()) + assert.Equal(t, peerAccount.GetTotalValidatorSuccessRate().NumFailure, validatorInfo.GetTotalValidatorFailure()) + assert.Equal(t, peerAccount.GetTotalValidatorSuccessRate().NumSuccess, validatorInfo.GetTotalValidatorSuccess()) + assert.Equal(t, peerAccount.GetTotalValidatorIgnoredSignaturesRate(), validatorInfo.GetTotalValidatorIgnoredSignatures()) + assert.Equal(t, peerAccount.GetTotalLeaderSuccessRate().NumFailure, validatorInfo.GetTotalLeaderFailure()) + assert.Equal(t, peerAccount.GetTotalLeaderSuccessRate().NumSuccess, validatorInfo.GetTotalLeaderSuccess()) + assert.Equal(t, peerAccount.GetList(), validatorInfo.GetList()) + assert.Equal(t, peerAccount.GetIndexInList(), validatorInfo.GetIndex()) + assert.Equal(t, peerAccount.GetRewardAddress(), validatorInfo.GetRewardAddress()) + assert.Equal(t, peerAccount.GetAccumulatedFees(), validatorInfo.GetAccumulatedFees()) + assert.Equal(t, peerAccount.GetNumSelectedInSuccessBlocks(), validatorInfo.GetNumSelectedInSuccessBlocks()) } func createPeerAccounts(addrBytes0 []byte, addrBytesMeta []byte) (state.PeerAccountHandler, state.PeerAccountHandler) { diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 04c1bfef373..95954eb892e 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -180,7 +180,8 @@ func (vp *validatorsProvider) updateCache() { return } allNodes, err := vp.validatorStatistics.GetValidatorInfoForRootHash(lastFinalizedRootHash) - if err != nil { + if err != nil || allNodes == nil { + allNodes = state.NewShardValidatorsInfoMap(0) log.Trace("validatorsProvider - GetLatestValidatorInfos failed", "error", err) } @@ -198,7 +199,7 @@ func (vp *validatorsProvider) updateCache() { func (vp *validatorsProvider) createNewCache( epoch uint32, - allNodes map[uint32][]*state.ValidatorInfo, + allNodes state.ShardValidatorsInfoMapHandler, ) map[string]*state.ValidatorApiResponse { newCache := vp.createValidatorApiResponseMapFromValidatorInfoMap(allNodes) @@ -217,29 +218,29 @@ func (vp *validatorsProvider) createNewCache( return newCache } -func (vp *validatorsProvider) createValidatorApiResponseMapFromValidatorInfoMap(allNodes map[uint32][]*state.ValidatorInfo) map[string]*state.ValidatorApiResponse { +func (vp *validatorsProvider) createValidatorApiResponseMapFromValidatorInfoMap(allNodes state.ShardValidatorsInfoMapHandler) map[string]*state.ValidatorApiResponse { newCache := make(map[string]*state.ValidatorApiResponse) - for _, validatorInfosInShard := range allNodes { - for _, validatorInfo := range validatorInfosInShard { - strKey := vp.pubkeyConverter.Encode(validatorInfo.PublicKey) - newCache[strKey] = &state.ValidatorApiResponse{ - NumLeaderSuccess: validatorInfo.LeaderSuccess, - NumLeaderFailure: validatorInfo.LeaderFailure, - NumValidatorSuccess: validatorInfo.ValidatorSuccess, - NumValidatorFailure: validatorInfo.ValidatorFailure, - NumValidatorIgnoredSignatures: validatorInfo.ValidatorIgnoredSignatures, - TotalNumLeaderSuccess: validatorInfo.TotalLeaderSuccess, - TotalNumLeaderFailure: validatorInfo.TotalLeaderFailure, - TotalNumValidatorSuccess: validatorInfo.TotalValidatorSuccess, - TotalNumValidatorFailure: validatorInfo.TotalValidatorFailure, - TotalNumValidatorIgnoredSignatures: validatorInfo.TotalValidatorIgnoredSignatures, - RatingModifier: validatorInfo.RatingModifier, - Rating: float32(validatorInfo.Rating) * 100 / float32(vp.maxRating), - TempRating: float32(validatorInfo.TempRating) * 100 / float32(vp.maxRating), - ShardId: validatorInfo.ShardId, - ValidatorStatus: validatorInfo.List, - } + + for _, validatorInfo := range allNodes.GetAllValidatorsInfo() { + strKey := vp.pubkeyConverter.Encode(validatorInfo.GetPublicKey()) + newCache[strKey] = &state.ValidatorApiResponse{ + NumLeaderSuccess: validatorInfo.GetLeaderSuccess(), + NumLeaderFailure: validatorInfo.GetLeaderFailure(), + NumValidatorSuccess: validatorInfo.GetValidatorSuccess(), + NumValidatorFailure: validatorInfo.GetValidatorFailure(), + NumValidatorIgnoredSignatures: validatorInfo.GetValidatorIgnoredSignatures(), + TotalNumLeaderSuccess: validatorInfo.GetTotalLeaderSuccess(), + TotalNumLeaderFailure: validatorInfo.GetTotalLeaderFailure(), + TotalNumValidatorSuccess: validatorInfo.GetTotalValidatorSuccess(), + TotalNumValidatorFailure: validatorInfo.GetTotalValidatorFailure(), + TotalNumValidatorIgnoredSignatures: validatorInfo.GetTotalValidatorIgnoredSignatures(), + RatingModifier: validatorInfo.GetRatingModifier(), + Rating: float32(validatorInfo.GetRating()) * 100 / float32(vp.maxRating), + TempRating: float32(validatorInfo.GetTempRating()) * 100 / float32(vp.maxRating), + ShardId: validatorInfo.GetShardId(), + ValidatorStatus: validatorInfo.GetList(), } + } return newCache diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 742a2ce7ce7..c4c2274d2d5 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -83,9 +83,8 @@ func TestValidatorsProvider_GetLatestValidatorsSecondHashDoesNotExist(t *testing e := errors.Errorf("not ok") initialInfo := createMockValidatorInfo() - validatorInfos := map[uint32][]*state.ValidatorInfo{ - 0: {initialInfo}, - } + validatorInfos := state.NewShardValidatorsInfoMap(1) + _ = validatorInfos.Add(initialInfo) gotOk := false gotNil := false @@ -95,7 +94,7 @@ func TestValidatorsProvider_GetLatestValidatorsSecondHashDoesNotExist(t *testing defer mut.Unlock() return root }, - GetValidatorInfoForRootHashCalled: func(rootHash []byte) (m map[uint32][]*state.ValidatorInfo, err error) { + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (m state.ShardValidatorsInfoMapHandler, err error) { mut.Lock() defer mut.Unlock() if bytes.Equal([]byte("rootHash"), rootHash) { @@ -167,7 +166,7 @@ func TestValidatorsProvider_CallsPopulateAndRegister(t *testing.T) { } arg.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ - GetValidatorInfoForRootHashCalled: func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { atomic.AddInt32(&numPopulateCacheCalled, 1) return nil, nil }, @@ -193,7 +192,7 @@ func TestValidatorsProvider_UpdateCache_WithError(t *testing.T) { return []byte("rootHash") }, } - validatorProc.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + validatorProc.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { return nil, expectedErr } @@ -263,21 +262,20 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { pk := []byte("pk1") initialShardId := uint32(1) initialList := string(common.EligibleList) - validatorsMap := make(map[uint32][]*state.ValidatorInfo) - validatorsMap[initialShardId] = []*state.ValidatorInfo{ - { - PublicKey: pk, - List: initialList, - ShardId: initialShardId, - }, - } + validatorsMap := state.NewShardValidatorsInfoMap(1) + _ = validatorsMap.Add(&state.ValidatorInfo{ + PublicKey: pk, + List: initialList, + ShardId: initialShardId, + }) + arg := createDefaultValidatorsProviderArg() validatorProc := &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, } - validatorProc.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + validatorProc.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { return validatorsMap, nil } @@ -294,7 +292,7 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { vsp.updateCache() assert.NotNil(t, vsp.cache) - assert.Equal(t, len(validatorsMap[initialShardId]), len(vsp.cache)) + assert.Equal(t, len(validatorsMap.GetShardValidatorsInfoMap()[initialShardId]), len(vsp.cache)) encodedKey := arg.PubKeyConverter.Encode(pk) assert.NotNil(t, vsp.cache[encodedKey]) assert.Equal(t, initialList, vsp.cache[encodedKey].ValidatorStatus) @@ -358,47 +356,41 @@ func TestValidatorsProvider_createCache(t *testing.T) { pkNew := []byte("pk5") newList := string(common.NewList) - validatorsMap := make(map[uint32][]*state.ValidatorInfo) + validatorsMap := state.NewShardValidatorsInfoMap(4) eligibleShardId := uint32(0) waitingShardId := uint32(1) leavingShardId := uint32(2) inactiveShardId := uint32(3) newShardId := core.MetachainShardId - validatorsMap[eligibleShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkEligible, - ShardId: eligibleShardId, - List: eligibleList, - }, - } - validatorsMap[waitingShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkWaiting, - ShardId: waitingShardId, - List: waitingList, - }, - } - validatorsMap[leavingShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkLeaving, - ShardId: leavingShardId, - List: leavingList, - }, - } - validatorsMap[inactiveShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkInactive, - ShardId: inactiveShardId, - List: inactiveList, - }, - } - validatorsMap[newShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkNew, - ShardId: newShardId, - List: newList, - }, - } + _ = validatorsMap.Add(&state.ValidatorInfo{ + PublicKey: pkEligible, + ShardId: eligibleShardId, + List: eligibleList, + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + + PublicKey: pkWaiting, + ShardId: waitingShardId, + List: waitingList, + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + + PublicKey: pkLeaving, + ShardId: leavingShardId, + List: leavingList, + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + + PublicKey: pkInactive, + ShardId: inactiveShardId, + List: inactiveList, + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + + PublicKey: pkNew, + ShardId: newShardId, + List: newList, + }) arg := createDefaultValidatorsProviderArg() pubKeyConverter := mock.NewPubkeyConverterMock(32) vsp := validatorsProvider{ @@ -443,31 +435,25 @@ func TestValidatorsProvider_createCache_combined(t *testing.T) { pkLeavingInTrie := []byte("pk3") leavingList := string(common.LeavingList) - validatorsMap := make(map[uint32][]*state.ValidatorInfo) + validatorsMap := state.NewShardValidatorsInfoMap(3) eligibleShardId := uint32(0) inactiveShardId := uint32(1) leavingShardId := uint32(2) - validatorsMap[eligibleShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkEligibleInTrie, - ShardId: eligibleShardId, - List: eligibleList, - }, - } - validatorsMap[inactiveShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkInactive, - ShardId: inactiveShardId, - List: inactiveList, - }, - } - validatorsMap[leavingShardId] = []*state.ValidatorInfo{ - { - PublicKey: pkLeavingInTrie, - ShardId: leavingShardId, - List: leavingList, - }, - } + _ = validatorsMap.Add(&state.ValidatorInfo{ + PublicKey: pkEligibleInTrie, + ShardId: eligibleShardId, + List: eligibleList, + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + PublicKey: pkInactive, + ShardId: inactiveShardId, + List: inactiveList, + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + PublicKey: pkLeavingInTrie, + ShardId: leavingShardId, + List: leavingList, + }) arg := createDefaultValidatorsProviderArg() nodesCoordinator := shardingMocks.NewNodesCoordinatorMock() nodesCoordinatorEligibleShardId := uint32(5) @@ -513,7 +499,7 @@ func TestValidatorsProvider_CallsPopulateOnlyAfterTimeout(t *testing.T) { return []byte("rootHash") }, } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { atomic.AddInt32(populateCacheCalled, 1) return nil, nil } @@ -554,20 +540,19 @@ func TestValidatorsProvider_CallsUpdateCacheOnEpochChange(t *testing.T) { return []byte("rootHash") }, } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { callNumber++ // first call comes from the constructor if callNumber == 1 { return nil, nil } - return map[uint32][]*state.ValidatorInfo{ - 0: { - { - PublicKey: pkEligibleInTrie, - List: string(common.EligibleList), - }, - }, - }, nil + validatorsMap := state.NewShardValidatorsInfoMap(1) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: pkEligibleInTrie, + List: string(common.EligibleList), + }) + return validatorsMap, nil } arg.ValidatorStatistics = validatorStatisticsProcessor @@ -593,20 +578,19 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin return []byte("rootHash") }, } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { callNumber++ // first call comes from the constructor if callNumber == 1 { return nil, nil } - return map[uint32][]*state.ValidatorInfo{ - 0: { - { - PublicKey: pkEligibleInTrie, - List: string(common.EligibleList), - }, - }, - }, nil + validatorsMap := state.NewShardValidatorsInfoMap(1) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: pkEligibleInTrie, + List: string(common.EligibleList), + }) + return validatorsMap, nil } arg.ValidatorStatistics = validatorStatisticsProcessor diff --git a/state/interface.go b/state/interface.go index dd8c6633b12..cce1b7ed6ba 100644 --- a/state/interface.go +++ b/state/interface.go @@ -243,4 +243,6 @@ type ValidatorInfoHandler interface { SetTotalValidatorSuccess(totalValidatorSuccess uint32) SetTotalValidatorFailure(totalValidatorFailure uint32) SetTotalValidatorIgnoredSignatures(totalValidatorIgnoredSignatures uint32) + + String() string } diff --git a/testscommon/validatorStatisticsProcessorStub.go b/testscommon/validatorStatisticsProcessorStub.go index cf5086d9f7c..81ae86a1dbd 100644 --- a/testscommon/validatorStatisticsProcessorStub.go +++ b/testscommon/validatorStatisticsProcessorStub.go @@ -12,9 +12,9 @@ type ValidatorStatisticsProcessorStub struct { GetPeerAccountCalled func(address []byte) (state.PeerAccountHandler, error) RootHashCalled func() ([]byte, error) LastFinalizedRootHashCalled func() []byte - ResetValidatorStatisticsAtNewEpochCalled func(vInfos map[uint32][]*state.ValidatorInfo) error - GetValidatorInfoForRootHashCalled func(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) - ProcessRatingsEndOfEpochCalled func(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error + ResetValidatorStatisticsAtNewEpochCalled func(vInfos state.ShardValidatorsInfoMapHandler) error + GetValidatorInfoForRootHashCalled func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) + ProcessRatingsEndOfEpochCalled func(validatorInfos state.ShardValidatorsInfoMapHandler, epoch uint32) error ProcessCalled func(validatorInfo data.ShardValidatorInfoHandler) error CommitCalled func() ([]byte, error) PeerAccountToValidatorInfoCalled func(peerAccount state.PeerAccountHandler) *state.ValidatorInfo @@ -48,7 +48,7 @@ func (vsp *ValidatorStatisticsProcessorStub) Commit() ([]byte, error) { } // ResetValidatorStatisticsAtNewEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ResetValidatorStatisticsAtNewEpoch(vInfos map[uint32][]*state.ValidatorInfo) error { +func (vsp *ValidatorStatisticsProcessorStub) ResetValidatorStatisticsAtNewEpoch(vInfos state.ShardValidatorsInfoMapHandler) error { if vsp.ResetValidatorStatisticsAtNewEpochCalled != nil { return vsp.ResetValidatorStatisticsAtNewEpochCalled(vInfos) } @@ -56,11 +56,11 @@ func (vsp *ValidatorStatisticsProcessorStub) ResetValidatorStatisticsAtNewEpoch( } // GetValidatorInfoForRootHash - -func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHash []byte) (map[uint32][]*state.ValidatorInfo, error) { +func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { if vsp.GetValidatorInfoForRootHashCalled != nil { return vsp.GetValidatorInfoForRootHashCalled(rootHash) } - return nil, nil + return state.NewShardValidatorsInfoMap(0), nil } // UpdatePeerState - @@ -72,7 +72,7 @@ func (vsp *ValidatorStatisticsProcessorStub) UpdatePeerState(header data.MetaHea } // ProcessRatingsEndOfEpoch - -func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos map[uint32][]*state.ValidatorInfo, epoch uint32) error { +func (vsp *ValidatorStatisticsProcessorStub) ProcessRatingsEndOfEpoch(validatorInfos state.ShardValidatorsInfoMapHandler, epoch uint32) error { if vsp.ProcessRatingsEndOfEpochCalled != nil { return vsp.ProcessRatingsEndOfEpochCalled(validatorInfos, epoch) } From 7574f0b5a6fdb4ed4342c4fdf685f4b0f9ed5d89 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 11:37:52 +0200 Subject: [PATCH 129/958] FIX: Review findings --- vm/systemSmartContracts/staking.go | 176 ++++++++++++++++++ vm/systemSmartContracts/stakingWaitingList.go | 153 ++------------- 2 files changed, 189 insertions(+), 140 deletions(-) diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index c1974344707..ea8f1058bec 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -517,6 +517,61 @@ func (s *stakingSC) stake(args *vmcommon.ContractCallInput, onlyRegister bool) v return vmcommon.Ok } +func (s *stakingSC) unStakeAtEndOfEpoch(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { + // backward compatibility - no need for return message + return vmcommon.UserError + } + if len(args.Arguments) != 1 { + s.eei.AddReturnMessage("not enough arguments, needed the BLS key") + return vmcommon.UserError + } + + registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) + return vmcommon.UserError + } + if len(registrationData.RewardAddress) == 0 { + s.eei.AddReturnMessage("cannot unStake a key that is not registered") + return vmcommon.UserError + } + if registrationData.Jailed && !registrationData.Staked { + s.eei.AddReturnMessage("already unStaked at switchJailedToWaiting") + return vmcommon.Ok + } + + if !registrationData.Staked && !registrationData.Waiting { + log.Debug("stakingSC.unStakeAtEndOfEpoch: cannot unStake node which was already unStaked", "blsKey", hex.EncodeToString(args.Arguments[0])) + return vmcommon.Ok + } + + if registrationData.Staked { + s.removeFromStakedNodes() + } + + if registrationData.Waiting { + err = s.removeFromWaitingList(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + } + + registrationData.Staked = false + registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() + registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() + registrationData.Waiting = false + + err = s.saveStakingData(args.Arguments[0], registrationData) + if err != nil { + s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + func (s *stakingSC) activeStakingFor(stakingData *StakedDataV2_0) { stakingData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() stakingData.Staked = true @@ -526,6 +581,105 @@ func (s *stakingSC) activeStakingFor(stakingData *StakedDataV2_0) { stakingData.Waiting = false } +func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { + if s.flagStakingV4.IsSet() { + return s.processStakeV2(registrationData) + } + + return s.processStakeV1(blsKey, registrationData, addFirst) +} + +func (s *stakingSC) processStakeV2(registrationData *StakedDataV2_0) error { + if registrationData.Staked { + return nil + } + + registrationData.RegisterNonce = s.eei.BlockChainHook().CurrentNonce() + s.addToStakedNodes(1) + s.activeStakingFor(registrationData) + + return nil +} + +func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if s.flagStakingV4.IsSet() { + return s.unStakeV2(args) + } + + return s.unStakeV1(args) +} + +func (s *stakingSC) unStakeV2(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + registrationData, retCode := s.checkUnStakeArgs(args) + if retCode != vmcommon.Ok { + return retCode + } + + if !registrationData.Staked { + s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) + return vmcommon.ExecutionFailed + } + + return s.tryUnStake(args.Arguments[0], registrationData) +} + +func (s *stakingSC) checkUnStakeArgs(args *vmcommon.ContractCallInput) (*StakedDataV2_0, vmcommon.ReturnCode) { + if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { + s.eei.AddReturnMessage("unStake function not allowed to be called by address " + string(args.CallerAddr)) + return nil, vmcommon.UserError + } + if len(args.Arguments) < 2 { + s.eei.AddReturnMessage("not enough arguments, needed BLS key and reward address") + return nil, vmcommon.UserError + } + + registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) + if err != nil { + s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) + return nil, vmcommon.UserError + } + if len(registrationData.RewardAddress) == 0 { + s.eei.AddReturnMessage("cannot unStake a key that is not registered") + return nil, vmcommon.UserError + } + if !bytes.Equal(args.Arguments[1], registrationData.RewardAddress) { + s.eei.AddReturnMessage("unStake possible only from staker caller") + return nil, vmcommon.UserError + } + if s.isNodeJailedOrWithBadRating(registrationData, args.Arguments[0]) { + s.eei.AddReturnMessage("cannot unStake node which is jailed or with bad rating") + return nil, vmcommon.UserError + } + + if !registrationData.Staked && !registrationData.Waiting { + s.eei.AddReturnMessage("cannot unStake node which was already unStaked") + return nil, vmcommon.UserError + } + + return registrationData, vmcommon.Ok +} + +func (s *stakingSC) tryUnStake(key []byte, registrationData *StakedDataV2_0) vmcommon.ReturnCode { + if !s.canUnStake() { + s.eei.AddReturnMessage("unStake is not possible as too many left") + return vmcommon.UserError + } + + s.removeFromStakedNodes() + registrationData.Staked = false + registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() + registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() + registrationData.Waiting = false + + err := s.saveStakingData(key, registrationData) + if err != nil { + s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + func (s *stakingSC) unBond(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { s.eei.AddReturnMessage("unBond function not allowed to be called by address " + string(args.CallerAddr)) @@ -771,6 +925,28 @@ func (s *stakingSC) getBLSKeyStatus(args *vmcommon.ContractCallInput) vmcommon.R return vmcommon.Ok } +func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + if !s.flagStakingV2.IsSet() { + s.eei.AddReturnMessage("invalid method to call") + return vmcommon.UserError + } + if args.CallValue.Cmp(zero) != 0 { + s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) + return vmcommon.UserError + } + + waitingListHead, err := s.getWaitingListHead() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError + } + + stakeConfig := s.getConfig() + totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + int64(waitingListHead.Length) + s.eei.Finish(big.NewInt(totalRegistered).Bytes()) + return vmcommon.Ok +} + func (s *stakingSC) getRemainingUnbondPeriod(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if args.CallValue.Cmp(zero) != 0 { s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index aadabe9a027..f6673290e6d 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -23,7 +23,7 @@ type waitingListReturnData struct { afterLastJailed bool } -func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { +func (s *stakingSC) processStakeV1(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { if registrationData.Staked { return nil } @@ -54,100 +54,14 @@ func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0 return nil } -func (s *stakingSC) unStakeAtEndOfEpoch(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, s.endOfEpochAccessAddr) { - // backward compatibility - no need for return message - return vmcommon.UserError - } - if len(args.Arguments) != 1 { - s.eei.AddReturnMessage("not enough arguments, needed the BLS key") - return vmcommon.UserError - } - - registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) - return vmcommon.UserError - } - if len(registrationData.RewardAddress) == 0 { - s.eei.AddReturnMessage("cannot unStake a key that is not registered") - return vmcommon.UserError - } - if registrationData.Jailed && !registrationData.Staked { - s.eei.AddReturnMessage("already unStaked at switchJailedToWaiting") - return vmcommon.Ok - } - - if !registrationData.Staked && !registrationData.Waiting { - log.Debug("stakingSC.unStakeAtEndOfEpoch: cannot unStake node which was already unStaked", "blsKey", hex.EncodeToString(args.Arguments[0])) - return vmcommon.Ok - } - - if registrationData.Staked { - s.removeFromStakedNodes() - } - - if registrationData.Waiting { - err = s.removeFromWaitingList(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - } - - registrationData.Staked = false - registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() - registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() - registrationData.Waiting = false - - err = s.saveStakingData(args.Arguments[0], registrationData) - if err != nil { - s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, s.stakeAccessAddr) { - s.eei.AddReturnMessage("unStake function not allowed to be called by address " + string(args.CallerAddr)) - return vmcommon.UserError - } - if len(args.Arguments) < 2 { - s.eei.AddReturnMessage("not enough arguments, needed BLS key and reward address") - return vmcommon.UserError - } - - registrationData, err := s.getOrCreateRegisteredData(args.Arguments[0]) - if err != nil { - s.eei.AddReturnMessage("cannot get or create registered data: error " + err.Error()) - return vmcommon.UserError - } - if len(registrationData.RewardAddress) == 0 { - s.eei.AddReturnMessage("cannot unStake a key that is not registered") - return vmcommon.UserError - } - if !bytes.Equal(args.Arguments[1], registrationData.RewardAddress) { - s.eei.AddReturnMessage("unStake possible only from staker caller") - return vmcommon.UserError - } - if s.isNodeJailedOrWithBadRating(registrationData, args.Arguments[0]) { - s.eei.AddReturnMessage("cannot unStake node which is jailed or with bad rating") - return vmcommon.UserError - } - - if !registrationData.Staked && !registrationData.Waiting { - s.eei.AddReturnMessage("cannot unStake node which was already unStaked") - return vmcommon.UserError +func (s *stakingSC) unStakeV1(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { + registrationData, retCode := s.checkUnStakeArgs(args) + if retCode != vmcommon.Ok { + return retCode } + var err error if !registrationData.Staked { - if s.flagStakingV4.IsSet() { - s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) - return vmcommon.ExecutionFailed - } - registrationData.Waiting = false err = s.removeFromWaitingList(args.Arguments[0]) if err != nil { @@ -163,35 +77,16 @@ func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod return vmcommon.Ok } - if !s.flagStakingV4.IsSet() { - addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() - if addOneFromQueue { - _, err = s.moveFirstFromWaitingToStaked() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() + if addOneFromQueue { + _, err = s.moveFirstFromWaitingToStaked() + if err != nil { + s.eei.AddReturnMessage(err.Error()) + return vmcommon.UserError } } - if !s.canUnStake() { - s.eei.AddReturnMessage("unStake is not possible as too many left") - return vmcommon.UserError - } - - s.removeFromStakedNodes() - registrationData.Staked = false - registrationData.UnStakedEpoch = s.eei.BlockChainHook().CurrentEpoch() - registrationData.UnStakedNonce = s.eei.BlockChainHook().CurrentNonce() - registrationData.Waiting = false - - err = s.saveStakingData(args.Arguments[0], registrationData) - if err != nil { - s.eei.AddReturnMessage("cannot save staking data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok + return s.tryUnStake(args.Arguments[0], registrationData) } func (s *stakingSC) moveFirstFromWaitingToStakedIfNeeded(blsKey []byte) (bool, error) { @@ -743,28 +638,6 @@ func (s *stakingSC) getWaitingListRegisterNonceAndRewardAddress(args *vmcommon.C return vmcommon.Ok } -func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { - s.eei.AddReturnMessage("invalid method to call") - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - s.eei.AddReturnMessage(vm.TransactionValueMustBeZero) - return vmcommon.UserError - } - - waitingListHead, err := s.getWaitingListHead() - if err != nil { - s.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - stakeConfig := s.getConfig() - totalRegistered := stakeConfig.StakedNodes + stakeConfig.JailedNodes + int64(waitingListHead.Length) - s.eei.Finish(big.NewInt(totalRegistered).Bytes()) - return vmcommon.Ok -} - func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { if !s.flagCorrectLastUnjailed.IsSet() { // backward compatibility From ed96dede99a6223579314ed18e1c9084d8457c54 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 11:54:56 +0200 Subject: [PATCH 130/958] FIX: Remove flag --- vm/systemSmartContracts/stakingWaitingList.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index f6673290e6d..577bf0ce020 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -41,13 +41,12 @@ func (s *stakingSC) processStakeV1(blsKey []byte, registrationData *StakedDataV2 return nil } - if !s.flagStakingV4.IsSet() { - err := s.removeFromWaitingList(blsKey) - if err != nil { - s.eei.AddReturnMessage("error while removing from waiting") - return err - } + err := s.removeFromWaitingList(blsKey) + if err != nil { + s.eei.AddReturnMessage("error while removing from waiting") + return err } + s.addToStakedNodes(1) s.activeStakingFor(registrationData) From 83ac54c69b7fc25d9d6b8d8bac20ddbff5f2e6b5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 12:58:58 +0200 Subject: [PATCH 131/958] FIX: Review findings --- state/validatorsInfoMap.go | 4 +- state/validatorsInfoMap_test.go | 68 ++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 75611e3ffd6..e348767da27 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -16,10 +16,10 @@ type shardValidatorsInfoMap struct { // NewShardValidatorsInfoMap creates an instance of shardValidatorsInfoMap which manages a // map internally -func NewShardValidatorsInfoMap(numOfShards uint32) *shardValidatorsInfoMap { +func NewShardValidatorsInfoMap() *shardValidatorsInfoMap { return &shardValidatorsInfoMap{ mutex: sync.RWMutex{}, - valInfoMap: make(map[uint32][]ValidatorInfoHandler, numOfShards), + valInfoMap: make(map[uint32][]ValidatorInfoHandler), } } diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index 111b76820ad..381dbf7f719 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -11,32 +11,48 @@ import ( "github.com/stretchr/testify/require" ) -func TestShardValidatorsInfoMap_Add_Delete_Replace_SetValidatorsInShard_NilValidators(t *testing.T) { +func TestShardValidatorsInfoMap_OperationsWithNilValidators(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(1) + vi := NewShardValidatorsInfoMap() - err := vi.Add(nil) - require.Equal(t, ErrNilValidatorInfo, err) + t.Run("add nil validator", func(t *testing.T) { + t.Parallel() - err = vi.Delete(nil) - require.Equal(t, ErrNilValidatorInfo, err) + err := vi.Add(nil) + require.Equal(t, ErrNilValidatorInfo, err) + }) - err = vi.Replace(nil, &ValidatorInfo{}) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) - require.True(t, strings.Contains(err.Error(), "old")) + t.Run("delete nil validator", func(t *testing.T) { + t.Parallel() - err = vi.Replace(&ValidatorInfo{}, nil) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) - require.True(t, strings.Contains(err.Error(), "new")) + err := vi.Delete(nil) + require.Equal(t, ErrNilValidatorInfo, err) + }) - v := &ValidatorInfo{ShardId: 3, PublicKey: []byte("pk")} - err = vi.SetValidatorsInShard(3, []ValidatorInfoHandler{v, nil}) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) - require.True(t, strings.Contains(err.Error(), "index 1")) + t.Run("replace nil validator", func(t *testing.T) { + t.Parallel() + + err := vi.Replace(nil, &ValidatorInfo{}) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) + require.True(t, strings.Contains(err.Error(), "old")) + + err = vi.Replace(&ValidatorInfo{}, nil) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) + require.True(t, strings.Contains(err.Error(), "new")) + }) + + t.Run("set nil validators in shard", func(t *testing.T) { + t.Parallel() + + v := &ValidatorInfo{ShardId: 3, PublicKey: []byte("pk")} + err := vi.SetValidatorsInShard(3, []ValidatorInfoHandler{v, nil}) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), ErrNilValidatorInfo.Error())) + require.True(t, strings.Contains(err.Error(), "index 1")) + }) } func TestCreateShardValidatorsMap(t *testing.T) { @@ -62,7 +78,7 @@ func TestCreateShardValidatorsMap(t *testing.T) { func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsInfo_GetValInfoPointerMap(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(3) + vi := NewShardValidatorsInfoMap() v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} @@ -101,7 +117,7 @@ func TestShardValidatorsInfoMap_Add_GetShardValidatorsInfoMap_GetAllValidatorsIn func TestShardValidatorsInfoMap_GetValidator(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(1) + vi := NewShardValidatorsInfoMap() pubKey0 := []byte("pk0") pubKey1 := []byte("pk1") @@ -119,7 +135,7 @@ func TestShardValidatorsInfoMap_GetValidator(t *testing.T) { func TestShardValidatorsInfoMap_Delete(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(2) + vi := NewShardValidatorsInfoMap() v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} @@ -148,7 +164,7 @@ func TestShardValidatorsInfoMap_Delete(t *testing.T) { func TestShardValidatorsInfoMap_Replace(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(2) + vi := NewShardValidatorsInfoMap() v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} v1 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk1")} @@ -178,7 +194,7 @@ func TestShardValidatorsInfoMap_Replace(t *testing.T) { func TestShardValidatorsInfoMap_SetValidatorsInShard(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(2) + vi := NewShardValidatorsInfoMap() v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} _ = vi.Add(v0) @@ -215,7 +231,7 @@ func TestShardValidatorsInfoMap_SetValidatorsInShard(t *testing.T) { func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(2) + vi := NewShardValidatorsInfoMap() v0 := &ValidatorInfo{ShardId: 0, PublicKey: []byte("pk0")} v1 := &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk1")} @@ -244,7 +260,7 @@ func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testi func TestShardValidatorsInfoMap_Concurrency(t *testing.T) { t.Parallel() - vi := NewShardValidatorsInfoMap(2) + vi := NewShardValidatorsInfoMap() numValidatorsShard0 := 100 numValidatorsShard1 := 50 From 560c72d88135f39b3c7cd73a56a77a276cf7d9ce Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 13:42:52 +0200 Subject: [PATCH 132/958] FIX: NewShardValidatorsInfoMap without numOfShards --- epochStart/metachain/systemSCs_test.go | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 749dcc1916b..e698f165003 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -175,7 +175,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { jailedAcc, _ := args.PeerAccountsDB.LoadAccount([]byte("jailedPubKey0")) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() vInfo := &state.ValidatorInfo{ PublicKey: []byte("jailedPubKey0"), ShardId: 0, @@ -228,7 +228,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s addValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.SetValidatorsInShard(0, jailed) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) @@ -291,7 +291,7 @@ func TestSystemSCProcessor_NobodyToSwapWithStakingV2(t *testing.T) { _ = s.initDelegationSystemSC() doStake(t, s.systemVM, s.userAccountsDB, owner1, big.NewInt(1000), blsKeys...) doUnStake(t, s.systemVM, s.userAccountsDB, owner1, blsKeys[:3]...) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() jailed := &state.ValidatorInfo{ PublicKey: blsKeys[0], ShardId: 0, @@ -1054,7 +1054,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin s, _ := NewSystemSCProcessor(args) _ = s.flagDelegationEnabled.SetReturningPrevious() - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) @@ -1197,7 +1197,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueue(t * []byte("rewardAddress"), ) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) @@ -1249,7 +1249,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwne args.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: 10, }) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{Epoch: 10}) assert.Nil(t, err) @@ -1313,7 +1313,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t args.Marshalizer, ) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), @@ -1381,7 +1381,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor addValidatorDataWithUnStakedKey(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, big.NewInt(1000), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), @@ -1458,7 +1458,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), @@ -1547,7 +1547,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional addDelegationData(args.UserAccountsDB, delegationAddr, allStakedKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), @@ -1645,7 +1645,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( addDelegationData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), @@ -1717,7 +1717,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractWrongValidatorInfoShouldBeC []byte("oneAddress1"), ) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: "", @@ -1815,7 +1815,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T addValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("stakedPubKey0"), List: string(common.EligibleList), @@ -1905,7 +1905,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) addKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) - validatorsInfo := state.NewShardValidatorsInfoMap(2) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) @@ -1951,7 +1951,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) @@ -1985,7 +1985,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) @@ -2013,7 +2013,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) - validatorsInfo := state.NewShardValidatorsInfoMap(1) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) @@ -2053,7 +2053,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) - validatorsInfo := state.NewShardValidatorsInfoMap(2) + validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1, 0)) From 908635a403bacfa242655f56e5b51da5bf6b74b3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 13:51:49 +0200 Subject: [PATCH 133/958] FIX: NewShardValidatorsInfoMap without numOfShards --- process/block/metablock_test.go | 2 +- process/peer/process.go | 3 +-- process/peer/process_test.go | 12 ++++++------ process/peer/validatorsProvider.go | 2 +- process/peer/validatorsProvider_test.go | 12 ++++++------ testscommon/validatorStatisticsProcessorStub.go | 2 +- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 1d543340837..53c118b00f1 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3276,7 +3276,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() - expectedValidatorsInfo := state.NewShardValidatorsInfoMap(1) + expectedValidatorsInfo := state.NewShardValidatorsInfoMap() _ = expectedValidatorsInfo.Add( &state.ValidatorInfo{ ShardId: 1, diff --git a/process/peer/process.go b/process/peer/process.go index 32f4e1e9be0..3ee1c8f7692 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -446,8 +446,7 @@ func (vs *validatorStatistics) RootHash() ([]byte, error) { func (vs *validatorStatistics) getValidatorDataFromLeaves( leavesChannel chan core.KeyValueHolder, ) (state.ShardValidatorsInfoMapHandler, error) { - validators := state.NewShardValidatorsInfoMap(vs.shardCoordinator.NumberOfShards() + 1) - + validators := state.NewShardValidatorsInfoMap() for pa := range leavesChannel { peerAccount, err := vs.unmarshalPeer(pa.Value()) if err != nil { diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 342f593f350..4fbb67ddb0b 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2091,7 +2091,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNilMapShouldErr( err := validatorStatistics.ProcessRatingsEndOfEpoch(nil, 1) assert.Equal(t, process.ErrNilValidatorInfos, err) - vi := state.NewShardValidatorsInfoMap(1) + vi := state.NewShardValidatorsInfoMap() err = validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) assert.Equal(t, process.ErrNilValidatorInfos, err) } @@ -2109,7 +2109,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithNoValidatorFailu tempRating1 := uint32(75) tempRating2 := uint32(80) - vi := state.NewShardValidatorsInfoMap(2) + vi := state.NewShardValidatorsInfoMap() _ = vi.Add(&state.ValidatorInfo{ PublicKey: nil, ShardId: core.MetachainShardId, @@ -2171,7 +2171,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithSmallValidatorFa validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := state.NewShardValidatorsInfoMap(2) + vi := state.NewShardValidatorsInfoMap() _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) _ = vi.Add(createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2)) @@ -2208,7 +2208,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochComputesJustEligible validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := state.NewShardValidatorsInfoMap(2) + vi := state.NewShardValidatorsInfoMap() _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) @@ -2249,7 +2249,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochV2ComputesEligibleLe validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := state.NewShardValidatorsInfoMap(2) + vi := state.NewShardValidatorsInfoMap() validatorLeaving := createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) validatorLeaving.SetList(string(common.LeavingList)) _ = vi.Add(validatorLeaving) @@ -2289,7 +2289,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochWithLargeValidatorFa validatorIgnored2 := uint32(90) validatorFailure2 := uint32(9) - vi := state.NewShardValidatorsInfoMap(2) + vi := state.NewShardValidatorsInfoMap() _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) _ = vi.Add(createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2)) diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 95954eb892e..dc3512c7db6 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -181,7 +181,7 @@ func (vp *validatorsProvider) updateCache() { } allNodes, err := vp.validatorStatistics.GetValidatorInfoForRootHash(lastFinalizedRootHash) if err != nil || allNodes == nil { - allNodes = state.NewShardValidatorsInfoMap(0) + allNodes = state.NewShardValidatorsInfoMap() log.Trace("validatorsProvider - GetLatestValidatorInfos failed", "error", err) } diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index c4c2274d2d5..de5a7ca180d 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -83,7 +83,7 @@ func TestValidatorsProvider_GetLatestValidatorsSecondHashDoesNotExist(t *testing e := errors.Errorf("not ok") initialInfo := createMockValidatorInfo() - validatorInfos := state.NewShardValidatorsInfoMap(1) + validatorInfos := state.NewShardValidatorsInfoMap() _ = validatorInfos.Add(initialInfo) gotOk := false @@ -262,7 +262,7 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { pk := []byte("pk1") initialShardId := uint32(1) initialList := string(common.EligibleList) - validatorsMap := state.NewShardValidatorsInfoMap(1) + validatorsMap := state.NewShardValidatorsInfoMap() _ = validatorsMap.Add(&state.ValidatorInfo{ PublicKey: pk, List: initialList, @@ -356,7 +356,7 @@ func TestValidatorsProvider_createCache(t *testing.T) { pkNew := []byte("pk5") newList := string(common.NewList) - validatorsMap := state.NewShardValidatorsInfoMap(4) + validatorsMap := state.NewShardValidatorsInfoMap() eligibleShardId := uint32(0) waitingShardId := uint32(1) leavingShardId := uint32(2) @@ -435,7 +435,7 @@ func TestValidatorsProvider_createCache_combined(t *testing.T) { pkLeavingInTrie := []byte("pk3") leavingList := string(common.LeavingList) - validatorsMap := state.NewShardValidatorsInfoMap(3) + validatorsMap := state.NewShardValidatorsInfoMap() eligibleShardId := uint32(0) inactiveShardId := uint32(1) leavingShardId := uint32(2) @@ -546,7 +546,7 @@ func TestValidatorsProvider_CallsUpdateCacheOnEpochChange(t *testing.T) { if callNumber == 1 { return nil, nil } - validatorsMap := state.NewShardValidatorsInfoMap(1) + validatorsMap := state.NewShardValidatorsInfoMap() _ = validatorsMap.Add(&state.ValidatorInfo{ ShardId: 0, PublicKey: pkEligibleInTrie, @@ -584,7 +584,7 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin if callNumber == 1 { return nil, nil } - validatorsMap := state.NewShardValidatorsInfoMap(1) + validatorsMap := state.NewShardValidatorsInfoMap() _ = validatorsMap.Add(&state.ValidatorInfo{ ShardId: 0, PublicKey: pkEligibleInTrie, diff --git a/testscommon/validatorStatisticsProcessorStub.go b/testscommon/validatorStatisticsProcessorStub.go index 81ae86a1dbd..b9e28ce6b8b 100644 --- a/testscommon/validatorStatisticsProcessorStub.go +++ b/testscommon/validatorStatisticsProcessorStub.go @@ -60,7 +60,7 @@ func (vsp *ValidatorStatisticsProcessorStub) GetValidatorInfoForRootHash(rootHas if vsp.GetValidatorInfoForRootHashCalled != nil { return vsp.GetValidatorInfoForRootHashCalled(rootHash) } - return state.NewShardValidatorsInfoMap(0), nil + return state.NewShardValidatorsInfoMap(), nil } // UpdatePeerState - From 5342faf32a1b60b2eba5f039d764f1d28d9a73d9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 13:56:57 +0200 Subject: [PATCH 134/958] FIX: Broken tests --- integrationTests/testP2PNode.go | 8 ++++---- integrationTests/testProcessorNode.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index 233ca7239bb..c56fd5ba516 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -171,10 +171,10 @@ func (tP2pNode *TestP2PNode) initNode() { processComponents.NodesCoord = tP2pNode.NodesCoordinator processComponents.ValidatorProvider = &mock.ValidatorsProviderStub{} processComponents.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ - GetValidatorInfoForRootHashCalled: func(_ []byte) (map[uint32][]*state.ValidatorInfo, error) { - return map[uint32][]*state.ValidatorInfo{ - 0: {{PublicKey: []byte("pk0")}}, - }, nil + GetValidatorInfoForRootHashCalled: func(_ []byte) (state.ShardValidatorsInfoMapHandler, error) { + ret := state.NewShardValidatorsInfoMap() + _ = ret.Add(&state.ValidatorInfo{PublicKey: []byte("pk0")}) + return ret, nil }, } processComponents.EpochNotifier = epochStartNotifier diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 27f3515ecc2..8d5cc16f135 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2923,10 +2923,10 @@ func (tpn *TestProcessorNode) createHeartbeatWithHardforkTrigger(heartbeatPk str processComponents.ShardCoord = tpn.ShardCoordinator processComponents.IntContainer = tpn.InterceptorsContainer processComponents.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ - GetValidatorInfoForRootHashCalled: func(_ []byte) (map[uint32][]*state.ValidatorInfo, error) { - return map[uint32][]*state.ValidatorInfo{ - 0: {{PublicKey: []byte("pk0")}}, - }, nil + GetValidatorInfoForRootHashCalled: func(_ []byte) (state.ShardValidatorsInfoMapHandler, error) { + ret := state.NewShardValidatorsInfoMap() + _ = ret.Add(&state.ValidatorInfo{PublicKey: []byte("pk0")}) + return ret, nil }, } processComponents.ValidatorProvider = &mock.ValidatorsProviderStub{} From 2b139c7a659cc1884780a096f0b5441080b6ae38 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 14:08:12 +0200 Subject: [PATCH 135/958] FIX: Another broken tests --- node/node_test.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/node/node_test.go b/node/node_test.go index 293008e84de..8bdb48383ee 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -2416,12 +2416,11 @@ func TestNode_ValidatorStatisticsApi(t *testing.T) { initialPubKeys[1] = keys[1] initialPubKeys[2] = keys[2] - validatorsInfo := make(map[uint32][]*state.ValidatorInfo) + validatorsInfo := state.NewShardValidatorsInfoMap() for shardId, pubkeysPerShard := range initialPubKeys { - validatorsInfo[shardId] = make([]*state.ValidatorInfo, 0) for _, pubKey := range pubkeysPerShard { - validatorsInfo[shardId] = append(validatorsInfo[shardId], &state.ValidatorInfo{ + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte(pubKey), ShardId: shardId, List: "", @@ -2447,7 +2446,7 @@ func TestNode_ValidatorStatisticsApi(t *testing.T) { RootHashCalled: func() (i []byte, err error) { return []byte("hash"), nil }, - GetValidatorInfoForRootHashCalled: func(rootHash []byte) (m map[uint32][]*state.ValidatorInfo, err error) { + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (m state.ShardValidatorsInfoMapHandler, err error) { return validatorsInfo, nil }, } @@ -2455,10 +2454,8 @@ func TestNode_ValidatorStatisticsApi(t *testing.T) { validatorProvider := &mock.ValidatorsProviderStub{GetLatestValidatorsCalled: func() map[string]*state.ValidatorApiResponse { apiResponses := make(map[string]*state.ValidatorApiResponse) - for _, vis := range validatorsInfo { - for _, vi := range vis { - apiResponses[hex.EncodeToString(vi.GetPublicKey())] = &state.ValidatorApiResponse{} - } + for _, vi := range validatorsInfo.GetAllValidatorsInfo() { + apiResponses[hex.EncodeToString(vi.GetPublicKey())] = &state.ValidatorApiResponse{} } return apiResponses From 86206114e3aa593db561dee3cced656eac0d8705 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 15:44:33 +0200 Subject: [PATCH 136/958] FEAT: Remove duplicated stubs --- integrationTests/testSyncNode.go | 2 +- process/block/metablock_test.go | 6 +- process/mock/epochValidatorInfoCreatorStub.go | 59 ------------------- .../epochValidatorInfoCreatorStub.go | 2 +- 4 files changed, 5 insertions(+), 64 deletions(-) delete mode 100644 process/mock/epochValidatorInfoCreatorStub.go rename {integrationTests/mock => testscommon}/epochValidatorInfoCreatorStub.go (99%) diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index 0eb1c52332f..9f02b91edcb 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -239,7 +239,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, - EpochValidatorInfoCreator: &mock.EpochValidatorInfoCreatorStub{}, + EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, } diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 53c118b00f1..b80dfe6317e 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -139,7 +139,7 @@ func createMockMetaArguments( EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, - EpochValidatorInfoCreator: &mock.EpochValidatorInfoCreatorStub{}, + EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, } @@ -3353,7 +3353,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { }, } - arguments.EpochValidatorInfoCreator = &mock.EpochValidatorInfoCreatorStub{ + arguments.EpochValidatorInfoCreator = &testscommon.EpochValidatorInfoCreatorStub{ CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) return validatorInfoMiniBlocks, nil @@ -3415,7 +3415,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { }, } - arguments.EpochValidatorInfoCreator = &mock.EpochValidatorInfoCreatorStub{ + arguments.EpochValidatorInfoCreator = &testscommon.EpochValidatorInfoCreatorStub{ CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) return validatorInfoMiniBlocks, nil diff --git a/process/mock/epochValidatorInfoCreatorStub.go b/process/mock/epochValidatorInfoCreatorStub.go deleted file mode 100644 index 3533131a117..00000000000 --- a/process/mock/epochValidatorInfoCreatorStub.go +++ /dev/null @@ -1,59 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/state" -) - -// EpochValidatorInfoCreatorStub - -type EpochValidatorInfoCreatorStub struct { - CreateValidatorInfoMiniBlocksCalled func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) - VerifyValidatorInfoMiniBlocksCalled func(miniblocks []*block.MiniBlock, validatorsInfo map[uint32][]*state.ValidatorInfo) error - CreateMarshalizedDataCalled func(body block.Body) map[string][][]byte - SaveTxBlockToStorageCalled func(metaBlock data.HeaderHandler, body *block.Body) - DeleteTxsFromStorageCalled func(metaBlock data.HeaderHandler) - RemoveBlockDataFromPoolsCalled func(metaBlock data.HeaderHandler, body *block.Body) -} - -// CreateValidatorInfoMiniBlocks - -func (e *EpochValidatorInfoCreatorStub) CreateValidatorInfoMiniBlocks(validatorInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { - if e.CreateValidatorInfoMiniBlocksCalled != nil { - return e.CreateValidatorInfoMiniBlocksCalled(validatorInfo) - } - return make(block.MiniBlockSlice, 0), nil -} - -// VerifyValidatorInfoMiniBlocks - -func (e *EpochValidatorInfoCreatorStub) VerifyValidatorInfoMiniBlocks(miniblocks []*block.MiniBlock, validatorsInfo map[uint32][]*state.ValidatorInfo) error { - if e.VerifyValidatorInfoMiniBlocksCalled != nil { - return e.VerifyValidatorInfoMiniBlocksCalled(miniblocks, validatorsInfo) - } - return nil -} - -// SaveValidatorInfoBlocksToStorage - -func (e *EpochValidatorInfoCreatorStub) SaveValidatorInfoBlocksToStorage(metaBlock data.HeaderHandler, body *block.Body) { - if e.SaveTxBlockToStorageCalled != nil { - e.SaveTxBlockToStorageCalled(metaBlock, body) - } -} - -// DeleteValidatorInfoBlocksFromStorage - -func (e *EpochValidatorInfoCreatorStub) DeleteValidatorInfoBlocksFromStorage(metaBlock data.HeaderHandler) { - if e.DeleteTxsFromStorageCalled != nil { - e.DeleteTxsFromStorageCalled(metaBlock) - } -} - -// IsInterfaceNil - -func (e *EpochValidatorInfoCreatorStub) IsInterfaceNil() bool { - return e == nil -} - -// RemoveBlockDataFromPools - -func (e *EpochValidatorInfoCreatorStub) RemoveBlockDataFromPools(metaBlock data.HeaderHandler, body *block.Body) { - if e.RemoveBlockDataFromPoolsCalled != nil { - e.RemoveBlockDataFromPoolsCalled(metaBlock, body) - } -} diff --git a/integrationTests/mock/epochValidatorInfoCreatorStub.go b/testscommon/epochValidatorInfoCreatorStub.go similarity index 99% rename from integrationTests/mock/epochValidatorInfoCreatorStub.go rename to testscommon/epochValidatorInfoCreatorStub.go index 3533131a117..fb703e95d00 100644 --- a/integrationTests/mock/epochValidatorInfoCreatorStub.go +++ b/testscommon/epochValidatorInfoCreatorStub.go @@ -1,4 +1,4 @@ -package mock +package testscommon import ( "github.com/ElrondNetwork/elrond-go-core/data" From c567d72679d03963ffcb1c9fd852b3cc110e36b1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 21 Mar 2022 16:37:43 +0200 Subject: [PATCH 137/958] FEAT: Refactor code to use new interface --- epochStart/metachain/validators.go | 26 +-- epochStart/metachain/validators_test.go | 186 +++++++++---------- process/block/metablock.go | 26 ++- process/block/metablock_test.go | 8 +- process/interface.go | 4 +- testscommon/epochValidatorInfoCreatorStub.go | 8 +- 6 files changed, 139 insertions(+), 119 deletions(-) diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index eea1720ca65..25080ceabea 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -67,7 +67,7 @@ func NewValidatorInfoCreator(args ArgsNewValidatorInfoCreator) (*validatorInfoCr } // CreateValidatorInfoMiniBlocks creates the validatorInfo miniblocks according to the provided validatorInfo map -func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { +func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo state.ShardValidatorsInfoMapHandler) (block.MiniBlockSlice, error) { if validatorsInfo == nil { return nil, epochStart.ErrNilValidatorInfo } @@ -75,7 +75,7 @@ func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo ma miniblocks := make([]*block.MiniBlock, 0) for shardId := uint32(0); shardId < vic.shardCoordinator.NumberOfShards(); shardId++ { - validators := validatorsInfo[shardId] + validators := validatorsInfo.GetShardValidatorsInfoMap()[shardId] if len(validators) == 0 { continue } @@ -88,7 +88,7 @@ func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo ma miniblocks = append(miniblocks, miniBlock) } - validators := validatorsInfo[core.MetachainShardId] + validators := validatorsInfo.GetShardValidatorsInfoMap()[core.MetachainShardId] if len(validators) == 0 { return miniblocks, nil } @@ -103,17 +103,17 @@ func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo ma return miniblocks, nil } -func (vic *validatorInfoCreator) createMiniBlock(validatorsInfo []*state.ValidatorInfo) (*block.MiniBlock, error) { +func (vic *validatorInfoCreator) createMiniBlock(validatorsInfo []state.ValidatorInfoHandler) (*block.MiniBlock, error) { miniBlock := &block.MiniBlock{} miniBlock.SenderShardID = vic.shardCoordinator.SelfId() miniBlock.ReceiverShardID = core.AllShardId miniBlock.TxHashes = make([][]byte, len(validatorsInfo)) miniBlock.Type = block.PeerBlock - validatorCopy := make([]*state.ValidatorInfo, len(validatorsInfo)) + validatorCopy := make([]state.ValidatorInfoHandler, len(validatorsInfo)) copy(validatorCopy, validatorsInfo) sort.Slice(validatorCopy, func(a, b int) bool { - return bytes.Compare(validatorCopy[a].PublicKey, validatorCopy[b].PublicKey) < 0 + return bytes.Compare(validatorCopy[a].GetPublicKey(), validatorCopy[b].GetPublicKey()) < 0 }) for index, validator := range validatorCopy { @@ -129,20 +129,20 @@ func (vic *validatorInfoCreator) createMiniBlock(validatorsInfo []*state.Validat return miniBlock, nil } -func createShardValidatorInfo(validator *state.ValidatorInfo) *state.ShardValidatorInfo { +func createShardValidatorInfo(validator state.ValidatorInfoHandler) *state.ShardValidatorInfo { return &state.ShardValidatorInfo{ - PublicKey: validator.PublicKey, - ShardId: validator.ShardId, - List: validator.List, - Index: validator.Index, - TempRating: validator.TempRating, + PublicKey: validator.GetPublicKey(), + ShardId: validator.GetShardId(), + List: validator.GetList(), + Index: validator.GetIndex(), + TempRating: validator.GetTempRating(), } } // VerifyValidatorInfoMiniBlocks verifies if received validatorinfo miniblocks are correct func (vic *validatorInfoCreator) VerifyValidatorInfoMiniBlocks( miniblocks []*block.MiniBlock, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, ) error { if len(miniblocks) == 0 { return epochStart.ErrNilMiniblocks diff --git a/epochStart/metachain/validators_test.go b/epochStart/metachain/validators_test.go index c65c0a2ecbb..6984717c688 100644 --- a/epochStart/metachain/validators_test.go +++ b/epochStart/metachain/validators_test.go @@ -21,90 +21,90 @@ import ( "github.com/stretchr/testify/require" ) -func createMockValidatorInfo() map[uint32][]*state.ValidatorInfo { - validatorInfo := map[uint32][]*state.ValidatorInfo{ - 0: { - &state.ValidatorInfo{ - PublicKey: []byte("a1"), - ShardId: 0, - List: "eligible", - Index: 1, - TempRating: 100, - Rating: 1000, - RewardAddress: []byte("rewardA1"), - LeaderSuccess: 1, - LeaderFailure: 2, - ValidatorSuccess: 3, - ValidatorFailure: 4, - TotalLeaderSuccess: 10, - TotalLeaderFailure: 20, - TotalValidatorSuccess: 30, - TotalValidatorFailure: 40, - NumSelectedInSuccessBlocks: 5, - AccumulatedFees: big.NewInt(100), - }, - &state.ValidatorInfo{ - PublicKey: []byte("a2"), - ShardId: 0, - List: "waiting", - Index: 2, - TempRating: 101, - Rating: 1001, - RewardAddress: []byte("rewardA2"), - LeaderSuccess: 6, - LeaderFailure: 7, - ValidatorSuccess: 8, - ValidatorFailure: 9, - TotalLeaderSuccess: 60, - TotalLeaderFailure: 70, - TotalValidatorSuccess: 80, - TotalValidatorFailure: 90, - NumSelectedInSuccessBlocks: 10, - AccumulatedFees: big.NewInt(101), - }, - }, - core.MetachainShardId: { - &state.ValidatorInfo{ - PublicKey: []byte("m1"), - ShardId: core.MetachainShardId, - List: "eligible", - Index: 1, - TempRating: 100, - Rating: 1000, - RewardAddress: []byte("rewardM1"), - LeaderSuccess: 1, - LeaderFailure: 2, - ValidatorSuccess: 3, - ValidatorFailure: 4, - TotalLeaderSuccess: 10, - TotalLeaderFailure: 20, - TotalValidatorSuccess: 30, - TotalValidatorFailure: 40, - NumSelectedInSuccessBlocks: 5, - AccumulatedFees: big.NewInt(100), - }, - &state.ValidatorInfo{ - PublicKey: []byte("m0"), - ShardId: core.MetachainShardId, - List: "waiting", - Index: 2, - TempRating: 101, - Rating: 1001, - RewardAddress: []byte("rewardM2"), - LeaderSuccess: 6, - LeaderFailure: 7, - ValidatorSuccess: 8, - ValidatorFailure: 9, - TotalLeaderSuccess: 60, - TotalLeaderFailure: 70, - TotalValidatorSuccess: 80, - TotalValidatorFailure: 90, - NumSelectedInSuccessBlocks: 10, - AccumulatedFees: big.NewInt(101), - }, - }, - } - return validatorInfo +func createMockValidatorInfo() state.ShardValidatorsInfoMapHandler { + validatorsInfo := state.NewShardValidatorsInfoMap() + + _ = validatorsInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("a1"), + ShardId: 0, + List: "eligible", + Index: 1, + TempRating: 100, + Rating: 1000, + RewardAddress: []byte("rewardA1"), + LeaderSuccess: 1, + LeaderFailure: 2, + ValidatorSuccess: 3, + ValidatorFailure: 4, + TotalLeaderSuccess: 10, + TotalLeaderFailure: 20, + TotalValidatorSuccess: 30, + TotalValidatorFailure: 40, + NumSelectedInSuccessBlocks: 5, + AccumulatedFees: big.NewInt(100), + }) + + _ = validatorsInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("a2"), + ShardId: 0, + List: "waiting", + Index: 2, + TempRating: 101, + Rating: 1001, + RewardAddress: []byte("rewardA2"), + LeaderSuccess: 6, + LeaderFailure: 7, + ValidatorSuccess: 8, + ValidatorFailure: 9, + TotalLeaderSuccess: 60, + TotalLeaderFailure: 70, + TotalValidatorSuccess: 80, + TotalValidatorFailure: 90, + NumSelectedInSuccessBlocks: 10, + AccumulatedFees: big.NewInt(101), + }) + + _ = validatorsInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("m1"), + ShardId: core.MetachainShardId, + List: "eligible", + Index: 1, + TempRating: 100, + Rating: 1000, + RewardAddress: []byte("rewardM1"), + LeaderSuccess: 1, + LeaderFailure: 2, + ValidatorSuccess: 3, + ValidatorFailure: 4, + TotalLeaderSuccess: 10, + TotalLeaderFailure: 20, + TotalValidatorSuccess: 30, + TotalValidatorFailure: 40, + NumSelectedInSuccessBlocks: 5, + AccumulatedFees: big.NewInt(100), + }) + + _ = validatorsInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("m0"), + ShardId: core.MetachainShardId, + List: "waiting", + Index: 2, + TempRating: 101, + Rating: 1001, + RewardAddress: []byte("rewardM2"), + LeaderSuccess: 6, + LeaderFailure: 7, + ValidatorSuccess: 8, + ValidatorFailure: 9, + TotalLeaderSuccess: 60, + TotalLeaderFailure: 70, + TotalValidatorSuccess: 80, + TotalValidatorFailure: 90, + NumSelectedInSuccessBlocks: 10, + AccumulatedFees: big.NewInt(101), + }) + + return validatorsInfo } func createMockEpochValidatorInfoCreatorsArguments() ArgsNewValidatorInfoCreator { @@ -127,7 +127,7 @@ func createMockEpochValidatorInfoCreatorsArguments() ArgsNewValidatorInfoCreator return argsNewEpochEconomics } -func verifyMiniBlocks(bl *block.MiniBlock, infos []*state.ValidatorInfo, marshalizer marshal.Marshalizer) bool { +func verifyMiniBlocks(bl *block.MiniBlock, infos []state.ValidatorInfoHandler, marshalizer marshal.Marshalizer) bool { if bl.SenderShardID != core.MetachainShardId || bl.ReceiverShardID != core.AllShardId || len(bl.TxHashes) == 0 || @@ -135,10 +135,10 @@ func verifyMiniBlocks(bl *block.MiniBlock, infos []*state.ValidatorInfo, marshal return false } - validatorCopy := make([]*state.ValidatorInfo, len(infos)) + validatorCopy := make([]state.ValidatorInfoHandler, len(infos)) copy(validatorCopy, infos) sort.Slice(validatorCopy, func(a, b int) bool { - return bytes.Compare(validatorCopy[a].PublicKey, validatorCopy[b].PublicKey) < 0 + return bytes.Compare(validatorCopy[a].GetPublicKey(), validatorCopy[b].GetPublicKey()) < 0 }) for i, txHash := range bl.TxHashes { @@ -264,9 +264,9 @@ func TestEpochValidatorInfoCreator_CreateValidatorInfoMiniBlocksShouldBeCorrect( vic, _ := NewValidatorInfoCreator(arguments) mbs, _ := vic.CreateValidatorInfoMiniBlocks(validatorInfo) - correctMB0 := verifyMiniBlocks(mbs[0], validatorInfo[0], arguments.Marshalizer) + correctMB0 := verifyMiniBlocks(mbs[0], validatorInfo.GetShardValidatorsInfoMap()[0], arguments.Marshalizer) require.True(t, correctMB0) - correctMbMeta := verifyMiniBlocks(mbs[1], validatorInfo[core.MetachainShardId], arguments.Marshalizer) + correctMbMeta := verifyMiniBlocks(mbs[1], validatorInfo.GetShardValidatorsInfoMap()[core.MetachainShardId], arguments.Marshalizer) require.True(t, correctMbMeta) } @@ -345,11 +345,11 @@ func TestEpochValidatorInfoCreator_VerifyValidatorInfoMiniBlocksNilOneMiniblock( } func createValidatorInfoMiniBlocks( - validatorInfo map[uint32][]*state.ValidatorInfo, + validatorInfo state.ShardValidatorsInfoMapHandler, arguments ArgsNewValidatorInfoCreator, ) []*block.MiniBlock { miniblocks := make([]*block.MiniBlock, 0) - for _, validators := range validatorInfo { + for _, validators := range validatorInfo.GetShardValidatorsInfoMap() { if len(validators) == 0 { continue } @@ -360,10 +360,10 @@ func createValidatorInfoMiniBlocks( miniBlock.TxHashes = make([][]byte, len(validators)) miniBlock.Type = block.PeerBlock - validatorCopy := make([]*state.ValidatorInfo, len(validators)) + validatorCopy := make([]state.ValidatorInfoHandler, len(validators)) copy(validatorCopy, validators) sort.Slice(validatorCopy, func(a, b int) bool { - return bytes.Compare(validatorCopy[a].PublicKey, validatorCopy[b].PublicKey) < 0 + return bytes.Compare(validatorCopy[a].GetPublicKey(), validatorCopy[b].GetPublicKey()) < 0 }) for index, validator := range validatorCopy { diff --git a/process/block/metablock.go b/process/block/metablock.go index e61695bc7d9..a3a4da91b57 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -446,7 +446,7 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - err = mp.validatorInfoCreator.VerifyValidatorInfoMiniBlocks(body.MiniBlocks, oldValidatorsInfoMap) + err = mp.verifyValidatorInfoMiniBlocks(oldValidatorsInfoMap, body.MiniBlocks) if err != nil { return err } @@ -918,7 +918,7 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - validatorMiniBlocks, err := mp.validatorInfoCreator.CreateValidatorInfoMiniBlocks(oldValidatorsInfoMap) + validatorMiniBlocks, err := mp.createValidatorInfoMiniBlocks(oldValidatorsInfoMap) if err != nil { return nil, err } @@ -2506,7 +2506,7 @@ func (mp *metaProcessor) DecodeBlockHeader(dta []byte) data.HeaderHandler { return metaBlock } -// TODO: StakingV4 delete this once map[uint32][]*ValidatorInfo is replaced with interface +// TODO: StakingV4 delete these funcs once map[uint32][]*ValidatorInfo is replaced with interface func (mp *metaProcessor) processSystemSCsWithNewValidatorsInfo(allValidatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) err := mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) @@ -2516,3 +2516,23 @@ func (mp *metaProcessor) processSystemSCsWithNewValidatorsInfo(allValidatorsInfo state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) return nil } + +func (mp *metaProcessor) verifyValidatorInfoMiniBlocks(allValidatorsInfo map[uint32][]*state.ValidatorInfo, miniBlocks []*block.MiniBlock) error { + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + err := mp.validatorInfoCreator.VerifyValidatorInfoMiniBlocks(miniBlocks, validatorsInfoMap) + if err != nil { + return err + } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) + return nil +} + +func (mp *metaProcessor) createValidatorInfoMiniBlocks(allValidatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { + validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) + validatorMiniBlocks, err := mp.validatorInfoCreator.CreateValidatorInfoMiniBlocks(validatorsInfoMap) + if err != nil { + return nil, err + } + state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) + return validatorMiniBlocks, err +} diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index b80dfe6317e..5bc0f8bd94c 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3354,8 +3354,8 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } arguments.EpochValidatorInfoCreator = &testscommon.EpochValidatorInfoCreatorStub{ - CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { - assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) + CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler) (block.MiniBlockSlice, error) { + assert.Equal(t, expectedValidatorsInfo, validatorsInfo) return validatorInfoMiniBlocks, nil }, } @@ -3416,8 +3416,8 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } arguments.EpochValidatorInfoCreator = &testscommon.EpochValidatorInfoCreatorStub{ - CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { - assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) + CreateValidatorInfoMiniBlocksCalled: func(validatorsInfo state.ShardValidatorsInfoMapHandler) (block.MiniBlockSlice, error) { + assert.Equal(t, expectedValidatorsInfo, validatorsInfo) return validatorInfoMiniBlocks, nil }, } diff --git a/process/interface.go b/process/interface.go index 2f4c8192d95..3e79a1b3e63 100644 --- a/process/interface.go +++ b/process/interface.go @@ -897,8 +897,8 @@ type RewardsCreator interface { // EpochStartValidatorInfoCreator defines the functionality for the metachain to create validator statistics at end of epoch type EpochStartValidatorInfoCreator interface { - CreateValidatorInfoMiniBlocks(validatorInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) - VerifyValidatorInfoMiniBlocks(miniblocks []*block.MiniBlock, validatorsInfo map[uint32][]*state.ValidatorInfo) error + CreateValidatorInfoMiniBlocks(validatorInfo state.ShardValidatorsInfoMapHandler) (block.MiniBlockSlice, error) + VerifyValidatorInfoMiniBlocks(miniblocks []*block.MiniBlock, validatorsInfo state.ShardValidatorsInfoMapHandler) error SaveValidatorInfoBlocksToStorage(metaBlock data.HeaderHandler, body *block.Body) DeleteValidatorInfoBlocksFromStorage(metaBlock data.HeaderHandler) RemoveBlockDataFromPools(metaBlock data.HeaderHandler, body *block.Body) diff --git a/testscommon/epochValidatorInfoCreatorStub.go b/testscommon/epochValidatorInfoCreatorStub.go index fb703e95d00..a56497955fa 100644 --- a/testscommon/epochValidatorInfoCreatorStub.go +++ b/testscommon/epochValidatorInfoCreatorStub.go @@ -8,8 +8,8 @@ import ( // EpochValidatorInfoCreatorStub - type EpochValidatorInfoCreatorStub struct { - CreateValidatorInfoMiniBlocksCalled func(validatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) - VerifyValidatorInfoMiniBlocksCalled func(miniblocks []*block.MiniBlock, validatorsInfo map[uint32][]*state.ValidatorInfo) error + CreateValidatorInfoMiniBlocksCalled func(validatorsInfo state.ShardValidatorsInfoMapHandler) (block.MiniBlockSlice, error) + VerifyValidatorInfoMiniBlocksCalled func(miniblocks []*block.MiniBlock, validatorsInfo state.ShardValidatorsInfoMapHandler) error CreateMarshalizedDataCalled func(body block.Body) map[string][][]byte SaveTxBlockToStorageCalled func(metaBlock data.HeaderHandler, body *block.Body) DeleteTxsFromStorageCalled func(metaBlock data.HeaderHandler) @@ -17,7 +17,7 @@ type EpochValidatorInfoCreatorStub struct { } // CreateValidatorInfoMiniBlocks - -func (e *EpochValidatorInfoCreatorStub) CreateValidatorInfoMiniBlocks(validatorInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { +func (e *EpochValidatorInfoCreatorStub) CreateValidatorInfoMiniBlocks(validatorInfo state.ShardValidatorsInfoMapHandler) (block.MiniBlockSlice, error) { if e.CreateValidatorInfoMiniBlocksCalled != nil { return e.CreateValidatorInfoMiniBlocksCalled(validatorInfo) } @@ -25,7 +25,7 @@ func (e *EpochValidatorInfoCreatorStub) CreateValidatorInfoMiniBlocks(validatorI } // VerifyValidatorInfoMiniBlocks - -func (e *EpochValidatorInfoCreatorStub) VerifyValidatorInfoMiniBlocks(miniblocks []*block.MiniBlock, validatorsInfo map[uint32][]*state.ValidatorInfo) error { +func (e *EpochValidatorInfoCreatorStub) VerifyValidatorInfoMiniBlocks(miniblocks []*block.MiniBlock, validatorsInfo state.ShardValidatorsInfoMapHandler) error { if e.VerifyValidatorInfoMiniBlocksCalled != nil { return e.VerifyValidatorInfoMiniBlocksCalled(miniblocks, validatorsInfo) } From 068c23a54914337d5fb692a8ca8d5167fc29cd29 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 11:15:16 +0200 Subject: [PATCH 138/958] FEAT: Create nodesCoordinatorRegistryFactory.go --- epochStart/bootstrap/common.go | 4 + epochStart/bootstrap/fromLocalStorage.go | 2 +- epochStart/bootstrap/process.go | 132 +++---- epochStart/bootstrap/process_test.go | 10 +- epochStart/bootstrap/syncValidatorStatus.go | 44 ++- factory/bootstrapComponents.go | 51 ++- factory/shardingFactory.go | 47 ++- integrationTests/consensus/testInitializer.go | 36 +- integrationTests/nodesCoordinatorFactory.go | 39 +- integrationTests/testP2PNode.go | 81 ++-- .../testProcessorNodeWithMultisigner.go | 78 ++-- node/nodeRunner.go | 1 + sharding/nodesCoordinator/common.go | 34 -- sharding/nodesCoordinator/errors.go | 9 +- .../indexHashedNodesCoordinator.go | 105 +++--- .../indexHashedNodesCoordinatorRegistry.go | 2 +- ...ndexHashedNodesCoordinatorRegistry_test.go | 4 +- ...dexHashedNodesCoordinatorWithRater_test.go | 179 ++++----- .../indexHashedNodesCoordinator_test.go | 347 +++++++++--------- sharding/nodesCoordinator/interface.go | 8 + .../nodesCoordinatorRegistryFactory.go | 73 ++++ sharding/nodesCoordinator/shardingArgs.go | 43 +-- 22 files changed, 727 insertions(+), 602 deletions(-) create mode 100644 sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go diff --git a/epochStart/bootstrap/common.go b/epochStart/bootstrap/common.go index 03160c08145..4d409f181d8 100644 --- a/epochStart/bootstrap/common.go +++ b/epochStart/bootstrap/common.go @@ -5,6 +5,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" ) const baseErrorMessage = "error with epoch start bootstrapper arguments" @@ -106,6 +107,9 @@ func checkArguments(args ArgsEpochStartBootstrap) error { if args.GeneralConfig.TrieSync.NumConcurrentTrieSyncers < 1 { return fmt.Errorf("%s: %w", baseErrorMessage, epochStart.ErrInvalidNumConcurrentTrieSyncers) } + if check.IfNil(args.NodesCoordinatorRegistryFactory) { + return fmt.Errorf("%s: %w", baseErrorMessage, nodesCoordinator.ErrNilNodesCoordinatorRegistryFactory) + } return nil } diff --git a/epochStart/bootstrap/fromLocalStorage.go b/epochStart/bootstrap/fromLocalStorage.go index fb3b147395f..16d378b2d4c 100644 --- a/epochStart/bootstrap/fromLocalStorage.go +++ b/epochStart/bootstrap/fromLocalStorage.go @@ -263,7 +263,7 @@ func (e *epochStartBootstrap) getLastBootstrapData(storer storage.Storer) (*boot return nil, nil, err } - config, err := nodesCoordinator.CreateNodesCoordinatorRegistry(e.coreComponentsHolder.InternalMarshalizer(), d) + config, err := e.nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry(d) if err != nil { return nil, nil, err } diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index c129676d225..e0f4b76568f 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -104,23 +104,24 @@ type epochStartBootstrap struct { trieSyncerVersion int // created components - requestHandler process.RequestHandler - interceptorContainer process.InterceptorsContainer - dataPool dataRetriever.PoolsHolder - miniBlocksSyncer epochStart.PendingMiniBlocksSyncHandler - headersSyncer epochStart.HeadersByHashSyncer - txSyncerForScheduled update.TransactionsSyncHandler - epochStartMetaBlockSyncer epochStart.StartOfEpochMetaSyncer - nodesConfigHandler StartOfEpochNodesConfigHandler - whiteListHandler update.WhiteListHandler - whiteListerVerifiedTxs update.WhiteListHandler - storageOpenerHandler storage.UnitOpenerHandler - latestStorageDataProvider storage.LatestStorageDataProviderHandler - argumentsParser process.ArgumentsParser - enableEpochs config.EnableEpochs - dataSyncerFactory types.ScheduledDataSyncerCreator - dataSyncerWithScheduled types.ScheduledDataSyncer - storageService dataRetriever.StorageService + requestHandler process.RequestHandler + interceptorContainer process.InterceptorsContainer + dataPool dataRetriever.PoolsHolder + miniBlocksSyncer epochStart.PendingMiniBlocksSyncHandler + headersSyncer epochStart.HeadersByHashSyncer + txSyncerForScheduled update.TransactionsSyncHandler + epochStartMetaBlockSyncer epochStart.StartOfEpochMetaSyncer + nodesConfigHandler StartOfEpochNodesConfigHandler + whiteListHandler update.WhiteListHandler + whiteListerVerifiedTxs update.WhiteListHandler + storageOpenerHandler storage.UnitOpenerHandler + latestStorageDataProvider storage.LatestStorageDataProviderHandler + argumentsParser process.ArgumentsParser + enableEpochs config.EnableEpochs + dataSyncerFactory types.ScheduledDataSyncerCreator + dataSyncerWithScheduled types.ScheduledDataSyncer + storageService dataRetriever.StorageService + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory // gathered data epochStartMeta data.MetaHeaderHandler @@ -145,26 +146,27 @@ type baseDataInStorage struct { // ArgsEpochStartBootstrap holds the arguments needed for creating an epoch start data provider component type ArgsEpochStartBootstrap struct { - CoreComponentsHolder process.CoreComponentsHolder - CryptoComponentsHolder process.CryptoComponentsHolder - DestinationShardAsObserver uint32 - Messenger Messenger - GeneralConfig config.Config - PrefsConfig config.PreferencesConfig - EnableEpochs config.EnableEpochs - EconomicsData process.EconomicsDataHandler - GenesisNodesConfig sharding.GenesisNodesSetupHandler - GenesisShardCoordinator sharding.Coordinator - StorageUnitOpener storage.UnitOpenerHandler - LatestStorageDataProvider storage.LatestStorageDataProviderHandler - Rater nodesCoordinator.ChanceComputer - NodeShuffler nodesCoordinator.NodesShuffler - RoundHandler epochStart.RoundHandler - ArgumentsParser process.ArgumentsParser - StatusHandler core.AppStatusHandler - HeaderIntegrityVerifier process.HeaderIntegrityVerifier - DataSyncerCreator types.ScheduledDataSyncerCreator - ScheduledSCRsStorer storage.Storer + CoreComponentsHolder process.CoreComponentsHolder + CryptoComponentsHolder process.CryptoComponentsHolder + DestinationShardAsObserver uint32 + Messenger Messenger + GeneralConfig config.Config + PrefsConfig config.PreferencesConfig + EnableEpochs config.EnableEpochs + EconomicsData process.EconomicsDataHandler + GenesisNodesConfig sharding.GenesisNodesSetupHandler + GenesisShardCoordinator sharding.Coordinator + StorageUnitOpener storage.UnitOpenerHandler + LatestStorageDataProvider storage.LatestStorageDataProviderHandler + Rater nodesCoordinator.ChanceComputer + NodeShuffler nodesCoordinator.NodesShuffler + RoundHandler epochStart.RoundHandler + ArgumentsParser process.ArgumentsParser + StatusHandler core.AppStatusHandler + HeaderIntegrityVerifier process.HeaderIntegrityVerifier + DataSyncerCreator types.ScheduledDataSyncerCreator + ScheduledSCRsStorer storage.Storer + NodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } type dataToSync struct { @@ -182,33 +184,34 @@ func NewEpochStartBootstrap(args ArgsEpochStartBootstrap) (*epochStartBootstrap, } epochStartProvider := &epochStartBootstrap{ - coreComponentsHolder: args.CoreComponentsHolder, - cryptoComponentsHolder: args.CryptoComponentsHolder, - messenger: args.Messenger, - generalConfig: args.GeneralConfig, - prefsConfig: args.PrefsConfig, - economicsData: args.EconomicsData, - genesisNodesConfig: args.GenesisNodesConfig, - genesisShardCoordinator: args.GenesisShardCoordinator, - rater: args.Rater, - destinationShardAsObserver: args.DestinationShardAsObserver, - nodeShuffler: args.NodeShuffler, - roundHandler: args.RoundHandler, - storageOpenerHandler: args.StorageUnitOpener, - latestStorageDataProvider: args.LatestStorageDataProvider, - shuffledOut: false, - statusHandler: args.StatusHandler, - nodeType: core.NodeTypeObserver, - argumentsParser: args.ArgumentsParser, - headerIntegrityVerifier: args.HeaderIntegrityVerifier, - epochNotifier: args.CoreComponentsHolder.EpochNotifier(), - numConcurrentTrieSyncers: args.GeneralConfig.TrieSync.NumConcurrentTrieSyncers, - maxHardCapForMissingNodes: args.GeneralConfig.TrieSync.MaxHardCapForMissingNodes, - trieSyncerVersion: args.GeneralConfig.TrieSync.TrieSyncerVersion, - enableEpochs: args.EnableEpochs, - dataSyncerFactory: args.DataSyncerCreator, - storerScheduledSCRs: args.ScheduledSCRsStorer, - shardCoordinator: args.GenesisShardCoordinator, + coreComponentsHolder: args.CoreComponentsHolder, + cryptoComponentsHolder: args.CryptoComponentsHolder, + messenger: args.Messenger, + generalConfig: args.GeneralConfig, + prefsConfig: args.PrefsConfig, + economicsData: args.EconomicsData, + genesisNodesConfig: args.GenesisNodesConfig, + genesisShardCoordinator: args.GenesisShardCoordinator, + rater: args.Rater, + destinationShardAsObserver: args.DestinationShardAsObserver, + nodeShuffler: args.NodeShuffler, + roundHandler: args.RoundHandler, + storageOpenerHandler: args.StorageUnitOpener, + latestStorageDataProvider: args.LatestStorageDataProvider, + shuffledOut: false, + statusHandler: args.StatusHandler, + nodeType: core.NodeTypeObserver, + argumentsParser: args.ArgumentsParser, + headerIntegrityVerifier: args.HeaderIntegrityVerifier, + epochNotifier: args.CoreComponentsHolder.EpochNotifier(), + numConcurrentTrieSyncers: args.GeneralConfig.TrieSync.NumConcurrentTrieSyncers, + maxHardCapForMissingNodes: args.GeneralConfig.TrieSync.MaxHardCapForMissingNodes, + trieSyncerVersion: args.GeneralConfig.TrieSync.TrieSyncerVersion, + enableEpochs: args.EnableEpochs, + dataSyncerFactory: args.DataSyncerCreator, + storerScheduledSCRs: args.ScheduledSCRsStorer, + shardCoordinator: args.GenesisShardCoordinator, + nodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, } log.Debug("process: enable epoch for transaction signed with tx hash", "epoch", epochStartProvider.enableEpochs.TransactionSignedWithTxHashEnableEpoch) @@ -710,6 +713,7 @@ func (e *epochStartBootstrap) processNodesConfig(pubKey []byte) error { ChanNodeStop: e.coreComponentsHolder.ChanStopNodeProcess(), NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), IsFullArchive: e.prefsConfig.FullArchive, + StakingV4EnableEpoch: e.enableEpochs.StakingV4EnableEpoch, } e.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index 0c7e355ef34..f7902eaed9d 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -87,11 +87,13 @@ func createMockEpochStartBootstrapArgs( cryptoMock *mock.CryptoComponentsMock, ) ArgsEpochStartBootstrap { generalCfg := testscommon.GetGeneralConfig() + ncr, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, 444) return ArgsEpochStartBootstrap{ - ScheduledSCRsStorer: genericMocks.NewStorerMock("path", 0), - CoreComponentsHolder: coreMock, - CryptoComponentsHolder: cryptoMock, - Messenger: &mock.MessengerStub{}, + ScheduledSCRsStorer: genericMocks.NewStorerMock("path", 0), + CoreComponentsHolder: coreMock, + CryptoComponentsHolder: cryptoMock, + Messenger: &mock.MessengerStub{}, + NodesCoordinatorRegistryFactory: ncr, GeneralConfig: config.Config{ MiniBlocksStorage: generalCfg.MiniBlocksStorage, PeerBlockBodyStorage: generalCfg.PeerBlockBodyStorage, diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index c2e288a6b65..b86c5a6c161 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -44,6 +44,7 @@ type ArgsNewSyncValidatorStatus struct { PubKey []byte ShardIdAsObserver uint32 WaitingListFixEnableEpoch uint32 + StakingV4EnableEpoch uint32 ChanNodeStop chan endProcess.ArgEndProcess NodeTypeProvider NodeTypeProviderHandler IsFullArchive bool @@ -92,25 +93,32 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat s.memDB = disabled.CreateMemUnit() + ncf, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory(args.Marshalizer, args.StakingV4EnableEpoch) + if err != nil { + return nil, err + } + argsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), - MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), - Marshalizer: args.Marshalizer, - Hasher: args.Hasher, - Shuffler: args.NodeShuffler, - EpochStartNotifier: &disabled.EpochStartNotifier{}, - BootStorer: s.memDB, - ShardIDAsObserver: args.ShardIdAsObserver, - NbShards: args.GenesisNodesConfig.NumberOfShards(), - EligibleNodes: eligibleValidators, - WaitingNodes: waitingValidators, - SelfPublicKey: args.PubKey, - ConsensusGroupCache: consensusGroupCache, - ShuffledOutHandler: disabled.NewShuffledOutHandler(), - WaitingListFixEnabledEpoch: args.WaitingListFixEnableEpoch, - ChanStopNode: args.ChanNodeStop, - NodeTypeProvider: args.NodeTypeProvider, - IsFullArchive: args.IsFullArchive, + ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), + MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), + Marshalizer: args.Marshalizer, + Hasher: args.Hasher, + Shuffler: args.NodeShuffler, + EpochStartNotifier: &disabled.EpochStartNotifier{}, + BootStorer: s.memDB, + ShardIDAsObserver: args.ShardIdAsObserver, + NbShards: args.GenesisNodesConfig.NumberOfShards(), + EligibleNodes: eligibleValidators, + WaitingNodes: waitingValidators, + SelfPublicKey: args.PubKey, + ConsensusGroupCache: consensusGroupCache, + ShuffledOutHandler: disabled.NewShuffledOutHandler(), + WaitingListFixEnabledEpoch: args.WaitingListFixEnableEpoch, + ChanStopNode: args.ChanNodeStop, + NodeTypeProvider: args.NodeTypeProvider, + IsFullArchive: args.IsFullArchive, + StakingV4EnableEpoch: args.StakingV4EnableEpoch, + NodesCoordinatorRegistryFactory: ncf, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/factory/bootstrapComponents.go b/factory/bootstrapComponents.go index 18e2d2f3084..06c64560691 100644 --- a/factory/bootstrapComponents.go +++ b/factory/bootstrapComponents.go @@ -17,6 +17,7 @@ import ( "github.com/ElrondNetwork/elrond-go/process/roundActivation" "github.com/ElrondNetwork/elrond-go/process/smartContract" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/storage" storageFactory "github.com/ElrondNetwork/elrond-go/storage/factory" "github.com/ElrondNetwork/elrond-go/storage/factory/directoryhandler" @@ -160,27 +161,37 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { dataSyncerFactory := bootstrap.NewScheduledDataSyncerFactory() + nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + bcf.coreComponents.InternalMarshalizer(), + bcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + ) + if err != nil { + return nil, err + } + bcf.coreComponents.EpochNotifier().RegisterNotifyHandler(nodesCoordinatorRegistryFactory) + epochStartBootstrapArgs := bootstrap.ArgsEpochStartBootstrap{ - CoreComponentsHolder: bcf.coreComponents, - CryptoComponentsHolder: bcf.cryptoComponents, - Messenger: bcf.networkComponents.NetworkMessenger(), - GeneralConfig: bcf.config, - PrefsConfig: bcf.prefConfig.Preferences, - EnableEpochs: bcf.epochConfig.EnableEpochs, - EconomicsData: bcf.coreComponents.EconomicsData(), - GenesisNodesConfig: bcf.coreComponents.GenesisNodesSetup(), - GenesisShardCoordinator: genesisShardCoordinator, - StorageUnitOpener: unitOpener, - Rater: bcf.coreComponents.Rater(), - DestinationShardAsObserver: destShardIdAsObserver, - NodeShuffler: bcf.coreComponents.NodesShuffler(), - RoundHandler: bcf.coreComponents.RoundHandler(), - LatestStorageDataProvider: latestStorageDataProvider, - ArgumentsParser: smartContract.NewArgumentParser(), - StatusHandler: bcf.coreComponents.StatusHandler(), - HeaderIntegrityVerifier: headerIntegrityVerifier, - DataSyncerCreator: dataSyncerFactory, - ScheduledSCRsStorer: nil, // will be updated after sync from network + CoreComponentsHolder: bcf.coreComponents, + CryptoComponentsHolder: bcf.cryptoComponents, + Messenger: bcf.networkComponents.NetworkMessenger(), + GeneralConfig: bcf.config, + PrefsConfig: bcf.prefConfig.Preferences, + EnableEpochs: bcf.epochConfig.EnableEpochs, + EconomicsData: bcf.coreComponents.EconomicsData(), + GenesisNodesConfig: bcf.coreComponents.GenesisNodesSetup(), + GenesisShardCoordinator: genesisShardCoordinator, + StorageUnitOpener: unitOpener, + Rater: bcf.coreComponents.Rater(), + DestinationShardAsObserver: destShardIdAsObserver, + NodeShuffler: bcf.coreComponents.NodesShuffler(), + RoundHandler: bcf.coreComponents.RoundHandler(), + LatestStorageDataProvider: latestStorageDataProvider, + ArgumentsParser: smartContract.NewArgumentParser(), + StatusHandler: bcf.coreComponents.StatusHandler(), + HeaderIntegrityVerifier: headerIntegrityVerifier, + DataSyncerCreator: dataSyncerFactory, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + ScheduledSCRsStorer: nil, // will be updated after sync from network } var epochStartBootstrapper EpochStartBootstrapper diff --git a/factory/shardingFactory.go b/factory/shardingFactory.go index 4a369b0b8b5..4d8cf09250f 100644 --- a/factory/shardingFactory.go +++ b/factory/shardingFactory.go @@ -103,6 +103,7 @@ func CreateNodesCoordinator( bootstrapParameters BootstrapParamsHolder, startEpoch uint32, waitingListFixEnabledEpoch uint32, + stakingV4EnableEpoch uint32, chanNodeStop chan endProcess.ArgEndProcess, nodeTypeProvider core.NodeTypeProviderHandler, ) (nodesCoordinator.NodesCoordinator, error) { @@ -173,27 +174,33 @@ func CreateNodesCoordinator( return nil, err } + nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory(marshalizer, stakingV4EnableEpoch) + if err != nil { + return nil, err + } + argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: marshalizer, - Hasher: hasher, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartNotifier, - BootStorer: bootStorer, - ShardIDAsObserver: shardIDAsObserver, - NbShards: nbShards, - EligibleNodes: eligibleValidators, - WaitingNodes: waitingValidators, - SelfPublicKey: pubKeyBytes, - ConsensusGroupCache: consensusGroupCache, - ShuffledOutHandler: shuffledOutHandler, - Epoch: currentEpoch, - StartEpoch: startEpoch, - WaitingListFixEnabledEpoch: waitingListFixEnabledEpoch, - ChanStopNode: chanNodeStop, - NodeTypeProvider: nodeTypeProvider, - IsFullArchive: prefsConfig.FullArchive, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: marshalizer, + Hasher: hasher, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartNotifier, + BootStorer: bootStorer, + ShardIDAsObserver: shardIDAsObserver, + NbShards: nbShards, + EligibleNodes: eligibleValidators, + WaitingNodes: waitingValidators, + SelfPublicKey: pubKeyBytes, + ConsensusGroupCache: consensusGroupCache, + ShuffledOutHandler: shuffledOutHandler, + Epoch: currentEpoch, + StartEpoch: startEpoch, + WaitingListFixEnabledEpoch: waitingListFixEnabledEpoch, + ChanStopNode: chanNodeStop, + NodeTypeProvider: nodeTypeProvider, + IsFullArchive: prefsConfig.FullArchive, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/consensus/testInitializer.go b/integrationTests/consensus/testInitializer.go index dffd5e91550..28a101b39a3 100644 --- a/integrationTests/consensus/testInitializer.go +++ b/integrationTests/consensus/testInitializer.go @@ -520,24 +520,26 @@ func createNodes( bootStorer := integrationTests.CreateMemUnit() consensusCache, _ := lrucache.NewCache(10000) + ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, integrationTests.StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusSize, - MetaConsensusGroupSize: 1, - Marshalizer: integrationTests.TestMarshalizer, - Hasher: createHasher(consensusType), - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartRegistrationHandler, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte(strconv.Itoa(i)), - ConsensusGroupCache: consensusCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: consensusSize, + MetaConsensusGroupSize: 1, + Marshalizer: integrationTests.TestMarshalizer, + Hasher: createHasher(consensusType), + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartRegistrationHandler, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte(strconv.Itoa(i)), + ConsensusGroupCache: consensusCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: ncf, } nodesCoord, _ := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 30de1b24a80..2f83c6b7f57 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -9,6 +9,7 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/storage" + "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" ) @@ -103,25 +104,27 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato WaitingListFixEnableEpoch: 0, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) + ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: arg.shardConsensusGroupSize, - MetaConsensusGroupSize: arg.metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: arg.hasher, - Shuffler: nodeShuffler, - EpochStartNotifier: arg.epochStartSubscriber, - ShardIDAsObserver: arg.shardId, - NbShards: uint32(arg.nbShards), - EligibleNodes: arg.validatorsMap, - WaitingNodes: arg.waitingMap, - SelfPublicKey: pubKeyBytes, - ConsensusGroupCache: arg.consensusGroupCache, - BootStorer: arg.bootStorer, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: arg.shardConsensusGroupSize, + MetaConsensusGroupSize: arg.metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: arg.hasher, + Shuffler: nodeShuffler, + EpochStartNotifier: arg.epochStartSubscriber, + ShardIDAsObserver: arg.shardId, + NbShards: uint32(arg.nbShards), + EligibleNodes: arg.validatorsMap, + WaitingNodes: arg.waitingMap, + SelfPublicKey: pubKeyBytes, + ConsensusGroupCache: arg.consensusGroupCache, + BootStorer: arg.bootStorer, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: ncf, } baseCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index db8f6765b95..61b0741d835 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -330,26 +330,28 @@ func CreateNodesWithTestP2PNodes( cacherCfg := storageUnit.CacheConfig{Capacity: 10000, Type: storageUnit.LRUCache, Shards: 1} cache, _ := storageUnit.NewCache(cacherCfg) for shardId, validatorList := range validatorsMap { + ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: uint32(numShards), - EligibleNodes: validatorsForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: cache, - Shuffler: &shardingMocks.NodeShufflerMock{}, - BootStorer: CreateMemUnit(), - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - Epoch: 0, - EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: uint32(numShards), + EligibleNodes: validatorsForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: cache, + Shuffler: &shardingMocks.NodeShufflerMock{}, + BootStorer: CreateMemUnit(), + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + Epoch: 0, + EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: ncf, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) @@ -375,26 +377,29 @@ func CreateNodesWithTestP2PNodes( shardId = core.MetachainShardId } + ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: uint32(numShards), - EligibleNodes: validatorsForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: cache, - Shuffler: &shardingMocks.NodeShufflerMock{}, - BootStorer: CreateMemUnit(), - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - Epoch: 0, - EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: uint32(numShards), + EligibleNodes: validatorsForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: cache, + Shuffler: &shardingMocks.NodeShufflerMock{}, + BootStorer: CreateMemUnit(), + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + Epoch: 0, + EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + StakingV4EnableEpoch: StakingV4Epoch, + NodesCoordinatorRegistryFactory: ncf, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 574ba4eed38..98ff92cd2a3 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -496,25 +496,28 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( completeNodesList := make([]Connectable, 0) for shardId, validatorList := range validatorsMap { consensusCache, _ := lrucache.NewCache(10000) + ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - Shuffler: nodeShuffler, - BootStorer: bootStorer, - EpochStartNotifier: epochStartSubscriber, - ShardIDAsObserver: shardId, - NbShards: uint32(nbShards), - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: consensusCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + Shuffler: nodeShuffler, + BootStorer: bootStorer, + EpochStartNotifier: epochStartSubscriber, + ShardIDAsObserver: shardId, + NbShards: uint32(nbShards), + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: consensusCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + StakingV4EnableEpoch: StakingV4Epoch, + NodesCoordinatorRegistryFactory: ncf, } nodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -595,25 +598,28 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( for shardId, validatorList := range validatorsMap { bootStorer := CreateMemUnit() cache, _ := lrucache.NewCache(10000) + ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardId, - NbShards: uint32(nbShards), - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: waitingMapForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: cache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardId, + NbShards: uint32(nbShards), + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: waitingMapForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: cache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: ncf, + StakingV4EnableEpoch: StakingV4Epoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index ba136a23f9a..5e2952f7360 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -328,6 +328,7 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), ) diff --git a/sharding/nodesCoordinator/common.go b/sharding/nodesCoordinator/common.go index 604433765ac..ef085facbef 100644 --- a/sharding/nodesCoordinator/common.go +++ b/sharding/nodesCoordinator/common.go @@ -2,11 +2,9 @@ package nodesCoordinator import ( "encoding/hex" - "encoding/json" "strconv" "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/marshal" logger "github.com/ElrondNetwork/elrond-go-logger" ) @@ -115,35 +113,3 @@ func SerializableShardValidatorListToValidatorList(shardValidators []*Serializab } return newValidators, nil } - -// CreateNodesCoordinatorRegistry creates a NodesCoordinatorRegistryHandler depending on the buffer. Old version uses -// NodesCoordinatorRegistry with a json marshaller; while the new version(from staking v4) uses NodesCoordinatorRegistryWithAuction -// with proto marshaller -func CreateNodesCoordinatorRegistry(marshaller marshal.Marshalizer, buff []byte) (NodesCoordinatorRegistryHandler, error) { - registry, err := createOldRegistry(buff) - if err == nil { - return registry, nil - } - - return createRegistryWithAuction(marshaller, buff) -} - -func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { - registry := &NodesCoordinatorRegistry{} - err := json.Unmarshal(buff, registry) - if err != nil { - return nil, err - } - - return registry, nil -} - -func createRegistryWithAuction(marshaller marshal.Marshalizer, buff []byte) (*NodesCoordinatorRegistryWithAuction, error) { - registry := &NodesCoordinatorRegistryWithAuction{} - err := marshaller.Unmarshal(registry, buff) - if err != nil { - return nil, err - } - - return registry, nil -} diff --git a/sharding/nodesCoordinator/errors.go b/sharding/nodesCoordinator/errors.go index ab63ba12f8c..2b316586425 100644 --- a/sharding/nodesCoordinator/errors.go +++ b/sharding/nodesCoordinator/errors.go @@ -91,12 +91,6 @@ var ErrNilBlockBody = errors.New("nil block body") // ErrNilShuffledOutHandler signals that a nil shuffled out handler has been provided var ErrNilShuffledOutHandler = errors.New("nil shuffled out handler") -// ErrNilEpochNotifier signals that the provided epoch notifier is nil -var ErrNilEpochNotifier = errors.New("nil epoch notifier") - -// ErrNilEndOfProcessingHandler signals that a nil end of processing handler has been provided -var ErrNilEndOfProcessingHandler = errors.New("nil end of processing handler") - // ErrNilOrEmptyDestinationForDistribute signals that a nil or empty value was provided for destination of distributedNodes var ErrNilOrEmptyDestinationForDistribute = errors.New("nil or empty destination list for distributeNodes") @@ -111,3 +105,6 @@ var ErrValidatorCannotBeFullArchive = errors.New("validator cannot be a full arc // ErrNilNodeTypeProvider signals that a nil node type provider has been given var ErrNilNodeTypeProvider = errors.New("nil node type provider") + +// ErrNilNodesCoordinatorRegistryFactory signals that a nil nodes coordinator registry factory has been given +var ErrNilNodesCoordinatorRegistryFactory = errors.New("nil nodes coordinator registry factory has been given") diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 12a7ceed950..b612918771c 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -69,34 +69,35 @@ type epochNodesConfig struct { } type indexHashedNodesCoordinator struct { - shardIDAsObserver uint32 - currentEpoch uint32 - shardConsensusGroupSize int - metaConsensusGroupSize int - numTotalEligible uint64 - selfPubKey []byte - savedStateKey []byte - marshalizer marshal.Marshalizer - hasher hashing.Hasher - shuffler NodesShuffler - epochStartRegistrationHandler EpochStartEventNotifier - bootStorer storage.Storer - nodesConfig map[uint32]*epochNodesConfig - mutNodesConfig sync.RWMutex - mutSavedStateKey sync.RWMutex - nodesCoordinatorHelper NodesCoordinatorHelper - consensusGroupCacher Cacher - loadingFromDisk atomic.Value - shuffledOutHandler ShuffledOutHandler - startEpoch uint32 - publicKeyToValidatorMap map[string]*validatorWithShardID - waitingListFixEnableEpoch uint32 - stakingV4EnableEpoch uint32 - isFullArchive bool - chanStopNode chan endProcess.ArgEndProcess - flagWaitingListFix atomicFlags.Flag - flagStakingV4 atomicFlags.Flag - nodeTypeProvider NodeTypeProviderHandler + shardIDAsObserver uint32 + currentEpoch uint32 + shardConsensusGroupSize int + metaConsensusGroupSize int + numTotalEligible uint64 + selfPubKey []byte + savedStateKey []byte + marshalizer marshal.Marshalizer + hasher hashing.Hasher + shuffler NodesShuffler + epochStartRegistrationHandler EpochStartEventNotifier + bootStorer storage.Storer + nodesConfig map[uint32]*epochNodesConfig + mutNodesConfig sync.RWMutex + mutSavedStateKey sync.RWMutex + nodesCoordinatorHelper NodesCoordinatorHelper + consensusGroupCacher Cacher + loadingFromDisk atomic.Value + shuffledOutHandler ShuffledOutHandler + startEpoch uint32 + publicKeyToValidatorMap map[string]*validatorWithShardID + waitingListFixEnableEpoch uint32 + stakingV4EnableEpoch uint32 + isFullArchive bool + chanStopNode chan endProcess.ArgEndProcess + flagWaitingListFix atomicFlags.Flag + flagStakingV4 atomicFlags.Flag + nodeTypeProvider NodeTypeProviderHandler + nodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory } // NewIndexHashedNodesCoordinator creates a new index hashed group selector @@ -123,27 +124,28 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed savedKey := arguments.Hasher.Compute(string(arguments.SelfPublicKey)) ihnc := &indexHashedNodesCoordinator{ - marshalizer: arguments.Marshalizer, - hasher: arguments.Hasher, - shuffler: arguments.Shuffler, - epochStartRegistrationHandler: arguments.EpochStartNotifier, - bootStorer: arguments.BootStorer, - selfPubKey: arguments.SelfPublicKey, - nodesConfig: nodesConfig, - currentEpoch: arguments.Epoch, - savedStateKey: savedKey, - shardConsensusGroupSize: arguments.ShardConsensusGroupSize, - metaConsensusGroupSize: arguments.MetaConsensusGroupSize, - consensusGroupCacher: arguments.ConsensusGroupCache, - shardIDAsObserver: arguments.ShardIDAsObserver, - shuffledOutHandler: arguments.ShuffledOutHandler, - startEpoch: arguments.StartEpoch, - publicKeyToValidatorMap: make(map[string]*validatorWithShardID), - waitingListFixEnableEpoch: arguments.WaitingListFixEnabledEpoch, - stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, - chanStopNode: arguments.ChanStopNode, - nodeTypeProvider: arguments.NodeTypeProvider, - isFullArchive: arguments.IsFullArchive, + marshalizer: arguments.Marshalizer, + hasher: arguments.Hasher, + shuffler: arguments.Shuffler, + epochStartRegistrationHandler: arguments.EpochStartNotifier, + bootStorer: arguments.BootStorer, + selfPubKey: arguments.SelfPublicKey, + nodesConfig: nodesConfig, + currentEpoch: arguments.Epoch, + savedStateKey: savedKey, + shardConsensusGroupSize: arguments.ShardConsensusGroupSize, + metaConsensusGroupSize: arguments.MetaConsensusGroupSize, + consensusGroupCacher: arguments.ConsensusGroupCache, + shardIDAsObserver: arguments.ShardIDAsObserver, + shuffledOutHandler: arguments.ShuffledOutHandler, + startEpoch: arguments.StartEpoch, + publicKeyToValidatorMap: make(map[string]*validatorWithShardID), + waitingListFixEnableEpoch: arguments.WaitingListFixEnabledEpoch, + stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, + chanStopNode: arguments.ChanStopNode, + nodeTypeProvider: arguments.NodeTypeProvider, + isFullArchive: arguments.IsFullArchive, + nodesCoordinatorRegistryFactory: arguments.NodesCoordinatorRegistryFactory, } log.Debug("indexHashedNodesCoordinator: enable epoch for waiting waiting list", "epoch", ihnc.waitingListFixEnableEpoch) log.Debug("indexHashedNodesCoordinator: staking v4", "epoch", ihnc.stakingV4EnableEpoch) @@ -220,6 +222,9 @@ func checkArguments(arguments ArgNodesCoordinator) error { if check.IfNil(arguments.NodeTypeProvider) { return ErrNilNodeTypeProvider } + if check.IfNil(arguments.NodesCoordinatorRegistryFactory) { + return ErrNilNodesCoordinatorRegistryFactory + } if nil == arguments.ChanStopNode { return ErrNilNodeStopChannel } @@ -1228,4 +1233,6 @@ func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4EnableEpoch) log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4.IsSet()) + + ihnc.nodesCoordinatorRegistryFactory.EpochConfirmed(epoch, 0) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go index 0714bff74ea..4224b7b9983 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go @@ -26,7 +26,7 @@ func (ihnc *indexHashedNodesCoordinator) baseLoadState(key []byte) error { return err } - config, err := CreateNodesCoordinatorRegistry(ihnc.marshalizer, data) + config, err := ihnc.nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry(data) if err != nil { return err } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go index a398e66fe32..0ba32543aee 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go @@ -6,7 +6,6 @@ import ( "strconv" "testing" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -102,9 +101,8 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing. t.Parallel() args := createArguments() - args.Marshalizer = &marshal.GogoProtoMarshalizer{} nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) - nodesCoordinator.flagStakingV4.SetValue(true) + nodesCoordinator.updateEpochFlags(stakingV4Epoch) nodesCoordinator.nodesConfig[0].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) nodesCoordinator.nodesConfig[0].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go index 49dcb65658a..c887ec03cae 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go @@ -15,8 +15,8 @@ import ( "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/sharding/mock" - "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -76,23 +76,24 @@ func TestIndexHashedGroupSelectorWithRater_OkValShouldWork(t *testing.T) { bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 2, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("test"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: 2, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("test"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } nc, err := NewIndexHashedNodesCoordinator(arguments) assert.Nil(t, err) @@ -316,23 +317,24 @@ func TestIndexHashedGroupSelectorWithRater_GetValidatorWithPublicKeyShouldReturn bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } nc, _ := NewIndexHashedNodesCoordinator(arguments) ihnc, _ := NewIndexHashedNodesCoordinatorWithRater(nc, &mock.RaterMock{}) @@ -368,23 +370,24 @@ func TestIndexHashedGroupSelectorWithRater_GetValidatorWithPublicKeyShouldReturn bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } nc, _ := NewIndexHashedNodesCoordinator(arguments) ihnc, _ := NewIndexHashedNodesCoordinatorWithRater(nc, &mock.RaterMock{}) @@ -434,23 +437,24 @@ func TestIndexHashedGroupSelectorWithRater_GetValidatorWithPublicKeyShouldWork(t eligibleMap[1] = listShard1 arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } nc, _ := NewIndexHashedNodesCoordinator(arguments) ihnc, _ := NewIndexHashedNodesCoordinatorWithRater(nc, &mock.RaterMock{}) @@ -516,24 +520,25 @@ func TestIndexHashedGroupSelectorWithRater_GetAllEligibleValidatorsPublicKeys(t eligibleMap[shardOneId] = listShard1 arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardZeroId, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardZeroId, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } nc, _ := NewIndexHashedNodesCoordinator(arguments) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index d6c10a20110..e5eaa1df608 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -28,6 +28,8 @@ import ( "github.com/stretchr/testify/require" ) +const stakingV4Epoch = 444 + func createDummyNodesList(nbNodes uint32, suffix string) []Validator { list := make([]Validator, 0) hasher := sha256.NewSha256() @@ -75,6 +77,11 @@ func isStringSubgroup(a []string, b []string) bool { return found } +func createNodesCoordinatorRegistryFactory() NodesCoordinatorRegistryFactory { + ncf, _ := NewNodesCoordinatorRegistryFactory(&mock.MarshalizerMock{}, stakingV4Epoch) + return ncf +} + func createArguments() ArgNodesCoordinator { nbShards := uint32(1) eligibleMap := createDummyNodesMap(10, nbShards, "eligible") @@ -86,7 +93,7 @@ func createArguments() ArgNodesCoordinator { Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 444, + StakingV4EnableEpoch: stakingV4Epoch, } nodeShuffler, _ := NewHashValidatorsShuffler(shufflerArgs) @@ -94,24 +101,25 @@ func createArguments() ArgNodesCoordinator { bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: nbShards, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("test"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - IsFullArchive: false, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - StakingV4EnableEpoch: 444, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: nbShards, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("test"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + IsFullArchive: false, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + StakingV4EnableEpoch: stakingV4Epoch, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } return arguments } @@ -244,22 +252,23 @@ func TestIndexHashedNodesCoordinator_OkValShouldWork(t *testing.T) { bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 2, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 2, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, err := NewIndexHashedNodesCoordinator(arguments) @@ -302,22 +311,23 @@ func TestIndexHashedNodesCoordinator_NewCoordinatorTooFewNodesShouldErr(t *testi bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 10, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 10, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, err := NewIndexHashedNodesCoordinator(arguments) @@ -374,22 +384,23 @@ func TestIndexHashedNodesCoordinator_ComputeValidatorsGroup1ValidatorShouldRetur bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: nodesMap, - WaitingNodes: make(map[uint32][]Validator), - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: nodesMap, + WaitingNodes: make(map[uint32][]Validator), + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) list2, err := ihnc.ComputeConsensusGroup([]byte("randomness"), 0, 0, 0) @@ -432,22 +443,23 @@ func TestIndexHashedNodesCoordinator_ComputeValidatorsGroup400of400For10locksNoM } arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusGroupSize, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: cache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: consensusGroupSize, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: cache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, err := NewIndexHashedNodesCoordinator(arguments) @@ -518,22 +530,23 @@ func TestIndexHashedNodesCoordinator_ComputeValidatorsGroup400of400For10BlocksMe } arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusGroupSize, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: cache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: consensusGroupSize, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: cache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, err := NewIndexHashedNodesCoordinator(arguments) @@ -906,22 +919,23 @@ func TestIndexHashedNodesCoordinator_GetValidatorWithPublicKeyShouldWork(t *test bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: make(map[uint32][]Validator), - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: make(map[uint32][]Validator), + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -987,23 +1001,24 @@ func TestIndexHashedGroupSelector_GetAllEligibleValidatorsPublicKeys(t *testing. bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardZeroId, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: make(map[uint32][]Validator), - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardZeroId, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: make(map[uint32][]Validator), + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -1064,23 +1079,24 @@ func TestIndexHashedGroupSelector_GetAllWaitingValidatorsPublicKeys(t *testing.T eligibleMap[shardZeroId] = []Validator{&validator{}} arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardZeroId, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardZeroId, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -1440,22 +1456,23 @@ func TestIndexHashedNodesCoordinator_EpochStart_EligibleSortedAscendingByIndex(t bootStorer := mock.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: nbShards, - EligibleNodes: eligibleMap, - WaitingNodes: map[uint32][]Validator{}, - SelfPublicKey: []byte("test"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: nbShards, + EligibleNodes: eligibleMap, + WaitingNodes: map[uint32][]Validator{}, + SelfPublicKey: []byte("test"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, err := NewIndexHashedNodesCoordinator(arguments) diff --git a/sharding/nodesCoordinator/interface.go b/sharding/nodesCoordinator/interface.go index acd343d5664..69d5bf12603 100644 --- a/sharding/nodesCoordinator/interface.go +++ b/sharding/nodesCoordinator/interface.go @@ -150,3 +150,11 @@ type NodesCoordinatorRegistryHandler interface { GetCurrentEpoch() uint32 SetCurrentEpoch(epoch uint32) } + +// NodesCoordinatorRegistryFactory defines a NodesCoordinatorRegistryHandler factory +// from the provided buffer +type NodesCoordinatorRegistryFactory interface { + CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) + EpochConfirmed(epoch uint32, timestamp uint64) + IsInterfaceNil() bool +} diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go new file mode 100644 index 00000000000..140c04c02d7 --- /dev/null +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -0,0 +1,73 @@ +package nodesCoordinator + +import ( + "encoding/json" + + "github.com/ElrondNetwork/elrond-go-core/core/atomic" + "github.com/ElrondNetwork/elrond-go-core/core/check" + "github.com/ElrondNetwork/elrond-go-core/marshal" +) + +type nodesCoordinatorRegistryFactory struct { + stakingV4EnableEpoch uint32 + flagStakingV4 atomic.Flag + marshaller marshal.Marshalizer +} + +// NewNodesCoordinatorRegistryFactory creates a nodes coordinator registry factory which will create a +// NodesCoordinatorRegistryHandler from a buffer depending on the epoch +func NewNodesCoordinatorRegistryFactory( + marshaller marshal.Marshalizer, + stakingV4EnableEpoch uint32, +) (*nodesCoordinatorRegistryFactory, error) { + if check.IfNil(marshaller) { + return nil, ErrNilMarshalizer + } + + log.Debug("nodesCoordinatorRegistryFactory: staking v4 enable epoch", "epoch", stakingV4EnableEpoch) + return &nodesCoordinatorRegistryFactory{ + marshaller: marshaller, + stakingV4EnableEpoch: stakingV4EnableEpoch, + }, nil +} + +// CreateNodesCoordinatorRegistry creates a NodesCoordinatorRegistryHandler depending on the buffer. Old version uses +// NodesCoordinatorRegistry with a json marshaller; while the new version(from staking v4) uses NodesCoordinatorRegistryWithAuction +// with proto marshaller +func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) { + if ncf.flagStakingV4.IsSet() { + return ncf.createRegistryWithAuction(buff) + } + return createOldRegistry(buff) +} + +func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { + registry := &NodesCoordinatorRegistry{} + err := json.Unmarshal(buff, registry) + if err != nil { + return nil, err + } + + return registry, nil +} + +func (ncf *nodesCoordinatorRegistryFactory) createRegistryWithAuction(buff []byte) (*NodesCoordinatorRegistryWithAuction, error) { + registry := &NodesCoordinatorRegistryWithAuction{} + err := ncf.marshaller.Unmarshal(registry, buff) + if err != nil { + return nil, err + } + + return registry, nil +} + +// IsInterfaceNil checks if the underlying pointer is nil +func (ncf *nodesCoordinatorRegistryFactory) IsInterfaceNil() bool { + return ncf == nil +} + +// EpochConfirmed is called whenever a new epoch is confirmed +func (ncf *nodesCoordinatorRegistryFactory) EpochConfirmed(epoch uint32, _ uint64) { + ncf.flagStakingV4.SetValue(epoch >= ncf.stakingV4EnableEpoch) + log.Debug("nodesCoordinatorRegistryFactory: staking v4", "enabled", ncf.flagStakingV4.IsSet()) +} diff --git a/sharding/nodesCoordinator/shardingArgs.go b/sharding/nodesCoordinator/shardingArgs.go index 66d080aa419..ee1827053bb 100644 --- a/sharding/nodesCoordinator/shardingArgs.go +++ b/sharding/nodesCoordinator/shardingArgs.go @@ -9,25 +9,26 @@ import ( // ArgNodesCoordinator holds all dependencies required by the nodes coordinator in order to create new instances type ArgNodesCoordinator struct { - ShardConsensusGroupSize int - MetaConsensusGroupSize int - Marshalizer marshal.Marshalizer - Hasher hashing.Hasher - Shuffler NodesShuffler - EpochStartNotifier EpochStartEventNotifier - BootStorer storage.Storer - ShardIDAsObserver uint32 - NbShards uint32 - EligibleNodes map[uint32][]Validator - WaitingNodes map[uint32][]Validator - SelfPublicKey []byte - Epoch uint32 - StartEpoch uint32 - ConsensusGroupCache Cacher - ShuffledOutHandler ShuffledOutHandler - WaitingListFixEnabledEpoch uint32 - ChanStopNode chan endProcess.ArgEndProcess - NodeTypeProvider NodeTypeProviderHandler - IsFullArchive bool - StakingV4EnableEpoch uint32 + ShardConsensusGroupSize int + MetaConsensusGroupSize int + Marshalizer marshal.Marshalizer + Hasher hashing.Hasher + Shuffler NodesShuffler + EpochStartNotifier EpochStartEventNotifier + BootStorer storage.Storer + ShardIDAsObserver uint32 + NbShards uint32 + EligibleNodes map[uint32][]Validator + WaitingNodes map[uint32][]Validator + SelfPublicKey []byte + Epoch uint32 + StartEpoch uint32 + ConsensusGroupCache Cacher + ShuffledOutHandler ShuffledOutHandler + WaitingListFixEnabledEpoch uint32 + ChanStopNode chan endProcess.ArgEndProcess + NodeTypeProvider NodeTypeProviderHandler + IsFullArchive bool + StakingV4EnableEpoch uint32 + NodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory } From ccea2111c3a89cf068336c11e4bb6fba35db09ac Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 11:42:35 +0200 Subject: [PATCH 139/958] FIX: Test --- factory/bootstrapComponents_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/factory/bootstrapComponents_test.go b/factory/bootstrapComponents_test.go index f2f864e0302..aeca1e591fd 100644 --- a/factory/bootstrapComponents_test.go +++ b/factory/bootstrapComponents_test.go @@ -11,6 +11,7 @@ import ( "github.com/ElrondNetwork/elrond-go/factory/mock" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/stretchr/testify/require" @@ -170,5 +171,6 @@ func getDefaultCoreComponents() *mock.CoreComponentsMock { NodesConfig: &testscommon.NodesSetupStub{}, StartTime: time.Time{}, NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EpochChangeNotifier: &epochNotifier.EpochNotifierStub{}, } } From 04b6888c1c5dd2d788ce7c866a1ba802eba19082 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 11:55:10 +0200 Subject: [PATCH 140/958] FIX: CreateNodesCoordinator --- .../factory/consensusComponents/consensusComponents_test.go | 1 + .../factory/processComponents/processComponents_test.go | 1 + .../factory/statusComponents/statusComponents_test.go | 1 + 3 files changed, 3 insertions(+) diff --git a/integrationTests/factory/consensusComponents/consensusComponents_test.go b/integrationTests/factory/consensusComponents/consensusComponents_test.go index 5c74cfdec98..11711e9f32a 100644 --- a/integrationTests/factory/consensusComponents/consensusComponents_test.go +++ b/integrationTests/factory/consensusComponents/consensusComponents_test.go @@ -63,6 +63,7 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), ) diff --git a/integrationTests/factory/processComponents/processComponents_test.go b/integrationTests/factory/processComponents/processComponents_test.go index 3f0371137f7..c69c2caf88b 100644 --- a/integrationTests/factory/processComponents/processComponents_test.go +++ b/integrationTests/factory/processComponents/processComponents_test.go @@ -64,6 +64,7 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), ) diff --git a/integrationTests/factory/statusComponents/statusComponents_test.go b/integrationTests/factory/statusComponents/statusComponents_test.go index 30da3113aad..637f1ded899 100644 --- a/integrationTests/factory/statusComponents/statusComponents_test.go +++ b/integrationTests/factory/statusComponents/statusComponents_test.go @@ -64,6 +64,7 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), ) From eca5854a98720fc98104b01b8c4554bc23cf4d3b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 12:27:53 +0200 Subject: [PATCH 141/958] FIX: Review findings --- sharding/nodesCoordinator/errors.go | 3 +++ sharding/nodesCoordinator/hashValidatorShuffler.go | 2 ++ sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 4 +++- sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go | 4 ++-- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/sharding/nodesCoordinator/errors.go b/sharding/nodesCoordinator/errors.go index 2b316586425..c28f6e61be0 100644 --- a/sharding/nodesCoordinator/errors.go +++ b/sharding/nodesCoordinator/errors.go @@ -108,3 +108,6 @@ var ErrNilNodeTypeProvider = errors.New("nil node type provider") // ErrNilNodesCoordinatorRegistryFactory signals that a nil nodes coordinator registry factory has been given var ErrNilNodesCoordinatorRegistryFactory = errors.New("nil nodes coordinator registry factory has been given") + +// ErrReceivedAuctionValidatorsBeforeStakingV4 signals that auction nodes have been received from peer mini blocks before enabling staking v4 +var ErrReceivedAuctionValidatorsBeforeStakingV4 = errors.New("should no have received selected nodes from auction in peer mini blocks, since staking v4 is not enabled yet") diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index de50c57744e..c7cc625020b 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -298,11 +298,13 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { } if arg.flagStakingV4 { + // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) if err != nil { log.Warn("distributeValidators auction list failed", "error", err) } } else { + // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) if err != nil { log.Warn("distributeValidators shuffledOut failed", "error", err) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index b612918771c..8ee4a0bda0f 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -148,7 +148,7 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed nodesCoordinatorRegistryFactory: arguments.NodesCoordinatorRegistryFactory, } log.Debug("indexHashedNodesCoordinator: enable epoch for waiting waiting list", "epoch", ihnc.waitingListFixEnableEpoch) - log.Debug("indexHashedNodesCoordinator: staking v4", "epoch", ihnc.stakingV4EnableEpoch) + log.Debug("indexHashedNodesCoordinator: enable epoch for staking v4", "epoch", ihnc.stakingV4EnableEpoch) ihnc.loadingFromDisk.Store(false) @@ -759,6 +759,8 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.SelectedFromAuctionList): if ihnc.flagStakingV4.IsSet() { auctionList = append(auctionList, currentValidator) + } else { + return nil, ErrReceivedAuctionValidatorsBeforeStakingV4 } } } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index e5eaa1df608..5371332551f 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -2099,8 +2099,8 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * } newNodesConfig, err := nc.computeNodesConfigFromList(previousConfig, validatorInfos) - require.Nil(t, err) - require.Empty(t, newNodesConfig.auctionList) + require.Equal(t, ErrReceivedAuctionValidatorsBeforeStakingV4, err) + require.Nil(t, newNodesConfig) nc.flagStakingV4.SetReturningPrevious() From f0f8e67cd2f65e041f252ce2f95a0176faeba494 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 12:53:19 +0200 Subject: [PATCH 142/958] FEAT: Remove duplicated stubs --- .../metachain/rewardsCreatorProxy_test.go | 31 ++--- .../mock/epochRewardsCreatorStub.go | 109 ------------------ integrationTests/testSyncNode.go | 2 +- process/block/metablock_test.go | 14 +-- process/mock/epochRewardsCreatorStub.go | 109 ------------------ .../rewardsCreatorStub.go | 2 +- 6 files changed, 25 insertions(+), 242 deletions(-) delete mode 100644 integrationTests/mock/epochRewardsCreatorStub.go delete mode 100644 process/mock/epochRewardsCreatorStub.go rename {epochStart/mock => testscommon}/rewardsCreatorStub.go (99%) diff --git a/epochStart/metachain/rewardsCreatorProxy_test.go b/epochStart/metachain/rewardsCreatorProxy_test.go index 0be19faba25..5e702f6e844 100644 --- a/epochStart/metachain/rewardsCreatorProxy_test.go +++ b/epochStart/metachain/rewardsCreatorProxy_test.go @@ -14,6 +14,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/stretchr/testify/require" @@ -53,7 +54,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithError(t *testing.T) { t.Parallel() expectedErr := fmt.Errorf("expectedError") - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { @@ -72,7 +73,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithError(t *testing.T) { func TestRewardsCreatorProxy_CreateRewardsMiniBlocksOK(t *testing.T) { t.Parallel() - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { @@ -91,7 +92,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksOK(t *testing.T) { func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithSwitchToRewardsCreatorV2(t *testing.T) { t.Parallel() - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { @@ -117,7 +118,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithSwitchToRewardsCreatorV2 func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithSwitchToRewardsCreatorV1(t *testing.T) { t.Parallel() - rewardCreatorV2 := &mock.RewardsCreatorStub{ + rewardCreatorV2 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { @@ -144,7 +145,7 @@ func TestRewardsCreatorProxy_VerifyRewardsMiniBlocksWithError(t *testing.T) { t.Parallel() expectedErr := fmt.Errorf("expectedError") - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics) error { return expectedErr @@ -161,7 +162,7 @@ func TestRewardsCreatorProxy_VerifyRewardsMiniBlocksWithError(t *testing.T) { func TestRewardsCreatorProxy_VerifyRewardsMiniBlocksOK(t *testing.T) { t.Parallel() - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics) error { return nil @@ -179,7 +180,7 @@ func TestRewardsCreatorProxy_GetProtocolSustainabilityRewards(t *testing.T) { t.Parallel() expectedValue := big.NewInt(12345) - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ GetProtocolSustainabilityRewardsCalled: func() *big.Int { return expectedValue }, @@ -195,7 +196,7 @@ func TestRewardsCreatorProxy_GetLocalTxCache(t *testing.T) { t.Parallel() expectedValue := &mock.TxForCurrentBlockStub{} - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ GetLocalTxCacheCalled: func() epochStart.TransactionCacher { return expectedValue }, @@ -213,7 +214,7 @@ func TestRewardsCreatorProxy_CreateMarshalizedData(t *testing.T) { expectedValue := make(map[string][][]byte) blockBody := createDefaultBlockBody() - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateMarshalizedDataCalled: func(body *block.Body) map[string][][]byte { if blockBody == body { return expectedValue @@ -237,7 +238,7 @@ func TestRewardsCreatorProxy_GetRewardsTxs(t *testing.T) { } blockBody := createDefaultBlockBody() - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ GetRewardsTxsCalled: func(body *block.Body) map[string]data.TransactionHandler { if blockBody == body { return expectedValue @@ -258,7 +259,7 @@ func TestRewardsCreatorProxy_SaveTxBlockToStorage(t *testing.T) { blockBody := createDefaultBlockBody() functionCalled := false - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ SaveTxBlockToStorageCalled: func(metaBlock data.MetaHeaderHandler, body *block.Body) { functionCalled = true }, @@ -276,7 +277,7 @@ func TestRewardsCreatorProxy_DeleteTxsFromStorage(t *testing.T) { blockBody := createDefaultBlockBody() functionCalled := false - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ DeleteTxsFromStorageCalled: func(metaBlock data.MetaHeaderHandler, body *block.Body) { functionCalled = true }, @@ -294,7 +295,7 @@ func TestRewardsCreatorProxy_RemoveBlockDataFromPools(t *testing.T) { blockBody := createDefaultBlockBody() functionCalled := false - rewardCreatorV1 := &mock.RewardsCreatorStub{ + rewardCreatorV1 := &testscommon.RewardsCreatorStub{ RemoveBlockDataFromPoolsCalled: func(metaBlock data.MetaHeaderHandler, body *block.Body) { functionCalled = true }, @@ -312,13 +313,13 @@ func TestRewardsCreatorProxy_IsInterfaceNil(t *testing.T) { var rewardsCreatorProxy epochStart.RewardsCreator require.True(t, check.IfNil(rewardsCreatorProxy)) - rewardCreatorV1 := &mock.RewardsCreatorStub{} + rewardCreatorV1 := &testscommon.RewardsCreatorStub{} rewardsCreatorProxy, _, _ = createTestData(rewardCreatorV1, rCreatorV1) require.False(t, check.IfNil(rewardsCreatorProxy)) } -func createTestData(rewardCreator *mock.RewardsCreatorStub, rcType configuredRewardsCreator) (*rewardsCreatorProxy, map[uint32][]*state.ValidatorInfo, *block.MetaBlock) { +func createTestData(rewardCreator epochStart.RewardsCreator, rcType configuredRewardsCreator) (*rewardsCreatorProxy, map[uint32][]*state.ValidatorInfo, *block.MetaBlock) { args := createDefaultRewardsCreatorProxyArgs() rewardsCreatorProxy := &rewardsCreatorProxy{ rc: rewardCreator, diff --git a/integrationTests/mock/epochRewardsCreatorStub.go b/integrationTests/mock/epochRewardsCreatorStub.go deleted file mode 100644 index 5302875ec54..00000000000 --- a/integrationTests/mock/epochRewardsCreatorStub.go +++ /dev/null @@ -1,109 +0,0 @@ -package mock - -import ( - "math/big" - - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/state" -) - -// EpochRewardsCreatorStub - -type EpochRewardsCreatorStub struct { - CreateRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) (block.MiniBlockSlice, error) - VerifyRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) error - CreateMarshalizedDataCalled func(body *block.Body) map[string][][]byte - SaveTxBlockToStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - DeleteTxsFromStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - RemoveBlockDataFromPoolsCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - GetRewardsTxsCalled func(body *block.Body) map[string]data.TransactionHandler - GetProtocolSustainCalled func() *big.Int - GetLocalTxCacheCalled func() epochStart.TransactionCacher -} - -// GetProtocolSustainabilityRewards - -func (e *EpochRewardsCreatorStub) GetProtocolSustainabilityRewards() *big.Int { - if e.GetProtocolSustainCalled != nil { - return e.GetProtocolSustainCalled() - } - return big.NewInt(0) -} - -// GetLocalTxCache - -func (e *EpochRewardsCreatorStub) GetLocalTxCache() epochStart.TransactionCacher { - if e.GetLocalTxCacheCalled != nil { - return e.GetLocalTxCacheCalled() - } - return &TxForCurrentBlockStub{} -} - -// CreateRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) CreateRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) (block.MiniBlockSlice, error) { - if e.CreateRewardsMiniBlocksCalled != nil { - return e.CreateRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil, nil -} - -// GetRewardsTxs -- -func (e *EpochRewardsCreatorStub) GetRewardsTxs(body *block.Body) map[string]data.TransactionHandler { - if e.GetRewardsTxsCalled != nil { - return e.GetRewardsTxsCalled(body) - } - return nil -} - -// VerifyRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) VerifyRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) error { - if e.VerifyRewardsMiniBlocksCalled != nil { - return e.VerifyRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil -} - -// CreateMarshalizedData - -func (e *EpochRewardsCreatorStub) CreateMarshalizedData(body *block.Body) map[string][][]byte { - if e.CreateMarshalizedDataCalled != nil { - return e.CreateMarshalizedDataCalled(body) - } - return nil -} - -// SaveTxBlockToStorage - -func (e *EpochRewardsCreatorStub) SaveTxBlockToStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.SaveTxBlockToStorageCalled != nil { - e.SaveTxBlockToStorageCalled(metaBlock, body) - } -} - -// DeleteTxsFromStorage - -func (e *EpochRewardsCreatorStub) DeleteTxsFromStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.DeleteTxsFromStorageCalled != nil { - e.DeleteTxsFromStorageCalled(metaBlock, body) - } -} - -// IsInterfaceNil - -func (e *EpochRewardsCreatorStub) IsInterfaceNil() bool { - return e == nil -} - -// RemoveBlockDataFromPools - -func (e *EpochRewardsCreatorStub) RemoveBlockDataFromPools(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.RemoveBlockDataFromPoolsCalled != nil { - e.RemoveBlockDataFromPoolsCalled(metaBlock, body) - } -} diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index 9f02b91edcb..509e19e5549 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -238,7 +238,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, EpochEconomics: &mock.EpochEconomicsStub{}, - EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, + EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 5bc0f8bd94c..05f2eebe129 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -138,7 +138,7 @@ func createMockMetaArguments( PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, EpochEconomics: &mock.EpochEconomicsStub{}, - EpochRewardsCreator: &mock.EpochRewardsCreatorStub{}, + EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, @@ -3082,7 +3082,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) wasCalled := false - arguments.EpochRewardsCreator = &mock.EpochRewardsCreatorStub{ + arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) error { @@ -3113,7 +3113,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{} wasCalled := false - arguments.EpochRewardsCreator = &mock.EpochRewardsCreatorStub{ + arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) error { @@ -3339,7 +3339,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { } expectedRewardsForProtocolSustain := big.NewInt(11) - arguments.EpochRewardsCreator = &mock.EpochRewardsCreatorStub{ + arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { @@ -3348,7 +3348,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { assert.True(t, wasCalled) return rewardMiniBlocks, nil }, - GetProtocolSustainCalled: func() *big.Int { + GetProtocolSustainabilityRewardsCalled: func() *big.Int { return expectedRewardsForProtocolSustain }, } @@ -3401,7 +3401,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { wasCalled := false expectedRewardsForProtocolSustain := big.NewInt(11) - arguments.EpochRewardsCreator = &mock.EpochRewardsCreatorStub{ + arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { @@ -3410,7 +3410,7 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { assert.Equal(t, mb, metaBlock) return rewardMiniBlocks, nil }, - GetProtocolSustainCalled: func() *big.Int { + GetProtocolSustainabilityRewardsCalled: func() *big.Int { return expectedRewardsForProtocolSustain }, } diff --git a/process/mock/epochRewardsCreatorStub.go b/process/mock/epochRewardsCreatorStub.go deleted file mode 100644 index e465ef2bdf9..00000000000 --- a/process/mock/epochRewardsCreatorStub.go +++ /dev/null @@ -1,109 +0,0 @@ -package mock - -import ( - "math/big" - - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/state" -) - -// EpochRewardsCreatorStub - -type EpochRewardsCreatorStub struct { - CreateRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) (block.MiniBlockSlice, error) - VerifyRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) error - CreateMarshalizedDataCalled func(body *block.Body) map[string][][]byte - SaveTxBlockToStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - DeleteTxsFromStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - RemoveBlockDataFromPoolsCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - GetRewardsTxsCalled func(body *block.Body) map[string]data.TransactionHandler - GetProtocolSustainCalled func() *big.Int - GetLocalTxCacheCalled func() epochStart.TransactionCacher -} - -// GetProtocolSustainabilityRewards - -func (e *EpochRewardsCreatorStub) GetProtocolSustainabilityRewards() *big.Int { - if e.GetProtocolSustainCalled != nil { - return e.GetProtocolSustainCalled() - } - return big.NewInt(0) -} - -// GetLocalTxCache - -func (e *EpochRewardsCreatorStub) GetLocalTxCache() epochStart.TransactionCacher { - if e.GetLocalTxCacheCalled != nil { - return e.GetLocalTxCacheCalled() - } - return &TxForCurrentBlockStub{} -} - -// CreateRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) CreateRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) (block.MiniBlockSlice, error) { - if e.CreateRewardsMiniBlocksCalled != nil { - return e.CreateRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil, nil -} - -// VerifyRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) VerifyRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) error { - if e.VerifyRewardsMiniBlocksCalled != nil { - return e.VerifyRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil -} - -// CreateMarshalizedData - -func (e *EpochRewardsCreatorStub) CreateMarshalizedData(body *block.Body) map[string][][]byte { - if e.CreateMarshalizedDataCalled != nil { - return e.CreateMarshalizedDataCalled(body) - } - return nil -} - -// GetRewardsTxs -- -func (e *EpochRewardsCreatorStub) GetRewardsTxs(body *block.Body) map[string]data.TransactionHandler { - if e.GetRewardsTxsCalled != nil { - return e.GetRewardsTxsCalled(body) - } - return nil -} - -// SaveTxBlockToStorage - -func (e *EpochRewardsCreatorStub) SaveTxBlockToStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.SaveTxBlockToStorageCalled != nil { - e.SaveTxBlockToStorageCalled(metaBlock, body) - } -} - -// DeleteTxsFromStorage - -func (e *EpochRewardsCreatorStub) DeleteTxsFromStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.DeleteTxsFromStorageCalled != nil { - e.DeleteTxsFromStorageCalled(metaBlock, body) - } -} - -// IsInterfaceNil - -func (e *EpochRewardsCreatorStub) IsInterfaceNil() bool { - return e == nil -} - -// RemoveBlockDataFromPools - -func (e *EpochRewardsCreatorStub) RemoveBlockDataFromPools(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.RemoveBlockDataFromPoolsCalled != nil { - e.RemoveBlockDataFromPoolsCalled(metaBlock, body) - } -} diff --git a/epochStart/mock/rewardsCreatorStub.go b/testscommon/rewardsCreatorStub.go similarity index 99% rename from epochStart/mock/rewardsCreatorStub.go rename to testscommon/rewardsCreatorStub.go index 3be87ced58a..3bc412c8f3c 100644 --- a/epochStart/mock/rewardsCreatorStub.go +++ b/testscommon/rewardsCreatorStub.go @@ -1,4 +1,4 @@ -package mock +package testscommon import ( "math/big" From c80091d7071d16e1197ffb354df6389cfb783206 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 14:14:45 +0200 Subject: [PATCH 143/958] FEAT: Refactor code to use new interface --- epochStart/interface.go | 4 +- epochStart/metachain/rewards.go | 55 +++-- epochStart/metachain/rewardsCreatorProxy.go | 4 +- .../metachain/rewardsCreatorProxy_test.go | 14 +- epochStart/metachain/rewardsV2.go | 32 +-- epochStart/metachain/rewardsV2_test.go | 103 +++++----- epochStart/metachain/rewards_test.go | 194 ++++++++---------- process/block/metablock.go | 59 ++---- process/block/metablock_test.go | 12 +- process/interface.go | 4 +- testscommon/rewardsCreatorStub.go | 8 +- 11 files changed, 212 insertions(+), 277 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index 44387393337..f170416f771 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -176,10 +176,10 @@ type EpochEconomicsDataProvider interface { // RewardsCreator defines the functionality for the metachain to create rewards at end of epoch type RewardsCreator interface { CreateRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) VerifyRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error GetProtocolSustainabilityRewards() *big.Int GetLocalTxCache() TransactionCacher diff --git a/epochStart/metachain/rewards.go b/epochStart/metachain/rewards.go index e63001a8b01..03228f67e63 100644 --- a/epochStart/metachain/rewards.go +++ b/epochStart/metachain/rewards.go @@ -49,7 +49,7 @@ func NewRewardsCreator(args ArgsNewRewardsCreator) (*rewardsCreator, error) { // CreateRewardsMiniBlocks creates the rewards miniblocks according to economics data and validator info func (rc *rewardsCreator) CreateRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { if check.IfNil(metaBlock) { @@ -115,7 +115,7 @@ func (rc *rewardsCreator) adjustProtocolSustainabilityRewards(protocolSustainabi } func (rc *rewardsCreator) addValidatorRewardsToMiniBlocks( - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, metaBlock data.HeaderHandler, miniBlocks block.MiniBlockSlice, protocolSustainabilityRwdTx *rewardTx.RewardTx, @@ -161,41 +161,40 @@ func (rc *rewardsCreator) addValidatorRewardsToMiniBlocks( } func (rc *rewardsCreator) computeValidatorInfoPerRewardAddress( - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, protocolSustainabilityRwd *rewardTx.RewardTx, epoch uint32, ) map[string]*rewardInfoData { rwdAddrValidatorInfo := make(map[string]*rewardInfoData) - for _, shardValidatorsInfo := range validatorsInfo { - for _, validatorInfo := range shardValidatorsInfo { - rewardsPerBlockPerNodeForShard := rc.mapBaseRewardsPerBlockPerValidator[validatorInfo.ShardId] - protocolRewardValue := big.NewInt(0).Mul(rewardsPerBlockPerNodeForShard, big.NewInt(0).SetUint64(uint64(validatorInfo.NumSelectedInSuccessBlocks))) + for _, validatorInfo := range validatorsInfo.GetAllValidatorsInfo() { + rewardsPerBlockPerNodeForShard := rc.mapBaseRewardsPerBlockPerValidator[validatorInfo.GetShardId()] + protocolRewardValue := big.NewInt(0).Mul(rewardsPerBlockPerNodeForShard, big.NewInt(0).SetUint64(uint64(validatorInfo.GetNumSelectedInSuccessBlocks()))) - isFix1Enabled := rc.isRewardsFix1Enabled(epoch) - if isFix1Enabled && validatorInfo.LeaderSuccess == 0 && validatorInfo.ValidatorSuccess == 0 { - protocolSustainabilityRwd.Value.Add(protocolSustainabilityRwd.Value, protocolRewardValue) - continue - } - if !isFix1Enabled && validatorInfo.LeaderSuccess == 0 && validatorInfo.ValidatorFailure == 0 { - protocolSustainabilityRwd.Value.Add(protocolSustainabilityRwd.Value, protocolRewardValue) - continue - } + isFix1Enabled := rc.isRewardsFix1Enabled(epoch) + if isFix1Enabled && validatorInfo.GetLeaderSuccess() == 0 && validatorInfo.GetValidatorSuccess() == 0 { + protocolSustainabilityRwd.Value.Add(protocolSustainabilityRwd.Value, protocolRewardValue) + continue + } + if !isFix1Enabled && validatorInfo.GetLeaderSuccess() == 0 && validatorInfo.GetValidatorFailure() == 0 { + protocolSustainabilityRwd.Value.Add(protocolSustainabilityRwd.Value, protocolRewardValue) + continue + } - rwdInfo, ok := rwdAddrValidatorInfo[string(validatorInfo.RewardAddress)] - if !ok { - rwdInfo = &rewardInfoData{ - accumulatedFees: big.NewInt(0), - rewardsFromProtocol: big.NewInt(0), - address: string(validatorInfo.RewardAddress), - } - rwdAddrValidatorInfo[string(validatorInfo.RewardAddress)] = rwdInfo + rwdInfo, ok := rwdAddrValidatorInfo[string(validatorInfo.GetRewardAddress())] + if !ok { + rwdInfo = &rewardInfoData{ + accumulatedFees: big.NewInt(0), + rewardsFromProtocol: big.NewInt(0), + address: string(validatorInfo.GetRewardAddress()), } - - rwdInfo.accumulatedFees.Add(rwdInfo.accumulatedFees, validatorInfo.AccumulatedFees) - rwdInfo.rewardsFromProtocol.Add(rwdInfo.rewardsFromProtocol, protocolRewardValue) + rwdAddrValidatorInfo[string(validatorInfo.GetRewardAddress())] = rwdInfo } + + rwdInfo.accumulatedFees.Add(rwdInfo.accumulatedFees, validatorInfo.GetAccumulatedFees()) + rwdInfo.rewardsFromProtocol.Add(rwdInfo.rewardsFromProtocol, protocolRewardValue) + } return rwdAddrValidatorInfo @@ -204,7 +203,7 @@ func (rc *rewardsCreator) computeValidatorInfoPerRewardAddress( // VerifyRewardsMiniBlocks verifies if received rewards miniblocks are correct func (rc *rewardsCreator) VerifyRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error { if check.IfNil(metaBlock) { diff --git a/epochStart/metachain/rewardsCreatorProxy.go b/epochStart/metachain/rewardsCreatorProxy.go index 0fc7feebd75..fdfc8f51079 100644 --- a/epochStart/metachain/rewardsCreatorProxy.go +++ b/epochStart/metachain/rewardsCreatorProxy.go @@ -68,7 +68,7 @@ func NewRewardsCreatorProxy(args RewardsCreatorProxyArgs) (*rewardsCreatorProxy, // CreateRewardsMiniBlocks proxies the CreateRewardsMiniBlocks method of the configured rewardsCreator instance func (rcp *rewardsCreatorProxy) CreateRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { err := rcp.changeRewardCreatorIfNeeded(metaBlock.GetEpoch()) @@ -81,7 +81,7 @@ func (rcp *rewardsCreatorProxy) CreateRewardsMiniBlocks( // VerifyRewardsMiniBlocks proxies the same method of the configured rewardsCreator instance func (rcp *rewardsCreatorProxy) VerifyRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error { err := rcp.changeRewardCreatorIfNeeded(metaBlock.GetEpoch()) diff --git a/epochStart/metachain/rewardsCreatorProxy_test.go b/epochStart/metachain/rewardsCreatorProxy_test.go index 5e702f6e844..3059128e2ee 100644 --- a/epochStart/metachain/rewardsCreatorProxy_test.go +++ b/epochStart/metachain/rewardsCreatorProxy_test.go @@ -56,7 +56,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithError(t *testing.T) { rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { return nil, expectedErr }, @@ -75,7 +75,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksOK(t *testing.T) { rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { return make(block.MiniBlockSlice, 2), nil }, @@ -94,7 +94,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithSwitchToRewardsCreatorV2 rewardCreatorV1 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { return make(block.MiniBlockSlice, 2), nil }, @@ -120,7 +120,7 @@ func TestRewardsCreatorProxy_CreateRewardsMiniBlocksWithSwitchToRewardsCreatorV1 rewardCreatorV2 := &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { return make(block.MiniBlockSlice, 2), nil }, @@ -147,7 +147,7 @@ func TestRewardsCreatorProxy_VerifyRewardsMiniBlocksWithError(t *testing.T) { expectedErr := fmt.Errorf("expectedError") rewardCreatorV1 := &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics) error { + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics) error { return expectedErr }, } @@ -164,7 +164,7 @@ func TestRewardsCreatorProxy_VerifyRewardsMiniBlocksOK(t *testing.T) { rewardCreatorV1 := &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics) error { + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics) error { return nil }, } @@ -319,7 +319,7 @@ func TestRewardsCreatorProxy_IsInterfaceNil(t *testing.T) { require.False(t, check.IfNil(rewardsCreatorProxy)) } -func createTestData(rewardCreator epochStart.RewardsCreator, rcType configuredRewardsCreator) (*rewardsCreatorProxy, map[uint32][]*state.ValidatorInfo, *block.MetaBlock) { +func createTestData(rewardCreator epochStart.RewardsCreator, rcType configuredRewardsCreator) (*rewardsCreatorProxy, state.ShardValidatorsInfoMapHandler, *block.MetaBlock) { args := createDefaultRewardsCreatorProxyArgs() rewardsCreatorProxy := &rewardsCreatorProxy{ rc: rewardCreator, diff --git a/epochStart/metachain/rewardsV2.go b/epochStart/metachain/rewardsV2.go index eb6d49dc96f..8c495efe8eb 100644 --- a/epochStart/metachain/rewardsV2.go +++ b/epochStart/metachain/rewardsV2.go @@ -24,7 +24,7 @@ type nodeRewardsData struct { fullRewards *big.Int topUpStake *big.Int powerInShard *big.Int - valInfo *state.ValidatorInfo + valInfo state.ValidatorInfoHandler } // RewardsCreatorArgsV2 holds the data required to create end of epoch rewards @@ -74,7 +74,7 @@ func NewRewardsCreatorV2(args RewardsCreatorArgsV2) (*rewardsCreatorV2, error) { // stake top-up values per node func (rc *rewardsCreatorV2) CreateRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { if check.IfNil(metaBlock) { @@ -150,7 +150,7 @@ func (rc *rewardsCreatorV2) adjustProtocolSustainabilityRewards(protocolSustaina // VerifyRewardsMiniBlocks verifies if received rewards miniblocks are correct func (rc *rewardsCreatorV2) VerifyRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error { if check.IfNil(metaBlock) { @@ -221,23 +221,23 @@ func (rc *rewardsCreatorV2) computeValidatorInfoPerRewardAddress( for _, nodeInfoList := range nodesRewardInfo { for _, nodeInfo := range nodeInfoList { - if nodeInfo.valInfo.LeaderSuccess == 0 && nodeInfo.valInfo.ValidatorSuccess == 0 { + if nodeInfo.valInfo.GetLeaderSuccess() == 0 && nodeInfo.valInfo.GetValidatorSuccess() == 0 { accumulatedUnassigned.Add(accumulatedUnassigned, nodeInfo.fullRewards) continue } - rwdInfo, ok := rwdAddrValidatorInfo[string(nodeInfo.valInfo.RewardAddress)] + rwdInfo, ok := rwdAddrValidatorInfo[string(nodeInfo.valInfo.GetRewardAddress())] if !ok { rwdInfo = &rewardInfoData{ accumulatedFees: big.NewInt(0), rewardsFromProtocol: big.NewInt(0), - address: string(nodeInfo.valInfo.RewardAddress), + address: string(nodeInfo.valInfo.GetRewardAddress()), } - rwdAddrValidatorInfo[string(nodeInfo.valInfo.RewardAddress)] = rwdInfo + rwdAddrValidatorInfo[string(nodeInfo.valInfo.GetRewardAddress())] = rwdInfo } - distributedLeaderFees.Add(distributedLeaderFees, nodeInfo.valInfo.AccumulatedFees) - rwdInfo.accumulatedFees.Add(rwdInfo.accumulatedFees, nodeInfo.valInfo.AccumulatedFees) + distributedLeaderFees.Add(distributedLeaderFees, nodeInfo.valInfo.GetAccumulatedFees()) + rwdInfo.accumulatedFees.Add(rwdInfo.accumulatedFees, nodeInfo.valInfo.GetAccumulatedFees()) rwdInfo.rewardsFromProtocol.Add(rwdInfo.rewardsFromProtocol, nodeInfo.fullRewards) } } @@ -262,7 +262,7 @@ func (rc *rewardsCreatorV2) IsInterfaceNil() bool { } func (rc *rewardsCreatorV2) computeRewardsPerNode( - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, ) (map[uint32][]*nodeRewardsData, *big.Int) { var baseRewardsPerBlock *big.Int @@ -301,11 +301,11 @@ func (rc *rewardsCreatorV2) computeRewardsPerNode( } func (rc *rewardsCreatorV2) initNodesRewardsInfo( - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, ) map[uint32][]*nodeRewardsData { nodesRewardsInfo := make(map[uint32][]*nodeRewardsData) - for shardID, valInfoList := range validatorsInfo { + for shardID, valInfoList := range validatorsInfo.GetShardValidatorsInfoMap() { nodesRewardsInfo[shardID] = make([]*nodeRewardsData, 0, len(valInfoList)) for _, valInfo := range valInfoList { if validatorInfo.WasEligibleInCurrentEpoch(valInfo) { @@ -335,7 +335,7 @@ func (rc *rewardsCreatorV2) computeBaseRewardsPerNode( for _, nodeRewardsInfo := range nodeRewardsInfoList { nodeRewardsInfo.baseReward = big.NewInt(0).Mul( rc.mapBaseRewardsPerBlockPerValidator[shardID], - big.NewInt(int64(nodeRewardsInfo.valInfo.NumSelectedInSuccessBlocks))) + big.NewInt(int64(nodeRewardsInfo.valInfo.GetNumSelectedInSuccessBlocks()))) accumulatedRewards.Add(accumulatedRewards, nodeRewardsInfo.baseReward) } } @@ -505,13 +505,13 @@ func computeNodesPowerInShard( // power in epoch is computed as nbBlocks*nodeTopUp, where nbBlocks represents the number of blocks the node // participated at creation/validation -func computeNodePowerInShard(nodeInfo *state.ValidatorInfo, nodeTopUp *big.Int) *big.Int { +func computeNodePowerInShard(nodeInfo state.ValidatorInfoHandler, nodeTopUp *big.Int) *big.Int { // if node was offline, it had no power, so the rewards should go to the others - if nodeInfo.LeaderSuccess == 0 && nodeInfo.ValidatorSuccess == 0 { + if nodeInfo.GetLeaderSuccess() == 0 && nodeInfo.GetValidatorSuccess() == 0 { return big.NewInt(0) } - nbBlocks := big.NewInt(0).SetUint64(uint64(nodeInfo.NumSelectedInSuccessBlocks)) + nbBlocks := big.NewInt(0).SetUint64(uint64(nodeInfo.GetNumSelectedInSuccessBlocks())) return big.NewInt(0).Mul(nbBlocks, nodeTopUp) } diff --git a/epochStart/metachain/rewardsV2_test.go b/epochStart/metachain/rewardsV2_test.go index 6e098807f5c..72637079ffc 100644 --- a/epochStart/metachain/rewardsV2_test.go +++ b/epochStart/metachain/rewardsV2_test.go @@ -106,12 +106,12 @@ func TestNewRewardsCreatorV2_initNodesRewardsInfo(t *testing.T) { valInfoEligibleWithExtra := addNonEligibleValidatorInfo(100, valInfoEligible, string(common.WaitingList)) nodesRewardInfo := rwd.initNodesRewardsInfo(valInfoEligibleWithExtra) - require.Equal(t, len(valInfoEligible), len(nodesRewardInfo)) + require.Equal(t, len(valInfoEligible.GetShardValidatorsInfoMap()), len(nodesRewardInfo)) for shardID, nodeInfoList := range nodesRewardInfo { - require.Equal(t, len(nodeInfoList), len(valInfoEligible[shardID])) + require.Equal(t, len(nodeInfoList), len(valInfoEligible.GetShardValidatorsInfoMap()[shardID])) for i, nodeInfo := range nodeInfoList { - require.True(t, valInfoEligible[shardID][i] == nodeInfo.valInfo) + require.True(t, valInfoEligible.GetShardValidatorsInfoMap()[shardID][i] == nodeInfo.valInfo) require.Equal(t, zero, nodeInfo.topUpStake) require.Equal(t, zero, nodeInfo.powerInShard) require.Equal(t, zero, nodeInfo.baseReward) @@ -170,9 +170,9 @@ func TestNewRewardsCreatorV2_getTopUpForAllEligibleSomeBLSKeysNotFoundZeroed(t * nodesPerShard := uint32(10) valInfo := createDefaultValidatorInfo(nodesPerShard, args.ShardCoordinator, args.NodesConfigProvider, 100, defaultBlocksPerShard) - for _, valList := range valInfo { - valList[0].PublicKey = notFoundKey - valList[1].PublicKey = notFoundKey + for _, valList := range valInfo.GetShardValidatorsInfoMap() { + valList[0].SetPublicKey(notFoundKey) + valList[1].SetPublicKey(notFoundKey) } nodesRewardInfo := rwd.initNodesRewardsInfo(valInfo) @@ -387,7 +387,7 @@ func TestNewRewardsCreatorV2_computeNodesPowerInShard(t *testing.T) { for _, nodeInfoList := range nodesRewardInfo { for _, nodeInfo := range nodeInfoList { - blocks := nodeInfo.valInfo.NumSelectedInSuccessBlocks + blocks := nodeInfo.valInfo.GetNumSelectedInSuccessBlocks() topUp := nodeInfo.topUpStake require.Equal(t, big.NewInt(0).Mul(big.NewInt(int64(blocks)), topUp), nodeInfo.powerInShard) } @@ -609,9 +609,9 @@ func TestNewRewardsCreatorV2_computeTopUpRewardsPerNode(t *testing.T) { args.StakingDataProvider = &mock.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -743,9 +743,9 @@ func TestNewRewardsCreatorV2_computeRewardsPerNode(t *testing.T) { return topUpStake }, GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -1050,9 +1050,9 @@ func TestNewRewardsCreatorV35_computeRewardsPer3200NodesWithDifferentTopups(t *t return baseEligibleStake }, GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -1157,9 +1157,9 @@ func TestNewRewardsCreatorV2_computeRewardsPer3200NodesWithDifferentTopups(t *te return baseEligibleStake }, GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -1200,7 +1200,7 @@ func TestNewRewardsCreatorV2_computeRewardsPer3200NodesWithDifferentTopups(t *te func setupNodeRewardInfo( setupResult SetupRewardsResult, - vInfo map[uint32][]*state.ValidatorInfo, + vInfo state.ShardValidatorsInfoMapHandler, topupStakePerNode *big.Int, validatorTopupStake *big.Int, ) (map[uint32][]*nodeRewardsData, error) { @@ -1275,9 +1275,9 @@ func computeRewardsAndDust(nbEligiblePerShard uint32, args SetupRewardsResult, t return totalEligibleStake }, GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -1360,11 +1360,11 @@ func TestNewRewardsCreatorV2_computeValidatorInfoPerRewardAddressWithOfflineVali nbShards := int64(args.ShardCoordinator.NumberOfShards()) + 1 args.EconomicsDataProvider.SetLeadersFees(big.NewInt(0).Mul(big.NewInt(int64(proposerFee)), big.NewInt(int64(nbEligiblePerShard-nbOfflinePerShard)*nbShards))) valInfo := createDefaultValidatorInfo(nbEligiblePerShard, args.ShardCoordinator, args.NodesConfigProvider, proposerFee, defaultBlocksPerShard) - for _, valList := range valInfo { + for _, valList := range valInfo.GetShardValidatorsInfoMap() { for i := 0; i < int(nbOfflinePerShard); i++ { - valList[i].LeaderSuccess = 0 - valList[i].ValidatorSuccess = 0 - valList[i].AccumulatedFees = big.NewInt(0) + valList[i].SetLeaderSuccess(0) + valList[i].SetValidatorSuccess(0) + valList[i].SetAccumulatedFees(big.NewInt(0)) } } @@ -1412,9 +1412,9 @@ func TestNewRewardsCreatorV2_computeValidatorInfoPerRewardAddressWithLeavingVali nbShards := int64(args.ShardCoordinator.NumberOfShards()) + 1 args.EconomicsDataProvider.SetLeadersFees(big.NewInt(0).Mul(big.NewInt(int64(proposerFee)), big.NewInt(int64(nbEligiblePerShard)*nbShards))) valInfo := createDefaultValidatorInfo(nbEligiblePerShard, args.ShardCoordinator, args.NodesConfigProvider, proposerFee, defaultBlocksPerShard) - for _, valList := range valInfo { + for _, valList := range valInfo.GetShardValidatorsInfoMap() { for i := 0; i < int(nbLeavingPerShard); i++ { - valList[i].List = string(common.LeavingList) + valList[i].SetList(string(common.LeavingList)) } } @@ -1500,10 +1500,8 @@ func TestNewRewardsCreatorV2_addValidatorRewardsToMiniBlocks(t *testing.T) { DevFeesInEpoch: big.NewInt(0), } sumFees := big.NewInt(0) - for _, vInfoList := range valInfo { - for _, vInfo := range vInfoList { - sumFees.Add(sumFees, vInfo.AccumulatedFees) - } + for _, vInfo := range valInfo.GetAllValidatorsInfo() { + sumFees.Add(sumFees, vInfo.GetAccumulatedFees()) } accumulatedDust, err := rwd.addValidatorRewardsToMiniBlocks(metaBlock, miniBlocks, nodesRewardInfo) @@ -1548,12 +1546,12 @@ func TestNewRewardsCreatorV2_addValidatorRewardsToMiniBlocksAddressInMetaChainDe nbAddrInMetachainPerShard := 2 sumFees := big.NewInt(0) - for _, vInfoList := range valInfo { + for _, vInfoList := range valInfo.GetShardValidatorsInfoMap() { for i, vInfo := range vInfoList { if i < nbAddrInMetachainPerShard { - vInfo.RewardAddress = addrInMeta + vInfo.SetRewardAddress(addrInMeta) } - sumFees.Add(sumFees, vInfo.AccumulatedFees) + sumFees.Add(sumFees, vInfo.GetAccumulatedFees()) } } @@ -1591,9 +1589,9 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks(t *testing.T) { return totalTopUpStake }, GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -1637,10 +1635,8 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks(t *testing.T) { } sumFees := big.NewInt(0) - for _, vInfoList := range vInfo { - for _, v := range vInfoList { - sumFees.Add(sumFees, v.AccumulatedFees) - } + for _, v := range vInfo.GetAllValidatorsInfo() { + sumFees.Add(sumFees, v.GetAccumulatedFees()) } totalRws := rwd.economicsDataProvider.RewardsToBeDistributedForBlocks() @@ -1688,9 +1684,9 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks2169Nodes(t *testing.T) { return totalTopupStake }, GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - for shardID, vList := range vInfo { + for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { - if bytes.Equal(v.PublicKey, blsKey) { + if bytes.Equal(v.GetPublicKey(), blsKey) { return nodesRewardInfo[shardID][i].topUpStake, nil } } @@ -1734,10 +1730,8 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks2169Nodes(t *testing.T) { } sumFees := big.NewInt(0) - for _, vInfoList := range vInfo { - for _, v := range vInfoList { - sumFees.Add(sumFees, v.AccumulatedFees) - } + for _, v := range vInfo.GetAllValidatorsInfo() { + sumFees.Add(sumFees, v.GetAccumulatedFees()) } totalRws := rwd.economicsDataProvider.RewardsToBeDistributedForBlocks() @@ -1877,7 +1871,7 @@ func createDefaultValidatorInfo( nodesConfigProvider epochStart.NodesConfigProvider, proposerFeesPerNode uint32, nbBlocksPerShard uint32, -) map[uint32][]*state.ValidatorInfo { +) state.ShardValidatorsInfoMapHandler { cGrShard := uint32(nodesConfigProvider.ConsensusGroupSize(0)) cGrMeta := uint32(nodesConfigProvider.ConsensusGroupSize(core.MetachainShardId)) nbBlocksSelectedNodeInShard := nbBlocksPerShard * cGrShard / eligibleNodesPerShard @@ -1886,9 +1880,8 @@ func createDefaultValidatorInfo( shardsMap := createShardsMap(shardCoordinator) var nbBlocksSelected uint32 - validators := make(map[uint32][]*state.ValidatorInfo) + validators := state.NewShardValidatorsInfoMap() for shardID := range shardsMap { - validators[shardID] = make([]*state.ValidatorInfo, eligibleNodesPerShard) nbBlocksSelected = nbBlocksSelectedNodeInShard if shardID == core.MetachainShardId { nbBlocksSelected = nbBlocksSelectedNodeInMeta @@ -1900,7 +1893,7 @@ func createDefaultValidatorInfo( _ = hex.Encode(addrHex, []byte(str)) leaderSuccess := uint32(20) - validators[shardID][i] = &state.ValidatorInfo{ + _ = validators.Add(&state.ValidatorInfo{ PublicKey: []byte(fmt.Sprintf("pubKeyBLS%d%d", shardID, i)), ShardId: shardID, RewardAddress: addrHex, @@ -1909,7 +1902,7 @@ func createDefaultValidatorInfo( NumSelectedInSuccessBlocks: nbBlocksSelected, AccumulatedFees: big.NewInt(int64(proposerFeesPerNode)), List: string(common.EligibleList), - } + }) } } @@ -1918,13 +1911,14 @@ func createDefaultValidatorInfo( func addNonEligibleValidatorInfo( nonEligiblePerShard uint32, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, list string, -) map[uint32][]*state.ValidatorInfo { - resultedValidatorsInfo := make(map[uint32][]*state.ValidatorInfo) - for shardID, valInfoList := range validatorsInfo { +) state.ShardValidatorsInfoMapHandler { + resultedValidatorsInfo := state.NewShardValidatorsInfoMap() + for shardID, valInfoList := range validatorsInfo.GetShardValidatorsInfoMap() { + resultedValidatorsInfo.SetValidatorsInShard(shardID, valInfoList) for i := uint32(0); i < nonEligiblePerShard; i++ { - vInfo := &state.ValidatorInfo{ + _ = resultedValidatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte(fmt.Sprintf("pubKeyBLSExtra%d", i)), ShardId: shardID, RewardAddress: []byte(fmt.Sprintf("addrRewardsExtra%d", i)), @@ -1933,8 +1927,7 @@ func addNonEligibleValidatorInfo( NumSelectedInSuccessBlocks: 1, AccumulatedFees: big.NewInt(int64(10)), List: list, - } - resultedValidatorsInfo[shardID] = append(valInfoList, vInfo) + }) } } diff --git a/epochStart/metachain/rewards_test.go b/epochStart/metachain/rewards_test.go index ec30f0d96d0..8f3753a15e4 100644 --- a/epochStart/metachain/rewards_test.go +++ b/epochStart/metachain/rewards_test.go @@ -136,14 +136,12 @@ func TestRewardsCreator_CreateRewardsMiniBlocks(t *testing.T) { EpochStart: getDefaultEpochStart(), DevFeesInEpoch: big.NewInt(0), } - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + }) bdy, err := rwd.CreateRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) assert.Nil(t, err) assert.NotNil(t, bdy) @@ -178,14 +176,12 @@ func TestRewardsCreator_VerifyRewardsMiniBlocksHashDoesNotMatch(t *testing.T) { }, DevFeesInEpoch: big.NewInt(0), } - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + }) err := rwd.VerifyRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) assert.Equal(t, epochStart.ErrRewardMiniBlockHashDoesNotMatch, err) @@ -236,15 +232,13 @@ func TestRewardsCreator_VerifyRewardsMiniBlocksRewardsMbNumDoesNotMatch(t *testi mbh.Hash = mbHash mb.MiniBlockHeaders = []block.MiniBlockHeader{mbh, mbh} - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + LeaderSuccess: 1, + }) err := rwd.VerifyRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) assert.Equal(t, epochStart.ErrRewardMiniBlocksNumDoesNotMatch, err) @@ -393,15 +387,13 @@ func TestRewardsCreator_VerifyRewardsMiniBlocksShouldWork(t *testing.T) { mb.EpochStart.Economics.RewardsForProtocolSustainability.Set(protocolSustainabilityRewardTx.Value) mb.EpochStart.Economics.TotalToDistribute.Set(big.NewInt(0).Add(rwdTx.Value, protocolSustainabilityRewardTx.Value)) - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + LeaderSuccess: 1, + }) err := rwd.VerifyRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) assert.Nil(t, err) @@ -463,15 +455,13 @@ func TestRewardsCreator_VerifyRewardsMiniBlocksShouldWorkEvenIfNotAllShardsHaveR mb.EpochStart.Economics.RewardsForProtocolSustainability.Set(protocolSustainabilityRewardTx.Value) mb.EpochStart.Economics.TotalToDistribute.Set(big.NewInt(0).Add(rwdTx.Value, protocolSustainabilityRewardTx.Value)) - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: receivedShardID, - AccumulatedFees: big.NewInt(100), - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: receivedShardID, + AccumulatedFees: big.NewInt(100), + LeaderSuccess: 1, + }) err := rwd.VerifyRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) assert.Nil(t, err) @@ -487,14 +477,12 @@ func TestRewardsCreator_CreateMarshalizedData(t *testing.T) { EpochStart: getDefaultEpochStart(), DevFeesInEpoch: big.NewInt(0), } - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + }) _, _ = rwd.CreateRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) rwdTx := rewardTx.RewardTx{ @@ -544,15 +532,13 @@ func TestRewardsCreator_SaveTxBlockToStorage(t *testing.T) { EpochStart: getDefaultEpochStart(), DevFeesInEpoch: big.NewInt(0), } - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + LeaderSuccess: 1, + }) _, _ = rwd.CreateRewardsMiniBlocks(mb, valInfo, &mb.EpochStart.Economics) mb2 := block.MetaBlock{ @@ -613,15 +599,13 @@ func TestRewardsCreator_addValidatorRewardsToMiniBlocks(t *testing.T) { expectedRwdTxHash, _ := core.CalculateHash(&marshal.JsonMarshalizer{}, &hashingMocks.HasherMock{}, expectedRwdTx) cloneMb.TxHashes = append(cloneMb.TxHashes, expectedRwdTxHash) - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - PublicKey: []byte("pubkey"), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + PublicKey: []byte("pubkey"), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + LeaderSuccess: 1, + }) rwdc.fillBaseRewardsPerBlockPerNode(mb.EpochStart.Economics.RewardsPerBlock) err := rwdc.addValidatorRewardsToMiniBlocks(valInfo, mb, miniBlocks, &rewardTx.RewardTx{}) @@ -648,25 +632,21 @@ func TestRewardsCreator_ProtocolRewardsForValidatorFromMultipleShards(t *testing } pubkey := "pubkey" - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - RewardAddress: []byte(pubkey), - ShardId: 0, - AccumulatedFees: big.NewInt(100), - NumSelectedInSuccessBlocks: 100, - LeaderSuccess: 1, - }, - } - valInfo[core.MetachainShardId] = []*state.ValidatorInfo{ - { - RewardAddress: []byte(pubkey), - ShardId: core.MetachainShardId, - AccumulatedFees: big.NewInt(100), - NumSelectedInSuccessBlocks: 200, - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + RewardAddress: []byte(pubkey), + ShardId: 0, + AccumulatedFees: big.NewInt(100), + NumSelectedInSuccessBlocks: 100, + LeaderSuccess: 1, + }) + _ = valInfo.Add(&state.ValidatorInfo{ + RewardAddress: []byte(pubkey), + ShardId: core.MetachainShardId, + AccumulatedFees: big.NewInt(100), + NumSelectedInSuccessBlocks: 200, + LeaderSuccess: 1, + }) rwdc.fillBaseRewardsPerBlockPerNode(mb.EpochStart.Economics.RewardsPerBlock) rwdInfoData := rwdc.computeValidatorInfoPerRewardAddress(valInfo, &rewardTx.RewardTx{}, 0) @@ -675,8 +655,8 @@ func TestRewardsCreator_ProtocolRewardsForValidatorFromMultipleShards(t *testing assert.Equal(t, rwdInfo.address, pubkey) assert.Equal(t, rwdInfo.accumulatedFees.Cmp(big.NewInt(200)), 0) - protocolRewards := uint64(valInfo[0][0].NumSelectedInSuccessBlocks) * (mb.EpochStart.Economics.RewardsPerBlock.Uint64() / uint64(args.NodesConfigProvider.ConsensusGroupSize(0))) - protocolRewards += uint64(valInfo[core.MetachainShardId][0].NumSelectedInSuccessBlocks) * (mb.EpochStart.Economics.RewardsPerBlock.Uint64() / uint64(args.NodesConfigProvider.ConsensusGroupSize(core.MetachainShardId))) + protocolRewards := uint64(valInfo.GetShardValidatorsInfoMap()[0][0].GetNumSelectedInSuccessBlocks()) * (mb.EpochStart.Economics.RewardsPerBlock.Uint64() / uint64(args.NodesConfigProvider.ConsensusGroupSize(0))) + protocolRewards += uint64(valInfo.GetShardValidatorsInfoMap()[core.MetachainShardId][0].GetNumSelectedInSuccessBlocks()) * (mb.EpochStart.Economics.RewardsPerBlock.Uint64() / uint64(args.NodesConfigProvider.ConsensusGroupSize(core.MetachainShardId))) assert.Equal(t, rwdInfo.rewardsFromProtocol.Uint64(), protocolRewards) } @@ -730,7 +710,7 @@ func TestRewardsCreator_AddProtocolSustainabilityRewardToMiniBlocks(t *testing.T metaBlk.EpochStart.Economics.RewardsForProtocolSustainability.Set(expectedRewardTx.Value) metaBlk.EpochStart.Economics.TotalToDistribute.Set(expectedRewardTx.Value) - miniBlocks, err := rwdc.CreateRewardsMiniBlocks(metaBlk, make(map[uint32][]*state.ValidatorInfo), &metaBlk.EpochStart.Economics) + miniBlocks, err := rwdc.CreateRewardsMiniBlocks(metaBlk, state.NewShardValidatorsInfoMap(), &metaBlk.EpochStart.Economics) assert.Nil(t, err) assert.Equal(t, cloneMb, miniBlocks[0]) } @@ -747,23 +727,21 @@ func TestRewardsCreator_ValidatorInfoWithMetaAddressAddedToProtocolSustainabilit DevFeesInEpoch: big.NewInt(0), } metaBlk.EpochStart.Economics.TotalToDistribute = big.NewInt(20250) - valInfo := make(map[uint32][]*state.ValidatorInfo) - valInfo[0] = []*state.ValidatorInfo{ - { - RewardAddress: vm.StakingSCAddress, - ShardId: 0, - AccumulatedFees: big.NewInt(100), - NumSelectedInSuccessBlocks: 1, - LeaderSuccess: 1, - }, - { - RewardAddress: vm.FirstDelegationSCAddress, - ShardId: 0, - AccumulatedFees: big.NewInt(100), - NumSelectedInSuccessBlocks: 1, - LeaderSuccess: 1, - }, - } + valInfo := state.NewShardValidatorsInfoMap() + _ = valInfo.Add(&state.ValidatorInfo{ + RewardAddress: vm.StakingSCAddress, + ShardId: 0, + AccumulatedFees: big.NewInt(100), + NumSelectedInSuccessBlocks: 1, + LeaderSuccess: 1, + }) + _ = valInfo.Add(&state.ValidatorInfo{ + RewardAddress: vm.FirstDelegationSCAddress, + ShardId: 0, + AccumulatedFees: big.NewInt(100), + NumSelectedInSuccessBlocks: 1, + LeaderSuccess: 1, + }) acc, _ := args.UserAccountsDB.LoadAccount(vm.FirstDelegationSCAddress) userAcc, _ := acc.(state.UserAccountHandler) diff --git a/process/block/metablock.go b/process/block/metablock.go index a3a4da91b57..c07746e13ef 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -417,25 +417,23 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - oldValidatorsInfoMap := make(map[uint32][]*state.ValidatorInfo) - state.Replace(oldValidatorsInfoMap, allValidatorsInfo.GetValInfoPointerMap()) if mp.isRewardsV2Enabled(header) { - err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, header) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header) if err != nil { return err } - err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, oldValidatorsInfoMap, computedEconomics) + err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, allValidatorsInfo, computedEconomics) if err != nil { return err } } else { - err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, oldValidatorsInfoMap, computedEconomics) + err = mp.epochRewardsCreator.VerifyRewardsMiniBlocks(header, allValidatorsInfo, computedEconomics) if err != nil { return err } - err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, header) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, header) if err != nil { return err } @@ -446,12 +444,12 @@ func (mp *metaProcessor) processEpochStartMetaBlock( return err } - err = mp.verifyValidatorInfoMiniBlocks(oldValidatorsInfoMap, body.MiniBlocks) + err = mp.validatorInfoCreator.VerifyValidatorInfoMiniBlocks(body.MiniBlocks, allValidatorsInfo) if err != nil { return err } - err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(state.CreateShardValidatorsMap(oldValidatorsInfoMap)) + err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(allValidatorsInfo) if err != nil { return err } @@ -887,25 +885,23 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. } var rewardMiniBlocks block.MiniBlockSlice - oldValidatorsInfoMap := make(map[uint32][]*state.ValidatorInfo) - state.Replace(oldValidatorsInfoMap, allValidatorsInfo.GetValInfoPointerMap()) if mp.isRewardsV2Enabled(metaBlock) { - err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, metaBlock) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock) if err != nil { return nil, err } - rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, oldValidatorsInfoMap, &metaBlock.EpochStart.Economics) + rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, allValidatorsInfo, &metaBlock.EpochStart.Economics) if err != nil { return nil, err } } else { - rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, oldValidatorsInfoMap, &metaBlock.EpochStart.Economics) + rewardMiniBlocks, err = mp.epochRewardsCreator.CreateRewardsMiniBlocks(metaBlock, allValidatorsInfo, &metaBlock.EpochStart.Economics) if err != nil { return nil, err } - err = mp.processSystemSCsWithNewValidatorsInfo(oldValidatorsInfoMap, metaBlock) + err = mp.epochSystemSCProcessor.ProcessSystemSmartContract(allValidatorsInfo, metaBlock) if err != nil { return nil, err } @@ -918,12 +914,12 @@ func (mp *metaProcessor) createEpochStartBody(metaBlock *block.MetaBlock) (data. return nil, err } - validatorMiniBlocks, err := mp.createValidatorInfoMiniBlocks(oldValidatorsInfoMap) + validatorMiniBlocks, err := mp.validatorInfoCreator.CreateValidatorInfoMiniBlocks(allValidatorsInfo) if err != nil { return nil, err } - err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(state.CreateShardValidatorsMap(oldValidatorsInfoMap)) + err = mp.validatorStatisticsProcessor.ResetValidatorStatisticsAtNewEpoch(allValidatorsInfo) if err != nil { return nil, err } @@ -2505,34 +2501,3 @@ func (mp *metaProcessor) DecodeBlockHeader(dta []byte) data.HeaderHandler { return metaBlock } - -// TODO: StakingV4 delete these funcs once map[uint32][]*ValidatorInfo is replaced with interface -func (mp *metaProcessor) processSystemSCsWithNewValidatorsInfo(allValidatorsInfo map[uint32][]*state.ValidatorInfo, header data.HeaderHandler) error { - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - err := mp.epochSystemSCProcessor.ProcessSystemSmartContract(validatorsInfoMap, header) - if err != nil { - return err - } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) - return nil -} - -func (mp *metaProcessor) verifyValidatorInfoMiniBlocks(allValidatorsInfo map[uint32][]*state.ValidatorInfo, miniBlocks []*block.MiniBlock) error { - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - err := mp.validatorInfoCreator.VerifyValidatorInfoMiniBlocks(miniBlocks, validatorsInfoMap) - if err != nil { - return err - } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) - return nil -} - -func (mp *metaProcessor) createValidatorInfoMiniBlocks(allValidatorsInfo map[uint32][]*state.ValidatorInfo) (block.MiniBlockSlice, error) { - validatorsInfoMap := state.CreateShardValidatorsMap(allValidatorsInfo) - validatorMiniBlocks, err := mp.validatorInfoCreator.CreateValidatorInfoMiniBlocks(validatorsInfoMap) - if err != nil { - return nil, err - } - state.Replace(allValidatorsInfo, validatorsInfoMap.GetValInfoPointerMap()) - return validatorMiniBlocks, err -} diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 05f2eebe129..6e49bbce6d1 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3084,7 +3084,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { wasCalled := false arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error { assert.True(t, wasCalled) return nil @@ -3115,7 +3115,7 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { wasCalled := false arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ VerifyRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error { wasCalled = true return nil @@ -3341,9 +3341,9 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { expectedRewardsForProtocolSustain := big.NewInt(11) arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { - assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) + assert.Equal(t, expectedValidatorsInfo, validatorsInfo) assert.Equal(t, mb, metaBlock) assert.True(t, wasCalled) return rewardMiniBlocks, nil @@ -3403,10 +3403,10 @@ func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { expectedRewardsForProtocolSustain := big.NewInt(11) arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ CreateRewardsMiniBlocksCalled: func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { wasCalled = true - assert.Equal(t, expectedValidatorsInfo.GetValInfoPointerMap(), validatorsInfo) + assert.Equal(t, expectedValidatorsInfo, validatorsInfo) assert.Equal(t, mb, metaBlock) return rewardMiniBlocks, nil }, diff --git a/process/interface.go b/process/interface.go index 3e79a1b3e63..ffccd810fe1 100644 --- a/process/interface.go +++ b/process/interface.go @@ -880,10 +880,10 @@ type EpochStartDataCreator interface { // RewardsCreator defines the functionality for the metachain to create rewards at end of epoch type RewardsCreator interface { CreateRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) VerifyRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error GetProtocolSustainabilityRewards() *big.Int GetLocalTxCache() epochStart.TransactionCacher diff --git a/testscommon/rewardsCreatorStub.go b/testscommon/rewardsCreatorStub.go index 3bc412c8f3c..662f5f76b55 100644 --- a/testscommon/rewardsCreatorStub.go +++ b/testscommon/rewardsCreatorStub.go @@ -12,10 +12,10 @@ import ( // RewardsCreatorStub - type RewardsCreatorStub struct { CreateRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) VerifyRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, + metaBlock data.MetaHeaderHandler, validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error GetProtocolSustainabilityRewardsCalled func() *big.Int GetLocalTxCacheCalled func() epochStart.TransactionCacher @@ -29,7 +29,7 @@ type RewardsCreatorStub struct { // CreateRewardsMiniBlocks - func (rcs *RewardsCreatorStub) CreateRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) (block.MiniBlockSlice, error) { if rcs.CreateRewardsMiniBlocksCalled != nil { @@ -42,7 +42,7 @@ func (rcs *RewardsCreatorStub) CreateRewardsMiniBlocks( // VerifyRewardsMiniBlocks - func (rcs *RewardsCreatorStub) VerifyRewardsMiniBlocks( metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, + validatorsInfo state.ShardValidatorsInfoMapHandler, computedEconomics *block.Economics, ) error { if rcs.VerifyRewardsMiniBlocksCalled != nil { From 53ad178cf3cabc4a0fa716b6d8381502e48dae3c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 14:37:38 +0200 Subject: [PATCH 144/958] FIX: Warning --- epochStart/metachain/rewardsV2_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/rewardsV2_test.go b/epochStart/metachain/rewardsV2_test.go index 72637079ffc..41f88f54f8b 100644 --- a/epochStart/metachain/rewardsV2_test.go +++ b/epochStart/metachain/rewardsV2_test.go @@ -1916,7 +1916,7 @@ func addNonEligibleValidatorInfo( ) state.ShardValidatorsInfoMapHandler { resultedValidatorsInfo := state.NewShardValidatorsInfoMap() for shardID, valInfoList := range validatorsInfo.GetShardValidatorsInfoMap() { - resultedValidatorsInfo.SetValidatorsInShard(shardID, valInfoList) + _ = resultedValidatorsInfo.SetValidatorsInShard(shardID, valInfoList) for i := uint32(0); i < nonEligiblePerShard; i++ { _ = resultedValidatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte(fmt.Sprintf("pubKeyBLSExtra%d", i)), From d8b870216a6eb5b30ad26d744ab414e6af384471 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 14:49:48 +0200 Subject: [PATCH 145/958] 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 146/958] 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) From 3eb31ebb6098ed14fb5c21231c355a0d70e24974 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 16:22:16 +0200 Subject: [PATCH 147/958] FIX: Review finding --- process/peer/validatorsProvider.go | 2 +- process/peer/validatorsProvider_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index dc3512c7db6..63ee0a4b904 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -180,7 +180,7 @@ func (vp *validatorsProvider) updateCache() { return } allNodes, err := vp.validatorStatistics.GetValidatorInfoForRootHash(lastFinalizedRootHash) - if err != nil || allNodes == nil { + if err != nil { allNodes = state.NewShardValidatorsInfoMap() log.Trace("validatorsProvider - GetLatestValidatorInfos failed", "error", err) } diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index de5a7ca180d..2424c3905e0 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -168,7 +168,7 @@ func TestValidatorsProvider_CallsPopulateAndRegister(t *testing.T) { arg.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { atomic.AddInt32(&numPopulateCacheCalled, 1) - return nil, nil + return state.NewShardValidatorsInfoMap(), nil }, LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") @@ -501,7 +501,7 @@ func TestValidatorsProvider_CallsPopulateOnlyAfterTimeout(t *testing.T) { } validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { atomic.AddInt32(populateCacheCalled, 1) - return nil, nil + return state.NewShardValidatorsInfoMap(), nil } arg.ValidatorStatistics = validatorStatisticsProcessor @@ -544,7 +544,7 @@ func TestValidatorsProvider_CallsUpdateCacheOnEpochChange(t *testing.T) { callNumber++ // first call comes from the constructor if callNumber == 1 { - return nil, nil + return state.NewShardValidatorsInfoMap(), nil } validatorsMap := state.NewShardValidatorsInfoMap() _ = validatorsMap.Add(&state.ValidatorInfo{ @@ -582,7 +582,7 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin callNumber++ // first call comes from the constructor if callNumber == 1 { - return nil, nil + return state.NewShardValidatorsInfoMap(), nil } validatorsMap := state.NewShardValidatorsInfoMap() _ = validatorsMap.Add(&state.ValidatorInfo{ From 8cd7d5b6c1d1c06b98866be6678ced4e4dbe69c7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 22 Mar 2022 16:26:34 +0200 Subject: [PATCH 148/958] FIX: Review finding --- epochStart/metachain/validators.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index 25080ceabea..532ae70ce99 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -74,8 +74,9 @@ func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo st miniblocks := make([]*block.MiniBlock, 0) + validatorsMap := validatorsInfo.GetShardValidatorsInfoMap() for shardId := uint32(0); shardId < vic.shardCoordinator.NumberOfShards(); shardId++ { - validators := validatorsInfo.GetShardValidatorsInfoMap()[shardId] + validators := validatorsMap[shardId] if len(validators) == 0 { continue } @@ -88,7 +89,7 @@ func (vic *validatorInfoCreator) CreateValidatorInfoMiniBlocks(validatorsInfo st miniblocks = append(miniblocks, miniBlock) } - validators := validatorsInfo.GetShardValidatorsInfoMap()[core.MetachainShardId] + validators := validatorsMap[core.MetachainShardId] if len(validators) == 0 { return miniblocks, nil } From fb6a3b96c579b13e21dfac8d5e5655668af960a0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 11:04:00 +0200 Subject: [PATCH 149/958] FIX: Tests --- .../startInEpoch/startInEpoch_test.go | 10 +++-- integrationTests/nodesCoordinatorFactory.go | 39 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index 6e878ed1dd7..39699d563fa 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -208,11 +208,13 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui coreComponents.NodeTypeProviderField = &nodeTypeProviderMock.NodeTypeProviderStub{} coreComponents.ChanStopNodeProcessField = endProcess.GetDummyEndProcessChannel() + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, 444) argsBootstrapHandler := bootstrap.ArgsEpochStartBootstrap{ - CryptoComponentsHolder: cryptoComponents, - CoreComponentsHolder: coreComponents, - Messenger: nodeToJoinLate.Messenger, - GeneralConfig: generalConfig, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + CryptoComponentsHolder: cryptoComponents, + CoreComponentsHolder: coreComponents, + Messenger: nodeToJoinLate.Messenger, + GeneralConfig: generalConfig, PrefsConfig: config.PreferencesConfig{ FullArchive: false, }, diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 2f83c6b7f57..3890d55461a 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -52,25 +52,28 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd BalanceWaitingListsEnableEpoch: 0, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(nodeShufflerArgs) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(TestMarshalizer, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: arg.shardConsensusGroupSize, - MetaConsensusGroupSize: arg.metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: arg.hasher, - Shuffler: nodeShuffler, - EpochStartNotifier: arg.epochStartSubscriber, - ShardIDAsObserver: arg.shardId, - NbShards: uint32(arg.nbShards), - EligibleNodes: arg.validatorsMap, - WaitingNodes: arg.waitingMap, - SelfPublicKey: pubKeyBytes, - ConsensusGroupCache: arg.consensusGroupCache, - BootStorer: arg.bootStorer, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: arg.shardConsensusGroupSize, + MetaConsensusGroupSize: arg.metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: arg.hasher, + Shuffler: nodeShuffler, + EpochStartNotifier: arg.epochStartSubscriber, + ShardIDAsObserver: arg.shardId, + NbShards: uint32(arg.nbShards), + EligibleNodes: arg.validatorsMap, + WaitingNodes: arg.waitingMap, + SelfPublicKey: pubKeyBytes, + ConsensusGroupCache: arg.consensusGroupCache, + BootStorer: arg.bootStorer, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: StakingV4Epoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) if err != nil { From bb4a1fa9f14113413aaf47cd7b2046cbad33178a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 13:00:41 +0200 Subject: [PATCH 150/958] FEAT: Change PublicKeysSelector interface to return all shuffled out nodes --- .../disabled/disabledNodesCoordinator.go | 5 ++++ .../indexHashedNodesCoordinator.go | 24 +++++++++++++++++++ sharding/nodesCoordinator/interface.go | 1 + .../shardingMocks/nodesCoordinatorMock.go | 5 ++++ .../shardingMocks/nodesCoordinatorStub.go | 7 +++++- 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/epochStart/bootstrap/disabled/disabledNodesCoordinator.go b/epochStart/bootstrap/disabled/disabledNodesCoordinator.go index 740224bfe6d..39b2b3d73c8 100644 --- a/epochStart/bootstrap/disabled/disabledNodesCoordinator.go +++ b/epochStart/bootstrap/disabled/disabledNodesCoordinator.go @@ -49,6 +49,11 @@ func (n *nodesCoordinator) GetAllWaitingValidatorsPublicKeys(_ uint32) (map[uint return nil, nil } +// GetAllShuffledOutValidatorsPublicKeys - +func (n *nodesCoordinator) GetAllShuffledOutValidatorsPublicKeys(_ uint32) (map[uint32][][]byte, error) { + return nil, nil +} + // GetConsensusValidatorsPublicKeys - func (n *nodesCoordinator) GetConsensusValidatorsPublicKeys(_ []byte, _ uint64, _ uint32, _ uint32) ([]string, error) { return nil, nil diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 12a7ceed950..292035cdb95 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -497,6 +497,30 @@ func (ihnc *indexHashedNodesCoordinator) GetAllLeavingValidatorsPublicKeys(epoch return validatorsPubKeys, nil } +// GetAllShuffledOutValidatorsPublicKeys - +func (ihnc *indexHashedNodesCoordinator) GetAllShuffledOutValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) { + validatorsPubKeys := make(map[uint32][][]byte) + + ihnc.mutNodesConfig.RLock() + nodesConfig, ok := ihnc.nodesConfig[epoch] + ihnc.mutNodesConfig.RUnlock() + + if !ok { + return nil, fmt.Errorf("%w epoch=%v", ErrEpochNodesConfigDoesNotExist, epoch) + } + + nodesConfig.mutNodesMaps.RLock() + defer nodesConfig.mutNodesMaps.RUnlock() + + for shardID, shuffledOutList := range nodesConfig.shuffledOutMap { + for _, shuffledOutValidator := range shuffledOutList { + validatorsPubKeys[shardID] = append(validatorsPubKeys[shardID], shuffledOutValidator.PubKey()) + } + } + + return validatorsPubKeys, nil +} + // GetValidatorsIndexes will return validators indexes for a block func (ihnc *indexHashedNodesCoordinator) GetValidatorsIndexes( publicKeys []string, diff --git a/sharding/nodesCoordinator/interface.go b/sharding/nodesCoordinator/interface.go index acd343d5664..3d268290476 100644 --- a/sharding/nodesCoordinator/interface.go +++ b/sharding/nodesCoordinator/interface.go @@ -45,6 +45,7 @@ type PublicKeysSelector interface { GetAllEligibleValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) GetAllWaitingValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) GetAllLeavingValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) + GetAllShuffledOutValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) GetConsensusValidatorsPublicKeys(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) GetOwnPublicKey() []byte } diff --git a/testscommon/shardingMocks/nodesCoordinatorMock.go b/testscommon/shardingMocks/nodesCoordinatorMock.go index ae7434058dc..278a2b3e533 100644 --- a/testscommon/shardingMocks/nodesCoordinatorMock.go +++ b/testscommon/shardingMocks/nodesCoordinatorMock.go @@ -100,6 +100,11 @@ func (ncm *NodesCoordinatorMock) GetAllWaitingValidatorsPublicKeys(_ uint32) (ma return nil, nil } +// GetAllShuffledOutValidatorsPublicKeys - +func (ncm *NodesCoordinatorMock) GetAllShuffledOutValidatorsPublicKeys(_ uint32) (map[uint32][][]byte, error) { + return nil, nil +} + // GetValidatorsIndexes - func (ncm *NodesCoordinatorMock) GetValidatorsIndexes(_ []string, _ uint32) ([]uint64, error) { return nil, nil diff --git a/testscommon/shardingMocks/nodesCoordinatorStub.go b/testscommon/shardingMocks/nodesCoordinatorStub.go index b16b9bd6e41..c7abf375cbc 100644 --- a/testscommon/shardingMocks/nodesCoordinatorStub.go +++ b/testscommon/shardingMocks/nodesCoordinatorStub.go @@ -3,7 +3,7 @@ package shardingMocks import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - state "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/state" ) // NodesCoordinatorStub - @@ -66,6 +66,11 @@ func (ncm *NodesCoordinatorStub) GetAllWaitingValidatorsPublicKeys(_ uint32) (ma return nil, nil } +// GetAllShuffledOutValidatorsPublicKeys - +func (ncm *NodesCoordinatorStub) GetAllShuffledOutValidatorsPublicKeys(_ uint32) (map[uint32][][]byte, error) { + return nil, nil +} + // GetNumTotalEligible - func (ncm *NodesCoordinatorStub) GetNumTotalEligible() uint64 { if ncm.GetNumTotalEligibleCalled != nil { From 5227ebffde89d0afc0bc9cef64366b32253c6320 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 14:53:02 +0200 Subject: [PATCH 151/958] FEAT: Save shuffled out in auction list + test --- epochStart/metachain/systemSCs_test.go | 1 + factory/processComponents.go | 1 + integrationTests/testProcessorNode.go | 1 + process/peer/process.go | 22 +++++ process/peer/process_test.go | 92 +++++++++++++++++++ .../shardingMocks/nodesCoordinatorMock.go | 36 ++++---- 6 files changed, 137 insertions(+), 16 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e741dfaa617..8a05765e46f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -844,6 +844,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS MaxConsecutiveRoundsOfRatingDecrease: 2000, EpochNotifier: en, StakingV2EnableEpoch: stakingV2EnableEpoch, + StakingV4EnableEpoch: 444, } vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) diff --git a/factory/processComponents.go b/factory/processComponents.go index 4fa27a9aac0..9143183b71b 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -644,6 +644,7 @@ func (pcf *processComponentsFactory) newValidatorStatisticsProcessor() (process. BelowSignedThresholdEnableEpoch: pcf.epochConfig.EnableEpochs.BelowSignedThresholdEnableEpoch, StakingV2EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV2EnableEpoch, StopDecreasingValidatorRatingWhenStuckEnableEpoch: pcf.epochConfig.EnableEpochs.StopDecreasingValidatorRatingWhenStuckEnableEpoch, + StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, } validatorStatisticsProcessor, err := peer.NewValidatorStatisticsProcessor(arguments) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 8d5cc16f135..8fc9ad1d026 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -711,6 +711,7 @@ func (tpn *TestProcessorNode) initValidatorStatistics() { GenesisNonce: tpn.BlockChain.GetGenesisHeader().GetNonce(), EpochNotifier: &epochNotifier.EpochNotifierStub{}, StakingV2EnableEpoch: StakingV2Epoch, + StakingV4EnableEpoch: StakingV4Epoch, } tpn.ValidatorStatisticsProcessor, _ = peer.NewValidatorStatisticsProcessor(arguments) diff --git a/process/peer/process.go b/process/peer/process.go index 3ee1c8f7692..ddb8f8badd6 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -57,6 +57,7 @@ type ArgValidatorStatisticsProcessor struct { BelowSignedThresholdEnableEpoch uint32 StakingV2EnableEpoch uint32 StopDecreasingValidatorRatingWhenStuckEnableEpoch uint32 + StakingV4EnableEpoch uint32 EpochNotifier process.EpochNotifier } @@ -81,9 +82,11 @@ type validatorStatistics struct { belowSignedThresholdEnableEpoch uint32 stakingV2EnableEpoch uint32 stopDecreasingValidatorRatingWhenStuckEnableEpoch uint32 + stakingV4EnableEpoch uint32 flagJailedEnabled atomic.Flag flagStakingV2Enabled atomic.Flag flagStopDecreasingValidatorRatingEnabled atomic.Flag + flagStakingV4 atomic.Flag } // NewValidatorStatisticsProcessor instantiates a new validatorStatistics structure responsible of keeping account of @@ -148,11 +151,13 @@ func NewValidatorStatisticsProcessor(arguments ArgValidatorStatisticsProcessor) belowSignedThresholdEnableEpoch: arguments.BelowSignedThresholdEnableEpoch, stakingV2EnableEpoch: arguments.StakingV2EnableEpoch, stopDecreasingValidatorRatingWhenStuckEnableEpoch: arguments.StopDecreasingValidatorRatingWhenStuckEnableEpoch, + stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, } log.Debug("peer/process: enable epoch for switch jail waiting", "epoch", vs.jailedEnableEpoch) log.Debug("peer/process: enable epoch for below signed threshold", "epoch", vs.belowSignedThresholdEnableEpoch) log.Debug("peer/process: enable epoch for staking v2", "epoch", vs.stakingV2EnableEpoch) log.Debug("peer/process: enable epoch for stop decreasing validator rating when stuck", "epoch", vs.stopDecreasingValidatorRatingWhenStuckEnableEpoch) + log.Debug("peer/process: enable epoch for staking v4", "epoch", vs.stakingV4EnableEpoch) arguments.EpochNotifier.RegisterNotifyHandler(vs) @@ -203,6 +208,18 @@ func (vs *validatorStatistics) saveNodesCoordinatorUpdates(epoch uint32) (bool, } nodeForcedToRemain = nodeForcedToRemain || tmpNodeForcedToRemain + if vs.flagStakingV4.IsSet() { + nodesMap, err = vs.nodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) + if err != nil { + return false, err + } + + _, err = vs.saveUpdatesForNodesMap(nodesMap, common.AuctionList) + if err != nil { + return false, err + } + } + return nodeForcedToRemain, nil } @@ -1243,10 +1260,15 @@ func (vs *validatorStatistics) LastFinalizedRootHash() []byte { func (vs *validatorStatistics) EpochConfirmed(epoch uint32, _ uint64) { vs.flagJailedEnabled.SetValue(epoch >= vs.jailedEnableEpoch) log.Debug("validatorStatistics: jailed", "enabled", vs.flagJailedEnabled.IsSet()) + vs.flagStakingV2Enabled.SetValue(epoch > vs.stakingV2EnableEpoch) log.Debug("validatorStatistics: stakingV2", vs.flagStakingV2Enabled.IsSet()) + vs.flagStopDecreasingValidatorRatingEnabled.SetValue(epoch >= vs.stopDecreasingValidatorRatingWhenStuckEnableEpoch) log.Debug("validatorStatistics: stop decreasing validator rating", "is enabled", vs.flagStopDecreasingValidatorRatingEnabled.IsSet(), "max consecutive rounds of rating decrease", vs.maxConsecutiveRoundsOfRatingDecrease) + + vs.flagStakingV4.SetValue(epoch >= vs.stakingV4EnableEpoch) + log.Debug("validatorStatistics: staking v4", "enabled", vs.flagStakingV4.IsSet()) } diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 4fbb67ddb0b..612f03e5c02 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/keyValStorage" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" @@ -119,6 +120,7 @@ func createMockArguments() peer.ArgValidatorStatisticsProcessor { EpochNotifier: &epochNotifier.EpochNotifierStub{}, StakingV2EnableEpoch: 5, StopDecreasingValidatorRatingWhenStuckEnableEpoch: 1500, + StakingV4EnableEpoch: 444, } return arguments } @@ -2567,6 +2569,96 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdates(t *testing.T) assert.False(t, nodeForcedToRemain) } +func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t *testing.T) { + t.Parallel() + + peerAdapter := getAccountsMock() + arguments := createMockArguments() + arguments.PeerAdapter = peerAdapter + + pk0 := []byte("pk0") + pk1 := []byte("pk1") + pk2 := []byte("pk2") + + account0, _ := state.NewPeerAccount(pk0) + account1, _ := state.NewPeerAccount(pk1) + account2, _ := state.NewPeerAccount(pk2) + + ctLoadAccount := &atomic.Counter{} + ctSaveAccount := &atomic.Counter{} + + peerAdapter.LoadAccountCalled = func(address []byte) (vmcommon.AccountHandler, error) { + ctLoadAccount.Increment() + + switch string(address) { + case string(pk0): + return account0, nil + case string(pk1): + return account1, nil + case string(pk2): + return account2, nil + default: + require.Fail(t, "should not have called this for other address") + return nil, nil + } + } + peerAdapter.SaveAccountCalled = func(account vmcommon.AccountHandler) error { + ctSaveAccount.Increment() + peerAccount := account.(state.PeerAccountHandler) + require.Equal(t, uint32(0), peerAccount.GetIndexInList()) + + switch string(account.AddressBytes()) { + case string(pk0): + require.Equal(t, string(common.EligibleList), peerAccount.GetList()) + require.Equal(t, uint32(0), peerAccount.GetShardId()) + return nil + case string(pk1): + require.Equal(t, string(common.AuctionList), peerAccount.GetList()) + require.Equal(t, uint32(0), peerAccount.GetShardId()) + return nil + case string(pk2): + require.Equal(t, string(common.AuctionList), peerAccount.GetList()) + require.Equal(t, core.MetachainShardId, peerAccount.GetShardId()) + return nil + } + + require.Fail(t, "should not have called this for other account") + return nil + } + + arguments.NodesCoordinator = &shardingMocks.NodesCoordinatorMock{ + GetAllEligibleValidatorsPublicKeysCalled: func(epoch uint32) (map[uint32][][]byte, error) { + mapNodes := map[uint32][][]byte{ + 0: {pk0}, + } + return mapNodes, nil + }, + GetAllShuffledOutValidatorsPublicKeysCalled: func(epoch uint32) (map[uint32][][]byte, error) { + mapNodes := map[uint32][][]byte{ + 0: {pk1}, + core.MetachainShardId: {pk2}, + } + return mapNodes, nil + }, + } + + validatorStatistics, _ := peer.NewValidatorStatisticsProcessor(arguments) + nodeForcedToRemain, err := validatorStatistics.SaveNodesCoordinatorUpdates(0) + require.Nil(t, err) + require.False(t, nodeForcedToRemain) + require.Equal(t, int64(1), ctSaveAccount.Get()) + require.Equal(t, int64(1), ctLoadAccount.Get()) + + ctSaveAccount.Reset() + ctLoadAccount.Reset() + validatorStatistics.EpochConfirmed(arguments.StakingV4EnableEpoch, 0) + nodeForcedToRemain, err = validatorStatistics.SaveNodesCoordinatorUpdates(0) + require.Nil(t, err) + require.False(t, nodeForcedToRemain) + require.Equal(t, int64(3), ctSaveAccount.Get()) + require.Equal(t, int64(3), ctLoadAccount.Get()) +} + func TestValidatorStatisticsProcessor_getActualList(t *testing.T) { eligibleList := string(common.EligibleList) eligiblePeer := &mock.PeerAccountHandlerMock{ diff --git a/testscommon/shardingMocks/nodesCoordinatorMock.go b/testscommon/shardingMocks/nodesCoordinatorMock.go index 278a2b3e533..aca6b57d505 100644 --- a/testscommon/shardingMocks/nodesCoordinatorMock.go +++ b/testscommon/shardingMocks/nodesCoordinatorMock.go @@ -11,21 +11,22 @@ import ( // NodesCoordinatorMock defines the behaviour of a struct able to do validator group selection type NodesCoordinatorMock struct { - Validators map[uint32][]nodesCoordinator.Validator - ShardConsensusSize uint32 - MetaConsensusSize uint32 - ShardId uint32 - NbShards uint32 - GetSelectedPublicKeysCalled func(selection []byte, shardId uint32, epoch uint32) (publicKeys []string, err error) - GetValidatorsPublicKeysCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) - GetValidatorsRewardsAddressesCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) - SetNodesPerShardsCalled func(nodes map[uint32][]nodesCoordinator.Validator, epoch uint32) error - ComputeValidatorsGroupCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) - GetValidatorWithPublicKeyCalled func(publicKey []byte) (validator nodesCoordinator.Validator, shardId uint32, err error) - GetAllEligibleValidatorsPublicKeysCalled func(epoch uint32) (map[uint32][][]byte, error) - GetAllWaitingValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) - ConsensusGroupSizeCalled func(uint32) int - GetNumTotalEligibleCalled func() uint64 + Validators map[uint32][]nodesCoordinator.Validator + ShardConsensusSize uint32 + MetaConsensusSize uint32 + ShardId uint32 + NbShards uint32 + GetSelectedPublicKeysCalled func(selection []byte, shardId uint32, epoch uint32) (publicKeys []string, err error) + GetValidatorsPublicKeysCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) + GetValidatorsRewardsAddressesCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) + SetNodesPerShardsCalled func(nodes map[uint32][]nodesCoordinator.Validator, epoch uint32) error + ComputeValidatorsGroupCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) + GetValidatorWithPublicKeyCalled func(publicKey []byte) (validator nodesCoordinator.Validator, shardId uint32, err error) + GetAllEligibleValidatorsPublicKeysCalled func(epoch uint32) (map[uint32][][]byte, error) + GetAllShuffledOutValidatorsPublicKeysCalled func(epoch uint32) (map[uint32][][]byte, error) + GetAllWaitingValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) + ConsensusGroupSizeCalled func(uint32) int + GetNumTotalEligibleCalled func() uint64 } // NewNodesCoordinatorMock - @@ -101,7 +102,10 @@ func (ncm *NodesCoordinatorMock) GetAllWaitingValidatorsPublicKeys(_ uint32) (ma } // GetAllShuffledOutValidatorsPublicKeys - -func (ncm *NodesCoordinatorMock) GetAllShuffledOutValidatorsPublicKeys(_ uint32) (map[uint32][][]byte, error) { +func (ncm *NodesCoordinatorMock) GetAllShuffledOutValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) { + if ncm.GetAllShuffledOutValidatorsPublicKeysCalled != nil { + return ncm.GetAllShuffledOutValidatorsPublicKeysCalled(epoch) + } return nil, nil } From 9f3294483162322c5ac691965ccb6c8c255b10e7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 16:36:02 +0200 Subject: [PATCH 152/958] FEAT: Save shuffled out in auction list + test --- epochStart/bootstrap/process.go | 28 +++++++-------- epochStart/bootstrap/process_test.go | 8 +++-- epochStart/bootstrap/syncValidatorStatus.go | 36 ++++++++----------- factory/bootstrapComponents.go | 32 +++++++++-------- factory/bootstrapComponentsHandler.go | 13 +++++++ factory/interface.go | 1 + factory/shardingFactory.go | 7 +--- integrationTests/consensus/testInitializer.go | 8 +++-- .../startInEpoch/startInEpoch_test.go | 7 +++- integrationTests/nodesCoordinatorFactory.go | 18 +++++++--- integrationTests/testP2PNode.go | 12 ++++--- .../testProcessorNodeWithMultisigner.go | 17 ++++++--- node/nodeRunner.go | 2 +- sharding/nodesCoordinator/errors.go | 3 ++ .../hashValidatorShuffler_test.go | 3 +- .../indexHashedNodesCoordinator_test.go | 7 +++- sharding/nodesCoordinator/interface.go | 9 +++++ .../nodesCoordinatorRegistryFactory.go | 11 ++++-- .../bootstrapComponentsStub.go | 23 +++++++----- 19 files changed, 158 insertions(+), 87 deletions(-) diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index e0f4b76568f..d8aaf1bccfe 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -700,20 +700,20 @@ func (e *epochStartBootstrap) processNodesConfig(pubKey []byte) error { shardId = e.genesisShardCoordinator.SelfId() } argsNewValidatorStatusSyncers := ArgsNewSyncValidatorStatus{ - DataPool: e.dataPool, - Marshalizer: e.coreComponentsHolder.InternalMarshalizer(), - RequestHandler: e.requestHandler, - ChanceComputer: e.rater, - GenesisNodesConfig: e.genesisNodesConfig, - NodeShuffler: e.nodeShuffler, - Hasher: e.coreComponentsHolder.Hasher(), - PubKey: pubKey, - ShardIdAsObserver: shardId, - WaitingListFixEnableEpoch: e.enableEpochs.WaitingListFixEnableEpoch, - ChanNodeStop: e.coreComponentsHolder.ChanStopNodeProcess(), - NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), - IsFullArchive: e.prefsConfig.FullArchive, - StakingV4EnableEpoch: e.enableEpochs.StakingV4EnableEpoch, + DataPool: e.dataPool, + Marshalizer: e.coreComponentsHolder.InternalMarshalizer(), + RequestHandler: e.requestHandler, + ChanceComputer: e.rater, + GenesisNodesConfig: e.genesisNodesConfig, + NodeShuffler: e.nodeShuffler, + Hasher: e.coreComponentsHolder.Hasher(), + PubKey: pubKey, + ShardIdAsObserver: shardId, + WaitingListFixEnableEpoch: e.enableEpochs.WaitingListFixEnableEpoch, + ChanNodeStop: e.coreComponentsHolder.ChanStopNodeProcess(), + NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), + IsFullArchive: e.prefsConfig.FullArchive, + nodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, } e.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index f7902eaed9d..dc4fa41bce6 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -87,13 +87,17 @@ func createMockEpochStartBootstrapArgs( cryptoMock *mock.CryptoComponentsMock, ) ArgsEpochStartBootstrap { generalCfg := testscommon.GetGeneralConfig() - ncr, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, 444) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &testscommon.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + 444, + ) return ArgsEpochStartBootstrap{ ScheduledSCRsStorer: genericMocks.NewStorerMock("path", 0), CoreComponentsHolder: coreMock, CryptoComponentsHolder: cryptoMock, Messenger: &mock.MessengerStub{}, - NodesCoordinatorRegistryFactory: ncr, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, GeneralConfig: config.Config{ MiniBlocksStorage: generalCfg.MiniBlocksStorage, PeerBlockBodyStorage: generalCfg.PeerBlockBodyStorage, diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index b86c5a6c161..d947d3967a9 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -34,20 +34,20 @@ type syncValidatorStatus struct { // ArgsNewSyncValidatorStatus holds the arguments needed for creating a new validator status process component type ArgsNewSyncValidatorStatus struct { - DataPool dataRetriever.PoolsHolder - Marshalizer marshal.Marshalizer - Hasher hashing.Hasher - RequestHandler process.RequestHandler - ChanceComputer nodesCoordinator.ChanceComputer - GenesisNodesConfig sharding.GenesisNodesSetupHandler - NodeShuffler nodesCoordinator.NodesShuffler - PubKey []byte - ShardIdAsObserver uint32 - WaitingListFixEnableEpoch uint32 - StakingV4EnableEpoch uint32 - ChanNodeStop chan endProcess.ArgEndProcess - NodeTypeProvider NodeTypeProviderHandler - IsFullArchive bool + DataPool dataRetriever.PoolsHolder + Marshalizer marshal.Marshalizer + Hasher hashing.Hasher + RequestHandler process.RequestHandler + ChanceComputer nodesCoordinator.ChanceComputer + GenesisNodesConfig sharding.GenesisNodesSetupHandler + NodeShuffler nodesCoordinator.NodesShuffler + PubKey []byte + ShardIdAsObserver uint32 + WaitingListFixEnableEpoch uint32 + ChanNodeStop chan endProcess.ArgEndProcess + NodeTypeProvider NodeTypeProviderHandler + IsFullArchive bool + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } // NewSyncValidatorStatus creates a new validator status process component @@ -93,11 +93,6 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat s.memDB = disabled.CreateMemUnit() - ncf, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory(args.Marshalizer, args.StakingV4EnableEpoch) - if err != nil { - return nil, err - } - argsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), @@ -117,8 +112,7 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat ChanStopNode: args.ChanNodeStop, NodeTypeProvider: args.NodeTypeProvider, IsFullArchive: args.IsFullArchive, - StakingV4EnableEpoch: args.StakingV4EnableEpoch, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: args.nodesCoordinatorRegistryFactory, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/factory/bootstrapComponents.go b/factory/bootstrapComponents.go index 06c64560691..fe8e388a997 100644 --- a/factory/bootstrapComponents.go +++ b/factory/bootstrapComponents.go @@ -51,14 +51,15 @@ type bootstrapComponentsFactory struct { } type bootstrapComponents struct { - epochStartBootstrapper EpochStartBootstrapper - bootstrapParamsHolder BootstrapParamsHolder - nodeType core.NodeType - shardCoordinator sharding.Coordinator - headerVersionHandler factory.HeaderVersionHandler - versionedHeaderFactory factory.VersionedHeaderFactory - headerIntegrityVerifier factory.HeaderIntegrityVerifierHandler - roundActivationHandler process.RoundActivationHandler + epochStartBootstrapper EpochStartBootstrapper + bootstrapParamsHolder BootstrapParamsHolder + nodeType core.NodeType + shardCoordinator sharding.Coordinator + headerVersionHandler factory.HeaderVersionHandler + versionedHeaderFactory factory.VersionedHeaderFactory + headerIntegrityVerifier factory.HeaderIntegrityVerifierHandler + roundActivationHandler process.RoundActivationHandler + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } // NewBootstrapComponentsFactory creates an instance of bootstrapComponentsFactory @@ -163,12 +164,12 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory( bcf.coreComponents.InternalMarshalizer(), + bcf.coreComponents.EpochNotifier(), bcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, ) if err != nil { return nil, err } - bcf.coreComponents.EpochNotifier().RegisterNotifyHandler(nodesCoordinatorRegistryFactory) epochStartBootstrapArgs := bootstrap.ArgsEpochStartBootstrap{ CoreComponentsHolder: bcf.coreComponents, @@ -250,12 +251,13 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { bootstrapParamsHolder: &bootstrapParams{ bootstrapParams: bootstrapParameters, }, - nodeType: nodeType, - shardCoordinator: shardCoordinator, - headerVersionHandler: headerVersionHandler, - headerIntegrityVerifier: headerIntegrityVerifier, - versionedHeaderFactory: versionedHeaderFactory, - roundActivationHandler: roundActivationHandler, + nodeType: nodeType, + shardCoordinator: shardCoordinator, + headerVersionHandler: headerVersionHandler, + headerIntegrityVerifier: headerIntegrityVerifier, + versionedHeaderFactory: versionedHeaderFactory, + roundActivationHandler: roundActivationHandler, + nodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, }, nil } diff --git a/factory/bootstrapComponentsHandler.go b/factory/bootstrapComponentsHandler.go index 286909baa1b..572f2a40bb4 100644 --- a/factory/bootstrapComponentsHandler.go +++ b/factory/bootstrapComponentsHandler.go @@ -7,6 +7,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/errors" "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" ) var _ ComponentHandler = (*managedBootstrapComponents)(nil) @@ -117,6 +118,18 @@ func (mbf *managedBootstrapComponents) RoundActivationHandler() process.RoundAct return mbf.bootstrapComponents.roundActivationHandler } +// NodesCoordinatorRegistryFactory returns the NodesCoordinatorRegistryFactory +func (mbf *managedBootstrapComponents) NodesCoordinatorRegistryFactory() nodesCoordinator.NodesCoordinatorRegistryFactory { + mbf.mutBootstrapComponents.RLock() + defer mbf.mutBootstrapComponents.RUnlock() + + if mbf.bootstrapComponents == nil { + return nil + } + + return mbf.bootstrapComponents.nodesCoordinatorRegistryFactory +} + // IsInterfaceNil returns true if the underlying object is nil func (mbf *managedBootstrapComponents) IsInterfaceNil() bool { return mbf == nil diff --git a/factory/interface.go b/factory/interface.go index b03437ab372..a78618d247f 100644 --- a/factory/interface.go +++ b/factory/interface.go @@ -426,6 +426,7 @@ type BootstrapComponentsHolder interface { VersionedHeaderFactory() factory.VersionedHeaderFactory HeaderVersionHandler() factory.HeaderVersionHandler HeaderIntegrityVerifier() factory.HeaderIntegrityVerifierHandler + NodesCoordinatorRegistryFactory() nodesCoordinator.NodesCoordinatorRegistryFactory IsInterfaceNil() bool } diff --git a/factory/shardingFactory.go b/factory/shardingFactory.go index 4d8cf09250f..abe32c3fd04 100644 --- a/factory/shardingFactory.go +++ b/factory/shardingFactory.go @@ -103,9 +103,9 @@ func CreateNodesCoordinator( bootstrapParameters BootstrapParamsHolder, startEpoch uint32, waitingListFixEnabledEpoch uint32, - stakingV4EnableEpoch uint32, chanNodeStop chan endProcess.ArgEndProcess, nodeTypeProvider core.NodeTypeProviderHandler, + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, ) (nodesCoordinator.NodesCoordinator, error) { if chanNodeStop == nil { return nil, nodesCoordinator.ErrNilNodeStopChannel @@ -174,11 +174,6 @@ func CreateNodesCoordinator( return nil, err } - nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory(marshalizer, stakingV4EnableEpoch) - if err != nil { - return nil, err - } - argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, diff --git a/integrationTests/consensus/testInitializer.go b/integrationTests/consensus/testInitializer.go index 28a101b39a3..957fc1e69fa 100644 --- a/integrationTests/consensus/testInitializer.go +++ b/integrationTests/consensus/testInitializer.go @@ -520,7 +520,11 @@ func createNodes( bootStorer := integrationTests.CreateMemUnit() consensusCache, _ := lrucache.NewCache(10000) - ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, integrationTests.StakingV4Epoch) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &testscommon.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + integrationTests.StakingV4Epoch, + ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: consensusSize, MetaConsensusGroupSize: 1, @@ -539,7 +543,7 @@ func createNodes( ChanStopNode: endProcess.GetDummyEndProcessChannel(), NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoord, _ := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index 39699d563fa..07ff8dccde9 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -29,6 +29,7 @@ import ( "github.com/ElrondNetwork/elrond-go/storage/factory" "github.com/ElrondNetwork/elrond-go/storage/storageUnit" "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/genericMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/scheduledDataSyncer" @@ -208,7 +209,11 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui coreComponents.NodeTypeProviderField = &nodeTypeProviderMock.NodeTypeProviderStub{} coreComponents.ChanStopNodeProcessField = endProcess.GetDummyEndProcessChannel() - nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, 444) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &testscommon.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + 444, + ) argsBootstrapHandler := bootstrap.ArgsEpochStartBootstrap{ NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, CryptoComponentsHolder: cryptoComponents, diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 3890d55461a..000ddf90c3b 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -9,7 +9,7 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/storage" - "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" ) @@ -51,8 +51,13 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd WaitingListFixEnableEpoch: 0, BalanceWaitingListsEnableEpoch: 0, } + nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(nodeShufflerArgs) - nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(TestMarshalizer, StakingV4Epoch) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + TestMarshalizer, + &epochNotifier.EpochNotifierStub{}, + StakingV4Epoch, + ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: arg.shardConsensusGroupSize, MetaConsensusGroupSize: arg.metaConsensusGroupSize, @@ -106,8 +111,13 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato BalanceWaitingListsEnableEpoch: 0, WaitingListFixEnableEpoch: 0, } + nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) - ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + TestMarshalizer, + &epochNotifier.EpochNotifierStub{}, + StakingV4Epoch, + ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: arg.shardConsensusGroupSize, MetaConsensusGroupSize: arg.metaConsensusGroupSize, @@ -127,7 +137,7 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato ChanStopNode: endProcess.GetDummyEndProcessChannel(), NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } baseCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index 61b0741d835..ef4209c80fa 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -28,6 +28,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage/storageUnit" "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" @@ -329,8 +330,12 @@ func CreateNodesWithTestP2PNodes( nodesMap := make(map[uint32][]*TestP2PNode) cacherCfg := storageUnit.CacheConfig{Capacity: 10000, Type: storageUnit.LRUCache, Shards: 1} cache, _ := storageUnit.NewCache(cacherCfg) + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &testscommon.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + StakingV4Epoch, + ) for shardId, validatorList := range validatorsMap { - ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, @@ -351,7 +356,7 @@ func CreateNodesWithTestP2PNodes( ChanStopNode: endProcess.GetDummyEndProcessChannel(), NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) @@ -377,7 +382,6 @@ func CreateNodesWithTestP2PNodes( shardId = core.MetachainShardId } - ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, @@ -399,7 +403,7 @@ func CreateNodesWithTestP2PNodes( NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, StakingV4EnableEpoch: StakingV4Epoch, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 98ff92cd2a3..8383965787a 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -32,6 +32,7 @@ import ( "github.com/ElrondNetwork/elrond-go/storage/storageUnit" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" ) @@ -493,10 +494,14 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( return validatorsMap, nil }} + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &testscommon.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + StakingV4Epoch, + ) completeNodesList := make([]Connectable, 0) for shardId, validatorList := range validatorsMap { consensusCache, _ := lrucache.NewCache(10000) - ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, @@ -517,7 +522,7 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, StakingV4EnableEpoch: StakingV4Epoch, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -594,11 +599,15 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( }, } + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &testscommon.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + StakingV4Epoch, + ) completeNodesList := make([]Connectable, 0) for shardId, validatorList := range validatorsMap { bootStorer := CreateMemUnit() cache, _ := lrucache.NewCache(10000) - ncf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(&testscommon.MarshalizerMock{}, StakingV4Epoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, @@ -618,7 +627,7 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( ChanStopNode: endProcess.GetDummyEndProcessChannel(), NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, - NodesCoordinatorRegistryFactory: ncf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, StakingV4EnableEpoch: StakingV4Epoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 5e2952f7360..0c660440d00 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -328,9 +328,9 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), + managedBootstrapComponents.NodesCoordinatorRegistryFactory(), ) if err != nil { return true, err diff --git a/sharding/nodesCoordinator/errors.go b/sharding/nodesCoordinator/errors.go index c28f6e61be0..5d85563b86f 100644 --- a/sharding/nodesCoordinator/errors.go +++ b/sharding/nodesCoordinator/errors.go @@ -111,3 +111,6 @@ var ErrNilNodesCoordinatorRegistryFactory = errors.New("nil nodes coordinator re // ErrReceivedAuctionValidatorsBeforeStakingV4 signals that auction nodes have been received from peer mini blocks before enabling staking v4 var ErrReceivedAuctionValidatorsBeforeStakingV4 = errors.New("should no have received selected nodes from auction in peer mini blocks, since staking v4 is not enabled yet") + +// ErrNilEpochNotifier signals that a nil EpochNotifier has been provided +var ErrNilEpochNotifier = errors.New("nil epoch notifier provided") diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index fa1a9dee938..ee58cd3ff06 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -2641,7 +2641,7 @@ func TestRandHashShuffler_UpdateNodeLists_WithStakingV4(t *testing.T) { Rand: generateRandomByteArray(32), Auction: auctionList, NbShards: nbShards, - Epoch: 444, + Epoch: stakingV4Epoch, } shuffler, _ := createHashShufflerIntraShards() @@ -2670,7 +2670,6 @@ func TestRandHashShuffler_UpdateNodeLists_WithStakingV4(t *testing.T) { previousNumberOfNodes := (numEligiblePerShard+numWaitingPerShard+numNewNodesPerShard)*(int(nbShards)+1) + numAuction currentNumberOfNodes := len(allNewEligible) + len(allNewWaiting) + len(allShuffledOut) assert.Equal(t, previousNumberOfNodes, currentNumberOfNodes) - } func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t *testing.T) { diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 5371332551f..2b1ecfe94da 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -22,6 +22,7 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding/mock" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage/lrucache" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/stretchr/testify/assert" @@ -78,7 +79,11 @@ func isStringSubgroup(a []string, b []string) bool { } func createNodesCoordinatorRegistryFactory() NodesCoordinatorRegistryFactory { - ncf, _ := NewNodesCoordinatorRegistryFactory(&mock.MarshalizerMock{}, stakingV4Epoch) + ncf, _ := NewNodesCoordinatorRegistryFactory( + &mock.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + stakingV4Epoch, + ) return ncf } diff --git a/sharding/nodesCoordinator/interface.go b/sharding/nodesCoordinator/interface.go index 69d5bf12603..f0471432354 100644 --- a/sharding/nodesCoordinator/interface.go +++ b/sharding/nodesCoordinator/interface.go @@ -5,6 +5,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" ) // Validator defines a node that can be allocated to a shard for participation in a consensus group as validator @@ -158,3 +159,11 @@ type NodesCoordinatorRegistryFactory interface { EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool } + +// EpochNotifier can notify upon an epoch change and provide the current epoch +type EpochNotifier interface { + RegisterNotifyHandler(handler vmcommon.EpochSubscriberHandler) + CurrentEpoch() uint32 + CheckEpoch(header data.HeaderHandler) + IsInterfaceNil() bool +} diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index 140c04c02d7..e2e0e00d243 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -18,17 +18,24 @@ type nodesCoordinatorRegistryFactory struct { // NodesCoordinatorRegistryHandler from a buffer depending on the epoch func NewNodesCoordinatorRegistryFactory( marshaller marshal.Marshalizer, + notifier EpochNotifier, stakingV4EnableEpoch uint32, ) (*nodesCoordinatorRegistryFactory, error) { if check.IfNil(marshaller) { return nil, ErrNilMarshalizer } + if check.IfNil(notifier) { + return nil, ErrNilEpochNotifier + } log.Debug("nodesCoordinatorRegistryFactory: staking v4 enable epoch", "epoch", stakingV4EnableEpoch) - return &nodesCoordinatorRegistryFactory{ + + ncf := &nodesCoordinatorRegistryFactory{ marshaller: marshaller, stakingV4EnableEpoch: stakingV4EnableEpoch, - }, nil + } + notifier.RegisterNotifyHandler(ncf) + return ncf, nil } // CreateNodesCoordinatorRegistry creates a NodesCoordinatorRegistryHandler depending on the buffer. Old version uses diff --git a/testscommon/mainFactoryMocks/bootstrapComponentsStub.go b/testscommon/mainFactoryMocks/bootstrapComponentsStub.go index 14daad9f5af..ff0c1a4b15c 100644 --- a/testscommon/mainFactoryMocks/bootstrapComponentsStub.go +++ b/testscommon/mainFactoryMocks/bootstrapComponentsStub.go @@ -6,18 +6,20 @@ import ( "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" ) // BootstrapComponentsStub - type BootstrapComponentsStub struct { - Bootstrapper factory.EpochStartBootstrapper - BootstrapParams factory.BootstrapParamsHolder - NodeRole core.NodeType - ShCoordinator sharding.Coordinator - HdrVersionHandler nodeFactory.HeaderVersionHandler - VersionedHdrFactory nodeFactory.VersionedHeaderFactory - HdrIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler - RoundActivationHandlerField process.RoundActivationHandler + Bootstrapper factory.EpochStartBootstrapper + BootstrapParams factory.BootstrapParamsHolder + NodeRole core.NodeType + ShCoordinator sharding.Coordinator + HdrVersionHandler nodeFactory.HeaderVersionHandler + VersionedHdrFactory nodeFactory.VersionedHeaderFactory + HdrIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler + RoundActivationHandlerField process.RoundActivationHandler + NodesCoordinatorRegistryFactoryField nodesCoordinator.NodesCoordinatorRegistryFactory } // Create - @@ -75,6 +77,11 @@ func (bcs *BootstrapComponentsStub) RoundActivationHandler() process.RoundActiva return bcs.RoundActivationHandlerField } +// NodesCoordinatorRegistryFactory - +func (bcs *BootstrapComponentsStub) NodesCoordinatorRegistryFactory() nodesCoordinator.NodesCoordinatorRegistryFactory { + return bcs.NodesCoordinatorRegistryFactoryField +} + // String - func (bcs *BootstrapComponentsStub) String() string { return "BootstrapComponentsStub" From 8f172651d5f5c4905b0e7827d14567a024c85131 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 17:07:59 +0200 Subject: [PATCH 153/958] FIX: Test --- epochStart/bootstrap/process.go | 2 +- epochStart/bootstrap/syncValidatorStatus.go | 4 ++-- .../bootstrap/syncValidatorStatus_test.go | 20 +++++++++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index d8aaf1bccfe..e8538dd7b1b 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -713,7 +713,7 @@ func (e *epochStartBootstrap) processNodesConfig(pubKey []byte) error { ChanNodeStop: e.coreComponentsHolder.ChanStopNodeProcess(), NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), IsFullArchive: e.prefsConfig.FullArchive, - nodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, + NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, } e.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index d947d3967a9..850a8fc2802 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -47,7 +47,7 @@ type ArgsNewSyncValidatorStatus struct { ChanNodeStop chan endProcess.ArgEndProcess NodeTypeProvider NodeTypeProviderHandler IsFullArchive bool - nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory + NodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } // NewSyncValidatorStatus creates a new validator status process component @@ -112,7 +112,7 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat ChanStopNode: args.ChanNodeStop, NodeTypeProvider: args.NodeTypeProvider, IsFullArchive: args.IsFullArchive, - NodesCoordinatorRegistryFactory: args.nodesCoordinatorRegistryFactory, + NodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/epochStart/bootstrap/syncValidatorStatus_test.go b/epochStart/bootstrap/syncValidatorStatus_test.go index 7d5a9fbce51..1b1e09eeee6 100644 --- a/epochStart/bootstrap/syncValidatorStatus_test.go +++ b/epochStart/bootstrap/syncValidatorStatus_test.go @@ -15,6 +15,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" epochStartMocks "github.com/ElrondNetwork/elrond-go/testscommon/bootstrapMocks/epochStart" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" @@ -240,6 +241,12 @@ func TestSyncValidatorStatus_getPeerBlockBodyForMeta(t *testing.T) { } func getSyncValidatorStatusArgs() ArgsNewSyncValidatorStatus { + nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + &mock.MarshalizerMock{}, + &epochNotifier.EpochNotifierStub{}, + 444, + ) + return ArgsNewSyncValidatorStatus{ DataPool: &dataRetrieverMock.PoolsHolderStub{ MiniBlocksCalled: func() storage.Cacher { @@ -292,11 +299,12 @@ func getSyncValidatorStatusArgs() ArgsNewSyncValidatorStatus { return 2 }, }, - NodeShuffler: &shardingMocks.NodeShufflerMock{}, - PubKey: []byte("public key"), - ShardIdAsObserver: 0, - ChanNodeStop: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + NodeShuffler: &shardingMocks.NodeShufflerMock{}, + PubKey: []byte("public key"), + ShardIdAsObserver: 0, + ChanNodeStop: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } } From d58e550b112313a74a1b1adfbec94380bb044927 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 17:22:08 +0200 Subject: [PATCH 154/958] FIX: Another test + typo --- epochStart/bootstrap/storageProcess.go | 25 +++++++++++++------------ sharding/nodesCoordinator/errors.go | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/epochStart/bootstrap/storageProcess.go b/epochStart/bootstrap/storageProcess.go index 8b65a65ee55..5f59bc8d5f3 100644 --- a/epochStart/bootstrap/storageProcess.go +++ b/epochStart/bootstrap/storageProcess.go @@ -403,18 +403,19 @@ func (sesb *storageEpochStartBootstrap) processNodesConfig(pubKey []byte) error shardId = sesb.genesisShardCoordinator.SelfId() } argsNewValidatorStatusSyncers := ArgsNewSyncValidatorStatus{ - DataPool: sesb.dataPool, - Marshalizer: sesb.coreComponentsHolder.InternalMarshalizer(), - RequestHandler: sesb.requestHandler, - ChanceComputer: sesb.rater, - GenesisNodesConfig: sesb.genesisNodesConfig, - NodeShuffler: sesb.nodeShuffler, - Hasher: sesb.coreComponentsHolder.Hasher(), - PubKey: pubKey, - ShardIdAsObserver: shardId, - ChanNodeStop: sesb.coreComponentsHolder.ChanStopNodeProcess(), - NodeTypeProvider: sesb.coreComponentsHolder.NodeTypeProvider(), - IsFullArchive: sesb.prefsConfig.FullArchive, + DataPool: sesb.dataPool, + Marshalizer: sesb.coreComponentsHolder.InternalMarshalizer(), + RequestHandler: sesb.requestHandler, + ChanceComputer: sesb.rater, + GenesisNodesConfig: sesb.genesisNodesConfig, + NodeShuffler: sesb.nodeShuffler, + Hasher: sesb.coreComponentsHolder.Hasher(), + PubKey: pubKey, + ShardIdAsObserver: shardId, + ChanNodeStop: sesb.coreComponentsHolder.ChanStopNodeProcess(), + NodeTypeProvider: sesb.coreComponentsHolder.NodeTypeProvider(), + IsFullArchive: sesb.prefsConfig.FullArchive, + NodesCoordinatorRegistryFactory: sesb.nodesCoordinatorRegistryFactory, } sesb.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) if err != nil { diff --git a/sharding/nodesCoordinator/errors.go b/sharding/nodesCoordinator/errors.go index 5d85563b86f..02d5b9fa6b0 100644 --- a/sharding/nodesCoordinator/errors.go +++ b/sharding/nodesCoordinator/errors.go @@ -110,7 +110,7 @@ var ErrNilNodeTypeProvider = errors.New("nil node type provider") var ErrNilNodesCoordinatorRegistryFactory = errors.New("nil nodes coordinator registry factory has been given") // ErrReceivedAuctionValidatorsBeforeStakingV4 signals that auction nodes have been received from peer mini blocks before enabling staking v4 -var ErrReceivedAuctionValidatorsBeforeStakingV4 = errors.New("should no have received selected nodes from auction in peer mini blocks, since staking v4 is not enabled yet") +var ErrReceivedAuctionValidatorsBeforeStakingV4 = errors.New("should not have received selected nodes from auction in peer mini blocks, since staking v4 is not enabled yet") // ErrNilEpochNotifier signals that a nil EpochNotifier has been provided var ErrNilEpochNotifier = errors.New("nil epoch notifier provided") From 7dd05936e683bfc86284c7e3586eb2c539a7d95c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 23 Mar 2022 17:41:04 +0200 Subject: [PATCH 155/958] FIX: Findings + tests --- .../consensusComponents/consensusComponents_test.go | 9 ++++++++- .../factory/processComponents/processComponents_test.go | 9 ++++++++- .../factory/statusComponents/statusComponents_test.go | 9 ++++++++- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 2 -- .../indexHashedNodesCoordinatorRegistry_test.go | 1 + .../nodesCoordinator/indexHashedNodesCoordinator_test.go | 4 ++-- 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/integrationTests/factory/consensusComponents/consensusComponents_test.go b/integrationTests/factory/consensusComponents/consensusComponents_test.go index 11711e9f32a..0cbaa9355df 100644 --- a/integrationTests/factory/consensusComponents/consensusComponents_test.go +++ b/integrationTests/factory/consensusComponents/consensusComponents_test.go @@ -11,6 +11,7 @@ import ( mainFactory "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests/factory" "github.com/ElrondNetwork/elrond-go/node" + nodesCoord "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/testscommon/goroutines" "github.com/stretchr/testify/require" ) @@ -48,6 +49,12 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { require.Nil(t, err) nodesShufflerOut, err := mainFactory.CreateNodesShuffleOut(managedCoreComponents.GenesisNodesSetup(), configs.GeneralConfig.EpochStartConfig, managedCoreComponents.ChanStopNodeProcess()) require.Nil(t, err) + nodesCoordinatorRegistryFactory, err := nodesCoord.NewNodesCoordinatorRegistryFactory( + managedCoreComponents.InternalMarshalizer(), + managedCoreComponents.EpochNotifier(), + 444, + ) + require.Nil(t, err) nodesCoordinator, err := mainFactory.CreateNodesCoordinator( nodesShufflerOut, managedCoreComponents.GenesisNodesSetup(), @@ -63,9 +70,9 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), + nodesCoordinatorRegistryFactory, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/processComponents/processComponents_test.go b/integrationTests/factory/processComponents/processComponents_test.go index c69c2caf88b..a79b790adf9 100644 --- a/integrationTests/factory/processComponents/processComponents_test.go +++ b/integrationTests/factory/processComponents/processComponents_test.go @@ -11,6 +11,7 @@ import ( mainFactory "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests/factory" "github.com/ElrondNetwork/elrond-go/node" + nodesCoord "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/testscommon/goroutines" "github.com/stretchr/testify/require" ) @@ -49,6 +50,12 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { require.Nil(t, err) nodesShufflerOut, err := mainFactory.CreateNodesShuffleOut(managedCoreComponents.GenesisNodesSetup(), configs.GeneralConfig.EpochStartConfig, managedCoreComponents.ChanStopNodeProcess()) require.Nil(t, err) + nodesCoordinatorRegistryFactory, err := nodesCoord.NewNodesCoordinatorRegistryFactory( + managedCoreComponents.InternalMarshalizer(), + managedCoreComponents.EpochNotifier(), + 444, + ) + require.Nil(t, err) nodesCoordinator, err := mainFactory.CreateNodesCoordinator( nodesShufflerOut, managedCoreComponents.GenesisNodesSetup(), @@ -64,9 +71,9 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), + nodesCoordinatorRegistryFactory, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/statusComponents/statusComponents_test.go b/integrationTests/factory/statusComponents/statusComponents_test.go index 637f1ded899..bd513856728 100644 --- a/integrationTests/factory/statusComponents/statusComponents_test.go +++ b/integrationTests/factory/statusComponents/statusComponents_test.go @@ -11,6 +11,7 @@ import ( mainFactory "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests/factory" "github.com/ElrondNetwork/elrond-go/node" + nodesCoord "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/testscommon/goroutines" "github.com/stretchr/testify/require" ) @@ -49,6 +50,12 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { require.Nil(t, err) nodesShufflerOut, err := mainFactory.CreateNodesShuffleOut(managedCoreComponents.GenesisNodesSetup(), configs.GeneralConfig.EpochStartConfig, managedCoreComponents.ChanStopNodeProcess()) require.Nil(t, err) + nodesCoordinatorRegistryFactory, err := nodesCoord.NewNodesCoordinatorRegistryFactory( + managedCoreComponents.InternalMarshalizer(), + managedCoreComponents.EpochNotifier(), + 444, + ) + require.Nil(t, err) nodesCoordinator, err := mainFactory.CreateNodesCoordinator( nodesShufflerOut, managedCoreComponents.GenesisNodesSetup(), @@ -64,9 +71,9 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { managedBootstrapComponents.EpochBootstrapParams(), managedBootstrapComponents.EpochBootstrapParams().Epoch(), configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), + nodesCoordinatorRegistryFactory, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 8ee4a0bda0f..2ac3514ba28 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -1235,6 +1235,4 @@ func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4EnableEpoch) log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4.IsSet()) - - ihnc.nodesCoordinatorRegistryFactory.EpochConfirmed(epoch, 0) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go index 0ba32543aee..f5305806e68 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go @@ -101,6 +101,7 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing. t.Parallel() args := createArguments() + args.NodesCoordinatorRegistryFactory.EpochConfirmed(stakingV4Epoch, 0) nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) nodesCoordinator.updateEpochFlags(stakingV4Epoch) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 2b1ecfe94da..d0c8c6e4abc 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -1351,7 +1351,7 @@ func TestIndexHashedNodesCoordinator_computeShardForSelfPublicKeyWithStakingV4(t require.Equal(t, nc.shardIDAsObserver, computedShardId) require.False(t, isValidator) - nc.flagStakingV4.SetReturningPrevious() + nc.flagStakingV4.SetValue(true) computedShardId, isValidator = nc.computeShardForSelfPublicKey(nc.nodesConfig[epoch]) require.Equal(t, metaShard, computedShardId) @@ -2107,7 +2107,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * require.Equal(t, ErrReceivedAuctionValidatorsBeforeStakingV4, err) require.Nil(t, newNodesConfig) - nc.flagStakingV4.SetReturningPrevious() + nc.flagStakingV4.SetValue(true) newNodesConfig, err = nc.computeNodesConfigFromList(previousConfig, validatorInfos) require.Nil(t, err) From ae762285d4b572428d385512f8e3683cee9543c5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 24 Mar 2022 11:06:59 +0200 Subject: [PATCH 156/958] FIX: Small fixes --- process/peer/process_test.go | 6 +++--- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 612f03e5c02..7a348a69e67 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2620,10 +2620,10 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t require.Equal(t, string(common.AuctionList), peerAccount.GetList()) require.Equal(t, core.MetachainShardId, peerAccount.GetShardId()) return nil + default: + require.Fail(t, "should not have called this for other account") + return nil } - - require.Fail(t, "should not have called this for other account") - return nil } arguments.NodesCoordinator = &shardingMocks.NodesCoordinatorMock{ diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 292035cdb95..eb4d84597ba 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -497,7 +497,7 @@ func (ihnc *indexHashedNodesCoordinator) GetAllLeavingValidatorsPublicKeys(epoch return validatorsPubKeys, nil } -// GetAllShuffledOutValidatorsPublicKeys - +// GetAllShuffledOutValidatorsPublicKeys will return all shuffled out validator public keys from all shards func (ihnc *indexHashedNodesCoordinator) GetAllShuffledOutValidatorsPublicKeys(epoch uint32) (map[uint32][][]byte, error) { validatorsPubKeys := make(map[uint32][][]byte) From 213a6b78705d0724c074664afba3d9a5071933dd Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 24 Mar 2022 11:20:18 +0200 Subject: [PATCH 157/958] FIX: Delete unused stub --- consensus/mock/peerProcessorStub.go | 37 ----------------------------- 1 file changed, 37 deletions(-) delete mode 100644 consensus/mock/peerProcessorStub.go diff --git a/consensus/mock/peerProcessorStub.go b/consensus/mock/peerProcessorStub.go deleted file mode 100644 index 0d43486dc83..00000000000 --- a/consensus/mock/peerProcessorStub.go +++ /dev/null @@ -1,37 +0,0 @@ -package mock - -import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go/sharding" -) - -// ValidatorStatisticsProcessorStub - -type ValidatorStatisticsProcessorStub struct { - LoadInitialStateCalled func(in []*sharding.InitialNode) error - UpdatePeerStateCalled func(header, previousHeader data.HeaderHandler) error - IsInterfaceNilCalled func() bool -} - -// LoadInitialState - -func (pm *ValidatorStatisticsProcessorStub) LoadInitialState(in []*sharding.InitialNode) error { - if pm.LoadInitialStateCalled != nil { - return pm.LoadInitialStateCalled(in) - } - return nil -} - -// UpdatePeerState - -func (pm *ValidatorStatisticsProcessorStub) UpdatePeerState(header, previousHeader data.HeaderHandler) error { - if pm.UpdatePeerStateCalled != nil { - return pm.UpdatePeerStateCalled(header, previousHeader) - } - return nil -} - -// IsInterfaceNil - -func (pm *ValidatorStatisticsProcessorStub) IsInterfaceNil() bool { - if pm.IsInterfaceNilCalled != nil { - return pm.IsInterfaceNilCalled() - } - return false -} From 6092f80b1f67cbd31fd4ae9df05de3938b167e9a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 24 Mar 2022 12:13:18 +0200 Subject: [PATCH 158/958] FIX: Review findings --- .../consensusComponents/consensusComponents_test.go | 9 +-------- .../factory/processComponents/processComponents_test.go | 9 +-------- .../factory/statusComponents/statusComponents_test.go | 9 +-------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/integrationTests/factory/consensusComponents/consensusComponents_test.go b/integrationTests/factory/consensusComponents/consensusComponents_test.go index 0cbaa9355df..01744b81ea7 100644 --- a/integrationTests/factory/consensusComponents/consensusComponents_test.go +++ b/integrationTests/factory/consensusComponents/consensusComponents_test.go @@ -11,7 +11,6 @@ import ( mainFactory "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests/factory" "github.com/ElrondNetwork/elrond-go/node" - nodesCoord "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/testscommon/goroutines" "github.com/stretchr/testify/require" ) @@ -49,12 +48,6 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { require.Nil(t, err) nodesShufflerOut, err := mainFactory.CreateNodesShuffleOut(managedCoreComponents.GenesisNodesSetup(), configs.GeneralConfig.EpochStartConfig, managedCoreComponents.ChanStopNodeProcess()) require.Nil(t, err) - nodesCoordinatorRegistryFactory, err := nodesCoord.NewNodesCoordinatorRegistryFactory( - managedCoreComponents.InternalMarshalizer(), - managedCoreComponents.EpochNotifier(), - 444, - ) - require.Nil(t, err) nodesCoordinator, err := mainFactory.CreateNodesCoordinator( nodesShufflerOut, managedCoreComponents.GenesisNodesSetup(), @@ -72,7 +65,7 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), - nodesCoordinatorRegistryFactory, + managedBootstrapComponents.NodesCoordinatorRegistryFactory(), ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/processComponents/processComponents_test.go b/integrationTests/factory/processComponents/processComponents_test.go index a79b790adf9..72188b0f106 100644 --- a/integrationTests/factory/processComponents/processComponents_test.go +++ b/integrationTests/factory/processComponents/processComponents_test.go @@ -11,7 +11,6 @@ import ( mainFactory "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests/factory" "github.com/ElrondNetwork/elrond-go/node" - nodesCoord "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/testscommon/goroutines" "github.com/stretchr/testify/require" ) @@ -50,12 +49,6 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { require.Nil(t, err) nodesShufflerOut, err := mainFactory.CreateNodesShuffleOut(managedCoreComponents.GenesisNodesSetup(), configs.GeneralConfig.EpochStartConfig, managedCoreComponents.ChanStopNodeProcess()) require.Nil(t, err) - nodesCoordinatorRegistryFactory, err := nodesCoord.NewNodesCoordinatorRegistryFactory( - managedCoreComponents.InternalMarshalizer(), - managedCoreComponents.EpochNotifier(), - 444, - ) - require.Nil(t, err) nodesCoordinator, err := mainFactory.CreateNodesCoordinator( nodesShufflerOut, managedCoreComponents.GenesisNodesSetup(), @@ -73,7 +66,7 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), - nodesCoordinatorRegistryFactory, + managedBootstrapComponents.NodesCoordinatorRegistryFactory(), ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/statusComponents/statusComponents_test.go b/integrationTests/factory/statusComponents/statusComponents_test.go index bd513856728..71428179214 100644 --- a/integrationTests/factory/statusComponents/statusComponents_test.go +++ b/integrationTests/factory/statusComponents/statusComponents_test.go @@ -11,7 +11,6 @@ import ( mainFactory "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests/factory" "github.com/ElrondNetwork/elrond-go/node" - nodesCoord "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/testscommon/goroutines" "github.com/stretchr/testify/require" ) @@ -50,12 +49,6 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { require.Nil(t, err) nodesShufflerOut, err := mainFactory.CreateNodesShuffleOut(managedCoreComponents.GenesisNodesSetup(), configs.GeneralConfig.EpochStartConfig, managedCoreComponents.ChanStopNodeProcess()) require.Nil(t, err) - nodesCoordinatorRegistryFactory, err := nodesCoord.NewNodesCoordinatorRegistryFactory( - managedCoreComponents.InternalMarshalizer(), - managedCoreComponents.EpochNotifier(), - 444, - ) - require.Nil(t, err) nodesCoordinator, err := mainFactory.CreateNodesCoordinator( nodesShufflerOut, managedCoreComponents.GenesisNodesSetup(), @@ -73,7 +66,7 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { configs.EpochConfig.EnableEpochs.WaitingListFixEnableEpoch, managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), - nodesCoordinatorRegistryFactory, + managedBootstrapComponents.NodesCoordinatorRegistryFactory(), ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( From 513386028b47e67ceeb0d1b48174e784c2c3ed08 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 30 Mar 2022 15:09:17 +0300 Subject: [PATCH 159/958] FEAT: Add file placeholder --- integrationTests/vm/staking/stakingV4_test.go | 15 + .../vm/staking/testMetaProcessor.go | 735 ++++++++++++++++++ 2 files changed, 750 insertions(+) create mode 100644 integrationTests/vm/staking/stakingV4_test.go create mode 100644 integrationTests/vm/staking/testMetaProcessor.go diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go new file mode 100644 index 00000000000..aefab2af896 --- /dev/null +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -0,0 +1,15 @@ +package staking + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewTestMetaProcessor(t *testing.T) { + node := NewTestMetaProcessor(1, 1, 1, 1, 1) + header, err := node.MetaBlockProcessor.CreateNewHeader(0, 0) + require.Nil(t, err) + fmt.Println(header) +} diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go new file mode 100644 index 00000000000..62028e8ecff --- /dev/null +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -0,0 +1,735 @@ +package staking + +import ( + "bytes" + "fmt" + "math/big" + "reflect" + "strconv" + "time" + + arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/nodetype" + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/data/endProcess" + "github.com/ElrondNetwork/elrond-go-core/data/rewardTx" + "github.com/ElrondNetwork/elrond-go-core/data/transaction" + "github.com/ElrondNetwork/elrond-go-core/hashing" + "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" + "github.com/ElrondNetwork/elrond-go/epochStart/metachain" + mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" + "github.com/ElrondNetwork/elrond-go/epochStart/notifier" + "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" + "github.com/ElrondNetwork/elrond-go/integrationTests" + mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + "github.com/ElrondNetwork/elrond-go/process" + blproc "github.com/ElrondNetwork/elrond-go/process/block" + "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" + economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" + vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" + metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" + "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/process/peer" + "github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions" + "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/state/factory" + "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" + "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" + "github.com/ElrondNetwork/elrond-go/storage" + "github.com/ElrondNetwork/elrond-go/storage/lrucache" + "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" + dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" + "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" + "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" + statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" + "github.com/ElrondNetwork/elrond-go/trie" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" +) + +// TestMetaProcessor - +type TestMetaProcessor struct { + MetaBlockProcessor process.BlockProcessor + SystemSCProcessor process.EpochStartSystemSCProcessor +} + +// NewTestMetaProcessor - +func NewTestMetaProcessor( + numOfMetaNodes int, + numOfShards int, + numOfNodesPerShard int, + shardConsensusGroupSize int, + metaConsensusGroupSize int, +) *TestMetaProcessor { + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize) + scp := createSystemSCProcessor() + return &TestMetaProcessor{ + MetaBlockProcessor: createMetaBlockProcessor(nc, scp), + } +} + +// shuffler constants +const ( + shuffleBetweenShards = false + adaptivity = false + hysteresis = float32(0.2) + maxTrieLevelInMemory = uint(5) + delegationManagementKey = "delegationManagement" + delegationContractsList = "delegationContracts" +) + +func createSystemSCProcessor() process.EpochStartSystemSCProcessor { + args, _ := createFullArgumentsForSystemSCProcessing(1000, integrationTests.CreateMemUnit()) + s, _ := metachain.NewSystemSCProcessor(args) + return s +} + +func createNodesCoordinator( + numOfMetaNodes int, + numOfShards int, + numOfNodesPerShard int, + shardConsensusGroupSize int, + metaConsensusGroupSize int, +) nodesCoordinator.NodesCoordinator { + //coordinatorFactory := &integrationTests.IndexHashedNodesCoordinatorWithRaterFactory{ + // PeerAccountListAndRatingHandler: testscommon.GetNewMockRater(), + //} + + validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) + validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) + + waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) + waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) + + //nodesSetup := &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + // return validatorsMap, waitingMap + //}} + + shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ + NodesShard: uint32(numOfNodesPerShard), + NodesMeta: uint32(numOfMetaNodes), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + WaitingListFixEnableEpoch: 0, + BalanceWaitingListsEnableEpoch: 0, + } + nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) + epochStartSubscriber := notifier.NewEpochStartSubscriptionHandler() + bootStorer := integrationTests.CreateMemUnit() + + cache, _ := lrucache.NewCache(10000) + ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(integrationTests.TestMarshalizer, forking.NewGenericEpochNotifier(), 4444) + argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: integrationTests.TestMarshalizer, + Hasher: integrationTests.TestHasher, + ShardIDAsObserver: core.MetachainShardId, + NbShards: uint32(numOfShards), + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: waitingMapForNodesCoordinator, + SelfPublicKey: validatorsMap[core.MetachainShardId][0].PubKeyBytes(), + ConsensusGroupCache: cache, + ShuffledOutHandler: &mock2.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + IsFullArchive: false, + Shuffler: nodeShuffler, + BootStorer: bootStorer, + EpochStartNotifier: epochStartSubscriber, + StakingV4EnableEpoch: 444, + NodesCoordinatorRegistryFactory: ncrf, + NodeTypeProvider: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), + } + + nodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) + if err != nil { + fmt.Println("error creating node coordinator") + } + + return nodesCoordinator +} + +func generateGenesisNodeInfoMap( + numOfMetaNodes int, + numOfShards int, + numOfNodesPerShard int, +) map[uint32][]nodesCoordinator.GenesisNodeInfoHandler { + validatorsMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) + for shardId := 0; shardId < numOfShards; shardId++ { + for n := 0; n < numOfNodesPerShard; n++ { + addr := []byte("addr" + strconv.Itoa(n) + "-shard" + strconv.Itoa(shardId)) + validator := mock2.NewNodeInfo(addr, addr, uint32(shardId), 5) + validatorsMap[uint32(shardId)] = append(validatorsMap[uint32(shardId)], validator) + } + } + + for n := 0; n < numOfMetaNodes; n++ { + addr := []byte("addr" + strconv.Itoa(n) + "-shard" + strconv.Itoa(int(core.MetachainShardId))) + validator := mock2.NewNodeInfo(addr, addr, uint32(core.MetachainShardId), 5) + validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) + } + + return validatorsMap +} + +func createMetaBlockProcessor(nc nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor) process.BlockProcessor { + coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor) + + metaProc, _ := blproc.NewMetaProcessor(arguments) + return metaProc +} + +func createMockComponentHolders() ( + *mock.CoreComponentsMock, + *mock.DataComponentsMock, + *mock.BootstrapComponentsMock, + *mock.StatusComponentsMock, +) { + mdp := initDataPool([]byte("tx_hash")) + + coreComponents := &mock.CoreComponentsMock{ + IntMarsh: &mock.MarshalizerMock{}, + Hash: &mock.HasherStub{}, + UInt64ByteSliceConv: &mock.Uint64ByteSliceConverterMock{}, + StatusField: &statusHandlerMock.AppStatusHandlerStub{}, + RoundField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, + } + + dataComponents := &mock.DataComponentsMock{ + Storage: &mock.ChainStorerMock{}, + DataPool: mdp, + BlockChain: createTestBlockchain(), + } + boostrapComponents := &mock.BootstrapComponentsMock{ + Coordinator: mock.NewOneShardCoordinatorMock(), + HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, + VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{ + CreateCalled: func(epoch uint32) data.HeaderHandler { + return &block.MetaBlock{} + }, + }, + } + + statusComponents := &mock.StatusComponentsMock{ + Outport: &testscommon.OutportStub{}, + } + + return coreComponents, dataComponents, boostrapComponents, statusComponents +} + +func initDataPool(testHash []byte) *dataRetrieverMock.PoolsHolderStub { + rwdTx := &rewardTx.RewardTx{ + Round: 1, + Epoch: 0, + Value: big.NewInt(10), + RcvAddr: []byte("receiver"), + } + txCalled := createShardedDataChacherNotifier(&transaction.Transaction{Nonce: 10}, testHash) + unsignedTxCalled := createShardedDataChacherNotifier(&transaction.Transaction{Nonce: 10}, testHash) + rewardTransactionsCalled := createShardedDataChacherNotifier(rwdTx, testHash) + + sdp := &dataRetrieverMock.PoolsHolderStub{ + TransactionsCalled: txCalled, + UnsignedTransactionsCalled: unsignedTxCalled, + RewardTransactionsCalled: rewardTransactionsCalled, + MetaBlocksCalled: func() storage.Cacher { + return &testscommon.CacherStub{ + GetCalled: func(key []byte) (value interface{}, ok bool) { + if reflect.DeepEqual(key, []byte("tx1_hash")) { + return &transaction.Transaction{Nonce: 10}, true + } + return nil, false + }, + KeysCalled: func() [][]byte { + return nil + }, + LenCalled: func() int { + return 0 + }, + MaxSizeCalled: func() int { + return 1000 + }, + PeekCalled: func(key []byte) (value interface{}, ok bool) { + if reflect.DeepEqual(key, []byte("tx1_hash")) { + return &transaction.Transaction{Nonce: 10}, true + } + return nil, false + }, + RegisterHandlerCalled: func(i func(key []byte, value interface{})) {}, + RemoveCalled: func(key []byte) {}, + } + }, + MiniBlocksCalled: func() storage.Cacher { + cs := testscommon.NewCacherStub() + cs.RegisterHandlerCalled = func(i func(key []byte, value interface{})) { + } + cs.GetCalled = func(key []byte) (value interface{}, ok bool) { + if bytes.Equal([]byte("bbb"), key) { + return make(block.MiniBlockSlice, 0), true + } + + return nil, false + } + cs.PeekCalled = func(key []byte) (value interface{}, ok bool) { + if bytes.Equal([]byte("bbb"), key) { + return make(block.MiniBlockSlice, 0), true + } + + return nil, false + } + cs.RegisterHandlerCalled = func(i func(key []byte, value interface{})) {} + cs.RemoveCalled = func(key []byte) {} + cs.LenCalled = func() int { + return 0 + } + cs.MaxSizeCalled = func() int { + return 300 + } + cs.KeysCalled = func() [][]byte { + return nil + } + return cs + }, + HeadersCalled: func() dataRetriever.HeadersPool { + cs := &mock.HeadersCacherStub{} + cs.RegisterHandlerCalled = func(i func(header data.HeaderHandler, key []byte)) { + } + cs.GetHeaderByHashCalled = func(hash []byte) (data.HeaderHandler, error) { + return nil, process.ErrMissingHeader + } + cs.RemoveHeaderByHashCalled = func(key []byte) { + } + cs.LenCalled = func() int { + return 0 + } + cs.MaxSizeCalled = func() int { + return 1000 + } + cs.NoncesCalled = func(shardId uint32) []uint64 { + return nil + } + return cs + }, + } + + return sdp +} + +func createShardedDataChacherNotifier( + handler data.TransactionHandler, + testHash []byte, +) func() dataRetriever.ShardedDataCacherNotifier { + return func() dataRetriever.ShardedDataCacherNotifier { + return &testscommon.ShardedDataStub{ + ShardDataStoreCalled: func(id string) (c storage.Cacher) { + return &testscommon.CacherStub{ + PeekCalled: func(key []byte) (value interface{}, ok bool) { + if reflect.DeepEqual(key, testHash) { + return handler, true + } + return nil, false + }, + KeysCalled: func() [][]byte { + return [][]byte{[]byte("key1"), []byte("key2")} + }, + LenCalled: func() int { + return 0 + }, + MaxSizeCalled: func() int { + return 1000 + }, + } + }, + RemoveSetOfDataFromPoolCalled: func(keys [][]byte, id string) {}, + SearchFirstDataCalled: func(key []byte) (value interface{}, ok bool) { + if reflect.DeepEqual(key, []byte("tx1_hash")) { + return handler, true + } + return nil, false + }, + AddDataCalled: func(key []byte, data interface{}, sizeInBytes int, cacheId string) { + }, + } + } +} + +func createTestBlockchain() *testscommon.ChainHandlerStub { + return &testscommon.ChainHandlerStub{ + GetGenesisHeaderCalled: func() data.HeaderHandler { + return &block.Header{Nonce: 0} + }, + } +} + +func createMockMetaArguments( + coreComponents *mock.CoreComponentsMock, + dataComponents *mock.DataComponentsMock, + bootstrapComponents *mock.BootstrapComponentsMock, + statusComponents *mock.StatusComponentsMock, + nodesCoord nodesCoordinator.NodesCoordinator, + systemSCProcessor process.EpochStartSystemSCProcessor, +) blproc.ArgMetaProcessor { + + argsHeaderValidator := blproc.ArgsHeaderValidator{ + Hasher: &mock.HasherStub{}, + Marshalizer: &mock.MarshalizerMock{}, + } + headerValidator, _ := blproc.NewHeaderValidator(argsHeaderValidator) + + startHeaders := createGenesisBlocks(bootstrapComponents.ShardCoordinator()) + accountsDb := make(map[state.AccountsDbIdentifier]state.AccountsAdapter) + accountsDb[state.UserAccountsState] = &stateMock.AccountsStub{ + CommitCalled: func() ([]byte, error) { + return nil, nil + }, + RootHashCalled: func() ([]byte, error) { + return nil, nil + }, + } + accountsDb[state.PeerAccountsState] = &stateMock.AccountsStub{ + CommitCalled: func() ([]byte, error) { + return nil, nil + }, + RootHashCalled: func() ([]byte, error) { + return nil, nil + }, + } + + arguments := blproc.ArgMetaProcessor{ + ArgBaseProcessor: blproc.ArgBaseProcessor{ + CoreComponents: coreComponents, + DataComponents: dataComponents, + BootstrapComponents: bootstrapComponents, + StatusComponents: statusComponents, + AccountsDB: accountsDb, + ForkDetector: &mock.ForkDetectorMock{}, + NodesCoordinator: nodesCoord, + FeeHandler: &mock.FeeAccumulatorStub{}, + RequestHandler: &testscommon.RequestHandlerStub{}, + BlockChainHook: &testscommon.BlockChainHookStub{}, + TxCoordinator: &mock.TransactionCoordinatorMock{}, + EpochStartTrigger: &mock.EpochStartTriggerStub{}, + HeaderValidator: headerValidator, + GasHandler: &mock.GasHandlerMock{}, + BootStorer: &mock.BoostrapStorerMock{ + PutCalled: func(round int64, bootData bootstrapStorage.BootstrapData) error { + return nil + }, + }, + BlockTracker: mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders), + BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, + HistoryRepository: &dblookupext.HistoryRepositoryStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + RoundNotifier: &mock.RoundNotifierStub{}, + ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, + ScheduledMiniBlocksEnableEpoch: 2, + }, + SCToProtocol: &mock.SCToProtocolStub{}, + PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, + EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, + EpochEconomics: &mock.EpochEconomicsStub{}, + EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, + EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, + ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, + EpochSystemSCProcessor: systemSCProcessor, + } + return arguments +} + +func createGenesisBlocks(shardCoordinator sharding.Coordinator) map[uint32]data.HeaderHandler { + genesisBlocks := make(map[uint32]data.HeaderHandler) + for ShardID := uint32(0); ShardID < shardCoordinator.NumberOfShards(); ShardID++ { + genesisBlocks[ShardID] = createGenesisBlock(ShardID) + } + + genesisBlocks[core.MetachainShardId] = createGenesisMetaBlock() + + return genesisBlocks +} + +func createGenesisBlock(ShardID uint32) *block.Header { + rootHash := []byte("roothash") + return &block.Header{ + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + ShardID: ShardID, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + } +} + +func createGenesisMetaBlock() *block.MetaBlock { + rootHash := []byte("roothash") + return &block.MetaBlock{ + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + } +} + +func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieStorer storage.Storer) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer) { + hasher := sha256.NewSha256() + marshalizer := &marshal.GogoProtoMarshalizer{} + trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(trieStorer) + userAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewAccountCreator(), trieFactoryManager) + peerAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewPeerAccountCreator(), trieFactoryManager) + en := forking.NewGenericEpochNotifier() + + argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ + Marshalizer: marshalizer, + NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + ShardCoordinator: &mock.ShardCoordinatorStub{}, + DataPool: &dataRetrieverMock.PoolsHolderStub{}, + StorageService: &mock3.ChainStorerStub{}, + PubkeyConv: &mock.PubkeyConverterMock{}, + PeerAdapter: peerAccountsDB, + Rater: &mock3.RaterStub{}, + RewardsHandler: &mock3.RewardsHandlerStub{}, + NodesSetup: &mock.NodesSetupStub{}, + MaxComputableRounds: 1, + MaxConsecutiveRoundsOfRatingDecrease: 2000, + EpochNotifier: en, + StakingV2EnableEpoch: stakingV2EnableEpoch, + StakingV4EnableEpoch: 444, + } + vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) + + blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) + gasSchedule := arwenConfig.MakeGasMapForTests() + gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) + argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ + GasSchedule: gasScheduleNotifier, + MapDNSAddresses: make(map[string]struct{}), + Marshalizer: marshalizer, + Accounts: userAccountsDB, + ShardCoordinator: &mock.ShardCoordinatorStub{SelfIdCalled: func() uint32 { + return core.MetachainShardId + }}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + } + builtInFuncs, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) + + testDataPool := dataRetrieverMock.NewPoolsHolderMock() + argsHook := hooks.ArgBlockChainHook{ + Accounts: userAccountsDB, + PubkeyConv: &mock.PubkeyConverterMock{}, + StorageService: &mock3.ChainStorerStub{}, + BlockChain: blockChain, + ShardCoordinator: &mock.ShardCoordinatorStub{}, + Marshalizer: marshalizer, + Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, + NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, + BuiltInFunctions: builtInFuncs, + DataPool: testDataPool, + CompiledSCPool: testDataPool.SmartContracts(), + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + NilCompiledSCStore: true, + } + + defaults.FillGasMapInternal(gasSchedule, 1) + signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) + + nodesSetup := &mock.NodesSetupStub{} + + blockChainHookImpl, _ := hooks.NewBlockChainHookImpl(argsHook) + argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ + BlockChainHook: blockChainHookImpl, + PubkeyConv: argsHook.PubkeyConv, + Economics: createEconomicsData(), + MessageSignVerifier: signVerifer, + GasSchedule: gasScheduleNotifier, + NodesConfigProvider: nodesSetup, + Hasher: hasher, + Marshalizer: marshalizer, + SystemSCConfig: &config.SystemSmartContractsConfig{ + ESDTSystemSCConfig: config.ESDTSystemSCConfig{ + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", + }, + GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ + Active: config.GovernanceSystemSCConfigActive{ + ProposalCost: "500", + MinQuorum: "50", + MinPassThreshold: "50", + MinVetoThreshold: "50", + }, + FirstWhitelistedAddress: "3132333435363738393031323334353637383930313233343536373839303234", + }, + StakingSystemSCConfig: config.StakingSystemSCConfig{ + GenesisNodePrice: "1000", + UnJailValue: "10", + MinStepValue: "10", + MinStakeValue: "1", + UnBondPeriod: 1, + NumRoundsWithoutBleed: 1, + MaximumPercentageToBleed: 1, + BleedPercentagePerRound: 1, + MaxNumberOfNodesForStake: 5, + ActivateBLSPubKeyMessageVerification: false, + MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, + }, + DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ + MinCreationDeposit: "100", + MinStakeAmount: "100", + ConfigChangeAddress: "3132333435363738393031323334353637383930313233343536373839303234", + }, + DelegationSystemSCConfig: config.DelegationSystemSCConfig{ + MinServiceFee: 0, + MaxServiceFee: 100, + }, + }, + ValidatorAccountsDB: peerAccountsDB, + ChanceComputer: &mock3.ChanceComputerStub{}, + EpochNotifier: en, + EpochConfig: &config.EpochConfig{ + EnableEpochs: config.EnableEpochs{ + StakingV2EnableEpoch: stakingV2EnableEpoch, + StakeEnableEpoch: 0, + DelegationManagerEnableEpoch: 0, + DelegationSmartContractEnableEpoch: 0, + StakeLimitsEnableEpoch: 10, + StakingV4InitEnableEpoch: 444, + StakingV4EnableEpoch: 445, + }, + }, + ShardCoordinator: &mock.ShardCoordinatorStub{}, + NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + } + metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) + + vmContainer, _ := metaVmFactory.Create() + systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) + + stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") + shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + + args := metachain.ArgsNewEpochStartSystemSCProcessing{ + SystemVM: systemVM, + UserAccountsDB: userAccountsDB, + PeerAccountsDB: peerAccountsDB, + Marshalizer: marshalizer, + StartRating: 5, + ValidatorInfoCreator: vCreator, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ChanceComputer: &mock3.ChanceComputerStub{}, + EpochNotifier: en, + GenesisNodesConfig: nodesSetup, + StakingDataProvider: stakingSCprovider, + NodesConfigProvider: &shardingMocks.NodesCoordinatorStub{ + ConsensusGroupSizeCalled: func(shardID uint32) int { + if shardID == core.MetachainShardId { + return 400 + } + return 63 + }, + }, + ShardCoordinator: shardCoordinator, + ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), + EpochConfig: config.EpochConfig{ + EnableEpochs: config.EnableEpochs{ + StakingV2EnableEpoch: 1000000, + ESDTEnableEpoch: 1000000, + StakingV4InitEnableEpoch: 444, + StakingV4EnableEpoch: 445, + }, + }, + } + return args, metaVmFactory.SystemSmartContractContainer() +} + +func createAccountsDB( + hasher hashing.Hasher, + marshalizer marshal.Marshalizer, + accountFactory state.AccountFactory, + trieStorageManager common.StorageManager, +) *state.AccountsDB { + tr, _ := trie.NewTrie(trieStorageManager, marshalizer, hasher, 5) + ewl, _ := evictionWaitingList.NewEvictionWaitingList(10, testscommon.NewMemDbMock(), marshalizer) + spm, _ := storagePruningManager.NewStoragePruningManager(ewl, 10) + adb, _ := state.NewAccountsDB(tr, hasher, marshalizer, accountFactory, spm, common.Normal) + return adb +} + +func createEconomicsData() process.EconomicsDataHandler { + maxGasLimitPerBlock := strconv.FormatUint(1500000000, 10) + minGasPrice := strconv.FormatUint(10, 10) + minGasLimit := strconv.FormatUint(10, 10) + + argsNewEconomicsData := economicsHandler.ArgsNewEconomicsData{ + Economics: &config.EconomicsConfig{ + GlobalSettings: config.GlobalSettings{ + GenesisTotalSupply: "2000000000000000000000", + MinimumInflation: 0, + YearSettings: []*config.YearSetting{ + { + Year: 0, + MaximumInflation: 0.01, + }, + }, + }, + RewardsSettings: config.RewardsSettings{ + RewardsConfigByEpoch: []config.EpochRewardSettings{ + { + LeaderPercentage: 0.1, + DeveloperPercentage: 0.1, + ProtocolSustainabilityPercentage: 0.1, + ProtocolSustainabilityAddress: "protocol", + TopUpGradientPoint: "300000000000000000000", + TopUpFactor: 0.25, + }, + }, + }, + FeeSettings: config.FeeSettings{ + GasLimitSettings: []config.GasLimitSetting{ + { + MaxGasLimitPerBlock: maxGasLimitPerBlock, + MaxGasLimitPerMiniBlock: maxGasLimitPerBlock, + MaxGasLimitPerMetaBlock: maxGasLimitPerBlock, + MaxGasLimitPerMetaMiniBlock: maxGasLimitPerBlock, + MaxGasLimitPerTx: maxGasLimitPerBlock, + MinGasLimit: minGasLimit, + }, + }, + MinGasPrice: minGasPrice, + GasPerDataByte: "1", + GasPriceModifier: 1.0, + }, + }, + PenalizedTooMuchGasEnableEpoch: 0, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, + } + economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) + return economicsData +} From 8ebc25f07cd9a81a6ffed5e1cdc585b5c1b91afc Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 31 Mar 2022 12:06:50 +0300 Subject: [PATCH 160/958] FEAT: Add intermediary code --- .../vm/staking/testMetaProcessor.go | 200 +++--------------- 1 file changed, 27 insertions(+), 173 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 62028e8ecff..bd3f014a2e3 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -3,8 +3,6 @@ package staking import ( "bytes" "fmt" - "math/big" - "reflect" "strconv" "time" @@ -14,15 +12,12 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/endProcess" - "github.com/ElrondNetwork/elrond-go-core/data/rewardTx" - "github.com/ElrondNetwork/elrond-go-core/data/transaction" "github.com/ElrondNetwork/elrond-go-core/hashing" "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" @@ -65,6 +60,7 @@ import ( type TestMetaProcessor struct { MetaBlockProcessor process.BlockProcessor SystemSCProcessor process.EpochStartSystemSCProcessor + NodesCoordinator nodesCoordinator.NodesCoordinator } // NewTestMetaProcessor - @@ -75,10 +71,11 @@ func NewTestMetaProcessor( shardConsensusGroupSize int, metaConsensusGroupSize int, ) *TestMetaProcessor { + coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders(uint32(numOfShards)) nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize) - scp := createSystemSCProcessor() + scp := createSystemSCProcessor(nc) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp), + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents), } } @@ -92,8 +89,8 @@ const ( delegationContractsList = "delegationContracts" ) -func createSystemSCProcessor() process.EpochStartSystemSCProcessor { - args, _ := createFullArgumentsForSystemSCProcessing(1000, integrationTests.CreateMemUnit()) +func createSystemSCProcessor(nc nodesCoordinator.NodesCoordinator) process.EpochStartSystemSCProcessor { + args, _ := createFullArgumentsForSystemSCProcessing(nc, 1000, integrationTests.CreateMemUnit()) s, _ := metachain.NewSystemSCProcessor(args) return s } @@ -105,20 +102,12 @@ func createNodesCoordinator( shardConsensusGroupSize int, metaConsensusGroupSize int, ) nodesCoordinator.NodesCoordinator { - //coordinatorFactory := &integrationTests.IndexHashedNodesCoordinatorWithRaterFactory{ - // PeerAccountListAndRatingHandler: testscommon.GetNewMockRater(), - //} - validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) - //nodesSetup := &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { - // return validatorsMap, waitingMap - //}} - shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ NodesShard: uint32(numOfNodesPerShard), NodesMeta: uint32(numOfMetaNodes), @@ -189,22 +178,26 @@ func generateGenesisNodeInfoMap( return validatorsMap } -func createMetaBlockProcessor(nc nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor) process.BlockProcessor { - coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() +func createMetaBlockProcessor( + nc nodesCoordinator.NodesCoordinator, + systemSCProcessor process.EpochStartSystemSCProcessor, + coreComponents *mock.CoreComponentsMock, + dataComponents *mock.DataComponentsMock, + bootstrapComponents *mock.BootstrapComponentsMock, + statusComponents *mock.StatusComponentsMock, +) process.BlockProcessor { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor) metaProc, _ := blproc.NewMetaProcessor(arguments) return metaProc } -func createMockComponentHolders() ( +func createMockComponentHolders(numOfShards uint32) ( *mock.CoreComponentsMock, *mock.DataComponentsMock, *mock.BootstrapComponentsMock, *mock.StatusComponentsMock, ) { - mdp := initDataPool([]byte("tx_hash")) - coreComponents := &mock.CoreComponentsMock{ IntMarsh: &mock.MarshalizerMock{}, Hash: &mock.HasherStub{}, @@ -214,12 +207,17 @@ func createMockComponentHolders() ( } dataComponents := &mock.DataComponentsMock{ - Storage: &mock.ChainStorerMock{}, - DataPool: mdp, - BlockChain: createTestBlockchain(), + Storage: &mock.ChainStorerMock{}, + DataPool: dataRetrieverMock.NewPoolsHolderMock(), + BlockChain: &testscommon.ChainHandlerStub{ + GetGenesisHeaderCalled: func() data.HeaderHandler { + return &block.Header{Nonce: 0} + }, + }, } + shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) boostrapComponents := &mock.BootstrapComponentsMock{ - Coordinator: mock.NewOneShardCoordinatorMock(), + Coordinator: shardCoordinator, HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{ CreateCalled: func(epoch uint32) data.HeaderHandler { @@ -235,150 +233,6 @@ func createMockComponentHolders() ( return coreComponents, dataComponents, boostrapComponents, statusComponents } -func initDataPool(testHash []byte) *dataRetrieverMock.PoolsHolderStub { - rwdTx := &rewardTx.RewardTx{ - Round: 1, - Epoch: 0, - Value: big.NewInt(10), - RcvAddr: []byte("receiver"), - } - txCalled := createShardedDataChacherNotifier(&transaction.Transaction{Nonce: 10}, testHash) - unsignedTxCalled := createShardedDataChacherNotifier(&transaction.Transaction{Nonce: 10}, testHash) - rewardTransactionsCalled := createShardedDataChacherNotifier(rwdTx, testHash) - - sdp := &dataRetrieverMock.PoolsHolderStub{ - TransactionsCalled: txCalled, - UnsignedTransactionsCalled: unsignedTxCalled, - RewardTransactionsCalled: rewardTransactionsCalled, - MetaBlocksCalled: func() storage.Cacher { - return &testscommon.CacherStub{ - GetCalled: func(key []byte) (value interface{}, ok bool) { - if reflect.DeepEqual(key, []byte("tx1_hash")) { - return &transaction.Transaction{Nonce: 10}, true - } - return nil, false - }, - KeysCalled: func() [][]byte { - return nil - }, - LenCalled: func() int { - return 0 - }, - MaxSizeCalled: func() int { - return 1000 - }, - PeekCalled: func(key []byte) (value interface{}, ok bool) { - if reflect.DeepEqual(key, []byte("tx1_hash")) { - return &transaction.Transaction{Nonce: 10}, true - } - return nil, false - }, - RegisterHandlerCalled: func(i func(key []byte, value interface{})) {}, - RemoveCalled: func(key []byte) {}, - } - }, - MiniBlocksCalled: func() storage.Cacher { - cs := testscommon.NewCacherStub() - cs.RegisterHandlerCalled = func(i func(key []byte, value interface{})) { - } - cs.GetCalled = func(key []byte) (value interface{}, ok bool) { - if bytes.Equal([]byte("bbb"), key) { - return make(block.MiniBlockSlice, 0), true - } - - return nil, false - } - cs.PeekCalled = func(key []byte) (value interface{}, ok bool) { - if bytes.Equal([]byte("bbb"), key) { - return make(block.MiniBlockSlice, 0), true - } - - return nil, false - } - cs.RegisterHandlerCalled = func(i func(key []byte, value interface{})) {} - cs.RemoveCalled = func(key []byte) {} - cs.LenCalled = func() int { - return 0 - } - cs.MaxSizeCalled = func() int { - return 300 - } - cs.KeysCalled = func() [][]byte { - return nil - } - return cs - }, - HeadersCalled: func() dataRetriever.HeadersPool { - cs := &mock.HeadersCacherStub{} - cs.RegisterHandlerCalled = func(i func(header data.HeaderHandler, key []byte)) { - } - cs.GetHeaderByHashCalled = func(hash []byte) (data.HeaderHandler, error) { - return nil, process.ErrMissingHeader - } - cs.RemoveHeaderByHashCalled = func(key []byte) { - } - cs.LenCalled = func() int { - return 0 - } - cs.MaxSizeCalled = func() int { - return 1000 - } - cs.NoncesCalled = func(shardId uint32) []uint64 { - return nil - } - return cs - }, - } - - return sdp -} - -func createShardedDataChacherNotifier( - handler data.TransactionHandler, - testHash []byte, -) func() dataRetriever.ShardedDataCacherNotifier { - return func() dataRetriever.ShardedDataCacherNotifier { - return &testscommon.ShardedDataStub{ - ShardDataStoreCalled: func(id string) (c storage.Cacher) { - return &testscommon.CacherStub{ - PeekCalled: func(key []byte) (value interface{}, ok bool) { - if reflect.DeepEqual(key, testHash) { - return handler, true - } - return nil, false - }, - KeysCalled: func() [][]byte { - return [][]byte{[]byte("key1"), []byte("key2")} - }, - LenCalled: func() int { - return 0 - }, - MaxSizeCalled: func() int { - return 1000 - }, - } - }, - RemoveSetOfDataFromPoolCalled: func(keys [][]byte, id string) {}, - SearchFirstDataCalled: func(key []byte) (value interface{}, ok bool) { - if reflect.DeepEqual(key, []byte("tx1_hash")) { - return handler, true - } - return nil, false - }, - AddDataCalled: func(key []byte, data interface{}, sizeInBytes int, cacheId string) { - }, - } - } -} - -func createTestBlockchain() *testscommon.ChainHandlerStub { - return &testscommon.ChainHandlerStub{ - GetGenesisHeaderCalled: func() data.HeaderHandler { - return &block.Header{Nonce: 0} - }, - } -} - func createMockMetaArguments( coreComponents *mock.CoreComponentsMock, dataComponents *mock.DataComponentsMock, @@ -494,7 +348,7 @@ func createGenesisMetaBlock() *block.MetaBlock { } } -func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieStorer storage.Storer) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer) { +func createFullArgumentsForSystemSCProcessing(nc nodesCoordinator.NodesCoordinator, stakingV2EnableEpoch uint32, trieStorer storage.Storer) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer) { hasher := sha256.NewSha256() marshalizer := &marshal.GogoProtoMarshalizer{} trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(trieStorer) @@ -504,7 +358,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ Marshalizer: marshalizer, - NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + NodesCoordinator: nc, ShardCoordinator: &mock.ShardCoordinatorStub{}, DataPool: &dataRetrieverMock.PoolsHolderStub{}, StorageService: &mock3.ChainStorerStub{}, @@ -623,7 +477,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS }, }, ShardCoordinator: &mock.ShardCoordinatorStub{}, - NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + NodesCoordinator: nc, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) From 6cb12757e7471179b4e2091175a13a86be5fce8c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 31 Mar 2022 13:27:46 +0300 Subject: [PATCH 161/958] FEAT: Refactor --- integrationTests/vm/staking/stakingV4_test.go | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index aefab2af896..91df4418615 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1,15 +1,38 @@ package staking import ( - "fmt" + "math/big" "testing" - "github.com/stretchr/testify/require" + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/stretchr/testify/assert" ) func TestNewTestMetaProcessor(t *testing.T) { node := NewTestMetaProcessor(1, 1, 1, 1, 1) - header, err := node.MetaBlockProcessor.CreateNewHeader(0, 0) - require.Nil(t, err) - fmt.Println(header) + metaHdr := &block.MetaBlock{} + headerHandler, bodyHandler, err := node.MetaBlockProcessor.CreateBlock(metaHdr, func() bool { return true }) + assert.Nil(t, err) + + err = headerHandler.SetRound(uint64(1)) + assert.Nil(t, err) + + err = headerHandler.SetNonce(1) + assert.Nil(t, err) + + err = headerHandler.SetPrevHash([]byte("hash")) + assert.Nil(t, err) + + err = headerHandler.SetAccumulatedFees(big.NewInt(0)) + assert.Nil(t, err) + + _ = bodyHandler + /* + metaHeaderHandler, _ := headerHandler.(data.MetaHeaderHandler) + err = metaHeaderHandler.SetAccumulatedFeesInEpoch(big.NewInt(0)) + assert.Nil(t, err) + + err = node.MetaBlockProcessor.ProcessBlock(headerHandler, bodyHandler, func() time.Duration { return time.Second }) + assert.Nil(t, err) + */ } From 4ebd97ece740fe9e494a256fc6478dbd366853fd Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 31 Mar 2022 16:11:59 +0300 Subject: [PATCH 162/958] FEAT: Refactor 2 --- .../vm/staking/testMetaProcessor.go | 218 ++++++++++-------- 1 file changed, 120 insertions(+), 98 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index bd3f014a2e3..f4b71ac714d 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -18,13 +18,16 @@ import ( "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" + factory2 "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/integrationTests" mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + factory3 "github.com/ElrondNetwork/elrond-go/node/mock/factory" "github.com/ElrondNetwork/elrond-go/process" blproc "github.com/ElrondNetwork/elrond-go/process/block" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" @@ -41,14 +44,13 @@ import ( "github.com/ElrondNetwork/elrond-go/state/factory" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" - "github.com/ElrondNetwork/elrond-go/storage" "github.com/ElrondNetwork/elrond-go/storage/lrucache" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" - "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" @@ -71,9 +73,9 @@ func NewTestMetaProcessor( shardConsensusGroupSize int, metaConsensusGroupSize int, ) *TestMetaProcessor { - coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders(uint32(numOfShards)) - nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize) - scp := createSystemSCProcessor(nc) + coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createMockComponentHolders(uint32(numOfShards)) + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents) + scp := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) return &TestMetaProcessor{ MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents), } @@ -89,18 +91,34 @@ const ( delegationContractsList = "delegationContracts" ) -func createSystemSCProcessor(nc nodesCoordinator.NodesCoordinator) process.EpochStartSystemSCProcessor { - args, _ := createFullArgumentsForSystemSCProcessing(nc, 1000, integrationTests.CreateMemUnit()) +// TODO: Pass epoch config + +func createSystemSCProcessor( + nc nodesCoordinator.NodesCoordinator, + coreComponents factory2.CoreComponentsHolder, + stateComponents factory2.StateComponentsHandler, + bootstrapComponents factory2.BootstrapComponentsHolder, + dataComponents factory2.DataComponentsHolder, +) process.EpochStartSystemSCProcessor { + args, _ := createFullArgumentsForSystemSCProcessing(nc, + 1000, + coreComponents, + stateComponents, + bootstrapComponents, + dataComponents, + ) s, _ := metachain.NewSystemSCProcessor(args) return s } +// TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator func createNodesCoordinator( numOfMetaNodes int, numOfShards int, numOfNodesPerShard int, shardConsensusGroupSize int, metaConsensusGroupSize int, + coreComponents factory2.CoreComponentsHolder, ) nodesCoordinator.NodesCoordinator { validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) @@ -119,7 +137,6 @@ func createNodesCoordinator( BalanceWaitingListsEnableEpoch: 0, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) - epochStartSubscriber := notifier.NewEpochStartSubscriptionHandler() bootStorer := integrationTests.CreateMemUnit() cache, _ := lrucache.NewCache(10000) @@ -127,8 +144,8 @@ func createNodesCoordinator( argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: integrationTests.TestMarshalizer, - Hasher: integrationTests.TestHasher, + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), ShardIDAsObserver: core.MetachainShardId, NbShards: uint32(numOfShards), EligibleNodes: validatorsMapForNodesCoordinator, @@ -141,18 +158,23 @@ func createNodesCoordinator( IsFullArchive: false, Shuffler: nodeShuffler, BootStorer: bootStorer, - EpochStartNotifier: epochStartSubscriber, + EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), StakingV4EnableEpoch: 444, NodesCoordinatorRegistryFactory: ncrf, NodeTypeProvider: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), } - nodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) + baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) + if err != nil { + fmt.Println("error creating node coordinator") + } + + nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinatorWithRater(baseNodesCoordinator, coreComponents.Rater()) if err != nil { fmt.Println("error creating node coordinator") } - return nodesCoordinator + return nodesCoord } func generateGenesisNodeInfoMap( @@ -181,9 +203,9 @@ func generateGenesisNodeInfoMap( func createMetaBlockProcessor( nc nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor, - coreComponents *mock.CoreComponentsMock, - dataComponents *mock.DataComponentsMock, - bootstrapComponents *mock.BootstrapComponentsMock, + coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, + bootstrapComponents factory2.BootstrapComponentsHolder, statusComponents *mock.StatusComponentsMock, ) process.BlockProcessor { arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor) @@ -193,31 +215,34 @@ func createMetaBlockProcessor( } func createMockComponentHolders(numOfShards uint32) ( - *mock.CoreComponentsMock, - *mock.DataComponentsMock, - *mock.BootstrapComponentsMock, + factory2.CoreComponentsHolder, + factory2.DataComponentsHolder, + factory2.BootstrapComponentsHolder, *mock.StatusComponentsMock, + factory2.StateComponentsHandler, ) { - coreComponents := &mock.CoreComponentsMock{ - IntMarsh: &mock.MarshalizerMock{}, - Hash: &mock.HasherStub{}, - UInt64ByteSliceConv: &mock.Uint64ByteSliceConverterMock{}, - StatusField: &statusHandlerMock.AppStatusHandlerStub{}, - RoundField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, + //hasher := sha256.NewSha256() + //marshalizer := &marshal.GogoProtoMarshalizer{} + coreComponents := &mock2.CoreComponentsStub{ + InternalMarshalizerField: &mock.MarshalizerMock{}, + HasherField: sha256.NewSha256(), + Uint64ByteSliceConverterField: &mock.Uint64ByteSliceConverterMock{}, + StatusHandlerField: &statusHandlerMock.AppStatusHandlerStub{}, + RoundHandlerField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, + EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), + EpochNotifierField: forking.NewGenericEpochNotifier(), + RaterField: &mock2.RaterMock{}, } - dataComponents := &mock.DataComponentsMock{ - Storage: &mock.ChainStorerMock{}, - DataPool: dataRetrieverMock.NewPoolsHolderMock(), - BlockChain: &testscommon.ChainHandlerStub{ - GetGenesisHeaderCalled: func() data.HeaderHandler { - return &block.Header{Nonce: 0} - }, - }, + blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) + dataComponents := &factory3.DataComponentsMock{ //&mock.DataComponentsMock{ + Store: dataRetriever.NewChainStorer(), + DataPool: dataRetrieverMock.NewPoolsHolderMock(), + BlockChain: blockChain, } shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) - boostrapComponents := &mock.BootstrapComponentsMock{ - Coordinator: shardCoordinator, + boostrapComponents := &mainFactoryMocks.BootstrapComponentsStub{ + ShCoordinator: shardCoordinator, HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{ CreateCalled: func(epoch uint32) data.HeaderHandler { @@ -230,13 +255,24 @@ func createMockComponentHolders(numOfShards uint32) ( Outport: &testscommon.OutportStub{}, } - return coreComponents, dataComponents, boostrapComponents, statusComponents + trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) + userAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewAccountCreator(), trieFactoryManager) + peerAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewPeerAccountCreator(), trieFactoryManager) + stateComponents := &testscommon.StateComponentsMock{ + PeersAcc: peerAccountsDB, + Accounts: userAccountsDB, + AccountsAPI: nil, + Tries: nil, + StorageManagers: nil, + } + + return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents } func createMockMetaArguments( - coreComponents *mock.CoreComponentsMock, - dataComponents *mock.DataComponentsMock, - bootstrapComponents *mock.BootstrapComponentsMock, + coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, + bootstrapComponents factory2.BootstrapComponentsHolder, statusComponents *mock.StatusComponentsMock, nodesCoord nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor, @@ -348,68 +384,63 @@ func createGenesisMetaBlock() *block.MetaBlock { } } -func createFullArgumentsForSystemSCProcessing(nc nodesCoordinator.NodesCoordinator, stakingV2EnableEpoch uint32, trieStorer storage.Storer) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer) { - hasher := sha256.NewSha256() - marshalizer := &marshal.GogoProtoMarshalizer{} - trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(trieStorer) - userAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewAccountCreator(), trieFactoryManager) - peerAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewPeerAccountCreator(), trieFactoryManager) - en := forking.NewGenericEpochNotifier() - +func createFullArgumentsForSystemSCProcessing( + nc nodesCoordinator.NodesCoordinator, + stakingV2EnableEpoch uint32, + coreComponents factory2.CoreComponentsHolder, + stateComponents factory2.StateComponentsHandler, + bootstrapComponents factory2.BootstrapComponentsHolder, + dataComponents factory2.DataComponentsHolder, +) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer) { argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ - Marshalizer: marshalizer, + Marshalizer: coreComponents.InternalMarshalizer(), NodesCoordinator: nc, - ShardCoordinator: &mock.ShardCoordinatorStub{}, - DataPool: &dataRetrieverMock.PoolsHolderStub{}, - StorageService: &mock3.ChainStorerStub{}, - PubkeyConv: &mock.PubkeyConverterMock{}, - PeerAdapter: peerAccountsDB, - Rater: &mock3.RaterStub{}, + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + DataPool: dataComponents.Datapool(), + StorageService: dataComponents.StorageService(), + PubkeyConv: coreComponents.AddressPubKeyConverter(), + PeerAdapter: stateComponents.PeerAccounts(), + Rater: coreComponents.Rater(), RewardsHandler: &mock3.RewardsHandlerStub{}, NodesSetup: &mock.NodesSetupStub{}, MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, - EpochNotifier: en, + EpochNotifier: coreComponents.EpochNotifier(), StakingV2EnableEpoch: stakingV2EnableEpoch, StakingV4EnableEpoch: 444, } vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) - blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) gasSchedule := arwenConfig.MakeGasMapForTests() gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: gasScheduleNotifier, - MapDNSAddresses: make(map[string]struct{}), - Marshalizer: marshalizer, - Accounts: userAccountsDB, - ShardCoordinator: &mock.ShardCoordinatorStub{SelfIdCalled: func() uint32 { - return core.MetachainShardId - }}, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, + GasSchedule: gasScheduleNotifier, + MapDNSAddresses: make(map[string]struct{}), + Marshalizer: coreComponents.InternalMarshalizer(), + Accounts: stateComponents.AccountsAdapter(), + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + EpochNotifier: coreComponents.EpochNotifier(), } builtInFuncs, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) - testDataPool := dataRetrieverMock.NewPoolsHolderMock() argsHook := hooks.ArgBlockChainHook{ - Accounts: userAccountsDB, - PubkeyConv: &mock.PubkeyConverterMock{}, - StorageService: &mock3.ChainStorerStub{}, - BlockChain: blockChain, - ShardCoordinator: &mock.ShardCoordinatorStub{}, - Marshalizer: marshalizer, - Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, + Accounts: stateComponents.AccountsAdapter(), + PubkeyConv: coreComponents.AddressPubKeyConverter(), + StorageService: dataComponents.StorageService(), + BlockChain: dataComponents.Blockchain(), + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + Marshalizer: coreComponents.InternalMarshalizer(), + Uint64Converter: coreComponents.Uint64ByteSliceConverter(), NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, BuiltInFunctions: builtInFuncs, - DataPool: testDataPool, - CompiledSCPool: testDataPool.SmartContracts(), - EpochNotifier: &epochNotifier.EpochNotifierStub{}, + DataPool: dataComponents.Datapool(), + CompiledSCPool: dataComponents.Datapool().SmartContracts(), + EpochNotifier: coreComponents.EpochNotifier(), NilCompiledSCStore: true, } defaults.FillGasMapInternal(gasSchedule, 1) signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) - nodesSetup := &mock.NodesSetupStub{} blockChainHookImpl, _ := hooks.NewBlockChainHookImpl(argsHook) @@ -420,8 +451,8 @@ func createFullArgumentsForSystemSCProcessing(nc nodesCoordinator.NodesCoordinat MessageSignVerifier: signVerifer, GasSchedule: gasScheduleNotifier, NodesConfigProvider: nodesSetup, - Hasher: hasher, - Marshalizer: marshalizer, + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ BaseIssuingCost: "1000", @@ -462,9 +493,9 @@ func createFullArgumentsForSystemSCProcessing(nc nodesCoordinator.NodesCoordinat MaxServiceFee: 100, }, }, - ValidatorAccountsDB: peerAccountsDB, + ValidatorAccountsDB: stateComponents.PeerAccounts(), ChanceComputer: &mock3.ChanceComputerStub{}, - EpochNotifier: en, + EpochNotifier: coreComponents.EpochNotifier(), EpochConfig: &config.EpochConfig{ EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: stakingV2EnableEpoch, @@ -476,40 +507,31 @@ func createFullArgumentsForSystemSCProcessing(nc nodesCoordinator.NodesCoordinat StakingV4EnableEpoch: 445, }, }, - ShardCoordinator: &mock.ShardCoordinatorStub{}, + ShardCoordinator: bootstrapComponents.ShardCoordinator(), NodesCoordinator: nc, } - metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) + metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) vmContainer, _ := metaVmFactory.Create() systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") - shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, - UserAccountsDB: userAccountsDB, - PeerAccountsDB: peerAccountsDB, - Marshalizer: marshalizer, + UserAccountsDB: stateComponents.AccountsAdapter(), + PeerAccountsDB: stateComponents.PeerAccounts(), + Marshalizer: coreComponents.InternalMarshalizer(), StartRating: 5, ValidatorInfoCreator: vCreator, EndOfEpochCallerAddress: vm.EndOfEpochAddress, StakingSCAddress: vm.StakingSCAddress, ChanceComputer: &mock3.ChanceComputerStub{}, - EpochNotifier: en, + EpochNotifier: coreComponents.EpochNotifier(), GenesisNodesConfig: nodesSetup, StakingDataProvider: stakingSCprovider, - NodesConfigProvider: &shardingMocks.NodesCoordinatorStub{ - ConsensusGroupSizeCalled: func(shardID uint32) int { - if shardID == core.MetachainShardId { - return 400 - } - return 63 - }, - }, - ShardCoordinator: shardCoordinator, - ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), + NodesConfigProvider: nc, + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: 1000000, From fca992daa662062c179da8133eca1710ec7ccb1f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 31 Mar 2022 17:45:43 +0300 Subject: [PATCH 163/958] FEAT: Refactor 3 --- .../vm/staking/testMetaProcessor.go | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index f4b71ac714d..b35232973a0 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -44,6 +44,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state/factory" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" + "github.com/ElrondNetwork/elrond-go/statusHandler" "github.com/ElrondNetwork/elrond-go/storage/lrucache" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" @@ -51,7 +52,6 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" - stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" @@ -74,10 +74,10 @@ func NewTestMetaProcessor( metaConsensusGroupSize int, ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createMockComponentHolders(uint32(numOfShards)) - nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents) - scp := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents) + scp, validatorsInfoCreator := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents), + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator), } } @@ -99,8 +99,8 @@ func createSystemSCProcessor( stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, -) process.EpochStartSystemSCProcessor { - args, _ := createFullArgumentsForSystemSCProcessing(nc, +) (process.EpochStartSystemSCProcessor, process.ValidatorStatisticsProcessor) { + args, _, validatorsInfOCreator := createFullArgumentsForSystemSCProcessing(nc, 1000, coreComponents, stateComponents, @@ -108,7 +108,7 @@ func createSystemSCProcessor( dataComponents, ) s, _ := metachain.NewSystemSCProcessor(args) - return s + return s, validatorsInfOCreator } // TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator @@ -119,6 +119,7 @@ func createNodesCoordinator( shardConsensusGroupSize int, metaConsensusGroupSize int, coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, ) nodesCoordinator.NodesCoordinator { validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) @@ -137,7 +138,6 @@ func createNodesCoordinator( BalanceWaitingListsEnableEpoch: 0, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) - bootStorer := integrationTests.CreateMemUnit() cache, _ := lrucache.NewCache(10000) ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(integrationTests.TestMarshalizer, forking.NewGenericEpochNotifier(), 4444) @@ -157,7 +157,7 @@ func createNodesCoordinator( ChanStopNode: endProcess.GetDummyEndProcessChannel(), IsFullArchive: false, Shuffler: nodeShuffler, - BootStorer: bootStorer, + BootStorer: dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), StakingV4EnableEpoch: 444, NodesCoordinatorRegistryFactory: ncrf, @@ -207,8 +207,10 @@ func createMetaBlockProcessor( dataComponents factory2.DataComponentsHolder, bootstrapComponents factory2.BootstrapComponentsHolder, statusComponents *mock.StatusComponentsMock, + stateComponents factory2.StateComponentsHandler, + validatorsInfoCreator process.ValidatorStatisticsProcessor, ) process.BlockProcessor { - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor) + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator) metaProc, _ := blproc.NewMetaProcessor(arguments) return metaProc @@ -232,11 +234,17 @@ func createMockComponentHolders(numOfShards uint32) ( EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), EpochNotifierField: forking.NewGenericEpochNotifier(), RaterField: &mock2.RaterMock{}, + AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, + EconomicsDataField: createEconomicsData(), } - blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) + blockChain, _ := blockchain.NewMetaChain(statusHandler.NewStatusMetrics()) + _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) + + chainStorer := dataRetriever.NewChainStorer() + chainStorer.AddStorer(dataRetriever.BootstrapUnit, integrationTests.CreateMemUnit()) dataComponents := &factory3.DataComponentsMock{ //&mock.DataComponentsMock{ - Store: dataRetriever.NewChainStorer(), + Store: chainStorer, DataPool: dataRetrieverMock.NewPoolsHolderMock(), BlockChain: blockChain, } @@ -276,69 +284,61 @@ func createMockMetaArguments( statusComponents *mock.StatusComponentsMock, nodesCoord nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor, + stateComponents factory2.StateComponentsHandler, + validatorsInfoCreator process.ValidatorStatisticsProcessor, ) blproc.ArgMetaProcessor { - argsHeaderValidator := blproc.ArgsHeaderValidator{ - Hasher: &mock.HasherStub{}, - Marshalizer: &mock.MarshalizerMock{}, + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), } headerValidator, _ := blproc.NewHeaderValidator(argsHeaderValidator) startHeaders := createGenesisBlocks(bootstrapComponents.ShardCoordinator()) accountsDb := make(map[state.AccountsDbIdentifier]state.AccountsAdapter) - accountsDb[state.UserAccountsState] = &stateMock.AccountsStub{ - CommitCalled: func() ([]byte, error) { - return nil, nil - }, - RootHashCalled: func() ([]byte, error) { - return nil, nil - }, - } - accountsDb[state.PeerAccountsState] = &stateMock.AccountsStub{ - CommitCalled: func() ([]byte, error) { - return nil, nil - }, - RootHashCalled: func() ([]byte, error) { - return nil, nil - }, - } + accountsDb[state.UserAccountsState] = stateComponents.AccountsAdapter() + accountsDb[state.PeerAccountsState] = stateComponents.PeerAccounts() + + bootStrapStorer, _ := bootstrapStorage.NewBootstrapStorer(coreComponents.InternalMarshalizer(), integrationTests.CreateMemUnit()) + valInfoCreator, _ := metachain.NewValidatorInfoCreator(metachain.ArgsNewValidatorInfoCreator{ + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + MiniBlockStorage: integrationTests.CreateMemUnit(), + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + DataPool: dataComponents.Datapool(), + }) arguments := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ - CoreComponents: coreComponents, - DataComponents: dataComponents, - BootstrapComponents: bootstrapComponents, - StatusComponents: statusComponents, - AccountsDB: accountsDb, - ForkDetector: &mock.ForkDetectorMock{}, - NodesCoordinator: nodesCoord, - FeeHandler: &mock.FeeAccumulatorStub{}, - RequestHandler: &testscommon.RequestHandlerStub{}, - BlockChainHook: &testscommon.BlockChainHookStub{}, - TxCoordinator: &mock.TransactionCoordinatorMock{}, - EpochStartTrigger: &mock.EpochStartTriggerStub{}, - HeaderValidator: headerValidator, - GasHandler: &mock.GasHandlerMock{}, - BootStorer: &mock.BoostrapStorerMock{ - PutCalled: func(round int64, bootData bootstrapStorage.BootstrapData) error { - return nil - }, - }, + CoreComponents: coreComponents, + DataComponents: dataComponents, + BootstrapComponents: bootstrapComponents, + StatusComponents: statusComponents, + AccountsDB: accountsDb, + ForkDetector: &mock.ForkDetectorMock{}, + NodesCoordinator: nodesCoord, + FeeHandler: &mock.FeeAccumulatorStub{}, + RequestHandler: &testscommon.RequestHandlerStub{}, + BlockChainHook: &testscommon.BlockChainHookStub{}, + TxCoordinator: &mock.TransactionCoordinatorMock{}, + EpochStartTrigger: &mock.EpochStartTriggerStub{}, + HeaderValidator: headerValidator, + GasHandler: &mock.GasHandlerMock{}, + BootStorer: bootStrapStorer, BlockTracker: mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders), BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, + EpochNotifier: coreComponents.EpochNotifier(), RoundNotifier: &mock.RoundNotifierStub{}, ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, - ScheduledMiniBlocksEnableEpoch: 2, + ScheduledMiniBlocksEnableEpoch: 10000, }, SCToProtocol: &mock.SCToProtocolStub{}, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, - EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, - ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{}, + EpochValidatorInfoCreator: valInfoCreator, + ValidatorStatisticsProcessor: validatorsInfoCreator, EpochSystemSCProcessor: systemSCProcessor, } return arguments @@ -391,7 +391,7 @@ func createFullArgumentsForSystemSCProcessing( stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, -) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer) { +) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer, process.ValidatorStatisticsProcessor) { argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ Marshalizer: coreComponents.InternalMarshalizer(), NodesCoordinator: nc, @@ -541,7 +541,7 @@ func createFullArgumentsForSystemSCProcessing( }, }, } - return args, metaVmFactory.SystemSmartContractContainer() + return args, metaVmFactory.SystemSmartContractContainer(), vCreator } func createAccountsDB( From d4e9a1ed7928f589033345df7f9f14b26401b0b9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 1 Apr 2022 12:31:37 +0300 Subject: [PATCH 164/958] FEAT: Refactor 4 --- integrationTests/vm/staking/stakingV4_test.go | 42 +++++++++++- .../vm/staking/testMetaProcessor.go | 64 +++++++++++-------- 2 files changed, 78 insertions(+), 28 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 91df4418615..834f0dd2b0e 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -8,9 +8,49 @@ import ( "github.com/stretchr/testify/assert" ) +func createMetaBlockHeader() *block.MetaBlock { + hdr := block.MetaBlock{ + Nonce: 1, + Round: 1, + PrevHash: []byte(""), + Signature: []byte("signature"), + PubKeysBitmap: []byte("pubKeysBitmap"), + RootHash: []byte("rootHash"), + ShardInfo: make([]block.ShardData, 0), + TxCount: 1, + PrevRandSeed: make([]byte, 0), + RandSeed: make([]byte, 0), + AccumulatedFeesInEpoch: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + DevFeesInEpoch: big.NewInt(0), + DeveloperFees: big.NewInt(0), + } + + shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) + shardMiniBlockHeader := block.MiniBlockHeader{ + Hash: []byte("mb_hash1"), + ReceiverShardID: 0, + SenderShardID: 0, + TxCount: 1, + } + shardMiniBlockHeaders = append(shardMiniBlockHeaders, shardMiniBlockHeader) + shardData := block.ShardData{ + Nonce: 1, + ShardID: 0, + HeaderHash: []byte("hdr_hash1"), + TxCount: 1, + ShardMiniBlockHeaders: shardMiniBlockHeaders, + DeveloperFees: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + } + hdr.ShardInfo = append(hdr.ShardInfo, shardData) + + return &hdr +} + func TestNewTestMetaProcessor(t *testing.T) { node := NewTestMetaProcessor(1, 1, 1, 1, 1) - metaHdr := &block.MetaBlock{} + metaHdr := createMetaBlockHeader() headerHandler, bodyHandler, err := node.MetaBlockProcessor.CreateBlock(metaHdr, func() bool { return true }) assert.Nil(t, err) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index b35232973a0..0376fbd9d61 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -3,6 +3,7 @@ package staking import ( "bytes" "fmt" + "math/big" "strconv" "time" @@ -31,6 +32,7 @@ import ( "github.com/ElrondNetwork/elrond-go/process" blproc "github.com/ElrondNetwork/elrond-go/process/block" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" + "github.com/ElrondNetwork/elrond-go/process/block/postprocess" economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" @@ -75,9 +77,9 @@ func NewTestMetaProcessor( ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createMockComponentHolders(uint32(numOfShards)) nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents) - scp, validatorsInfoCreator := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) + scp, blockChainHook, validatorsInfoCreator := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator), + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook), } } @@ -99,8 +101,8 @@ func createSystemSCProcessor( stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, -) (process.EpochStartSystemSCProcessor, process.ValidatorStatisticsProcessor) { - args, _, validatorsInfOCreator := createFullArgumentsForSystemSCProcessing(nc, +) (process.EpochStartSystemSCProcessor, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor) { + args, blockChainHook, validatorsInfOCreator := createFullArgumentsForSystemSCProcessing(nc, 1000, coreComponents, stateComponents, @@ -108,7 +110,7 @@ func createSystemSCProcessor( dataComponents, ) s, _ := metachain.NewSystemSCProcessor(args) - return s, validatorsInfOCreator + return s, blockChainHook, validatorsInfOCreator } // TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator @@ -209,8 +211,9 @@ func createMetaBlockProcessor( statusComponents *mock.StatusComponentsMock, stateComponents factory2.StateComponentsHandler, validatorsInfoCreator process.ValidatorStatisticsProcessor, + blockChainHook process.BlockChainHookHandler, ) process.BlockProcessor { - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator) + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook) metaProc, _ := blproc.NewMetaProcessor(arguments) return metaProc @@ -286,6 +289,7 @@ func createMockMetaArguments( systemSCProcessor process.EpochStartSystemSCProcessor, stateComponents factory2.StateComponentsHandler, validatorsInfoCreator process.ValidatorStatisticsProcessor, + blockChainHook process.BlockChainHookHandler, ) blproc.ArgMetaProcessor { argsHeaderValidator := blproc.ArgsHeaderValidator{ Hasher: coreComponents.Hasher(), @@ -307,6 +311,7 @@ func createMockMetaArguments( DataPool: dataComponents.Datapool(), }) + feeHandler, _ := postprocess.NewFeeAccumulator() arguments := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ CoreComponents: coreComponents, @@ -316,9 +321,9 @@ func createMockMetaArguments( AccountsDB: accountsDb, ForkDetector: &mock.ForkDetectorMock{}, NodesCoordinator: nodesCoord, - FeeHandler: &mock.FeeAccumulatorStub{}, + FeeHandler: feeHandler, RequestHandler: &testscommon.RequestHandlerStub{}, - BlockChainHook: &testscommon.BlockChainHookStub{}, + BlockChainHook: blockChainHook, TxCoordinator: &mock.TransactionCoordinatorMock{}, EpochStartTrigger: &mock.EpochStartTriggerStub{}, HeaderValidator: headerValidator, @@ -358,29 +363,33 @@ func createGenesisBlocks(shardCoordinator sharding.Coordinator) map[uint32]data. func createGenesisBlock(ShardID uint32) *block.Header { rootHash := []byte("roothash") return &block.Header{ - Nonce: 0, - Round: 0, - Signature: rootHash, - RandSeed: rootHash, - PrevRandSeed: rootHash, - ShardID: ShardID, - PubKeysBitmap: rootHash, - RootHash: rootHash, - PrevHash: rootHash, + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + ShardID: ShardID, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + AccumulatedFees: big.NewInt(0), + DeveloperFees: big.NewInt(0), } } func createGenesisMetaBlock() *block.MetaBlock { rootHash := []byte("roothash") return &block.MetaBlock{ - Nonce: 0, - Round: 0, - Signature: rootHash, - RandSeed: rootHash, - PrevRandSeed: rootHash, - PubKeysBitmap: rootHash, - RootHash: rootHash, - PrevHash: rootHash, + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + AccumulatedFees: big.NewInt(0), + DeveloperFees: big.NewInt(0), } } @@ -391,7 +400,7 @@ func createFullArgumentsForSystemSCProcessing( stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, -) (metachain.ArgsNewEpochStartSystemSCProcessing, vm.SystemSCContainer, process.ValidatorStatisticsProcessor) { +) (metachain.ArgsNewEpochStartSystemSCProcessing, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor) { argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ Marshalizer: coreComponents.InternalMarshalizer(), NodesCoordinator: nc, @@ -541,7 +550,8 @@ func createFullArgumentsForSystemSCProcessing( }, }, } - return args, metaVmFactory.SystemSmartContractContainer(), vCreator + + return args, blockChainHookImpl, vCreator } func createAccountsDB( From f3dbe32071f5eaa3575990fd40e610530b30c745 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 1 Apr 2022 13:45:30 +0300 Subject: [PATCH 165/958] FEAT: Refactor 5 --- integrationTests/vm/staking/stakingV4_test.go | 29 ++----- .../vm/staking/testMetaProcessor.go | 83 ++++++++++++++----- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 834f0dd2b0e..88f77eb9e2d 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -3,6 +3,7 @@ package staking import ( "math/big" "testing" + "time" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/stretchr/testify/assert" @@ -15,11 +16,11 @@ func createMetaBlockHeader() *block.MetaBlock { PrevHash: []byte(""), Signature: []byte("signature"), PubKeysBitmap: []byte("pubKeysBitmap"), - RootHash: []byte("rootHash"), + RootHash: []byte("roothash"), ShardInfo: make([]block.ShardData, 0), TxCount: 1, - PrevRandSeed: make([]byte, 0), - RandSeed: make([]byte, 0), + PrevRandSeed: []byte("roothash"), + RandSeed: []byte("roothash"), AccumulatedFeesInEpoch: big.NewInt(0), AccumulatedFees: big.NewInt(0), DevFeesInEpoch: big.NewInt(0), @@ -54,25 +55,9 @@ func TestNewTestMetaProcessor(t *testing.T) { headerHandler, bodyHandler, err := node.MetaBlockProcessor.CreateBlock(metaHdr, func() bool { return true }) assert.Nil(t, err) - err = headerHandler.SetRound(uint64(1)) - assert.Nil(t, err) - - err = headerHandler.SetNonce(1) - assert.Nil(t, err) + node.DisplayNodesConfig(0, 1) - err = headerHandler.SetPrevHash([]byte("hash")) + err = node.MetaBlockProcessor.ProcessBlock(headerHandler, bodyHandler, func() time.Duration { return time.Second }) assert.Nil(t, err) - - err = headerHandler.SetAccumulatedFees(big.NewInt(0)) - assert.Nil(t, err) - - _ = bodyHandler - /* - metaHeaderHandler, _ := headerHandler.(data.MetaHeaderHandler) - err = metaHeaderHandler.SetAccumulatedFeesInEpoch(big.NewInt(0)) - assert.Nil(t, err) - - err = node.MetaBlockProcessor.ProcessBlock(headerHandler, bodyHandler, func() time.Duration { return time.Second }) - assert.Nil(t, err) - */ + node.DisplayNodesConfig(0, 1) } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 0376fbd9d61..3d244fe450e 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -77,9 +77,38 @@ func NewTestMetaProcessor( ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createMockComponentHolders(uint32(numOfShards)) nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents) - scp, blockChainHook, validatorsInfoCreator := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) + scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook), + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory), + SystemSCProcessor: scp, + NodesCoordinator: nc, + } +} + +func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32, numOfShards int) { + eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) + waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) + leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) + shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) + + for shard := 0; shard < numOfShards; shard++ { + shardID := uint32(shard) + if shard == numOfShards { + shardID = core.MetachainShardId + } + + for _, pk := range eligible[shardID] { + fmt.Println("eligible", "pk", string(pk), "shardID", shardID) + } + for _, pk := range waiting[shardID] { + fmt.Println("waiting", "pk", string(pk), "shardID", shardID) + } + for _, pk := range leaving[shardID] { + fmt.Println("leaving", "pk", string(pk), "shardID", shardID) + } + for _, pk := range shuffledOut[shardID] { + fmt.Println("shuffled out", "pk", string(pk), "shardID", shardID) + } } } @@ -101,8 +130,8 @@ func createSystemSCProcessor( stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, -) (process.EpochStartSystemSCProcessor, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor) { - args, blockChainHook, validatorsInfOCreator := createFullArgumentsForSystemSCProcessing(nc, +) (process.EpochStartSystemSCProcessor, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { + args, blockChainHook, validatorsInfOCreator, metaVMFactory := createFullArgumentsForSystemSCProcessing(nc, 1000, coreComponents, stateComponents, @@ -110,7 +139,7 @@ func createSystemSCProcessor( dataComponents, ) s, _ := metachain.NewSystemSCProcessor(args) - return s, blockChainHook, validatorsInfOCreator + return s, blockChainHook, validatorsInfOCreator, metaVMFactory } // TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator @@ -123,10 +152,10 @@ func createNodesCoordinator( coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder, ) nodesCoordinator.NodesCoordinator { - validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) + validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) - waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard) + waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, numOfMetaNodes) waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ @@ -183,18 +212,19 @@ func generateGenesisNodeInfoMap( numOfMetaNodes int, numOfShards int, numOfNodesPerShard int, + startIdx int, ) map[uint32][]nodesCoordinator.GenesisNodeInfoHandler { validatorsMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) for shardId := 0; shardId < numOfShards; shardId++ { for n := 0; n < numOfNodesPerShard; n++ { - addr := []byte("addr" + strconv.Itoa(n) + "-shard" + strconv.Itoa(shardId)) + addr := []byte("addr" + strconv.Itoa(n+startIdx)) validator := mock2.NewNodeInfo(addr, addr, uint32(shardId), 5) validatorsMap[uint32(shardId)] = append(validatorsMap[uint32(shardId)], validator) } } for n := 0; n < numOfMetaNodes; n++ { - addr := []byte("addr" + strconv.Itoa(n) + "-shard" + strconv.Itoa(int(core.MetachainShardId))) + addr := []byte("addr" + strconv.Itoa(n+startIdx)) validator := mock2.NewNodeInfo(addr, addr, uint32(core.MetachainShardId), 5) validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) } @@ -212,8 +242,9 @@ func createMetaBlockProcessor( stateComponents factory2.StateComponentsHandler, validatorsInfoCreator process.ValidatorStatisticsProcessor, blockChainHook process.BlockChainHookHandler, + metaVMFactory process.VirtualMachinesContainerFactory, ) process.BlockProcessor { - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook) + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory) metaProc, _ := blproc.NewMetaProcessor(arguments) return metaProc @@ -242,6 +273,7 @@ func createMockComponentHolders(numOfShards uint32) ( } blockChain, _ := blockchain.NewMetaChain(statusHandler.NewStatusMetrics()) + _ = blockChain.SetCurrentBlockHeaderAndRootHash(createGenesisMetaBlock(), []byte("roothash")) _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) chainStorer := dataRetriever.NewChainStorer() @@ -290,6 +322,7 @@ func createMockMetaArguments( stateComponents factory2.StateComponentsHandler, validatorsInfoCreator process.ValidatorStatisticsProcessor, blockChainHook process.BlockChainHookHandler, + metaVMFactory process.VirtualMachinesContainerFactory, ) blproc.ArgMetaProcessor { argsHeaderValidator := blproc.ArgsHeaderValidator{ Hasher: coreComponents.Hasher(), @@ -312,6 +345,8 @@ func createMockMetaArguments( }) feeHandler, _ := postprocess.NewFeeAccumulator() + + vmContainer, _ := metaVMFactory.Create() arguments := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ CoreComponents: coreComponents, @@ -336,6 +371,8 @@ func createMockMetaArguments( RoundNotifier: &mock.RoundNotifierStub{}, ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, ScheduledMiniBlocksEnableEpoch: 10000, + VMContainersFactory: metaVMFactory, + VmContainer: vmContainer, }, SCToProtocol: &mock.SCToProtocolStub{}, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, @@ -380,16 +417,18 @@ func createGenesisBlock(ShardID uint32) *block.Header { func createGenesisMetaBlock() *block.MetaBlock { rootHash := []byte("roothash") return &block.MetaBlock{ - Nonce: 0, - Round: 0, - Signature: rootHash, - RandSeed: rootHash, - PrevRandSeed: rootHash, - PubKeysBitmap: rootHash, - RootHash: rootHash, - PrevHash: rootHash, - AccumulatedFees: big.NewInt(0), - DeveloperFees: big.NewInt(0), + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + AccumulatedFees: big.NewInt(0), + DeveloperFees: big.NewInt(0), + AccumulatedFeesInEpoch: big.NewInt(0), + DevFeesInEpoch: big.NewInt(0), } } @@ -400,7 +439,7 @@ func createFullArgumentsForSystemSCProcessing( stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, -) (metachain.ArgsNewEpochStartSystemSCProcessing, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor) { +) (metachain.ArgsNewEpochStartSystemSCProcessing, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ Marshalizer: coreComponents.InternalMarshalizer(), NodesCoordinator: nc, @@ -551,7 +590,7 @@ func createFullArgumentsForSystemSCProcessing( }, } - return args, blockChainHookImpl, vCreator + return args, blockChainHookImpl, vCreator, metaVmFactory } func createAccountsDB( From 1856d585c652249fbb4a58df8f3b9130b94e3908 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 4 Apr 2022 11:33:45 +0300 Subject: [PATCH 166/958] FEAT: Ugly version with 2 committed blocks --- factory/mock/forkDetectorStub.go | 5 +- integrationTests/vm/staking/stakingV4_test.go | 103 +++++++++++++++--- .../vm/staking/testMetaProcessor.go | 67 ++++++++++-- 3 files changed, 145 insertions(+), 30 deletions(-) diff --git a/factory/mock/forkDetectorStub.go b/factory/mock/forkDetectorStub.go index 4fa15b21d27..da4003d7525 100644 --- a/factory/mock/forkDetectorStub.go +++ b/factory/mock/forkDetectorStub.go @@ -28,7 +28,10 @@ func (fdm *ForkDetectorStub) RestoreToGenesis() { // AddHeader - func (fdm *ForkDetectorStub) AddHeader(header data.HeaderHandler, hash []byte, state process.BlockHeaderState, selfNotarizedHeaders []data.HeaderHandler, selfNotarizedHeadersHashes [][]byte) error { - return fdm.AddHeaderCalled(header, hash, state, selfNotarizedHeaders, selfNotarizedHeadersHashes) + if fdm.AddHeaderCalled != nil { + return fdm.AddHeaderCalled(header, hash, state, selfNotarizedHeaders, selfNotarizedHeadersHashes) + } + return nil } // RemoveHeader - diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 88f77eb9e2d..fd32037e763 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1,26 +1,32 @@ package staking import ( + "encoding/hex" + "fmt" "math/big" + "strconv" "testing" - "time" + "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/stretchr/testify/assert" + "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" + "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/stretchr/testify/require" ) -func createMetaBlockHeader() *block.MetaBlock { +func createMetaBlockHeader(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { hdr := block.MetaBlock{ - Nonce: 1, - Round: 1, - PrevHash: []byte(""), + Epoch: epoch, + Nonce: round, + Round: round, + PrevHash: prevHash, Signature: []byte("signature"), PubKeysBitmap: []byte("pubKeysBitmap"), RootHash: []byte("roothash"), ShardInfo: make([]block.ShardData, 0), TxCount: 1, PrevRandSeed: []byte("roothash"), - RandSeed: []byte("roothash"), + RandSeed: []byte("roothash" + strconv.Itoa(int(round))), AccumulatedFeesInEpoch: big.NewInt(0), AccumulatedFees: big.NewInt(0), DevFeesInEpoch: big.NewInt(0), @@ -29,16 +35,16 @@ func createMetaBlockHeader() *block.MetaBlock { shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: []byte("mb_hash1"), + Hash: []byte("mb_hash" + strconv.Itoa(int(round))), ReceiverShardID: 0, SenderShardID: 0, TxCount: 1, } shardMiniBlockHeaders = append(shardMiniBlockHeaders, shardMiniBlockHeader) shardData := block.ShardData{ - Nonce: 1, + Nonce: round, ShardID: 0, - HeaderHash: []byte("hdr_hash1"), + HeaderHash: []byte("hdr_hash" + strconv.Itoa(int(round))), TxCount: 1, ShardMiniBlockHeaders: shardMiniBlockHeaders, DeveloperFees: big.NewInt(0), @@ -51,13 +57,76 @@ func createMetaBlockHeader() *block.MetaBlock { func TestNewTestMetaProcessor(t *testing.T) { node := NewTestMetaProcessor(1, 1, 1, 1, 1) - metaHdr := createMetaBlockHeader() - headerHandler, bodyHandler, err := node.MetaBlockProcessor.CreateBlock(metaHdr, func() bool { return true }) - assert.Nil(t, err) - + //metaHdr := createMetaBlockHeader(1,1) + //headerHandler, bodyHandler, err := node.MetaBlockProcessor.CreateBlock(metaHdr, func() bool { return true }) + //assert.Nil(t, err) + // + //node.DisplayNodesConfig(0, 1) + // + //err = node.MetaBlockProcessor.ProcessBlock(headerHandler, bodyHandler, func() time.Duration { return time.Second }) + //assert.Nil(t, err) + // + //err = node.MetaBlockProcessor.CommitBlock(headerHandler, bodyHandler) node.DisplayNodesConfig(0, 1) + newHdr := createMetaBlockHeader(1, 1, []byte("")) + newHdr.SetPrevHash(node.GenesisHeader.Hash) + newHdr2, newBodyHandler2, err := node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - err = node.MetaBlockProcessor.ProcessBlock(headerHandler, bodyHandler, func() time.Duration { return time.Second }) - assert.Nil(t, err) - node.DisplayNodesConfig(0, 1) + require.Nil(t, err) + //newHdr22 := newHdr2.(*block.MetaBlock) + + //valstat, _ := hex.DecodeString("8de5a7881cdf0edc6f37d0382f870609c4a79559b0c4dbac8260fea955db9bb9") + //newHdr22.ValidatorStatsRootHash = valstat + + //err = node.MetaBlockProcessor.ProcessBlock(newHdr2, newBodyHandler2, func() time.Duration { return 4 * time.Second }) + //require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) + require.Nil(t, err) + + currentBlockHeader := node.BlockChain.GetCurrentBlockHeader() + if check.IfNil(currentBlockHeader) { + currentBlockHeader = node.BlockChain.GetGenesisHeader() + } + + marshaller := &mock.MarshalizerMock{} + prevBlockBytes, _ := marshaller.Marshal(newHdr2) + prevBlockBytes = sha256.NewSha256().Compute(string(prevBlockBytes)) + prevBlockHash := hex.EncodeToString(prevBlockBytes) + fmt.Println(prevBlockHash) + + //prevHash, _ := hex.DecodeString("a9307adeffe84090fab6a0e2e6c94c4102bdf083bc1314a389e4e85500861710") + prevRandomness := currentBlockHeader.GetRandSeed() + newRandomness := currentBlockHeader.GetRandSeed() + anotherHdr := createMetaBlockHeader(1, 2, prevBlockBytes) + + // rootHash ,_ := node.ValidatorStatistics.RootHash() + // anotherHdr.ValidatorStatsRootHash = rootHash + anotherHdr.PrevRandSeed = prevRandomness + anotherHdr.RandSeed = newRandomness + hh, bb, err := node.MetaBlockProcessor.CreateBlock(anotherHdr, func() bool { return true }) + require.Nil(t, err) + + //err = node.MetaBlockProcessor.ProcessBlock(hh,bb,func() time.Duration { return 4* time.Second }) + //require.Nil(t, err) + + err = node.MetaBlockProcessor.CommitBlock(hh, bb) + require.Nil(t, err) + + /* + prevHash, _ := hex.DecodeString("7a8de8d447691a793f053a7e744b28da19c42cedbef7e76caef7d4acb2ff3906") + prevRandSeed := newHdr2.GetRandSeed() + newHdr2 = createMetaBlockHeader(2,2, prevHash) + newHdr2.SetPrevRandSeed(prevRandSeed) + + metablk := newHdr2.(*block.MetaBlock) + valStats, _ := hex.DecodeString("5f4f6e8be67205b432eaf2aafb2b1aa3555cf58a936a5f93b3b89917a9a9fa42") + metablk.ValidatorStatsRootHash = valStats + newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr2, func() bool { return true }) + require.Nil(t, err) + err = node.MetaBlockProcessor.ProcessBlock(newHdr2, newBodyHandler2, func() time.Duration { return time.Second }) + require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) + require.Nil(t, err) + + */ } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 3d244fe450e..503389c148a 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -2,6 +2,7 @@ package staking import ( "bytes" + "encoding/hex" "fmt" "math/big" "strconv" @@ -25,6 +26,7 @@ import ( mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" factory2 "github.com/ElrondNetwork/elrond-go/factory" + mock4 "github.com/ElrondNetwork/elrond-go/factory/mock" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/integrationTests" mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" @@ -60,11 +62,19 @@ import ( "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" ) +type HeaderInfo struct { + Hash []byte + Header data.HeaderHandler +} + // TestMetaProcessor - type TestMetaProcessor struct { - MetaBlockProcessor process.BlockProcessor - SystemSCProcessor process.EpochStartSystemSCProcessor - NodesCoordinator nodesCoordinator.NodesCoordinator + MetaBlockProcessor process.BlockProcessor + SystemSCProcessor process.EpochStartSystemSCProcessor + NodesCoordinator nodesCoordinator.NodesCoordinator + BlockChain data.ChainHandler + ValidatorStatistics process.ValidatorStatisticsProcessor + GenesisHeader *HeaderInfo } // NewTestMetaProcessor - @@ -75,13 +85,20 @@ func NewTestMetaProcessor( shardConsensusGroupSize int, metaConsensusGroupSize int, ) *TestMetaProcessor { - coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createMockComponentHolders(uint32(numOfShards)) - nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents) + coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, genesisHeader := createMockComponentHolders(uint32(numOfShards)) + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents) scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) + + rootHash, _ := stateComponents.PeerAccounts().RootHash() + fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) + return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory), - SystemSCProcessor: scp, - NodesCoordinator: nc, + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory), + SystemSCProcessor: scp, + NodesCoordinator: nc, + BlockChain: dataComponents.Blockchain(), + ValidatorStatistics: validatorsInfoCreator, + GenesisHeader: genesisHeader, } } @@ -151,6 +168,7 @@ func createNodesCoordinator( metaConsensusGroupSize int, coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder, + stateComponents factory2.StateComponentsHandler, ) nodesCoordinator.NodesCoordinator { validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) @@ -158,6 +176,20 @@ func createNodesCoordinator( waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, numOfMetaNodes) waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) + // TODO: HERE SAVE ALL ACCOUNTS + acc, _ := stateComponents.PeerAccounts().LoadAccount(validatorsMap[0][0].PubKeyBytes()) + peerAcc := acc.(state.PeerAccountHandler) + peerAcc.SetTempRating(5) + stateComponents.PeerAccounts().SaveAccount(peerAcc) + + rootHash, _ := stateComponents.PeerAccounts().RootHash() + fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) + + //acc,_ = stateComponents.PeerAccounts().LoadAccount(waitingMap[0][0].PubKeyBytes()) + //peerAcc = acc.(state.PeerAccountHandler) + //peerAcc.SetTempRating(5) + //stateComponents.PeerAccounts().SaveAccount(peerAcc) + shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ NodesShard: uint32(numOfNodesPerShard), NodesMeta: uint32(numOfMetaNodes), @@ -256,6 +288,7 @@ func createMockComponentHolders(numOfShards uint32) ( factory2.BootstrapComponentsHolder, *mock.StatusComponentsMock, factory2.StateComponentsHandler, + *HeaderInfo, ) { //hasher := sha256.NewSha256() //marshalizer := &marshal.GogoProtoMarshalizer{} @@ -267,17 +300,24 @@ func createMockComponentHolders(numOfShards uint32) ( RoundHandlerField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), EpochNotifierField: forking.NewGenericEpochNotifier(), - RaterField: &mock2.RaterMock{}, + RaterField: mock.GetNewMockRater(), AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, EconomicsDataField: createEconomicsData(), } blockChain, _ := blockchain.NewMetaChain(statusHandler.NewStatusMetrics()) - _ = blockChain.SetCurrentBlockHeaderAndRootHash(createGenesisMetaBlock(), []byte("roothash")) + //_ = blockChain.SetCurrentBlockHeaderAndRootHash(createGenesisMetaBlock(), []byte("roothash")) + genesisBlock := createGenesisMetaBlock() + genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) + genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) + blockChain.SetGenesisHeaderHash(genesisBlockHash) + fmt.Println("GENESIS BLOCK HASH: " + hex.EncodeToString(genesisBlockHash)) chainStorer := dataRetriever.NewChainStorer() chainStorer.AddStorer(dataRetriever.BootstrapUnit, integrationTests.CreateMemUnit()) + chainStorer.AddStorer(dataRetriever.MetaHdrNonceHashDataUnit, integrationTests.CreateMemUnit()) + chainStorer.AddStorer(dataRetriever.MetaBlockUnit, integrationTests.CreateMemUnit()) dataComponents := &factory3.DataComponentsMock{ //&mock.DataComponentsMock{ Store: chainStorer, DataPool: dataRetrieverMock.NewPoolsHolderMock(), @@ -309,7 +349,10 @@ func createMockComponentHolders(numOfShards uint32) ( StorageManagers: nil, } - return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents + return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents, &HeaderInfo{ + Hash: genesisBlockHash, + Header: genesisBlock, + } } func createMockMetaArguments( @@ -354,7 +397,7 @@ func createMockMetaArguments( BootstrapComponents: bootstrapComponents, StatusComponents: statusComponents, AccountsDB: accountsDb, - ForkDetector: &mock.ForkDetectorMock{}, + ForkDetector: &mock4.ForkDetectorStub{}, NodesCoordinator: nodesCoord, FeeHandler: feeHandler, RequestHandler: &testscommon.RequestHandlerStub{}, From 4ea2b9d02ea95c7c11a2689f169eb77a7f66204a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 4 Apr 2022 16:42:57 +0300 Subject: [PATCH 167/958] FEAT: Test with epoch start prepare --- integrationTests/vm/staking/stakingV4_test.go | 134 ++++++++++-------- .../vm/staking/testMetaProcessor.go | 116 +++++++++++---- process/mock/epochEconomicsStub.go | 4 +- process/mock/epochStartDataCreatorStub.go | 12 +- testscommon/rewardsCreatorStub.go | 3 +- 5 files changed, 176 insertions(+), 93 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index fd32037e763..1032b29b8e2 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1,13 +1,10 @@ package staking import ( - "encoding/hex" - "fmt" "math/big" "strconv" "testing" - "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go/process/mock" @@ -56,77 +53,90 @@ func createMetaBlockHeader(epoch uint32, round uint64, prevHash []byte) *block.M } func TestNewTestMetaProcessor(t *testing.T) { - node := NewTestMetaProcessor(1, 1, 1, 1, 1) - //metaHdr := createMetaBlockHeader(1,1) - //headerHandler, bodyHandler, err := node.MetaBlockProcessor.CreateBlock(metaHdr, func() bool { return true }) - //assert.Nil(t, err) - // - //node.DisplayNodesConfig(0, 1) - // - //err = node.MetaBlockProcessor.ProcessBlock(headerHandler, bodyHandler, func() time.Duration { return time.Second }) - //assert.Nil(t, err) - // - //err = node.MetaBlockProcessor.CommitBlock(headerHandler, bodyHandler) - node.DisplayNodesConfig(0, 1) - newHdr := createMetaBlockHeader(1, 1, []byte("")) - newHdr.SetPrevHash(node.GenesisHeader.Hash) + node := NewTestMetaProcessor(3, 3, 3, 2, 2) + node.DisplayNodesConfig(0, 4) + + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + newHdr := createMetaBlockHeader(0, 1, node.GenesisHeader.Hash) + _, _ = node.MetaBlockProcessor.CreateNewHeader(1, 1) newHdr2, newBodyHandler2, err := node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) + require.Nil(t, err) + + node.DisplayNodesConfig(0, 4) + marshaller := &mock.MarshalizerMock{} + hasher := sha256.NewSha256() + + prevBlockBytes, _ := marshaller.Marshal(newHdr2) + prevBlockBytes = hasher.Compute(string(prevBlockBytes)) + prevRandomness := node.BlockChain.GetCurrentBlockHeader().GetRandSeed() + newHdr = createMetaBlockHeader(0, 2, prevBlockBytes) + newHdr.PrevRandSeed = prevRandomness + + _, _ = node.MetaBlockProcessor.CreateNewHeader(2, 2) + newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) require.Nil(t, err) - //newHdr22 := newHdr2.(*block.MetaBlock) + node.DisplayNodesConfig(0, 4) - //valstat, _ := hex.DecodeString("8de5a7881cdf0edc6f37d0382f870609c4a79559b0c4dbac8260fea955db9bb9") - //newHdr22.ValidatorStatsRootHash = valstat + prevBlockBytes, _ = marshaller.Marshal(newHdr2) + prevBlockBytes = hasher.Compute(string(prevBlockBytes)) + prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() + newHdr = createMetaBlockHeader(0, 3, prevBlockBytes) + newHdr.PrevRandSeed = prevRandomness - //err = node.MetaBlockProcessor.ProcessBlock(newHdr2, newBodyHandler2, func() time.Duration { return 4 * time.Second }) - //require.Nil(t, err) + _, _ = node.MetaBlockProcessor.CreateNewHeader(3, 3) + newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + require.Nil(t, err) err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) require.Nil(t, err) + node.DisplayNodesConfig(0, 4) - currentBlockHeader := node.BlockChain.GetCurrentBlockHeader() - if check.IfNil(currentBlockHeader) { - currentBlockHeader = node.BlockChain.GetGenesisHeader() - } + prevBlockBytes, _ = marshaller.Marshal(newHdr2) + prevBlockBytes = hasher.Compute(string(prevBlockBytes)) + prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() + newHdr = createMetaBlockHeader(1, 4, prevBlockBytes) + newHdr.PrevRandSeed = prevRandomness - marshaller := &mock.MarshalizerMock{} - prevBlockBytes, _ := marshaller.Marshal(newHdr2) - prevBlockBytes = sha256.NewSha256().Compute(string(prevBlockBytes)) - prevBlockHash := hex.EncodeToString(prevBlockBytes) - fmt.Println(prevBlockHash) - - //prevHash, _ := hex.DecodeString("a9307adeffe84090fab6a0e2e6c94c4102bdf083bc1314a389e4e85500861710") - prevRandomness := currentBlockHeader.GetRandSeed() - newRandomness := currentBlockHeader.GetRandSeed() - anotherHdr := createMetaBlockHeader(1, 2, prevBlockBytes) - - // rootHash ,_ := node.ValidatorStatistics.RootHash() - // anotherHdr.ValidatorStatsRootHash = rootHash - anotherHdr.PrevRandSeed = prevRandomness - anotherHdr.RandSeed = newRandomness - hh, bb, err := node.MetaBlockProcessor.CreateBlock(anotherHdr, func() bool { return true }) + _, _ = node.MetaBlockProcessor.CreateNewHeader(4, 4) + newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) require.Nil(t, err) + node.DisplayNodesConfig(0, 4) + + prevBlockBytes, _ = marshaller.Marshal(newHdr2) + prevBlockBytes = hasher.Compute(string(prevBlockBytes)) + prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() + newHdr = createMetaBlockHeader(1, 5, prevBlockBytes) + newHdr.PrevRandSeed = prevRandomness + newHdr.EpochStart.LastFinalizedHeaders = []block.EpochStartShardData{{}} + newHdr.EpochStart.Economics = block.Economics{RewardsForProtocolSustainability: big.NewInt(0)} + + _, _ = node.MetaBlockProcessor.CreateNewHeader(5, 5) + newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + //node.CoreComponents.EpochStartNotifierWithConfirm().NotifyAllPrepare(newHdr2,newBodyHandler2) + require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) + require.Nil(t, err) + node.DisplayNodesConfig(1, 4) - //err = node.MetaBlockProcessor.ProcessBlock(hh,bb,func() time.Duration { return 4* time.Second }) - //require.Nil(t, err) + // epoch start + prevBlockBytes, _ = marshaller.Marshal(newHdr2) + prevBlockBytes = hasher.Compute(string(prevBlockBytes)) + prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() + newHdr = createMetaBlockHeader(1, 6, prevBlockBytes) + newHdr.PrevRandSeed = prevRandomness - err = node.MetaBlockProcessor.CommitBlock(hh, bb) + _, _ = node.MetaBlockProcessor.CreateNewHeader(6, 6) + newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + require.Nil(t, err) + err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) require.Nil(t, err) + node.DisplayNodesConfig(1, 4) - /* - prevHash, _ := hex.DecodeString("7a8de8d447691a793f053a7e744b28da19c42cedbef7e76caef7d4acb2ff3906") - prevRandSeed := newHdr2.GetRandSeed() - newHdr2 = createMetaBlockHeader(2,2, prevHash) - newHdr2.SetPrevRandSeed(prevRandSeed) - - metablk := newHdr2.(*block.MetaBlock) - valStats, _ := hex.DecodeString("5f4f6e8be67205b432eaf2aafb2b1aa3555cf58a936a5f93b3b89917a9a9fa42") - metablk.ValidatorStatsRootHash = valStats - newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr2, func() bool { return true }) - require.Nil(t, err) - err = node.MetaBlockProcessor.ProcessBlock(newHdr2, newBodyHandler2, func() time.Duration { return time.Second }) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - - */ } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 503389c148a..f651ba38755 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -74,7 +74,9 @@ type TestMetaProcessor struct { NodesCoordinator nodesCoordinator.NodesCoordinator BlockChain data.ChainHandler ValidatorStatistics process.ValidatorStatisticsProcessor + EpochStartTrigger integrationTests.TestEpochStartTrigger GenesisHeader *HeaderInfo + CoreComponents factory2.CoreComponentsHolder } // NewTestMetaProcessor - @@ -86,6 +88,8 @@ func NewTestMetaProcessor( metaConsensusGroupSize int, ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, genesisHeader := createMockComponentHolders(uint32(numOfShards)) + epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents) + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents) scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) @@ -93,13 +97,35 @@ func NewTestMetaProcessor( fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory), + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartTrigger), SystemSCProcessor: scp, NodesCoordinator: nc, BlockChain: dataComponents.Blockchain(), ValidatorStatistics: validatorsInfoCreator, GenesisHeader: genesisHeader, + EpochStartTrigger: epochStartTrigger, + CoreComponents: coreComponents, + } +} + +func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder) integrationTests.TestEpochStartTrigger { + argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ + GenesisTime: time.Now(), + Settings: &config.EpochStartConfig{ + MinRoundsBetweenEpochs: 100, + RoundsPerEpoch: 100, + }, + Epoch: 0, + EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), + Storage: dataComponents.StorageService(), + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, } + epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) + ret := &metachain.TestTrigger{} + ret.SetTrigger(epochStartTrigger) + return ret } func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32, numOfShards int) { @@ -108,23 +134,20 @@ func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32, numOfShards int) leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) - for shard := 0; shard < numOfShards; shard++ { - shardID := uint32(shard) - if shard == numOfShards { - shardID = core.MetachainShardId - } + fmt.Println("############### Displaying nodes config in epoch " + strconv.Itoa(int(epoch))) - for _, pk := range eligible[shardID] { - fmt.Println("eligible", "pk", string(pk), "shardID", shardID) + for shard := range eligible { + for _, pk := range eligible[shard] { + fmt.Println("eligible", "pk", string(pk), "shardID", shard) } - for _, pk := range waiting[shardID] { - fmt.Println("waiting", "pk", string(pk), "shardID", shardID) + for _, pk := range waiting[shard] { + fmt.Println("waiting", "pk", string(pk), "shardID", shard) } - for _, pk := range leaving[shardID] { - fmt.Println("leaving", "pk", string(pk), "shardID", shardID) + for _, pk := range leaving[shard] { + fmt.Println("leaving", "pk", string(pk), "shardID", shard) } - for _, pk := range shuffledOut[shardID] { - fmt.Println("shuffled out", "pk", string(pk), "shardID", shardID) + for _, pk := range shuffledOut[shard] { + fmt.Println("shuffled out", "pk", string(pk), "shardID", shard) } } } @@ -173,14 +196,32 @@ func createNodesCoordinator( validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) - waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, numOfMetaNodes) + waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, numOfMetaNodes+numOfShards*numOfNodesPerShard) waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) // TODO: HERE SAVE ALL ACCOUNTS - acc, _ := stateComponents.PeerAccounts().LoadAccount(validatorsMap[0][0].PubKeyBytes()) - peerAcc := acc.(state.PeerAccountHandler) - peerAcc.SetTempRating(5) - stateComponents.PeerAccounts().SaveAccount(peerAcc) + + for shardID, vals := range validatorsMap { + for _, val := range vals { + peerAccount, _ := state.NewPeerAccount(val.PubKeyBytes()) + peerAccount.SetTempRating(5) + peerAccount.ShardId = shardID + peerAccount.BLSPublicKey = val.PubKeyBytes() + peerAccount.List = string(common.EligibleList) + stateComponents.PeerAccounts().SaveAccount(peerAccount) + } + } + + for shardID, vals := range waitingMap { + for _, val := range vals { + peerAccount, _ := state.NewPeerAccount(val.PubKeyBytes()) + peerAccount.SetTempRating(5) + peerAccount.ShardId = shardID + peerAccount.BLSPublicKey = val.PubKeyBytes() + peerAccount.List = string(common.WaitingList) + stateComponents.PeerAccounts().SaveAccount(peerAccount) + } + } rootHash, _ := stateComponents.PeerAccounts().RootHash() fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) @@ -199,11 +240,12 @@ func createNodesCoordinator( MaxNodesEnableConfig: nil, WaitingListFixEnableEpoch: 0, BalanceWaitingListsEnableEpoch: 0, + StakingV4EnableEpoch: 4444, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) cache, _ := lrucache.NewCache(10000) - ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(integrationTests.TestMarshalizer, forking.NewGenericEpochNotifier(), 4444) + ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(coreComponents.InternalMarshalizer(), coreComponents.EpochNotifier(), 4444) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, @@ -247,18 +289,21 @@ func generateGenesisNodeInfoMap( startIdx int, ) map[uint32][]nodesCoordinator.GenesisNodeInfoHandler { validatorsMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) + id := startIdx for shardId := 0; shardId < numOfShards; shardId++ { for n := 0; n < numOfNodesPerShard; n++ { - addr := []byte("addr" + strconv.Itoa(n+startIdx)) + addr := []byte("addr" + strconv.Itoa(id)) validator := mock2.NewNodeInfo(addr, addr, uint32(shardId), 5) validatorsMap[uint32(shardId)] = append(validatorsMap[uint32(shardId)], validator) + id++ } } for n := 0; n < numOfMetaNodes; n++ { - addr := []byte("addr" + strconv.Itoa(n+startIdx)) + addr := []byte("addr" + strconv.Itoa(id)) validator := mock2.NewNodeInfo(addr, addr, uint32(core.MetachainShardId), 5) validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) + id++ } return validatorsMap @@ -275,8 +320,9 @@ func createMetaBlockProcessor( validatorsInfoCreator process.ValidatorStatisticsProcessor, blockChainHook process.BlockChainHookHandler, metaVMFactory process.VirtualMachinesContainerFactory, + epochStartHandler process.EpochStartTriggerHandler, ) process.BlockProcessor { - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory) + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartHandler) metaProc, _ := blproc.NewMetaProcessor(arguments) return metaProc @@ -300,7 +346,7 @@ func createMockComponentHolders(numOfShards uint32) ( RoundHandlerField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), EpochNotifierField: forking.NewGenericEpochNotifier(), - RaterField: mock.GetNewMockRater(), + RaterField: &testscommon.RaterMock{Chance: 5}, //mock.GetNewMockRater(), AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, EconomicsDataField: createEconomicsData(), } @@ -366,6 +412,7 @@ func createMockMetaArguments( validatorsInfoCreator process.ValidatorStatisticsProcessor, blockChainHook process.BlockChainHookHandler, metaVMFactory process.VirtualMachinesContainerFactory, + epochStartHandler process.EpochStartTriggerHandler, ) blproc.ArgMetaProcessor { argsHeaderValidator := blproc.ArgsHeaderValidator{ Hasher: coreComponents.Hasher(), @@ -390,6 +437,21 @@ func createMockMetaArguments( feeHandler, _ := postprocess.NewFeeAccumulator() vmContainer, _ := metaVMFactory.Create() + blockTracker := mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders) + + argsEpochStartDataCreator := metachain.ArgsNewEpochStartData{ + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + Store: dataComponents.StorageService(), + DataPool: dataComponents.Datapool(), + BlockTracker: blockTracker, + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + EpochStartTrigger: epochStartHandler, + RequestHandler: &testscommon.RequestHandlerStub{}, + GenesisEpoch: 0, + } + epochStartDataCreator, _ := metachain.NewEpochStartData(argsEpochStartDataCreator) + arguments := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ CoreComponents: coreComponents, @@ -403,11 +465,11 @@ func createMockMetaArguments( RequestHandler: &testscommon.RequestHandlerStub{}, BlockChainHook: blockChainHook, TxCoordinator: &mock.TransactionCoordinatorMock{}, - EpochStartTrigger: &mock.EpochStartTriggerStub{}, + EpochStartTrigger: epochStartHandler, HeaderValidator: headerValidator, GasHandler: &mock.GasHandlerMock{}, BootStorer: bootStrapStorer, - BlockTracker: mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders), + BlockTracker: blockTracker, BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, EpochNotifier: coreComponents.EpochNotifier(), @@ -419,7 +481,7 @@ func createMockMetaArguments( }, SCToProtocol: &mock.SCToProtocolStub{}, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, - EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, + EpochStartDataCreator: epochStartDataCreator, EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, EpochValidatorInfoCreator: valInfoCreator, diff --git a/process/mock/epochEconomicsStub.go b/process/mock/epochEconomicsStub.go index 1a48a0a1792..a316d526320 100644 --- a/process/mock/epochEconomicsStub.go +++ b/process/mock/epochEconomicsStub.go @@ -19,7 +19,9 @@ func (e *EpochEconomicsStub) ComputeEndOfEpochEconomics(metaBlock *block.MetaBlo if e.ComputeEndOfEpochEconomicsCalled != nil { return e.ComputeEndOfEpochEconomicsCalled(metaBlock) } - return &block.Economics{}, nil + return &block.Economics{ + RewardsForProtocolSustainability: big.NewInt(0), + }, nil } // VerifyRewardsPerBlock - diff --git a/process/mock/epochStartDataCreatorStub.go b/process/mock/epochStartDataCreatorStub.go index 131cdacd083..48b15e48deb 100644 --- a/process/mock/epochStartDataCreatorStub.go +++ b/process/mock/epochStartDataCreatorStub.go @@ -1,6 +1,10 @@ package mock -import "github.com/ElrondNetwork/elrond-go-core/data/block" +import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go-core/data/block" +) // EpochStartDataCreatorStub - type EpochStartDataCreatorStub struct { @@ -13,7 +17,11 @@ func (e *EpochStartDataCreatorStub) CreateEpochStartData() (*block.EpochStart, e if e.CreateEpochStartDataCalled != nil { return e.CreateEpochStartDataCalled() } - return &block.EpochStart{}, nil + return &block.EpochStart{ + LastFinalizedHeaders: []block.EpochStartShardData{{}}, + Economics: block.Economics{ + RewardsForProtocolSustainability: big.NewInt(0)}, + }, nil } // VerifyEpochStartDataForMetablock - diff --git a/testscommon/rewardsCreatorStub.go b/testscommon/rewardsCreatorStub.go index 662f5f76b55..787231f496f 100644 --- a/testscommon/rewardsCreatorStub.go +++ b/testscommon/rewardsCreatorStub.go @@ -5,6 +5,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go/dataRetriever/dataPool" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" ) @@ -65,7 +66,7 @@ func (rcs *RewardsCreatorStub) GetLocalTxCache() epochStart.TransactionCacher { if rcs.GetLocalTxCacheCalled != nil { return rcs.GetLocalTxCacheCalled() } - return nil + return dataPool.NewCurrentBlockPool() } // CreateMarshalizedData - From 1449bcc9b98ef2744a1fe18354f75ba41a793262 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 5 Apr 2022 12:08:56 +0300 Subject: [PATCH 168/958] FEAT: Register bls keys + bugfixes --- epochStart/metachain/legacySystemSCs.go | 5 +- epochStart/metachain/systemSCs.go | 2 - .../vm/staking/testMetaProcessor.go | 119 ++++++++++++++++-- .../indexHashedNodesCoordinator.go | 6 +- .../indexHashedNodesCoordinatorLite.go | 2 +- ...dexHashedNodesCoordinatorWithRater_test.go | 2 +- .../indexHashedNodesCoordinator_test.go | 12 +- 7 files changed, 122 insertions(+), 26 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 0a8bf08cc25..4e3d0c425c3 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -55,6 +55,7 @@ type legacySystemSCProcessor struct { esdtEnableEpoch uint32 saveJailedAlwaysEnableEpoch uint32 stakingV4InitEnableEpoch uint32 + stakingV4EnableEpoch uint32 flagSwitchJailedWaiting atomic.Flag flagHystNodesEnabled atomic.Flag @@ -100,6 +101,7 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, + stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("legacySystemSC: enable epoch for switch jail waiting", "epoch", legacy.switchEnableEpoch) @@ -110,6 +112,7 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega log.Debug("legacySystemSC: enable epoch for correct last unjailed", "epoch", legacy.correctLastUnJailEpoch) log.Debug("legacySystemSC: enable epoch for save jailed always", "epoch", legacy.saveJailedAlwaysEnableEpoch) log.Debug("legacySystemSC: enable epoch for initializing staking v4", "epoch", legacy.stakingV4InitEnableEpoch) + log.Debug("legacySystemSC: enable epoch for staking v4", "epoch", legacy.stakingV4EnableEpoch) legacy.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(legacy.maxNodesEnableConfig, args.MaxNodesEnableConfig) @@ -1385,7 +1388,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagCorrectLastUnjailedEnabled.SetValue(epoch == s.correctLastUnJailEpoch) log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) - s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch) + s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch && epoch < s.stakingV4EnableEpoch) log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) s.flagESDTEnabled.SetValue(epoch == s.esdtEnableEpoch) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6ceacc241a6..d733fd7ab81 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -54,7 +54,6 @@ type systemSCProcessor struct { governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 - stakingV4EnableEpoch uint32 flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag @@ -77,7 +76,6 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr legacySystemSCProcessor: legacy, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, - stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index f651ba38755..340579665be 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "strconv" + "strings" "time" arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" @@ -59,9 +60,12 @@ import ( statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" ) +const stakingV4EnableEpoch = 1 + type HeaderInfo struct { Hash []byte Header data.HeaderHandler @@ -77,6 +81,7 @@ type TestMetaProcessor struct { EpochStartTrigger integrationTests.TestEpochStartTrigger GenesisHeader *HeaderInfo CoreComponents factory2.CoreComponentsHolder + AllPubKeys [][]byte } // NewTestMetaProcessor - @@ -90,7 +95,7 @@ func NewTestMetaProcessor( coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, genesisHeader := createMockComponentHolders(uint32(numOfShards)) epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents) - nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents) + nc, pubKeys := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents) scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) rootHash, _ := stateComponents.PeerAccounts().RootHash() @@ -105,6 +110,7 @@ func NewTestMetaProcessor( GenesisHeader: genesisHeader, EpochStartTrigger: epochStartTrigger, CoreComponents: coreComponents, + AllPubKeys: pubKeys, } } @@ -172,7 +178,7 @@ func createSystemSCProcessor( dataComponents factory2.DataComponentsHolder, ) (process.EpochStartSystemSCProcessor, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { args, blockChainHook, validatorsInfOCreator, metaVMFactory := createFullArgumentsForSystemSCProcessing(nc, - 1000, + 0, // 1000 coreComponents, stateComponents, bootstrapComponents, @@ -182,6 +188,12 @@ func createSystemSCProcessor( return s, blockChainHook, validatorsInfOCreator, metaVMFactory } +func generateUniqueKey(identifier int) []byte { + neededLength := 12 //192 + uniqueIdentifier := fmt.Sprintf("address-%d", identifier) + return []byte(strings.Repeat("0", neededLength-len(uniqueIdentifier)) + uniqueIdentifier) +} + // TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator func createNodesCoordinator( numOfMetaNodes int, @@ -192,7 +204,7 @@ func createNodesCoordinator( coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder, stateComponents factory2.StateComponentsHandler, -) nodesCoordinator.NodesCoordinator { +) (nodesCoordinator.NodesCoordinator, [][]byte) { validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) @@ -200,6 +212,7 @@ func createNodesCoordinator( waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) // TODO: HERE SAVE ALL ACCOUNTS + var allPubKeys [][]byte for shardID, vals := range validatorsMap { for _, val := range vals { @@ -209,6 +222,7 @@ func createNodesCoordinator( peerAccount.BLSPublicKey = val.PubKeyBytes() peerAccount.List = string(common.EligibleList) stateComponents.PeerAccounts().SaveAccount(peerAccount) + allPubKeys = append(allPubKeys, val.PubKeyBytes()) } } @@ -220,9 +234,14 @@ func createNodesCoordinator( peerAccount.BLSPublicKey = val.PubKeyBytes() peerAccount.List = string(common.WaitingList) stateComponents.PeerAccounts().SaveAccount(peerAccount) + allPubKeys = append(allPubKeys, val.PubKeyBytes()) } } + for idx, pubKey := range allPubKeys { + registerValidatorKeys(stateComponents.AccountsAdapter(), []byte(string(pubKey)+strconv.Itoa(idx)), []byte(string(pubKey)+strconv.Itoa(idx)), [][]byte{pubKey}, big.NewInt(20000), coreComponents.InternalMarshalizer()) + } + rootHash, _ := stateComponents.PeerAccounts().RootHash() fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) @@ -240,12 +259,12 @@ func createNodesCoordinator( MaxNodesEnableConfig: nil, WaitingListFixEnableEpoch: 0, BalanceWaitingListsEnableEpoch: 0, - StakingV4EnableEpoch: 4444, + StakingV4EnableEpoch: stakingV4EnableEpoch, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) cache, _ := lrucache.NewCache(10000) - ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(coreComponents.InternalMarshalizer(), coreComponents.EpochNotifier(), 4444) + ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(coreComponents.InternalMarshalizer(), coreComponents.EpochNotifier(), stakingV4EnableEpoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, @@ -264,7 +283,7 @@ func createNodesCoordinator( Shuffler: nodeShuffler, BootStorer: dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - StakingV4EnableEpoch: 444, + StakingV4EnableEpoch: stakingV4EnableEpoch, NodesCoordinatorRegistryFactory: ncrf, NodeTypeProvider: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), } @@ -279,7 +298,7 @@ func createNodesCoordinator( fmt.Println("error creating node coordinator") } - return nodesCoord + return nodesCoord, allPubKeys } func generateGenesisNodeInfoMap( @@ -292,7 +311,7 @@ func generateGenesisNodeInfoMap( id := startIdx for shardId := 0; shardId < numOfShards; shardId++ { for n := 0; n < numOfNodesPerShard; n++ { - addr := []byte("addr" + strconv.Itoa(id)) + addr := generateUniqueKey(id) //[]byte("addr" + strconv.Itoa(id)) validator := mock2.NewNodeInfo(addr, addr, uint32(shardId), 5) validatorsMap[uint32(shardId)] = append(validatorsMap[uint32(shardId)], validator) id++ @@ -300,7 +319,7 @@ func generateGenesisNodeInfoMap( } for n := 0; n < numOfMetaNodes; n++ { - addr := []byte("addr" + strconv.Itoa(id)) + addr := generateUniqueKey(id) validator := mock2.NewNodeInfo(addr, addr, uint32(core.MetachainShardId), 5) validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) id++ @@ -560,7 +579,7 @@ func createFullArgumentsForSystemSCProcessing( MaxConsecutiveRoundsOfRatingDecrease: 2000, EpochNotifier: coreComponents.EpochNotifier(), StakingV2EnableEpoch: stakingV2EnableEpoch, - StakingV4EnableEpoch: 444, + StakingV4EnableEpoch: stakingV4EnableEpoch, } vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) @@ -657,7 +676,7 @@ func createFullArgumentsForSystemSCProcessing( DelegationSmartContractEnableEpoch: 0, StakeLimitsEnableEpoch: 10, StakingV4InitEnableEpoch: 444, - StakingV4EnableEpoch: 445, + StakingV4EnableEpoch: stakingV4EnableEpoch, }, }, ShardCoordinator: bootstrapComponents.ShardCoordinator(), @@ -687,10 +706,10 @@ func createFullArgumentsForSystemSCProcessing( ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 1000000, + StakingV2EnableEpoch: 0, ESDTEnableEpoch: 1000000, StakingV4InitEnableEpoch: 444, - StakingV4EnableEpoch: 445, + StakingV4EnableEpoch: stakingV4EnableEpoch, }, }, } @@ -763,3 +782,77 @@ func createEconomicsData() process.EconomicsDataHandler { economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData } + +// ###### + +func registerValidatorKeys( + accountsDB state.AccountsAdapter, + ownerAddress []byte, + rewardAddress []byte, + stakedKeys [][]byte, + totalStake *big.Int, + marshaller marshal.Marshalizer, +) { + addValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) + addStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) + _, err := accountsDB.Commit() + if err != nil { + fmt.Println("ERROR REGISTERING VALIDATORS ", err) + } + //log.LogIfError(err) +} + +func addValidatorData( + accountsDB state.AccountsAdapter, + ownerKey []byte, + registeredKeys [][]byte, + totalStake *big.Int, + marshaller marshal.Marshalizer, +) { + validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) + validatorData := &systemSmartContracts.ValidatorDataV2{ + RegisterNonce: 0, + Epoch: 0, + RewardAddress: ownerKey, + TotalStakeValue: totalStake, + LockedStake: big.NewInt(0), + TotalUnstaked: big.NewInt(0), + BlsPubKeys: registeredKeys, + NumRegistered: uint32(len(registeredKeys)), + } + + marshaledData, _ := marshaller.Marshal(validatorData) + _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) + + _ = accountsDB.SaveAccount(validatorSC) +} + +func addStakingData( + accountsDB state.AccountsAdapter, + ownerAddress []byte, + rewardAddress []byte, + stakedKeys [][]byte, + marshaller marshal.Marshalizer, +) { + stakedData := &systemSmartContracts.StakedDataV2_0{ + Staked: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshaller.Marshal(stakedData) + + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + for _, key := range stakedKeys { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) + } + + _ = accountsDB.SaveAccount(stakingSCAcc) +} + +func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { + acc, _ := accountsDB.LoadAccount(address) + stakingSCAcc := acc.(state.UserAccountHandler) + + return stakingSCAcc +} diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 76bc253833e..d021cf2fa3f 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -153,7 +153,7 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed ihnc.loadingFromDisk.Store(false) ihnc.nodesCoordinatorHelper = ihnc - err = ihnc.setNodesPerShards(arguments.EligibleNodes, arguments.WaitingNodes, nil, arguments.Epoch) + err = ihnc.setNodesPerShards(arguments.EligibleNodes, arguments.WaitingNodes, nil, nil, arguments.Epoch) if err != nil { return nil, err } @@ -237,6 +237,7 @@ func (ihnc *indexHashedNodesCoordinator) setNodesPerShards( eligible map[uint32][]Validator, waiting map[uint32][]Validator, leaving map[uint32][]Validator, + shuffledOut map[uint32][]Validator, epoch uint32, ) error { ihnc.mutNodesConfig.Lock() @@ -276,6 +277,7 @@ func (ihnc *indexHashedNodesCoordinator) setNodesPerShards( nodesConfig.eligibleMap = eligible nodesConfig.waitingMap = waiting nodesConfig.leavingMap = leaving + nodesConfig.shuffledOutMap = shuffledOut nodesConfig.shardID, isValidator = ihnc.computeShardForSelfPublicKey(nodesConfig) nodesConfig.selectors, err = ihnc.createSelectors(nodesConfig) if err != nil { @@ -665,7 +667,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa resUpdateNodes.Leaving, ) - err = ihnc.setNodesPerShards(resUpdateNodes.Eligible, resUpdateNodes.Waiting, leavingNodesMap, newEpoch) + err = ihnc.setNodesPerShards(resUpdateNodes.Eligible, resUpdateNodes.Waiting, leavingNodesMap, resUpdateNodes.ShuffledOut, newEpoch) if err != nil { log.Error("set nodes per shard failed", "error", err.Error()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go index b33b59235d8..47b31f251f9 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go @@ -41,7 +41,7 @@ func (ihnc *indexHashedNodesCoordinator) SetNodesConfigFromValidatorsInfo(epoch resUpdateNodes.Leaving, ) - err = ihnc.setNodesPerShards(resUpdateNodes.Eligible, resUpdateNodes.Waiting, leavingNodesMap, epoch) + err = ihnc.setNodesPerShards(resUpdateNodes.Eligible, resUpdateNodes.Waiting, leavingNodesMap, resUpdateNodes.ShuffledOut, epoch) if err != nil { return err } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go index c887ec03cae..53b3065b927 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go @@ -53,7 +53,7 @@ func TestIndexHashedGroupSelectorWithRater_SetNilEligibleMapShouldErr(t *testing waiting := createDummyNodesMap(2, 1, "waiting") nc, _ := NewIndexHashedNodesCoordinator(createArguments()) ihnc, _ := NewIndexHashedNodesCoordinatorWithRater(nc, &mock.RaterMock{}) - assert.Equal(t, ErrNilInputNodesMap, ihnc.setNodesPerShards(nil, waiting, nil, 0)) + assert.Equal(t, ErrNilInputNodesMap, ihnc.setNodesPerShards(nil, waiting, nil, nil, 0)) } func TestIndexHashedGroupSelectorWithRater_OkValShouldWork(t *testing.T) { diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index d0c8c6e4abc..40d423d43a2 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -223,7 +223,7 @@ func TestIndexHashedNodesCoordinator_SetNilEligibleMapShouldErr(t *testing.T) { arguments := createArguments() ihnc, _ := NewIndexHashedNodesCoordinator(arguments) - require.Equal(t, ErrNilInputNodesMap, ihnc.setNodesPerShards(nil, waitingMap, nil, 0)) + require.Equal(t, ErrNilInputNodesMap, ihnc.setNodesPerShards(nil, waitingMap, nil, nil, 0)) } func TestIndexHashedNodesCoordinator_SetNilWaitingMapShouldErr(t *testing.T) { @@ -233,7 +233,7 @@ func TestIndexHashedNodesCoordinator_SetNilWaitingMapShouldErr(t *testing.T) { arguments := createArguments() ihnc, _ := NewIndexHashedNodesCoordinator(arguments) - require.Equal(t, ErrNilInputNodesMap, ihnc.setNodesPerShards(eligibleMap, nil, nil, 0)) + require.Equal(t, ErrNilInputNodesMap, ihnc.setNodesPerShards(eligibleMap, nil, nil, nil, 0)) } func TestIndexHashedNodesCoordinator_OkValShouldWork(t *testing.T) { @@ -1197,7 +1197,7 @@ func TestIndexHashedNodesCoordinator_setNodesPerShardsShouldTriggerWrongConfigur }, } - err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) + err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) require.NoError(t, err) value := <-chanStopNode @@ -1223,7 +1223,7 @@ func TestIndexHashedNodesCoordinator_setNodesPerShardsShouldNotTriggerWrongConfi }, } - err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) + err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) require.NoError(t, err) require.Empty(t, chanStopNode) @@ -1255,7 +1255,7 @@ func TestIndexHashedNodesCoordinator_setNodesPerShardsShouldSetNodeTypeValidator }, } - err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) + err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) require.NoError(t, err) require.True(t, setTypeWasCalled) require.Equal(t, core.NodeTypeValidator, nodeTypeResult) @@ -1287,7 +1287,7 @@ func TestIndexHashedNodesCoordinator_setNodesPerShardsShouldSetNodeTypeObserver( }, } - err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) + err = ihnc.setNodesPerShards(eligibleMap, map[uint32][]Validator{}, map[uint32][]Validator{}, map[uint32][]Validator{}, 2) require.NoError(t, err) require.True(t, setTypeWasCalled) require.Equal(t, core.NodeTypeObserver, nodeTypeResult) From 3c26053aa724766776f866dfc8101e4d06b3219c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 5 Apr 2022 12:41:13 +0300 Subject: [PATCH 169/958] FEAT: Add Process for num of rounds --- integrationTests/vm/staking/stakingV4_test.go | 130 +----------------- .../vm/staking/testMetaProcessor.go | 75 +++++++++- 2 files changed, 75 insertions(+), 130 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 1032b29b8e2..54a7f194b1a 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1,142 +1,14 @@ package staking import ( - "math/big" - "strconv" "testing" - - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" - "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/stretchr/testify/require" ) -func createMetaBlockHeader(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { - hdr := block.MetaBlock{ - Epoch: epoch, - Nonce: round, - Round: round, - PrevHash: prevHash, - Signature: []byte("signature"), - PubKeysBitmap: []byte("pubKeysBitmap"), - RootHash: []byte("roothash"), - ShardInfo: make([]block.ShardData, 0), - TxCount: 1, - PrevRandSeed: []byte("roothash"), - RandSeed: []byte("roothash" + strconv.Itoa(int(round))), - AccumulatedFeesInEpoch: big.NewInt(0), - AccumulatedFees: big.NewInt(0), - DevFeesInEpoch: big.NewInt(0), - DeveloperFees: big.NewInt(0), - } - - shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) - shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: []byte("mb_hash" + strconv.Itoa(int(round))), - ReceiverShardID: 0, - SenderShardID: 0, - TxCount: 1, - } - shardMiniBlockHeaders = append(shardMiniBlockHeaders, shardMiniBlockHeader) - shardData := block.ShardData{ - Nonce: round, - ShardID: 0, - HeaderHash: []byte("hdr_hash" + strconv.Itoa(int(round))), - TxCount: 1, - ShardMiniBlockHeaders: shardMiniBlockHeaders, - DeveloperFees: big.NewInt(0), - AccumulatedFees: big.NewInt(0), - } - hdr.ShardInfo = append(hdr.ShardInfo, shardData) - - return &hdr -} - func TestNewTestMetaProcessor(t *testing.T) { node := NewTestMetaProcessor(3, 3, 3, 2, 2) node.DisplayNodesConfig(0, 4) node.EpochStartTrigger.SetRoundsPerEpoch(4) - newHdr := createMetaBlockHeader(0, 1, node.GenesisHeader.Hash) - _, _ = node.MetaBlockProcessor.CreateNewHeader(1, 1) - newHdr2, newBodyHandler2, err := node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - - node.DisplayNodesConfig(0, 4) - - marshaller := &mock.MarshalizerMock{} - hasher := sha256.NewSha256() - - prevBlockBytes, _ := marshaller.Marshal(newHdr2) - prevBlockBytes = hasher.Compute(string(prevBlockBytes)) - prevRandomness := node.BlockChain.GetCurrentBlockHeader().GetRandSeed() - newHdr = createMetaBlockHeader(0, 2, prevBlockBytes) - newHdr.PrevRandSeed = prevRandomness - - _, _ = node.MetaBlockProcessor.CreateNewHeader(2, 2) - newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - node.DisplayNodesConfig(0, 4) - - prevBlockBytes, _ = marshaller.Marshal(newHdr2) - prevBlockBytes = hasher.Compute(string(prevBlockBytes)) - prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() - newHdr = createMetaBlockHeader(0, 3, prevBlockBytes) - newHdr.PrevRandSeed = prevRandomness - - _, _ = node.MetaBlockProcessor.CreateNewHeader(3, 3) - newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - node.DisplayNodesConfig(0, 4) - - prevBlockBytes, _ = marshaller.Marshal(newHdr2) - prevBlockBytes = hasher.Compute(string(prevBlockBytes)) - prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() - newHdr = createMetaBlockHeader(1, 4, prevBlockBytes) - newHdr.PrevRandSeed = prevRandomness - - _, _ = node.MetaBlockProcessor.CreateNewHeader(4, 4) - newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - node.DisplayNodesConfig(0, 4) - - prevBlockBytes, _ = marshaller.Marshal(newHdr2) - prevBlockBytes = hasher.Compute(string(prevBlockBytes)) - prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() - newHdr = createMetaBlockHeader(1, 5, prevBlockBytes) - newHdr.PrevRandSeed = prevRandomness - newHdr.EpochStart.LastFinalizedHeaders = []block.EpochStartShardData{{}} - newHdr.EpochStart.Economics = block.Economics{RewardsForProtocolSustainability: big.NewInt(0)} - - _, _ = node.MetaBlockProcessor.CreateNewHeader(5, 5) - newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - //node.CoreComponents.EpochStartNotifierWithConfirm().NotifyAllPrepare(newHdr2,newBodyHandler2) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - node.DisplayNodesConfig(1, 4) - - // epoch start - prevBlockBytes, _ = marshaller.Marshal(newHdr2) - prevBlockBytes = hasher.Compute(string(prevBlockBytes)) - prevRandomness = node.BlockChain.GetCurrentBlockHeader().GetRandSeed() - newHdr = createMetaBlockHeader(1, 6, prevBlockBytes) - newHdr.PrevRandSeed = prevRandomness - - _, _ = node.MetaBlockProcessor.CreateNewHeader(6, 6) - newHdr2, newBodyHandler2, err = node.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - require.Nil(t, err) - err = node.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - node.DisplayNodesConfig(1, 4) - + node.Process(t, 1, 7) } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 340579665be..ff43695eae0 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -7,6 +7,7 @@ import ( "math/big" "strconv" "strings" + "testing" "time" arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" @@ -62,6 +63,7 @@ import ( "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" + "github.com/stretchr/testify/require" ) const stakingV4EnableEpoch = 1 @@ -79,6 +81,7 @@ type TestMetaProcessor struct { BlockChain data.ChainHandler ValidatorStatistics process.ValidatorStatisticsProcessor EpochStartTrigger integrationTests.TestEpochStartTrigger + BlockChainHandler data.ChainHandler GenesisHeader *HeaderInfo CoreComponents factory2.CoreComponentsHolder AllPubKeys [][]byte @@ -111,9 +114,80 @@ func NewTestMetaProcessor( EpochStartTrigger: epochStartTrigger, CoreComponents: coreComponents, AllPubKeys: pubKeys, + BlockChainHandler: dataComponents.Blockchain(), } } +func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { + hdr := block.MetaBlock{ + Epoch: epoch, + Nonce: round, + Round: round, + PrevHash: prevHash, + Signature: []byte("signature"), + PubKeysBitmap: []byte("pubKeysBitmap"), + RootHash: []byte("roothash"), + ShardInfo: make([]block.ShardData, 0), + TxCount: 1, + PrevRandSeed: []byte("roothash"), + RandSeed: []byte("roothash" + strconv.Itoa(int(round))), + AccumulatedFeesInEpoch: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + DevFeesInEpoch: big.NewInt(0), + DeveloperFees: big.NewInt(0), + } + + shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) + shardMiniBlockHeader := block.MiniBlockHeader{ + Hash: []byte("mb_hash" + strconv.Itoa(int(round))), + ReceiverShardID: 0, + SenderShardID: 0, + TxCount: 1, + } + shardMiniBlockHeaders = append(shardMiniBlockHeaders, shardMiniBlockHeader) + shardData := block.ShardData{ + Nonce: round, + ShardID: 0, + HeaderHash: []byte("hdr_hash" + strconv.Itoa(int(round))), + TxCount: 1, + ShardMiniBlockHeaders: shardMiniBlockHeaders, + DeveloperFees: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + } + hdr.ShardInfo = append(hdr.ShardInfo, shardData) + + return &hdr +} + +func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint32) { + for r := fromRound; r < numOfRounds; r++ { + currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() + currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() + if currentHeader == nil { + currentHeader = tmp.GenesisHeader.Header + currentHash = tmp.GenesisHeader.Hash + } + + prevRandomness := currentHeader.GetRandSeed() + fmt.Println(fmt.Sprintf("########################################### CREATEING HEADER FOR EPOCH %v in round %v", + tmp.EpochStartTrigger.Epoch(), + r, + )) + + newHdr := createMetaBlockHeader2(tmp.EpochStartTrigger.Epoch(), uint64(r), currentHash) + newHdr.PrevRandSeed = prevRandomness + _, _ = tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) + + newHdr2, newBodyHandler2, err := tmp.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) + require.Nil(t, err) + err = tmp.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) + require.Nil(t, err) + + tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch(), 4) + } + +} + func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder) integrationTests.TestEpochStartTrigger { argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ GenesisTime: time.Now(), @@ -371,7 +445,6 @@ func createMockComponentHolders(numOfShards uint32) ( } blockChain, _ := blockchain.NewMetaChain(statusHandler.NewStatusMetrics()) - //_ = blockChain.SetCurrentBlockHeaderAndRootHash(createGenesisMetaBlock(), []byte("roothash")) genesisBlock := createGenesisMetaBlock() genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) From 53a59e04bf263f6949a614230189fbf44b535800 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 5 Apr 2022 15:08:52 +0300 Subject: [PATCH 170/958] FIX: Sub bug, add safeSub --- epochStart/metachain/systemSCs.go | 13 +++++-- integrationTests/vm/staking/stakingV4_test.go | 6 +++- .../vm/staking/testMetaProcessor.go | 34 ++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index d733fd7ab81..a394071d091 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -150,13 +150,13 @@ func (s *systemSCProcessor) processWithNewFlags( func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) - availableSlots := s.maxNodes - numOfValidators - if availableSlots <= 0 { + availableSlots, err := safeSub(s.maxNodes, numOfValidators) + if err != nil { log.Info("not enough available slots for auction nodes; skip selecting nodes from auction list") return nil } - err := s.sortAuctionList(auctionList, randomness) + err = s.sortAuctionList(auctionList, randomness) if err != nil { return err } @@ -177,6 +177,13 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S return nil } +func safeSub(a, b uint32) (uint32, error) { + if a < b { + return 0, core.ErrSubtractionOverflow + } + return a - b, nil +} + func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, uint32) { auctionList := make([]state.ValidatorInfoHandler, 0) numOfValidators := uint32(0) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 54a7f194b1a..a03d3fe2aaa 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -2,13 +2,17 @@ package staking import ( "testing" + + logger "github.com/ElrondNetwork/elrond-go-logger" ) func TestNewTestMetaProcessor(t *testing.T) { node := NewTestMetaProcessor(3, 3, 3, 2, 2) node.DisplayNodesConfig(0, 4) + //logger.SetLogLevel("*:DEBUG,process:TRACE") + logger.SetLogLevel("*:DEBUG") node.EpochStartTrigger.SetRoundsPerEpoch(4) - node.Process(t, 1, 7) + node.Process(t, 1, 27) } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index ff43695eae0..4e54d6f409b 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -66,7 +66,8 @@ import ( "github.com/stretchr/testify/require" ) -const stakingV4EnableEpoch = 1 +const stakingV4InitEpoch = 1 +const stakingV4EnableEpoch = 2 type HeaderInfo struct { Hash []byte @@ -174,6 +175,12 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 r, )) + fmt.Println("#######################DISPLAYING VALIDAOTRS BEFOOOOOOOOOOOOREEEEEEE ") + rootHash, _ := tmp.ValidatorStatistics.RootHash() + allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + require.Nil(t, err) + displayValidatorsInfo(allValidatorsInfo, rootHash) + newHdr := createMetaBlockHeader2(tmp.EpochStartTrigger.Epoch(), uint64(r), currentHash) newHdr.PrevRandSeed = prevRandomness _, _ = tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) @@ -184,10 +191,23 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 require.Nil(t, err) tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch(), 4) + + fmt.Println("#######################DISPLAYING VALIDAOTRS AFTEEEEEEEEEEEEEEEEER ") + rootHash, _ = tmp.ValidatorStatistics.RootHash() + allValidatorsInfo, err = tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + require.Nil(t, err) + displayValidatorsInfo(allValidatorsInfo, rootHash) } } +func displayValidatorsInfo(validatorsInfoMap state.ShardValidatorsInfoMapHandler, rootHash []byte) { + fmt.Println("#######################DISPLAYING VALIDAOTRS INFO for root hash ") + for _, validators := range validatorsInfoMap.GetAllValidatorsInfo() { + fmt.Println("PUBKEY: ", string(validators.GetPublicKey()), " SHARDID: ", validators.GetShardId(), " LIST: ", validators.GetList()) + } +} + func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder) integrationTests.TestEpochStartTrigger { argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ GenesisTime: time.Now(), @@ -313,7 +333,7 @@ func createNodesCoordinator( } for idx, pubKey := range allPubKeys { - registerValidatorKeys(stateComponents.AccountsAdapter(), []byte(string(pubKey)+strconv.Itoa(idx)), []byte(string(pubKey)+strconv.Itoa(idx)), [][]byte{pubKey}, big.NewInt(20000), coreComponents.InternalMarshalizer()) + registerValidatorKeys(stateComponents.AccountsAdapter(), []byte(string(pubKey)+strconv.Itoa(idx)), []byte(string(pubKey)+strconv.Itoa(idx)), [][]byte{pubKey}, big.NewInt(2000), coreComponents.InternalMarshalizer()) } rootHash, _ := stateComponents.PeerAccounts().RootHash() @@ -748,7 +768,7 @@ func createFullArgumentsForSystemSCProcessing( DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, StakeLimitsEnableEpoch: 10, - StakingV4InitEnableEpoch: 444, + StakingV4InitEnableEpoch: stakingV4InitEpoch, StakingV4EnableEpoch: stakingV4EnableEpoch, }, }, @@ -761,6 +781,11 @@ func createFullArgumentsForSystemSCProcessing( systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") + maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) + for i := 0; i < 444; i++ { + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 18}) + } + args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, UserAccountsDB: stateComponents.AccountsAdapter(), @@ -781,10 +806,11 @@ func createFullArgumentsForSystemSCProcessing( EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: 0, ESDTEnableEpoch: 1000000, - StakingV4InitEnableEpoch: 444, + StakingV4InitEnableEpoch: stakingV4InitEpoch, StakingV4EnableEpoch: stakingV4EnableEpoch, }, }, + MaxNodesEnableConfig: maxNodesConfig, } return args, blockChainHookImpl, vCreator, metaVmFactory From 65d9a690ac35b0b121c8bf48da47c6a085c2ceb9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 7 Apr 2022 08:08:37 +0300 Subject: [PATCH 171/958] FIX: Waiting list + stubs --- integrationTests/vm/staking/stakingV4_test.go | 8 +- .../vm/staking/testMetaProcessor.go | 282 ++++++++++++++++-- 2 files changed, 267 insertions(+), 23 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index a03d3fe2aaa..961caf60334 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -2,17 +2,15 @@ package staking import ( "testing" - - logger "github.com/ElrondNetwork/elrond-go-logger" ) func TestNewTestMetaProcessor(t *testing.T) { - node := NewTestMetaProcessor(3, 3, 3, 2, 2) + node := NewTestMetaProcessor(3, 3, 3, 2, 2, 10, t) node.DisplayNodesConfig(0, 4) //logger.SetLogLevel("*:DEBUG,process:TRACE") - logger.SetLogLevel("*:DEBUG") + //logger.SetLogLevel("*:DEBUG") node.EpochStartTrigger.SetRoundsPerEpoch(4) - node.Process(t, 1, 27) + node.Process(t, 1, 56) } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 4e54d6f409b..e6e218b61da 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -95,10 +95,49 @@ func NewTestMetaProcessor( numOfNodesPerShard int, shardConsensusGroupSize int, metaConsensusGroupSize int, + numOfNodesInStakingQueue int, + t *testing.T, ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, genesisHeader := createMockComponentHolders(uint32(numOfShards)) epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents) + /* + stakingScAcc := loadSCAccount(stateComponents.AccountsAdapter(), vm.StakingSCAddress) + _ = createWaitingNodes(t, numOfNodesInStakingQueue, stakingScAcc, stateComponents.AccountsAdapter(), coreComponents.InternalMarshalizer()) + + err := stateComponents.AccountsAdapter().SaveAccount(stakingScAcc) + require.Nil(t, err) + _, err = stateComponents.AccountsAdapter().Commit() + require.Nil(t, err) + */ + + owner := generateUniqueKey(50) + var ownerWaitingNodes [][]byte + for i := 51; i < 51+numOfNodesInStakingQueue; i++ { + ownerWaitingNodes = append(ownerWaitingNodes, generateUniqueKey(i)) + } + + saveOneKeyToWaitingList(stateComponents.AccountsAdapter(), + ownerWaitingNodes[0], + coreComponents.InternalMarshalizer(), + owner, + owner) + addValidatorData(stateComponents.AccountsAdapter(), + owner, + [][]byte{ownerWaitingNodes[0]}, + big.NewInt(10000000000), + coreComponents.InternalMarshalizer()) + + _, _ = stateComponents.PeerAccounts().Commit() + + addKeysToWaitingList(stateComponents.AccountsAdapter(), + ownerWaitingNodes[1:], + coreComponents.InternalMarshalizer(), + owner, owner) + addValidatorData(stateComponents.AccountsAdapter(), owner, ownerWaitingNodes[1:], big.NewInt(500000), coreComponents.InternalMarshalizer()) + + _, _ = stateComponents.AccountsAdapter().Commit() + nc, pubKeys := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents) scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) @@ -119,6 +158,70 @@ func NewTestMetaProcessor( } } +func createWaitingNodes(t *testing.T, numNodes int, stakingSCAcc state.UserAccountHandler, userAccounts state.AccountsAdapter, marshalizer marshal.Marshalizer) []*state.ValidatorInfo { + validatorInfos := make([]*state.ValidatorInfo, 0) + waitingKeyInList := []byte("waiting") + id := 40 // TODO: UGLY ; KEYS LENGTH TAKE CARE + id2 := 70 + for i := 0; i < numNodes; i++ { + id++ + id2++ + addValidatorData(userAccounts, generateUniqueKey(id), [][]byte{generateUniqueKey(id)}, big.NewInt(3333), marshalizer) + + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: generateUniqueKey(id), + OwnerAddress: generateUniqueKey(id), + StakeValue: big.NewInt(3333), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + err := stakingSCAcc.DataTrieTracker().SaveKeyValue(generateUniqueKey(id), marshaledData) + require.Nil(t, err) + previousKey := string(waitingKeyInList) + waitingKeyInList = append([]byte("w_"), generateUniqueKey(id)...) + waitingListHead := &systemSmartContracts.WaitingList{ + FirstKey: append([]byte("w_"), generateUniqueKey(40)...), + LastKey: append([]byte("w_"), generateUniqueKey(40+numNodes)...), + Length: uint32(numNodes), + } + marshaledData, _ = marshalizer.Marshal(waitingListHead) + err = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) + require.Nil(t, err) + waitingListElement := &systemSmartContracts.ElementInList{ + BLSPublicKey: append([]byte("w_"), generateUniqueKey(id)...), + PreviousKey: waitingKeyInList, + NextKey: append([]byte("w_"), generateUniqueKey(id+1)...), + } + if i == numNodes-1 { + waitingListElement.NextKey = make([]byte, 0) + } + if i > 0 { + waitingListElement.PreviousKey = []byte(previousKey) + } + + marshaledData, err = marshalizer.Marshal(waitingListElement) + require.Nil(t, err) + err = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) + require.Nil(t, err) + + vInfo := &state.ValidatorInfo{ + PublicKey: generateUniqueKey(id), + ShardId: 0, + List: string(common.WaitingList), + TempRating: 1, + RewardAddress: generateUniqueKey(id), + AccumulatedFees: big.NewInt(0), + } + + validatorInfos = append(validatorInfos, vInfo) + } + + err := userAccounts.SaveAccount(stakingSCAcc) + require.Nil(t, err) + + return validatorInfos +} + func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { hdr := block.MetaBlock{ Epoch: epoch, @@ -161,7 +264,7 @@ func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block. } func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint32) { - for r := fromRound; r < numOfRounds; r++ { + for r := fromRound; r < fromRound+numOfRounds; r++ { currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() if currentHeader == nil { @@ -175,26 +278,29 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 r, )) - fmt.Println("#######################DISPLAYING VALIDAOTRS BEFOOOOOOOOOOOOREEEEEEE ") - rootHash, _ := tmp.ValidatorStatistics.RootHash() - allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - require.Nil(t, err) - displayValidatorsInfo(allValidatorsInfo, rootHash) + //fmt.Println("#######################DISPLAYING VALIDAOTRS BEFOOOOOOOOOOOOREEEEEEE ") + //rootHash, _ := tmp.ValidatorStatistics.RootHash() + //allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + //require.Nil(t, err) + //displayValidatorsInfo(allValidatorsInfo, rootHash) newHdr := createMetaBlockHeader2(tmp.EpochStartTrigger.Epoch(), uint64(r), currentHash) newHdr.PrevRandSeed = prevRandomness - _, _ = tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) + createdHdr, _ := tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) + newHdr.SetEpoch(createdHdr.GetEpoch()) newHdr2, newBodyHandler2, err := tmp.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) require.Nil(t, err) err = tmp.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) require.Nil(t, err) + time.Sleep(time.Millisecond * 1000) + tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch(), 4) fmt.Println("#######################DISPLAYING VALIDAOTRS AFTEEEEEEEEEEEEEEEEER ") - rootHash, _ = tmp.ValidatorStatistics.RootHash() - allValidatorsInfo, err = tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + rootHash, _ := tmp.ValidatorStatistics.RootHash() + allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) require.Nil(t, err) displayValidatorsInfo(allValidatorsInfo, rootHash) } @@ -283,7 +389,7 @@ func createSystemSCProcessor( } func generateUniqueKey(identifier int) []byte { - neededLength := 12 //192 + neededLength := 15 //192 uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", neededLength-len(uniqueIdentifier)) + uniqueIdentifier) } @@ -344,13 +450,18 @@ func createNodesCoordinator( //peerAcc.SetTempRating(5) //stateComponents.PeerAccounts().SaveAccount(peerAcc) + maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) + for i := 0; i < 444; i++ { + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) + } + shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ NodesShard: uint32(numOfNodesPerShard), NodesMeta: uint32(numOfMetaNodes), Hysteresis: hysteresis, Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, + MaxNodesEnableConfig: maxNodesConfig, WaitingListFixEnableEpoch: 0, BalanceWaitingListsEnableEpoch: 0, StakingV4EnableEpoch: stakingV4EnableEpoch, @@ -482,12 +593,17 @@ func createMockComponentHolders(numOfShards uint32) ( BlockChain: blockChain, } shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) + + //cacheHeaderVersion:= + //headerVersionHandler, _ := block2.NewHeaderVersionHandler(nil,nil, testscommon.NewCacherMock()) + //metaHeaderFactory, _ := block2.NewMetaHeaderFactory() + boostrapComponents := &mainFactoryMocks.BootstrapComponentsStub{ ShCoordinator: shardCoordinator, HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{ CreateCalled: func(epoch uint32) data.HeaderHandler { - return &block.MetaBlock{} + return &block.MetaBlock{Epoch: epoch} }, }, } @@ -742,7 +858,7 @@ func createFullArgumentsForSystemSCProcessing( NumRoundsWithoutBleed: 1, MaximumPercentageToBleed: 1, BleedPercentagePerRound: 1, - MaxNumberOfNodesForStake: 5, + MaxNumberOfNodesForStake: 24, // TODO HERE ADD MAX NUM NODES ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", StakeLimitPercentage: 100.0, @@ -783,7 +899,7 @@ func createFullArgumentsForSystemSCProcessing( maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) for i := 0; i < 444; i++ { - maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 18}) + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) } args := metachain.ArgsNewEpochStartSystemSCProcessing{ @@ -804,10 +920,11 @@ func createFullArgumentsForSystemSCProcessing( ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 0, - ESDTEnableEpoch: 1000000, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV2EnableEpoch: 0, + ESDTEnableEpoch: 1000000, + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, + MaxNodesChangeEnableEpoch: maxNodesConfig, }, }, MaxNodesEnableConfig: maxNodesConfig, @@ -955,3 +1072,132 @@ func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserA return stakingSCAcc } + +func prepareStakingContractWithData( + accountsDB state.AccountsAdapter, + stakedKey []byte, + waitingKey []byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + addStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) + saveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) + addValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) + + _, _ = accountsDB.Commit() + +} + +func saveOneKeyToWaitingList( + accountsDB state.AccountsAdapter, + waitingKey []byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) + + waitingKeyInList := []byte("w_" + string(waitingKey)) + waitingListHead := &systemSmartContracts.WaitingList{ + FirstKey: waitingKeyInList, + LastKey: waitingKeyInList, + Length: 1, + } + marshaledData, _ = marshalizer.Marshal(waitingListHead) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) + + waitingListElement := &systemSmartContracts.ElementInList{ + BLSPublicKey: waitingKey, + PreviousKey: waitingKeyInList, + NextKey: make([]byte, 0), + } + marshaledData, _ = marshalizer.Marshal(waitingListElement) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) + + _ = accountsDB.SaveAccount(stakingSCAcc) +} + +func addKeysToWaitingList( + accountsDB state.AccountsAdapter, + waitingKeys [][]byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + + for _, waitingKey := range waitingKeys { + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) + } + + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + waitingListHead := &systemSmartContracts.WaitingList{} + _ = marshalizer.Unmarshal(waitingListHead, marshaledData) + + waitingListAlreadyHasElements := waitingListHead.Length > 0 + waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey + + waitingListHead.Length += uint32(len(waitingKeys)) + lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) + waitingListHead.LastKey = lastKeyInList + + marshaledData, _ = marshalizer.Marshal(waitingListHead) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) + + numWaitingKeys := len(waitingKeys) + previousKey := waitingListHead.LastKey + for i, waitingKey := range waitingKeys { + + waitingKeyInList := []byte("w_" + string(waitingKey)) + waitingListElement := &systemSmartContracts.ElementInList{ + BLSPublicKey: waitingKey, + PreviousKey: previousKey, + NextKey: make([]byte, 0), + } + + if i < numWaitingKeys-1 { + nextKey := []byte("w_" + string(waitingKeys[i+1])) + waitingListElement.NextKey = nextKey + } + + marshaledData, _ = marshalizer.Marshal(waitingListElement) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) + + previousKey = waitingKeyInList + } + + if waitingListAlreadyHasElements { + marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) + } else { + marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) + } + + waitingListElement := &systemSmartContracts.ElementInList{} + _ = marshalizer.Unmarshal(waitingListElement, marshaledData) + waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) + marshaledData, _ = marshalizer.Marshal(waitingListElement) + + if waitingListAlreadyHasElements { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) + } else { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) + } + + _ = accountsDB.SaveAccount(stakingSCAcc) +} From 23407f889831925d6224586b7b54e80d87f22b32 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 7 Apr 2022 11:35:12 +0300 Subject: [PATCH 172/958] FIX: Refactor 1 --- .../vm/staking/componentsHolderCreator.go | 108 ++++++++++ .../vm/staking/testMetaProcessor.go | 202 +----------------- 2 files changed, 117 insertions(+), 193 deletions(-) create mode 100644 integrationTests/vm/staking/componentsHolderCreator.go diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go new file mode 100644 index 00000000000..a351a28abbe --- /dev/null +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -0,0 +1,108 @@ +package staking + +import ( + "time" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/data/typeConverters/uint64ByteSlice" + "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" + "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" + "github.com/ElrondNetwork/elrond-go/epochStart/notifier" + factory2 "github.com/ElrondNetwork/elrond-go/factory" + "github.com/ElrondNetwork/elrond-go/integrationTests" + mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + factory3 "github.com/ElrondNetwork/elrond-go/node/mock/factory" + "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/state/factory" + "github.com/ElrondNetwork/elrond-go/statusHandler" + "github.com/ElrondNetwork/elrond-go/testscommon" + dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" + "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" + "github.com/ElrondNetwork/elrond-go/trie" +) + +func createComponentHolders(numOfShards uint32) ( + factory2.CoreComponentsHolder, + factory2.DataComponentsHolder, + factory2.BootstrapComponentsHolder, + factory2.StatusComponentsHolder, + factory2.StateComponentsHandler, +) { + coreComponents := createCoreComponents() + statusComponents := createStatusComponents() + dataComponents := createDataComponents(coreComponents) + stateComponents := createStateComponents(coreComponents) + boostrapComponents := createBootstrapComponents(numOfShards) + + return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents +} + +func createCoreComponents() factory2.CoreComponentsHolder { + return &mock2.CoreComponentsStub{ + InternalMarshalizerField: &testscommon.MarshalizerMock{}, + HasherField: sha256.NewSha256(), + Uint64ByteSliceConverterField: uint64ByteSlice.NewBigEndianConverter(), + StatusHandlerField: statusHandler.NewStatusMetrics(), + RoundHandlerField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, + EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), + EpochNotifierField: forking.NewGenericEpochNotifier(), + RaterField: &testscommon.RaterMock{Chance: 5}, + AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, + EconomicsDataField: createEconomicsData(), + } +} + +func createDataComponents(coreComponents factory2.CoreComponentsHolder) factory2.DataComponentsHolder { + blockChain, _ := blockchain.NewMetaChain(coreComponents.StatusHandler()) + genesisBlock := createGenesisMetaBlock() + genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) + genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) + _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) + blockChain.SetGenesisHeaderHash(genesisBlockHash) + + chainStorer := dataRetriever.NewChainStorer() + chainStorer.AddStorer(dataRetriever.BootstrapUnit, integrationTests.CreateMemUnit()) + chainStorer.AddStorer(dataRetriever.MetaHdrNonceHashDataUnit, integrationTests.CreateMemUnit()) + chainStorer.AddStorer(dataRetriever.MetaBlockUnit, integrationTests.CreateMemUnit()) + return &factory3.DataComponentsMock{ + Store: chainStorer, + DataPool: dataRetrieverMock.NewPoolsHolderMock(), + BlockChain: blockChain, + EconomicsData: createEconomicsData(), + } +} + +func createBootstrapComponents(numOfShards uint32) factory2.BootstrapComponentsHolder { + shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) + + return &mainFactoryMocks.BootstrapComponentsStub{ + ShCoordinator: shardCoordinator, + HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, + VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{ + CreateCalled: func(epoch uint32) data.HeaderHandler { + return &block.MetaBlock{Epoch: epoch} + }, + }, + } +} + +func createStateComponents(coreComponents factory2.CoreComponentsHolder) factory2.StateComponentsHandler { + trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) + userAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewAccountCreator(), trieFactoryManager) + peerAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewPeerAccountCreator(), trieFactoryManager) + return &testscommon.StateComponentsMock{ + PeersAcc: peerAccountsDB, + Accounts: userAccountsDB, + } +} + +func createStatusComponents() factory2.StatusComponentsHolder { + return &mock2.StatusComponentsStub{ + Outport: &testscommon.OutportStub{}, + } +} diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index e6e218b61da..553bae12703 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -17,22 +17,17 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/endProcess" "github.com/ElrondNetwork/elrond-go-core/hashing" - "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" - "github.com/ElrondNetwork/elrond-go/epochStart/notifier" factory2 "github.com/ElrondNetwork/elrond-go/factory" mock4 "github.com/ElrondNetwork/elrond-go/factory/mock" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/integrationTests" mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" - factory3 "github.com/ElrondNetwork/elrond-go/node/mock/factory" "github.com/ElrondNetwork/elrond-go/process" blproc "github.com/ElrondNetwork/elrond-go/process/block" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" @@ -47,17 +42,13 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/state/factory" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" - "github.com/ElrondNetwork/elrond-go/statusHandler" "github.com/ElrondNetwork/elrond-go/storage/lrucache" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" - dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" - "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" @@ -83,7 +74,6 @@ type TestMetaProcessor struct { ValidatorStatistics process.ValidatorStatisticsProcessor EpochStartTrigger integrationTests.TestEpochStartTrigger BlockChainHandler data.ChainHandler - GenesisHeader *HeaderInfo CoreComponents factory2.CoreComponentsHolder AllPubKeys [][]byte } @@ -98,19 +88,9 @@ func NewTestMetaProcessor( numOfNodesInStakingQueue int, t *testing.T, ) *TestMetaProcessor { - coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, genesisHeader := createMockComponentHolders(uint32(numOfShards)) + coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(uint32(numOfShards)) epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents) - /* - stakingScAcc := loadSCAccount(stateComponents.AccountsAdapter(), vm.StakingSCAddress) - _ = createWaitingNodes(t, numOfNodesInStakingQueue, stakingScAcc, stateComponents.AccountsAdapter(), coreComponents.InternalMarshalizer()) - - err := stateComponents.AccountsAdapter().SaveAccount(stakingScAcc) - require.Nil(t, err) - _, err = stateComponents.AccountsAdapter().Commit() - require.Nil(t, err) - */ - owner := generateUniqueKey(50) var ownerWaitingNodes [][]byte for i := 51; i < 51+numOfNodesInStakingQueue; i++ { @@ -122,11 +102,6 @@ func NewTestMetaProcessor( coreComponents.InternalMarshalizer(), owner, owner) - addValidatorData(stateComponents.AccountsAdapter(), - owner, - [][]byte{ownerWaitingNodes[0]}, - big.NewInt(10000000000), - coreComponents.InternalMarshalizer()) _, _ = stateComponents.PeerAccounts().Commit() @@ -134,7 +109,7 @@ func NewTestMetaProcessor( ownerWaitingNodes[1:], coreComponents.InternalMarshalizer(), owner, owner) - addValidatorData(stateComponents.AccountsAdapter(), owner, ownerWaitingNodes[1:], big.NewInt(500000), coreComponents.InternalMarshalizer()) + addValidatorData(stateComponents.AccountsAdapter(), owner, ownerWaitingNodes, big.NewInt(500000), coreComponents.InternalMarshalizer()) _, _ = stateComponents.AccountsAdapter().Commit() @@ -150,7 +125,6 @@ func NewTestMetaProcessor( NodesCoordinator: nc, BlockChain: dataComponents.Blockchain(), ValidatorStatistics: validatorsInfoCreator, - GenesisHeader: genesisHeader, EpochStartTrigger: epochStartTrigger, CoreComponents: coreComponents, AllPubKeys: pubKeys, @@ -158,70 +132,6 @@ func NewTestMetaProcessor( } } -func createWaitingNodes(t *testing.T, numNodes int, stakingSCAcc state.UserAccountHandler, userAccounts state.AccountsAdapter, marshalizer marshal.Marshalizer) []*state.ValidatorInfo { - validatorInfos := make([]*state.ValidatorInfo, 0) - waitingKeyInList := []byte("waiting") - id := 40 // TODO: UGLY ; KEYS LENGTH TAKE CARE - id2 := 70 - for i := 0; i < numNodes; i++ { - id++ - id2++ - addValidatorData(userAccounts, generateUniqueKey(id), [][]byte{generateUniqueKey(id)}, big.NewInt(3333), marshalizer) - - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: generateUniqueKey(id), - OwnerAddress: generateUniqueKey(id), - StakeValue: big.NewInt(3333), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - err := stakingSCAcc.DataTrieTracker().SaveKeyValue(generateUniqueKey(id), marshaledData) - require.Nil(t, err) - previousKey := string(waitingKeyInList) - waitingKeyInList = append([]byte("w_"), generateUniqueKey(id)...) - waitingListHead := &systemSmartContracts.WaitingList{ - FirstKey: append([]byte("w_"), generateUniqueKey(40)...), - LastKey: append([]byte("w_"), generateUniqueKey(40+numNodes)...), - Length: uint32(numNodes), - } - marshaledData, _ = marshalizer.Marshal(waitingListHead) - err = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - require.Nil(t, err) - waitingListElement := &systemSmartContracts.ElementInList{ - BLSPublicKey: append([]byte("w_"), generateUniqueKey(id)...), - PreviousKey: waitingKeyInList, - NextKey: append([]byte("w_"), generateUniqueKey(id+1)...), - } - if i == numNodes-1 { - waitingListElement.NextKey = make([]byte, 0) - } - if i > 0 { - waitingListElement.PreviousKey = []byte(previousKey) - } - - marshaledData, err = marshalizer.Marshal(waitingListElement) - require.Nil(t, err) - err = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - require.Nil(t, err) - - vInfo := &state.ValidatorInfo{ - PublicKey: generateUniqueKey(id), - ShardId: 0, - List: string(common.WaitingList), - TempRating: 1, - RewardAddress: generateUniqueKey(id), - AccumulatedFees: big.NewInt(0), - } - - validatorInfos = append(validatorInfos, vInfo) - } - - err := userAccounts.SaveAccount(stakingSCAcc) - require.Nil(t, err) - - return validatorInfos -} - func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { hdr := block.MetaBlock{ Epoch: epoch, @@ -268,8 +178,8 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() if currentHeader == nil { - currentHeader = tmp.GenesisHeader.Header - currentHash = tmp.GenesisHeader.Hash + currentHeader = tmp.BlockChain.GetGenesisHeader() + currentHash = tmp.BlockChain.GetGenesisHeaderHash() } prevRandomness := currentHeader.GetRandSeed() @@ -278,12 +188,6 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 r, )) - //fmt.Println("#######################DISPLAYING VALIDAOTRS BEFOOOOOOOOOOOOREEEEEEE ") - //rootHash, _ := tmp.ValidatorStatistics.RootHash() - //allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - //require.Nil(t, err) - //displayValidatorsInfo(allValidatorsInfo, rootHash) - newHdr := createMetaBlockHeader2(tmp.EpochStartTrigger.Epoch(), uint64(r), currentHash) newHdr.PrevRandSeed = prevRandomness createdHdr, _ := tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) @@ -360,12 +264,9 @@ func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32, numOfShards int) // shuffler constants const ( - shuffleBetweenShards = false - adaptivity = false - hysteresis = float32(0.2) - maxTrieLevelInMemory = uint(5) - delegationManagementKey = "delegationManagement" - delegationContractsList = "delegationContracts" + shuffleBetweenShards = false + adaptivity = false + hysteresis = float32(0.2) ) // TODO: Pass epoch config @@ -442,14 +343,6 @@ func createNodesCoordinator( registerValidatorKeys(stateComponents.AccountsAdapter(), []byte(string(pubKey)+strconv.Itoa(idx)), []byte(string(pubKey)+strconv.Itoa(idx)), [][]byte{pubKey}, big.NewInt(2000), coreComponents.InternalMarshalizer()) } - rootHash, _ := stateComponents.PeerAccounts().RootHash() - fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) - - //acc,_ = stateComponents.PeerAccounts().LoadAccount(waitingMap[0][0].PubKeyBytes()) - //peerAcc = acc.(state.PeerAccountHandler) - //peerAcc.SetTempRating(5) - //stateComponents.PeerAccounts().SaveAccount(peerAcc) - maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) for i := 0; i < 444; i++ { maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) @@ -539,7 +432,7 @@ func createMetaBlockProcessor( coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder, bootstrapComponents factory2.BootstrapComponentsHolder, - statusComponents *mock.StatusComponentsMock, + statusComponents factory2.StatusComponentsHolder, stateComponents factory2.StateComponentsHandler, validatorsInfoCreator process.ValidatorStatisticsProcessor, blockChainHook process.BlockChainHookHandler, @@ -552,88 +445,11 @@ func createMetaBlockProcessor( return metaProc } -func createMockComponentHolders(numOfShards uint32) ( - factory2.CoreComponentsHolder, - factory2.DataComponentsHolder, - factory2.BootstrapComponentsHolder, - *mock.StatusComponentsMock, - factory2.StateComponentsHandler, - *HeaderInfo, -) { - //hasher := sha256.NewSha256() - //marshalizer := &marshal.GogoProtoMarshalizer{} - coreComponents := &mock2.CoreComponentsStub{ - InternalMarshalizerField: &mock.MarshalizerMock{}, - HasherField: sha256.NewSha256(), - Uint64ByteSliceConverterField: &mock.Uint64ByteSliceConverterMock{}, - StatusHandlerField: &statusHandlerMock.AppStatusHandlerStub{}, - RoundHandlerField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, - EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), - EpochNotifierField: forking.NewGenericEpochNotifier(), - RaterField: &testscommon.RaterMock{Chance: 5}, //mock.GetNewMockRater(), - AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, - EconomicsDataField: createEconomicsData(), - } - - blockChain, _ := blockchain.NewMetaChain(statusHandler.NewStatusMetrics()) - genesisBlock := createGenesisMetaBlock() - genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) - genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) - _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) - blockChain.SetGenesisHeaderHash(genesisBlockHash) - fmt.Println("GENESIS BLOCK HASH: " + hex.EncodeToString(genesisBlockHash)) - - chainStorer := dataRetriever.NewChainStorer() - chainStorer.AddStorer(dataRetriever.BootstrapUnit, integrationTests.CreateMemUnit()) - chainStorer.AddStorer(dataRetriever.MetaHdrNonceHashDataUnit, integrationTests.CreateMemUnit()) - chainStorer.AddStorer(dataRetriever.MetaBlockUnit, integrationTests.CreateMemUnit()) - dataComponents := &factory3.DataComponentsMock{ //&mock.DataComponentsMock{ - Store: chainStorer, - DataPool: dataRetrieverMock.NewPoolsHolderMock(), - BlockChain: blockChain, - } - shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) - - //cacheHeaderVersion:= - //headerVersionHandler, _ := block2.NewHeaderVersionHandler(nil,nil, testscommon.NewCacherMock()) - //metaHeaderFactory, _ := block2.NewMetaHeaderFactory() - - boostrapComponents := &mainFactoryMocks.BootstrapComponentsStub{ - ShCoordinator: shardCoordinator, - HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, - VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{ - CreateCalled: func(epoch uint32) data.HeaderHandler { - return &block.MetaBlock{Epoch: epoch} - }, - }, - } - - statusComponents := &mock.StatusComponentsMock{ - Outport: &testscommon.OutportStub{}, - } - - trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) - userAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewAccountCreator(), trieFactoryManager) - peerAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewPeerAccountCreator(), trieFactoryManager) - stateComponents := &testscommon.StateComponentsMock{ - PeersAcc: peerAccountsDB, - Accounts: userAccountsDB, - AccountsAPI: nil, - Tries: nil, - StorageManagers: nil, - } - - return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents, &HeaderInfo{ - Hash: genesisBlockHash, - Header: genesisBlock, - } -} - func createMockMetaArguments( coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder, bootstrapComponents factory2.BootstrapComponentsHolder, - statusComponents *mock.StatusComponentsMock, + statusComponents factory2.StatusComponentsHolder, nodesCoord nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor, stateComponents factory2.StateComponentsHandler, From 28b4285657e20a9e3c80861130b44086b0c472de Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 7 Apr 2022 14:19:15 +0300 Subject: [PATCH 173/958] FIX: Refactor 2 --- factory/blockProcessorCreator.go | 12 +- integrationTests/testProcessorNode.go | 4 +- .../vm/staking/componentsHolderCreator.go | 25 +- .../vm/staking/metaBlockProcessorCreator.go | 154 ++++++++++ .../vm/staking/testMetaProcessor.go | 283 +++++------------- integrationTests/vm/testInitializer.go | 10 +- process/block/postprocess/feeHandler.go | 13 +- process/block/postprocess/feeHandler_test.go | 15 +- 8 files changed, 276 insertions(+), 240 deletions(-) create mode 100644 integrationTests/vm/staking/metaBlockProcessorCreator.go diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index d632bf8264e..61abeebc35a 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -195,11 +195,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( return nil, err } - txFeeHandler, err := postprocess.NewFeeAccumulator() - if err != nil { - return nil, err - } - + txFeeHandler := postprocess.NewFeeAccumulator() enableEpochs := pcf.epochConfig.EnableEpochs argsNewScProcessor := smartContract.ArgsNewSmartContractProcessor{ @@ -508,11 +504,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } - txFeeHandler, err := postprocess.NewFeeAccumulator() - if err != nil { - return nil, err - } - + txFeeHandler := postprocess.NewFeeAccumulator() enableEpochs := pcf.epochConfig.EnableEpochs argsNewScProcessor := smartContract.ArgsNewSmartContractProcessor{ VmContainer: vmContainer, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 8fc9ad1d026..a0b5bba7238 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1492,7 +1492,7 @@ func (tpn *TestProcessorNode) initInnerProcessors(gasMap map[string]map[string]u mockVM.GasForOperation = OpGasValueForMockVm _ = tpn.VMContainer.Add(procFactory.InternalTestingVM, mockVM) - tpn.FeeAccumulator, _ = postprocess.NewFeeAccumulator() + tpn.FeeAccumulator = postprocess.NewFeeAccumulator() tpn.ArgsParser = smartContract.NewArgumentParser() argsTxTypeHandler := coordinator.ArgNewTxTypeHandler{ @@ -1748,7 +1748,7 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors() { tpn.SystemSCFactory = vmFactory.SystemSmartContractContainerFactory() tpn.addMockVm(tpn.BlockchainHook) - tpn.FeeAccumulator, _ = postprocess.NewFeeAccumulator() + tpn.FeeAccumulator = postprocess.NewFeeAccumulator() tpn.ArgsParser = smartContract.NewArgumentParser() esdtTransferParser, _ := parsers.NewESDTTransferParser(TestMarshalizer) argsTxTypeHandler := coordinator.ArgNewTxTypeHandler{ diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index a351a28abbe..33c6a33bde2 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -6,6 +6,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/data/endProcess" "github.com/ElrondNetwork/elrond-go-core/data/typeConverters/uint64ByteSlice" "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go/common/forking" @@ -18,11 +19,13 @@ import ( factory3 "github.com/ElrondNetwork/elrond-go/node/mock/factory" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state/factory" "github.com/ElrondNetwork/elrond-go/statusHandler" "github.com/ElrondNetwork/elrond-go/testscommon" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" + statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" ) @@ -35,9 +38,9 @@ func createComponentHolders(numOfShards uint32) ( ) { coreComponents := createCoreComponents() statusComponents := createStatusComponents() - dataComponents := createDataComponents(coreComponents) stateComponents := createStateComponents(coreComponents) - boostrapComponents := createBootstrapComponents(numOfShards) + dataComponents := createDataComponents(coreComponents, numOfShards) + boostrapComponents := createBootstrapComponents(coreComponents, numOfShards) return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents } @@ -54,10 +57,11 @@ func createCoreComponents() factory2.CoreComponentsHolder { RaterField: &testscommon.RaterMock{Chance: 5}, AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, EconomicsDataField: createEconomicsData(), + ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), } } -func createDataComponents(coreComponents factory2.CoreComponentsHolder) factory2.DataComponentsHolder { +func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfShards uint32) factory2.DataComponentsHolder { blockChain, _ := blockchain.NewMetaChain(coreComponents.StatusHandler()) genesisBlock := createGenesisMetaBlock() genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) @@ -69,16 +73,23 @@ func createDataComponents(coreComponents factory2.CoreComponentsHolder) factory2 chainStorer.AddStorer(dataRetriever.BootstrapUnit, integrationTests.CreateMemUnit()) chainStorer.AddStorer(dataRetriever.MetaHdrNonceHashDataUnit, integrationTests.CreateMemUnit()) chainStorer.AddStorer(dataRetriever.MetaBlockUnit, integrationTests.CreateMemUnit()) + chainStorer.AddStorer(dataRetriever.MiniBlockUnit, integrationTests.CreateMemUnit()) + chainStorer.AddStorer(dataRetriever.BlockHeaderUnit, integrationTests.CreateMemUnit()) + for i := uint32(0); i < numOfShards; i++ { + chainStorer.AddStorer(dataRetriever.ShardHdrNonceHashDataUnit+dataRetriever.UnitType(i), integrationTests.CreateMemUnit()) + } + return &factory3.DataComponentsMock{ Store: chainStorer, DataPool: dataRetrieverMock.NewPoolsHolderMock(), BlockChain: blockChain, - EconomicsData: createEconomicsData(), + EconomicsData: coreComponents.EconomicsData(), } } -func createBootstrapComponents(numOfShards uint32) factory2.BootstrapComponentsHolder { +func createBootstrapComponents(coreComponents factory2.CoreComponentsHolder, numOfShards uint32) factory2.BootstrapComponentsHolder { shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) + ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(coreComponents.InternalMarshalizer(), coreComponents.EpochNotifier(), stakingV4EnableEpoch) return &mainFactoryMocks.BootstrapComponentsStub{ ShCoordinator: shardCoordinator, @@ -88,6 +99,7 @@ func createBootstrapComponents(numOfShards uint32) factory2.BootstrapComponentsH return &block.MetaBlock{Epoch: epoch} }, }, + NodesCoordinatorRegistryFactoryField: ncrf, } } @@ -103,6 +115,7 @@ func createStateComponents(coreComponents factory2.CoreComponentsHolder) factory func createStatusComponents() factory2.StatusComponentsHolder { return &mock2.StatusComponentsStub{ - Outport: &testscommon.OutportStub{}, + Outport: &testscommon.OutportStub{}, + AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, } } diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go new file mode 100644 index 00000000000..cce662801bc --- /dev/null +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -0,0 +1,154 @@ +package staking + +import ( + "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/epochStart/metachain" + factory2 "github.com/ElrondNetwork/elrond-go/factory" + mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + "github.com/ElrondNetwork/elrond-go/process" + blproc "github.com/ElrondNetwork/elrond-go/process/block" + "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" + "github.com/ElrondNetwork/elrond-go/process/block/postprocess" + "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" +) + +func createMetaBlockProcessor( + nc nodesCoordinator.NodesCoordinator, + systemSCProcessor process.EpochStartSystemSCProcessor, + coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, + bootstrapComponents factory2.BootstrapComponentsHolder, + statusComponents factory2.StatusComponentsHolder, + stateComponents factory2.StateComponentsHandler, + validatorsInfoCreator process.ValidatorStatisticsProcessor, + blockChainHook process.BlockChainHookHandler, + metaVMFactory process.VirtualMachinesContainerFactory, + epochStartHandler process.EpochStartTriggerHandler, +) process.BlockProcessor { + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartHandler) + + metaProc, _ := blproc.NewMetaProcessor(arguments) + return metaProc +} + +func createMockMetaArguments( + coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, + bootstrapComponents factory2.BootstrapComponentsHolder, + statusComponents factory2.StatusComponentsHolder, + nodesCoord nodesCoordinator.NodesCoordinator, + systemSCProcessor process.EpochStartSystemSCProcessor, + stateComponents factory2.StateComponentsHandler, + validatorsInfoCreator process.ValidatorStatisticsProcessor, + blockChainHook process.BlockChainHookHandler, + metaVMFactory process.VirtualMachinesContainerFactory, + epochStartHandler process.EpochStartTriggerHandler, +) blproc.ArgMetaProcessor { + shardCoordiantor := bootstrapComponents.ShardCoordinator() + valInfoCreator := createValidatorInfoCreator(coreComponents, dataComponents, shardCoordiantor) + blockTracker := createBlockTracker(shardCoordiantor) + epochStartDataCreator := createEpochStartDataCreator(coreComponents, dataComponents, shardCoordiantor, epochStartHandler, blockTracker) + + accountsDb := make(map[state.AccountsDbIdentifier]state.AccountsAdapter) + accountsDb[state.UserAccountsState] = stateComponents.AccountsAdapter() + accountsDb[state.PeerAccountsState] = stateComponents.PeerAccounts() + + bootStorer, _ := bootstrapStorage.NewBootstrapStorer(coreComponents.InternalMarshalizer(), dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit)) + headerValidator := createHeaderValidator(coreComponents) + vmContainer, _ := metaVMFactory.Create() + return blproc.ArgMetaProcessor{ + ArgBaseProcessor: blproc.ArgBaseProcessor{ + CoreComponents: coreComponents, + DataComponents: dataComponents, + BootstrapComponents: bootstrapComponents, + StatusComponents: statusComponents, + AccountsDB: accountsDb, + ForkDetector: &mock2.ForkDetectorStub{}, + NodesCoordinator: nodesCoord, + FeeHandler: postprocess.NewFeeAccumulator(), + RequestHandler: &testscommon.RequestHandlerStub{}, + BlockChainHook: blockChainHook, + TxCoordinator: &mock.TransactionCoordinatorMock{}, + EpochStartTrigger: epochStartHandler, + HeaderValidator: headerValidator, + GasHandler: &mock.GasHandlerMock{}, + BootStorer: bootStorer, + BlockTracker: blockTracker, + BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, + HistoryRepository: &dblookupext.HistoryRepositoryStub{}, + EpochNotifier: coreComponents.EpochNotifier(), + RoundNotifier: &mock.RoundNotifierStub{}, + ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, + ScheduledMiniBlocksEnableEpoch: 10000, + VMContainersFactory: metaVMFactory, + VmContainer: vmContainer, + }, + SCToProtocol: &mock.SCToProtocolStub{}, + PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, + EpochStartDataCreator: epochStartDataCreator, + EpochEconomics: &mock.EpochEconomicsStub{}, + EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, + EpochValidatorInfoCreator: valInfoCreator, + ValidatorStatisticsProcessor: validatorsInfoCreator, + EpochSystemSCProcessor: systemSCProcessor, + } +} + +func createValidatorInfoCreator( + coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, + shardCoordinator sharding.Coordinator, +) process.EpochStartValidatorInfoCreator { + args := metachain.ArgsNewValidatorInfoCreator{ + ShardCoordinator: shardCoordinator, + MiniBlockStorage: dataComponents.StorageService().GetStorer(dataRetriever.MiniBlockUnit), + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + DataPool: dataComponents.Datapool(), + } + + valInfoCreator, _ := metachain.NewValidatorInfoCreator(args) + return valInfoCreator +} + +func createEpochStartDataCreator( + coreComponents factory2.CoreComponentsHolder, + dataComponents factory2.DataComponentsHolder, + shardCoordinator sharding.Coordinator, + epochStartTrigger process.EpochStartTriggerHandler, + blockTracker process.BlockTracker, +) process.EpochStartDataCreator { + argsEpochStartDataCreator := metachain.ArgsNewEpochStartData{ + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + Store: dataComponents.StorageService(), + DataPool: dataComponents.Datapool(), + BlockTracker: blockTracker, + ShardCoordinator: shardCoordinator, + EpochStartTrigger: epochStartTrigger, + RequestHandler: &testscommon.RequestHandlerStub{}, + GenesisEpoch: 0, + } + epochStartDataCreator, _ := metachain.NewEpochStartData(argsEpochStartDataCreator) + return epochStartDataCreator +} + +func createBlockTracker(shardCoordinator sharding.Coordinator) process.BlockTracker { + startHeaders := createGenesisBlocks(shardCoordinator) + return mock.NewBlockTrackerMock(shardCoordinator, startHeaders) +} + +func createHeaderValidator(coreComponents factory2.CoreComponentsHolder) epochStart.HeaderValidator { + argsHeaderValidator := blproc.ArgsHeaderValidator{ + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + } + headerValidator, _ := blproc.NewHeaderValidator(argsHeaderValidator) + return headerValidator +} diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 553bae12703..71dd9c2dc28 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -2,7 +2,6 @@ package staking import ( "bytes" - "encoding/hex" "fmt" "math/big" "strconv" @@ -15,7 +14,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/nodetype" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/endProcess" "github.com/ElrondNetwork/elrond-go-core/hashing" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" @@ -24,14 +22,10 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart/metachain" mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" factory2 "github.com/ElrondNetwork/elrond-go/factory" - mock4 "github.com/ElrondNetwork/elrond-go/factory/mock" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/integrationTests" mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" "github.com/ElrondNetwork/elrond-go/process" - blproc "github.com/ElrondNetwork/elrond-go/process/block" - "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" - "github.com/ElrondNetwork/elrond-go/process/block/postprocess" economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" @@ -47,9 +41,7 @@ import ( "github.com/ElrondNetwork/elrond-go/storage/lrucache" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" - "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" - statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" @@ -68,32 +60,49 @@ type HeaderInfo struct { // TestMetaProcessor - type TestMetaProcessor struct { MetaBlockProcessor process.BlockProcessor - SystemSCProcessor process.EpochStartSystemSCProcessor NodesCoordinator nodesCoordinator.NodesCoordinator BlockChain data.ChainHandler ValidatorStatistics process.ValidatorStatisticsProcessor EpochStartTrigger integrationTests.TestEpochStartTrigger BlockChainHandler data.ChainHandler - CoreComponents factory2.CoreComponentsHolder - AllPubKeys [][]byte } // NewTestMetaProcessor - func NewTestMetaProcessor( - numOfMetaNodes int, - numOfShards int, - numOfNodesPerShard int, + numOfMetaNodes uint32, + numOfShards uint32, + numOfNodesPerShard uint32, shardConsensusGroupSize int, metaConsensusGroupSize int, - numOfNodesInStakingQueue int, + numOfNodesInStakingQueue uint32, t *testing.T, ) *TestMetaProcessor { - coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(uint32(numOfShards)) - epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents) + coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(numOfShards) + epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) + createStakingQueue(numOfNodesInStakingQueue, coreComponents, stateComponents) + + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents, bootstrapComponents.NodesCoordinatorRegistryFactory()) + scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) + + return &TestMetaProcessor{ + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartTrigger), + NodesCoordinator: nc, + BlockChain: dataComponents.Blockchain(), + ValidatorStatistics: validatorsInfoCreator, + EpochStartTrigger: epochStartTrigger, + BlockChainHandler: dataComponents.Blockchain(), + } +} + +func createStakingQueue( + numOfNodesInStakingQueue uint32, + coreComponents factory2.CoreComponentsHolder, + stateComponents factory2.StateComponentsHolder, +) { owner := generateUniqueKey(50) var ownerWaitingNodes [][]byte - for i := 51; i < 51+numOfNodesInStakingQueue; i++ { + for i := uint32(51); i < 51+numOfNodesInStakingQueue; i++ { ownerWaitingNodes = append(ownerWaitingNodes, generateUniqueKey(i)) } @@ -112,24 +121,6 @@ func NewTestMetaProcessor( addValidatorData(stateComponents.AccountsAdapter(), owner, ownerWaitingNodes, big.NewInt(500000), coreComponents.InternalMarshalizer()) _, _ = stateComponents.AccountsAdapter().Commit() - - nc, pubKeys := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents) - scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) - - rootHash, _ := stateComponents.PeerAccounts().RootHash() - fmt.Println("ROOT HASh FOR PEER ACCOUNTS " + hex.EncodeToString(rootHash)) - - return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartTrigger), - SystemSCProcessor: scp, - NodesCoordinator: nc, - BlockChain: dataComponents.Blockchain(), - ValidatorStatistics: validatorsInfoCreator, - EpochStartTrigger: epochStartTrigger, - CoreComponents: coreComponents, - AllPubKeys: pubKeys, - BlockChainHandler: dataComponents.Blockchain(), - } } func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { @@ -198,7 +189,7 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 err = tmp.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) require.Nil(t, err) - time.Sleep(time.Millisecond * 1000) + time.Sleep(time.Millisecond * 100) tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch(), 4) @@ -218,24 +209,24 @@ func displayValidatorsInfo(validatorsInfoMap state.ShardValidatorsInfoMapHandler } } -func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder) integrationTests.TestEpochStartTrigger { +func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, storageService dataRetriever.StorageService) integrationTests.TestEpochStartTrigger { argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ GenesisTime: time.Now(), Settings: &config.EpochStartConfig{ - MinRoundsBetweenEpochs: 100, - RoundsPerEpoch: 100, + MinRoundsBetweenEpochs: 10, + RoundsPerEpoch: 10, }, Epoch: 0, EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - Storage: dataComponents.StorageService(), + Storage: storageService, Marshalizer: coreComponents.InternalMarshalizer(), Hasher: coreComponents.Hasher(), - AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, + AppStatusHandler: coreComponents.StatusHandler(), } epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) - ret := &metachain.TestTrigger{} - ret.SetTrigger(epochStartTrigger) - return ret + testTrigger := &metachain.TestTrigger{} + testTrigger.SetTrigger(epochStartTrigger) + return testTrigger } func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32, numOfShards int) { @@ -267,6 +258,7 @@ const ( shuffleBetweenShards = false adaptivity = false hysteresis = float32(0.2) + initialRating = 5 ) // TODO: Pass epoch config @@ -279,7 +271,6 @@ func createSystemSCProcessor( dataComponents factory2.DataComponentsHolder, ) (process.EpochStartSystemSCProcessor, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { args, blockChainHook, validatorsInfOCreator, metaVMFactory := createFullArgumentsForSystemSCProcessing(nc, - 0, // 1000 coreComponents, stateComponents, bootstrapComponents, @@ -289,7 +280,7 @@ func createSystemSCProcessor( return s, blockChainHook, validatorsInfOCreator, metaVMFactory } -func generateUniqueKey(identifier int) []byte { +func generateUniqueKey(identifier uint32) []byte { neededLength := 15 //192 uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", neededLength-len(uniqueIdentifier)) + uniqueIdentifier) @@ -297,15 +288,16 @@ func generateUniqueKey(identifier int) []byte { // TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator func createNodesCoordinator( - numOfMetaNodes int, - numOfShards int, - numOfNodesPerShard int, + numOfMetaNodes uint32, + numOfShards uint32, + numOfNodesPerShard uint32, shardConsensusGroupSize int, metaConsensusGroupSize int, coreComponents factory2.CoreComponentsHolder, dataComponents factory2.DataComponentsHolder, stateComponents factory2.StateComponentsHandler, -) (nodesCoordinator.NodesCoordinator, [][]byte) { + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, +) nodesCoordinator.NodesCoordinator { validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) @@ -315,27 +307,27 @@ func createNodesCoordinator( // TODO: HERE SAVE ALL ACCOUNTS var allPubKeys [][]byte - for shardID, vals := range validatorsMap { + for shardID, vals := range validatorsMapForNodesCoordinator { for _, val := range vals { - peerAccount, _ := state.NewPeerAccount(val.PubKeyBytes()) - peerAccount.SetTempRating(5) + peerAccount, _ := state.NewPeerAccount(val.PubKey()) + peerAccount.SetTempRating(initialRating) peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = val.PubKeyBytes() + peerAccount.BLSPublicKey = val.PubKey() peerAccount.List = string(common.EligibleList) stateComponents.PeerAccounts().SaveAccount(peerAccount) - allPubKeys = append(allPubKeys, val.PubKeyBytes()) + allPubKeys = append(allPubKeys, val.PubKey()) } } - for shardID, vals := range waitingMap { + for shardID, vals := range waitingMapForNodesCoordinator { for _, val := range vals { - peerAccount, _ := state.NewPeerAccount(val.PubKeyBytes()) - peerAccount.SetTempRating(5) + peerAccount, _ := state.NewPeerAccount(val.PubKey()) + peerAccount.SetTempRating(initialRating) peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = val.PubKeyBytes() + peerAccount.BLSPublicKey = val.PubKey() peerAccount.List = string(common.WaitingList) stateComponents.PeerAccounts().SaveAccount(peerAccount) - allPubKeys = append(allPubKeys, val.PubKeyBytes()) + allPubKeys = append(allPubKeys, val.PubKey()) } } @@ -344,13 +336,11 @@ func createNodesCoordinator( } maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) - for i := 0; i < 444; i++ { - maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) - } + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: uint32(numOfNodesPerShard), - NodesMeta: uint32(numOfMetaNodes), + NodesShard: numOfNodesPerShard, + NodesMeta: numOfMetaNodes, Hysteresis: hysteresis, Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, @@ -362,27 +352,25 @@ func createNodesCoordinator( nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) cache, _ := lrucache.NewCache(10000) - ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(coreComponents.InternalMarshalizer(), coreComponents.EpochNotifier(), stakingV4EnableEpoch) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, MetaConsensusGroupSize: metaConsensusGroupSize, Marshalizer: coreComponents.InternalMarshalizer(), Hasher: coreComponents.Hasher(), ShardIDAsObserver: core.MetachainShardId, - NbShards: uint32(numOfShards), + NbShards: numOfShards, EligibleNodes: validatorsMapForNodesCoordinator, WaitingNodes: waitingMapForNodesCoordinator, SelfPublicKey: validatorsMap[core.MetachainShardId][0].PubKeyBytes(), ConsensusGroupCache: cache, ShuffledOutHandler: &mock2.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), + ChanStopNode: coreComponents.ChanStopNodeProcess(), IsFullArchive: false, Shuffler: nodeShuffler, BootStorer: dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), StakingV4EnableEpoch: stakingV4EnableEpoch, - NodesCoordinatorRegistryFactory: ncrf, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, NodeTypeProvider: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), } @@ -396,29 +384,29 @@ func createNodesCoordinator( fmt.Println("error creating node coordinator") } - return nodesCoord, allPubKeys + return nodesCoord } func generateGenesisNodeInfoMap( - numOfMetaNodes int, - numOfShards int, - numOfNodesPerShard int, - startIdx int, + numOfMetaNodes uint32, + numOfShards uint32, + numOfNodesPerShard uint32, + startIdx uint32, ) map[uint32][]nodesCoordinator.GenesisNodeInfoHandler { validatorsMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) id := startIdx - for shardId := 0; shardId < numOfShards; shardId++ { - for n := 0; n < numOfNodesPerShard; n++ { - addr := generateUniqueKey(id) //[]byte("addr" + strconv.Itoa(id)) - validator := mock2.NewNodeInfo(addr, addr, uint32(shardId), 5) - validatorsMap[uint32(shardId)] = append(validatorsMap[uint32(shardId)], validator) + for shardId := uint32(0); shardId < numOfShards; shardId++ { + for n := uint32(0); n < numOfNodesPerShard; n++ { + addr := generateUniqueKey(id) + validator := mock2.NewNodeInfo(addr, addr, shardId, initialRating) + validatorsMap[shardId] = append(validatorsMap[shardId], validator) id++ } } - for n := 0; n < numOfMetaNodes; n++ { + for n := uint32(0); n < numOfMetaNodes; n++ { addr := generateUniqueKey(id) - validator := mock2.NewNodeInfo(addr, addr, uint32(core.MetachainShardId), 5) + validator := mock2.NewNodeInfo(addr, addr, core.MetachainShardId, initialRating) validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) id++ } @@ -426,115 +414,6 @@ func generateGenesisNodeInfoMap( return validatorsMap } -func createMetaBlockProcessor( - nc nodesCoordinator.NodesCoordinator, - systemSCProcessor process.EpochStartSystemSCProcessor, - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, - bootstrapComponents factory2.BootstrapComponentsHolder, - statusComponents factory2.StatusComponentsHolder, - stateComponents factory2.StateComponentsHandler, - validatorsInfoCreator process.ValidatorStatisticsProcessor, - blockChainHook process.BlockChainHookHandler, - metaVMFactory process.VirtualMachinesContainerFactory, - epochStartHandler process.EpochStartTriggerHandler, -) process.BlockProcessor { - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartHandler) - - metaProc, _ := blproc.NewMetaProcessor(arguments) - return metaProc -} - -func createMockMetaArguments( - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, - bootstrapComponents factory2.BootstrapComponentsHolder, - statusComponents factory2.StatusComponentsHolder, - nodesCoord nodesCoordinator.NodesCoordinator, - systemSCProcessor process.EpochStartSystemSCProcessor, - stateComponents factory2.StateComponentsHandler, - validatorsInfoCreator process.ValidatorStatisticsProcessor, - blockChainHook process.BlockChainHookHandler, - metaVMFactory process.VirtualMachinesContainerFactory, - epochStartHandler process.EpochStartTriggerHandler, -) blproc.ArgMetaProcessor { - argsHeaderValidator := blproc.ArgsHeaderValidator{ - Hasher: coreComponents.Hasher(), - Marshalizer: coreComponents.InternalMarshalizer(), - } - headerValidator, _ := blproc.NewHeaderValidator(argsHeaderValidator) - - startHeaders := createGenesisBlocks(bootstrapComponents.ShardCoordinator()) - accountsDb := make(map[state.AccountsDbIdentifier]state.AccountsAdapter) - accountsDb[state.UserAccountsState] = stateComponents.AccountsAdapter() - accountsDb[state.PeerAccountsState] = stateComponents.PeerAccounts() - - bootStrapStorer, _ := bootstrapStorage.NewBootstrapStorer(coreComponents.InternalMarshalizer(), integrationTests.CreateMemUnit()) - valInfoCreator, _ := metachain.NewValidatorInfoCreator(metachain.ArgsNewValidatorInfoCreator{ - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - MiniBlockStorage: integrationTests.CreateMemUnit(), - Hasher: coreComponents.Hasher(), - Marshalizer: coreComponents.InternalMarshalizer(), - DataPool: dataComponents.Datapool(), - }) - - feeHandler, _ := postprocess.NewFeeAccumulator() - - vmContainer, _ := metaVMFactory.Create() - blockTracker := mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders) - - argsEpochStartDataCreator := metachain.ArgsNewEpochStartData{ - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - Store: dataComponents.StorageService(), - DataPool: dataComponents.Datapool(), - BlockTracker: blockTracker, - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - EpochStartTrigger: epochStartHandler, - RequestHandler: &testscommon.RequestHandlerStub{}, - GenesisEpoch: 0, - } - epochStartDataCreator, _ := metachain.NewEpochStartData(argsEpochStartDataCreator) - - arguments := blproc.ArgMetaProcessor{ - ArgBaseProcessor: blproc.ArgBaseProcessor{ - CoreComponents: coreComponents, - DataComponents: dataComponents, - BootstrapComponents: bootstrapComponents, - StatusComponents: statusComponents, - AccountsDB: accountsDb, - ForkDetector: &mock4.ForkDetectorStub{}, - NodesCoordinator: nodesCoord, - FeeHandler: feeHandler, - RequestHandler: &testscommon.RequestHandlerStub{}, - BlockChainHook: blockChainHook, - TxCoordinator: &mock.TransactionCoordinatorMock{}, - EpochStartTrigger: epochStartHandler, - HeaderValidator: headerValidator, - GasHandler: &mock.GasHandlerMock{}, - BootStorer: bootStrapStorer, - BlockTracker: blockTracker, - BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, - HistoryRepository: &dblookupext.HistoryRepositoryStub{}, - EpochNotifier: coreComponents.EpochNotifier(), - RoundNotifier: &mock.RoundNotifierStub{}, - ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, - ScheduledMiniBlocksEnableEpoch: 10000, - VMContainersFactory: metaVMFactory, - VmContainer: vmContainer, - }, - SCToProtocol: &mock.SCToProtocolStub{}, - PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, - EpochStartDataCreator: epochStartDataCreator, - EpochEconomics: &mock.EpochEconomicsStub{}, - EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, - EpochValidatorInfoCreator: valInfoCreator, - ValidatorStatisticsProcessor: validatorsInfoCreator, - EpochSystemSCProcessor: systemSCProcessor, - } - return arguments -} - func createGenesisBlocks(shardCoordinator sharding.Coordinator) map[uint32]data.HeaderHandler { genesisBlocks := make(map[uint32]data.HeaderHandler) for ShardID := uint32(0); ShardID < shardCoordinator.NumberOfShards(); ShardID++ { @@ -583,12 +462,12 @@ func createGenesisMetaBlock() *block.MetaBlock { func createFullArgumentsForSystemSCProcessing( nc nodesCoordinator.NodesCoordinator, - stakingV2EnableEpoch uint32, coreComponents factory2.CoreComponentsHolder, stateComponents factory2.StateComponentsHandler, bootstrapComponents factory2.BootstrapComponentsHolder, dataComponents factory2.DataComponentsHolder, ) (metachain.ArgsNewEpochStartSystemSCProcessing, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { + nodesSetup := &mock.NodesSetupStub{} argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ Marshalizer: coreComponents.InternalMarshalizer(), NodesCoordinator: nc, @@ -599,14 +478,14 @@ func createFullArgumentsForSystemSCProcessing( PeerAdapter: stateComponents.PeerAccounts(), Rater: coreComponents.Rater(), RewardsHandler: &mock3.RewardsHandlerStub{}, - NodesSetup: &mock.NodesSetupStub{}, + NodesSetup: nodesSetup, MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, EpochNotifier: coreComponents.EpochNotifier(), - StakingV2EnableEpoch: stakingV2EnableEpoch, + StakingV2EnableEpoch: 0, StakingV4EnableEpoch: stakingV4EnableEpoch, } - vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) + validatorStatisticsProcessor, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) gasSchedule := arwenConfig.MakeGasMapForTests() gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) @@ -638,13 +517,11 @@ func createFullArgumentsForSystemSCProcessing( defaults.FillGasMapInternal(gasSchedule, 1) signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) - nodesSetup := &mock.NodesSetupStub{} - blockChainHookImpl, _ := hooks.NewBlockChainHookImpl(argsHook) argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ BlockChainHook: blockChainHookImpl, PubkeyConv: argsHook.PubkeyConv, - Economics: createEconomicsData(), + Economics: coreComponents.EconomicsData(), MessageSignVerifier: signVerifer, GasSchedule: gasScheduleNotifier, NodesConfigProvider: nodesSetup, @@ -695,7 +572,7 @@ func createFullArgumentsForSystemSCProcessing( EpochNotifier: coreComponents.EpochNotifier(), EpochConfig: &config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: stakingV2EnableEpoch, + StakingV2EnableEpoch: 0, StakeEnableEpoch: 0, DelegationManagerEnableEpoch: 0, DelegationSmartContractEnableEpoch: 0, @@ -723,8 +600,8 @@ func createFullArgumentsForSystemSCProcessing( UserAccountsDB: stateComponents.AccountsAdapter(), PeerAccountsDB: stateComponents.PeerAccounts(), Marshalizer: coreComponents.InternalMarshalizer(), - StartRating: 5, - ValidatorInfoCreator: vCreator, + StartRating: initialRating, + ValidatorInfoCreator: validatorStatisticsProcessor, EndOfEpochCallerAddress: vm.EndOfEpochAddress, StakingSCAddress: vm.StakingSCAddress, ChanceComputer: &mock3.ChanceComputerStub{}, @@ -746,7 +623,7 @@ func createFullArgumentsForSystemSCProcessing( MaxNodesEnableConfig: maxNodesConfig, } - return args, blockChainHookImpl, vCreator, metaVmFactory + return args, blockChainHookImpl, validatorStatisticsProcessor, metaVmFactory } func createAccountsDB( diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 69024da7244..4b9a9197cea 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -1023,7 +1023,7 @@ func CreatePreparedTxProcessorAndAccountsWithVMs( senderBalance *big.Int, enableEpochs config.EnableEpochs, ) (*VMTestContext, error) { - feeAccumulator, _ := postprocess.NewFeeAccumulator() + feeAccumulator := postprocess.NewFeeAccumulator() accounts := CreateInMemoryShardAccountsDB() _, _ = CreateAccount(accounts, senderAddressBytes, senderNonce, senderBalance) vmConfig := createDefaultVMConfig() @@ -1072,7 +1072,7 @@ func CreatePreparedTxProcessorWithVMs(enableEpochs config.EnableEpochs) (*VMTest // CreatePreparedTxProcessorWithVMsWithShardCoordinator - func CreatePreparedTxProcessorWithVMsWithShardCoordinator(enableEpochs config.EnableEpochs, shardCoordinator sharding.Coordinator) (*VMTestContext, error) { - feeAccumulator, _ := postprocess.NewFeeAccumulator() + feeAccumulator := postprocess.NewFeeAccumulator() accounts := CreateInMemoryShardAccountsDB() vmConfig := createDefaultVMConfig() arwenChangeLocker := &sync.RWMutex{} @@ -1130,7 +1130,7 @@ func CreateTxProcessorArwenVMWithGasSchedule( gasScheduleMap map[string]map[string]uint64, enableEpochs config.EnableEpochs, ) (*VMTestContext, error) { - feeAccumulator, _ := postprocess.NewFeeAccumulator() + feeAccumulator := postprocess.NewFeeAccumulator() accounts := CreateInMemoryShardAccountsDB() _, _ = CreateAccount(accounts, senderAddressBytes, senderNonce, senderBalance) vmConfig := createDefaultVMConfig() @@ -1180,7 +1180,7 @@ func CreateTxProcessorArwenWithVMConfig( vmConfig *config.VirtualMachineConfig, gasSchedule map[string]map[string]uint64, ) (*VMTestContext, error) { - feeAccumulator, _ := postprocess.NewFeeAccumulator() + feeAccumulator := postprocess.NewFeeAccumulator() accounts := CreateInMemoryShardAccountsDB() arwenChangeLocker := &sync.RWMutex{} gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) @@ -1489,7 +1489,7 @@ func GetNodeIndex(nodeList []*integrationTests.TestProcessorNode, node *integrat func CreatePreparedTxProcessorWithVMsMultiShard(selfShardID uint32, enableEpochs config.EnableEpochs) (*VMTestContext, error) { shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, selfShardID) - feeAccumulator, _ := postprocess.NewFeeAccumulator() + feeAccumulator := postprocess.NewFeeAccumulator() accounts := CreateInMemoryShardAccountsDB() arwenChangeLocker := &sync.RWMutex{} diff --git a/process/block/postprocess/feeHandler.go b/process/block/postprocess/feeHandler.go index 93753b47634..4993c5dabee 100644 --- a/process/block/postprocess/feeHandler.go +++ b/process/block/postprocess/feeHandler.go @@ -25,12 +25,13 @@ type feeHandler struct { } // NewFeeAccumulator constructor for the fee accumulator -func NewFeeAccumulator() (*feeHandler, error) { - f := &feeHandler{} - f.accumulatedFees = big.NewInt(0) - f.developerFees = big.NewInt(0) - f.mapHashFee = make(map[string]*feeData) - return f, nil +func NewFeeAccumulator() *feeHandler { + return &feeHandler{ + mut: sync.RWMutex{}, + mapHashFee: make(map[string]*feeData), + accumulatedFees: big.NewInt(0), + developerFees: big.NewInt(0), + } } // CreateBlockStarted does the cleanup before creating a new block diff --git a/process/block/postprocess/feeHandler_test.go b/process/block/postprocess/feeHandler_test.go index 1f86fde5bdb..e50baf8ec43 100644 --- a/process/block/postprocess/feeHandler_test.go +++ b/process/block/postprocess/feeHandler_test.go @@ -13,15 +13,14 @@ import ( func TestNewFeeAccumulator(t *testing.T) { t.Parallel() - feeHandler, err := postprocess.NewFeeAccumulator() - require.Nil(t, err) + feeHandler := postprocess.NewFeeAccumulator() require.NotNil(t, feeHandler) } func TestFeeHandler_CreateBlockStarted(t *testing.T) { t.Parallel() - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFee(big.NewInt(100), big.NewInt(50), []byte("txhash")) zeroGasAndFees := process.GetZeroGasAndFees() @@ -37,7 +36,7 @@ func TestFeeHandler_CreateBlockStarted(t *testing.T) { func TestFeeHandler_GetAccumulatedFees(t *testing.T) { t.Parallel() - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFee(big.NewInt(100), big.NewInt(50), []byte("txhash")) accumulatedFees := feeHandler.GetAccumulatedFees() @@ -47,7 +46,7 @@ func TestFeeHandler_GetAccumulatedFees(t *testing.T) { func TestFeeHandler_GetDeveloperFees(t *testing.T) { t.Parallel() - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFee(big.NewInt(100), big.NewInt(50), []byte("txhash")) devFees := feeHandler.GetDeveloperFees() @@ -57,7 +56,7 @@ func TestFeeHandler_GetDeveloperFees(t *testing.T) { func TestFeeHandler_ProcessTransactionFee(t *testing.T) { t.Parallel() - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFee(big.NewInt(1000), big.NewInt(100), []byte("txhash1")) feeHandler.ProcessTransactionFee(big.NewInt(100), big.NewInt(10), []byte("txhash2")) @@ -72,7 +71,7 @@ func TestFeeHandler_ProcessTransactionFee(t *testing.T) { func TestFeeHandler_RevertFees(t *testing.T) { t.Parallel() - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFee(big.NewInt(1000), big.NewInt(100), []byte("txhash1")) feeHandler.ProcessTransactionFee(big.NewInt(100), big.NewInt(10), []byte("txhash2")) @@ -89,6 +88,6 @@ func TestFeeHandler_RevertFees(t *testing.T) { func TestFeeHandler_IsInterfaceNil(t *testing.T) { t.Parallel() - fee, _ := postprocess.NewFeeAccumulator() + fee := postprocess.NewFeeAccumulator() require.False(t, check.IfNil(fee)) } From cda1ce319b2064a04c84804cb7e1b0e7e221031f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 7 Apr 2022 15:39:45 +0300 Subject: [PATCH 174/958] FIX: Refactor 3 --- .../vm/staking/componentsHolderCreator.go | 2 + .../vm/staking/systemSCCreator.go | 156 ++++++++++++++++++ .../vm/staking/testMetaProcessor.go | 121 +------------- process/smartContract/process_test.go | 6 +- 4 files changed, 167 insertions(+), 118 deletions(-) create mode 100644 integrationTests/vm/staking/systemSCCreator.go diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 33c6a33bde2..92ac392fc4e 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -4,6 +4,7 @@ import ( "time" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/nodetype" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/endProcess" @@ -58,6 +59,7 @@ func createCoreComponents() factory2.CoreComponentsHolder { AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, EconomicsDataField: createEconomicsData(), ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), + NodeTypeProviderField: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), } } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go new file mode 100644 index 00000000000..d8cd6b14f96 --- /dev/null +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -0,0 +1,156 @@ +package staking + +import ( + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go/config" + mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" + factory2 "github.com/ElrondNetwork/elrond-go/factory" + "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" + "github.com/ElrondNetwork/elrond-go/process" + metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" + "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/process/peer" + "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" +) + +func createValidatorStatisticsProcessor( + dataComponents factory2.DataComponentsHolder, + coreComponents factory2.CoreComponentsHolder, + nc nodesCoordinator.NodesCoordinator, + shardCoordinator sharding.Coordinator, + peerAccounts state.AccountsAdapter, +) process.ValidatorStatisticsProcessor { + argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ + Marshalizer: coreComponents.InternalMarshalizer(), + NodesCoordinator: nc, + ShardCoordinator: shardCoordinator, + DataPool: dataComponents.Datapool(), + StorageService: dataComponents.StorageService(), + PubkeyConv: coreComponents.AddressPubKeyConverter(), + PeerAdapter: peerAccounts, + Rater: coreComponents.Rater(), + RewardsHandler: &mock3.RewardsHandlerStub{}, + NodesSetup: &mock.NodesSetupStub{}, + MaxComputableRounds: 1, + MaxConsecutiveRoundsOfRatingDecrease: 2000, + EpochNotifier: coreComponents.EpochNotifier(), + StakingV2EnableEpoch: 0, + StakingV4EnableEpoch: stakingV4EnableEpoch, + } + validatorStatisticsProcessor, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) + return validatorStatisticsProcessor +} + +func createBlockChainHook( + dataComponents factory2.DataComponentsHolder, + coreComponents factory2.CoreComponentsHolder, + accountsAdapter state.AccountsAdapter, + shardCoordinator sharding.Coordinator, + builtInFunctionsContainer vmcommon.BuiltInFunctionContainer, +) process.BlockChainHookHandler { + argsHook := hooks.ArgBlockChainHook{ + Accounts: accountsAdapter, + PubkeyConv: coreComponents.AddressPubKeyConverter(), + StorageService: dataComponents.StorageService(), + BlockChain: dataComponents.Blockchain(), + ShardCoordinator: shardCoordinator, + Marshalizer: coreComponents.InternalMarshalizer(), + Uint64Converter: coreComponents.Uint64ByteSliceConverter(), + NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, + BuiltInFunctions: builtInFunctionsContainer, + DataPool: dataComponents.Datapool(), + CompiledSCPool: dataComponents.Datapool().SmartContracts(), + EpochNotifier: coreComponents.EpochNotifier(), + NilCompiledSCStore: true, + } + + blockChainHook, _ := hooks.NewBlockChainHookImpl(argsHook) + return blockChainHook +} + +func createVMContainerFactory( + coreComponents factory2.CoreComponentsHolder, + gasScheduleNotifier core.GasScheduleNotifier, + blockChainHook process.BlockChainHookHandler, + peerAccounts state.AccountsAdapter, + shardCoordinator sharding.Coordinator, + nc nodesCoordinator.NodesCoordinator, +) process.VirtualMachinesContainerFactory { + signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) + + argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ + BlockChainHook: blockChainHook, + PubkeyConv: coreComponents.AddressPubKeyConverter(), + Economics: coreComponents.EconomicsData(), + MessageSignVerifier: signVerifer, + GasSchedule: gasScheduleNotifier, + NodesConfigProvider: &mock.NodesSetupStub{}, + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + SystemSCConfig: &config.SystemSmartContractsConfig{ + ESDTSystemSCConfig: config.ESDTSystemSCConfig{ + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", + DelegationTicker: "DEL", + }, + GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ + Active: config.GovernanceSystemSCConfigActive{ + ProposalCost: "500", + MinQuorum: "50", + MinPassThreshold: "50", + MinVetoThreshold: "50", + }, + FirstWhitelistedAddress: "3132333435363738393031323334353637383930313233343536373839303234", + }, + StakingSystemSCConfig: config.StakingSystemSCConfig{ + GenesisNodePrice: "1000", + UnJailValue: "10", + MinStepValue: "10", + MinStakeValue: "1", + UnBondPeriod: 1, + NumRoundsWithoutBleed: 1, + MaximumPercentageToBleed: 1, + BleedPercentagePerRound: 1, + MaxNumberOfNodesForStake: 24, // TODO HERE ADD MAX NUM NODES + ActivateBLSPubKeyMessageVerification: false, + MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100.0, + NodeLimitPercentage: 100.0, + }, + DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ + MinCreationDeposit: "100", + MinStakeAmount: "100", + ConfigChangeAddress: "3132333435363738393031323334353637383930313233343536373839303234", + }, + DelegationSystemSCConfig: config.DelegationSystemSCConfig{ + MinServiceFee: 0, + MaxServiceFee: 100, + }, + }, + ValidatorAccountsDB: peerAccounts, + ChanceComputer: &mock3.ChanceComputerStub{}, + EpochNotifier: coreComponents.EpochNotifier(), + EpochConfig: &config.EpochConfig{ + EnableEpochs: config.EnableEpochs{ + StakingV2EnableEpoch: 0, + StakeEnableEpoch: 0, + DelegationManagerEnableEpoch: 0, + DelegationSmartContractEnableEpoch: 0, + StakeLimitsEnableEpoch: 10, + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, + }, + }, + ShardCoordinator: shardCoordinator, + NodesCoordinator: nc, + } + + metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) + return metaVmFactory +} diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 71dd9c2dc28..085bb60f072 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -11,7 +11,6 @@ import ( arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/core/nodetype" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/hashing" @@ -22,17 +21,13 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart/metachain" mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" factory2 "github.com/ElrondNetwork/elrond-go/factory" - "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/integrationTests" mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" "github.com/ElrondNetwork/elrond-go/process" economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" - metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/process/peer" "github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions" - "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" @@ -40,7 +35,6 @@ import ( "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" "github.com/ElrondNetwork/elrond-go/storage/lrucache" "github.com/ElrondNetwork/elrond-go/testscommon" - "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" @@ -61,7 +55,6 @@ type HeaderInfo struct { type TestMetaProcessor struct { MetaBlockProcessor process.BlockProcessor NodesCoordinator nodesCoordinator.NodesCoordinator - BlockChain data.ChainHandler ValidatorStatistics process.ValidatorStatisticsProcessor EpochStartTrigger integrationTests.TestEpochStartTrigger BlockChainHandler data.ChainHandler @@ -88,7 +81,6 @@ func NewTestMetaProcessor( return &TestMetaProcessor{ MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartTrigger), NodesCoordinator: nc, - BlockChain: dataComponents.Blockchain(), ValidatorStatistics: validatorsInfoCreator, EpochStartTrigger: epochStartTrigger, BlockChainHandler: dataComponents.Blockchain(), @@ -169,8 +161,8 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() if currentHeader == nil { - currentHeader = tmp.BlockChain.GetGenesisHeader() - currentHash = tmp.BlockChain.GetGenesisHeaderHash() + currentHeader = tmp.BlockChainHandler.GetGenesisHeader() + currentHash = tmp.BlockChainHandler.GetGenesisHeaderHash() } prevRandomness := currentHeader.GetRandSeed() @@ -371,7 +363,7 @@ func createNodesCoordinator( EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), StakingV4EnableEpoch: stakingV4EnableEpoch, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - NodeTypeProvider: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), + NodeTypeProvider: coreComponents.NodeTypeProvider(), } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -468,24 +460,8 @@ func createFullArgumentsForSystemSCProcessing( dataComponents factory2.DataComponentsHolder, ) (metachain.ArgsNewEpochStartSystemSCProcessing, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { nodesSetup := &mock.NodesSetupStub{} - argsValidatorsProcessor := peer.ArgValidatorStatisticsProcessor{ - Marshalizer: coreComponents.InternalMarshalizer(), - NodesCoordinator: nc, - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - DataPool: dataComponents.Datapool(), - StorageService: dataComponents.StorageService(), - PubkeyConv: coreComponents.AddressPubKeyConverter(), - PeerAdapter: stateComponents.PeerAccounts(), - Rater: coreComponents.Rater(), - RewardsHandler: &mock3.RewardsHandlerStub{}, - NodesSetup: nodesSetup, - MaxComputableRounds: 1, - MaxConsecutiveRoundsOfRatingDecrease: 2000, - EpochNotifier: coreComponents.EpochNotifier(), - StakingV2EnableEpoch: 0, - StakingV4EnableEpoch: stakingV4EnableEpoch, - } - validatorStatisticsProcessor, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) + + validatorStatisticsProcessor := createValidatorStatisticsProcessor(dataComponents, coreComponents, nc, bootstrapComponents.ShardCoordinator(), stateComponents.PeerAccounts()) gasSchedule := arwenConfig.MakeGasMapForTests() gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) @@ -499,93 +475,10 @@ func createFullArgumentsForSystemSCProcessing( } builtInFuncs, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) - argsHook := hooks.ArgBlockChainHook{ - Accounts: stateComponents.AccountsAdapter(), - PubkeyConv: coreComponents.AddressPubKeyConverter(), - StorageService: dataComponents.StorageService(), - BlockChain: dataComponents.Blockchain(), - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - Marshalizer: coreComponents.InternalMarshalizer(), - Uint64Converter: coreComponents.Uint64ByteSliceConverter(), - NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, - BuiltInFunctions: builtInFuncs, - DataPool: dataComponents.Datapool(), - CompiledSCPool: dataComponents.Datapool().SmartContracts(), - EpochNotifier: coreComponents.EpochNotifier(), - NilCompiledSCStore: true, - } - defaults.FillGasMapInternal(gasSchedule, 1) - signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) - blockChainHookImpl, _ := hooks.NewBlockChainHookImpl(argsHook) - argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ - BlockChainHook: blockChainHookImpl, - PubkeyConv: argsHook.PubkeyConv, - Economics: coreComponents.EconomicsData(), - MessageSignVerifier: signVerifer, - GasSchedule: gasScheduleNotifier, - NodesConfigProvider: nodesSetup, - Hasher: coreComponents.Hasher(), - Marshalizer: coreComponents.InternalMarshalizer(), - SystemSCConfig: &config.SystemSmartContractsConfig{ - ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", - }, - GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ - Active: config.GovernanceSystemSCConfigActive{ - ProposalCost: "500", - MinQuorum: "50", - MinPassThreshold: "50", - MinVetoThreshold: "50", - }, - FirstWhitelistedAddress: "3132333435363738393031323334353637383930313233343536373839303234", - }, - StakingSystemSCConfig: config.StakingSystemSCConfig{ - GenesisNodePrice: "1000", - UnJailValue: "10", - MinStepValue: "10", - MinStakeValue: "1", - UnBondPeriod: 1, - NumRoundsWithoutBleed: 1, - MaximumPercentageToBleed: 1, - BleedPercentagePerRound: 1, - MaxNumberOfNodesForStake: 24, // TODO HERE ADD MAX NUM NODES - ActivateBLSPubKeyMessageVerification: false, - MinUnstakeTokensValue: "1", - StakeLimitPercentage: 100.0, - NodeLimitPercentage: 100.0, - }, - DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ - MinCreationDeposit: "100", - MinStakeAmount: "100", - ConfigChangeAddress: "3132333435363738393031323334353637383930313233343536373839303234", - }, - DelegationSystemSCConfig: config.DelegationSystemSCConfig{ - MinServiceFee: 0, - MaxServiceFee: 100, - }, - }, - ValidatorAccountsDB: stateComponents.PeerAccounts(), - ChanceComputer: &mock3.ChanceComputerStub{}, - EpochNotifier: coreComponents.EpochNotifier(), - EpochConfig: &config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 0, - StakeEnableEpoch: 0, - DelegationManagerEnableEpoch: 0, - DelegationSmartContractEnableEpoch: 0, - StakeLimitsEnableEpoch: 10, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, - }, - }, - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - NodesCoordinator: nc, - } + blockChainHookImpl := createBlockChainHook(dataComponents, coreComponents, stateComponents.AccountsAdapter(), bootstrapComponents.ShardCoordinator(), builtInFuncs) - metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) + metaVmFactory := createVMContainerFactory(coreComponents, gasScheduleNotifier, blockChainHookImpl, stateComponents.PeerAccounts(), bootstrapComponents.ShardCoordinator(), nc) vmContainer, _ := metaVmFactory.Create() systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") diff --git a/process/smartContract/process_test.go b/process/smartContract/process_test.go index 46368d27f1d..1e2f000069f 100644 --- a/process/smartContract/process_test.go +++ b/process/smartContract/process_test.go @@ -3666,7 +3666,7 @@ func TestSmartContractProcessor_computeTotalConsumedFeeAndDevRwdWithDifferentSCC feeHandler, err := economics.NewEconomicsData(*args) require.Nil(t, err) require.NotNil(t, feeHandler) - arguments.TxFeeHandler, _ = postprocess.NewFeeAccumulator() + arguments.TxFeeHandler = postprocess.NewFeeAccumulator() arguments.EconomicsFee = feeHandler arguments.ShardCoordinator = shardCoordinator @@ -3755,9 +3755,7 @@ func TestSmartContractProcessor_finishSCExecutionV2(t *testing.T) { arguments.EconomicsFee, err = economics.NewEconomicsData(*args) require.Nil(t, err) - arguments.TxFeeHandler, err = postprocess.NewFeeAccumulator() - require.Nil(t, err) - + arguments.TxFeeHandler = postprocess.NewFeeAccumulator() arguments.ShardCoordinator = shardCoordinator arguments.AccountsDB = &stateMock.AccountsStub{ RevertToSnapshotCalled: func(snapshot int) error { From b37fc7625fd7e7129d05e7ae917cf4605148a8e5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 7 Apr 2022 16:49:34 +0300 Subject: [PATCH 175/958] FIX: Refactor 4 --- epochStart/metachain/systemSCs.go | 23 ++- integrationTests/vm/staking/stakingV4_test.go | 1 - .../vm/staking/systemSCCreator.go | 91 +++++++++- .../vm/staking/testMetaProcessor.go | 157 ++++-------------- 4 files changed, 131 insertions(+), 141 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index a394071d091..595caaff85c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -14,7 +14,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -150,8 +149,16 @@ func (s *systemSCProcessor) processWithNewFlags( func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) + numOfValidators -= 2 * 4 availableSlots, err := safeSub(s.maxNodes, numOfValidators) - if err != nil { + log.Info("systemSCProcessor.selectNodesFromAuctionList", + "max nodes", s.maxNodes, + "num of validators", numOfValidators, + "auction list size", len(auctionList), + "available slots", availableSlots, + ) // todo: change to log.debug + + if availableSlots == 0 || err != nil { log.Info("not enough available slots for auction nodes; skip selecting nodes from auction list") return nil } @@ -255,9 +262,9 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - if log.GetLevel() > logger.LogDebug { - return - } + //if log.GetLevel() > logger.LogDebug { + // return + //} tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -273,8 +280,8 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo horizontalLine = uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(pubKey), + string([]byte(owner)), + string(pubKey), topUp.String(), }) lines = append(lines, line) @@ -287,7 +294,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Debug(message) + log.Error(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 961caf60334..066bebac675 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -6,7 +6,6 @@ import ( func TestNewTestMetaProcessor(t *testing.T) { node := NewTestMetaProcessor(3, 3, 3, 2, 2, 10, t) - node.DisplayNodesConfig(0, 4) //logger.SetLogLevel("*:DEBUG,process:TRACE") //logger.SetLogLevel("*:DEBUG") diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index d8cd6b14f96..352fad22a1b 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -1,24 +1,92 @@ package staking import ( + "bytes" + "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/epochStart/metachain" mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" factory2 "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" + vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/process/peer" + "github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions" "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/ElrondNetwork/elrond-go/vm" ) +// TODO: Pass epoch config +func createSystemSCProcessor( + nc nodesCoordinator.NodesCoordinator, + coreComponents factory2.CoreComponentsHolder, + stateComponents factory2.StateComponentsHandler, + bootstrapComponents factory2.BootstrapComponentsHolder, + maxNodesConfig []config.MaxNodesChangeConfig, + validatorStatisticsProcessor process.ValidatorStatisticsProcessor, + vmContainer process.VirtualMachinesContainer, +) process.EpochStartSystemSCProcessor { + args := createFullArgumentsForSystemSCProcessing(nc, + coreComponents, + stateComponents, + bootstrapComponents, + maxNodesConfig, + validatorStatisticsProcessor, + vmContainer, + ) + s, _ := metachain.NewSystemSCProcessor(args) + return s +} + +func createFullArgumentsForSystemSCProcessing( + nc nodesCoordinator.NodesCoordinator, + coreComponents factory2.CoreComponentsHolder, + stateComponents factory2.StateComponentsHandler, + bootstrapComponents factory2.BootstrapComponentsHolder, + maxNodesConfig []config.MaxNodesChangeConfig, + validatorStatisticsProcessor process.ValidatorStatisticsProcessor, + vmContainer process.VirtualMachinesContainer, +) metachain.ArgsNewEpochStartSystemSCProcessing { + systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) + stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") + + args := metachain.ArgsNewEpochStartSystemSCProcessing{ + SystemVM: systemVM, + UserAccountsDB: stateComponents.AccountsAdapter(), + PeerAccountsDB: stateComponents.PeerAccounts(), + Marshalizer: coreComponents.InternalMarshalizer(), + StartRating: initialRating, + ValidatorInfoCreator: validatorStatisticsProcessor, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ChanceComputer: &mock3.ChanceComputerStub{}, + EpochNotifier: coreComponents.EpochNotifier(), + GenesisNodesConfig: &mock.NodesSetupStub{}, + StakingDataProvider: stakingSCprovider, + NodesConfigProvider: nc, + ShardCoordinator: bootstrapComponents.ShardCoordinator(), + ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), + EpochConfig: config.EpochConfig{ + EnableEpochs: config.EnableEpochs{ + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, + MaxNodesChangeEnableEpoch: maxNodesConfig, + }, + }, + MaxNodesEnableConfig: maxNodesConfig, + } + + return args +} + func createValidatorStatisticsProcessor( dataComponents factory2.DataComponentsHolder, coreComponents factory2.CoreComponentsHolder, @@ -52,8 +120,18 @@ func createBlockChainHook( coreComponents factory2.CoreComponentsHolder, accountsAdapter state.AccountsAdapter, shardCoordinator sharding.Coordinator, - builtInFunctionsContainer vmcommon.BuiltInFunctionContainer, + gasScheduleNotifier core.GasScheduleNotifier, ) process.BlockChainHookHandler { + argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ + GasSchedule: gasScheduleNotifier, + MapDNSAddresses: make(map[string]struct{}), + Marshalizer: coreComponents.InternalMarshalizer(), + Accounts: accountsAdapter, + ShardCoordinator: shardCoordinator, + EpochNotifier: coreComponents.EpochNotifier(), + } + builtInFunctionsContainer, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) + argsHook := hooks.ArgBlockChainHook{ Accounts: accountsAdapter, PubkeyConv: coreComponents.AddressPubKeyConverter(), @@ -138,13 +216,8 @@ func createVMContainerFactory( EpochNotifier: coreComponents.EpochNotifier(), EpochConfig: &config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 0, - StakeEnableEpoch: 0, - DelegationManagerEnableEpoch: 0, - DelegationSmartContractEnableEpoch: 0, - StakeLimitsEnableEpoch: 10, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, }, }, ShardCoordinator: shardCoordinator, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 085bb60f072..26e866dd4cf 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,7 +1,6 @@ package staking import ( - "bytes" "fmt" "math/big" "strconv" @@ -19,15 +18,12 @@ import ( "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" factory2 "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" "github.com/ElrondNetwork/elrond-go/process" economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" - vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" @@ -73,15 +69,35 @@ func NewTestMetaProcessor( coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(numOfShards) epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) + maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 2 * (numOfMetaNodes + numOfShards*numOfNodesPerShard), NodesToShufflePerShard: 2}) + createStakingQueue(numOfNodesInStakingQueue, coreComponents, stateComponents) - nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents, bootstrapComponents.NodesCoordinatorRegistryFactory()) - scp, blockChainHook, validatorsInfoCreator, metaVMFactory := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, dataComponents) + nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents, bootstrapComponents.NodesCoordinatorRegistryFactory(), maxNodesConfig) + + validatorStatisticsProcessor := createValidatorStatisticsProcessor(dataComponents, coreComponents, nc, bootstrapComponents.ShardCoordinator(), stateComponents.PeerAccounts()) + + gasSchedule := arwenConfig.MakeGasMapForTests() + defaults.FillGasMapInternal(gasSchedule, 1) + gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) + + blockChainHook := createBlockChainHook( + dataComponents, coreComponents, + stateComponents.AccountsAdapter(), + bootstrapComponents.ShardCoordinator(), + gasScheduleNotifier, + ) + + metaVmFactory := createVMContainerFactory(coreComponents, gasScheduleNotifier, blockChainHook, stateComponents.PeerAccounts(), bootstrapComponents.ShardCoordinator(), nc) + vmContainer, _ := metaVmFactory.Create() + + scp := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, maxNodesConfig, validatorStatisticsProcessor, vmContainer) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartTrigger), + MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorStatisticsProcessor, blockChainHook, metaVmFactory, epochStartTrigger), NodesCoordinator: nc, - ValidatorStatistics: validatorsInfoCreator, + ValidatorStatistics: validatorStatisticsProcessor, EpochStartTrigger: epochStartTrigger, BlockChainHandler: dataComponents.Blockchain(), } @@ -93,7 +109,7 @@ func createStakingQueue( stateComponents factory2.StateComponentsHolder, ) { owner := generateUniqueKey(50) - var ownerWaitingNodes [][]byte + ownerWaitingNodes := make([][]byte, 0) for i := uint32(51); i < 51+numOfNodesInStakingQueue; i++ { ownerWaitingNodes = append(ownerWaitingNodes, generateUniqueKey(i)) } @@ -174,7 +190,7 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 newHdr := createMetaBlockHeader2(tmp.EpochStartTrigger.Epoch(), uint64(r), currentHash) newHdr.PrevRandSeed = prevRandomness createdHdr, _ := tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) - newHdr.SetEpoch(createdHdr.GetEpoch()) + _ = newHdr.SetEpoch(createdHdr.GetEpoch()) newHdr2, newBodyHandler2, err := tmp.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) require.Nil(t, err) @@ -183,19 +199,18 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint3 time.Sleep(time.Millisecond * 100) - tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch(), 4) + tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch()) - fmt.Println("#######################DISPLAYING VALIDAOTRS AFTEEEEEEEEEEEEEEEEER ") rootHash, _ := tmp.ValidatorStatistics.RootHash() allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) require.Nil(t, err) - displayValidatorsInfo(allValidatorsInfo, rootHash) + displayValidatorsInfo(allValidatorsInfo) } } -func displayValidatorsInfo(validatorsInfoMap state.ShardValidatorsInfoMapHandler, rootHash []byte) { - fmt.Println("#######################DISPLAYING VALIDAOTRS INFO for root hash ") +func displayValidatorsInfo(validatorsInfoMap state.ShardValidatorsInfoMapHandler) { + fmt.Println("#######################DISPLAYING VALIDATORS INFO") for _, validators := range validatorsInfoMap.GetAllValidatorsInfo() { fmt.Println("PUBKEY: ", string(validators.GetPublicKey()), " SHARDID: ", validators.GetShardId(), " LIST: ", validators.GetList()) } @@ -221,7 +236,7 @@ func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, stora return testTrigger } -func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32, numOfShards int) { +func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32) { eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) @@ -253,25 +268,6 @@ const ( initialRating = 5 ) -// TODO: Pass epoch config - -func createSystemSCProcessor( - nc nodesCoordinator.NodesCoordinator, - coreComponents factory2.CoreComponentsHolder, - stateComponents factory2.StateComponentsHandler, - bootstrapComponents factory2.BootstrapComponentsHolder, - dataComponents factory2.DataComponentsHolder, -) (process.EpochStartSystemSCProcessor, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { - args, blockChainHook, validatorsInfOCreator, metaVMFactory := createFullArgumentsForSystemSCProcessing(nc, - coreComponents, - stateComponents, - bootstrapComponents, - dataComponents, - ) - s, _ := metachain.NewSystemSCProcessor(args) - return s, blockChainHook, validatorsInfOCreator, metaVMFactory -} - func generateUniqueKey(identifier uint32) []byte { neededLength := 15 //192 uniqueIdentifier := fmt.Sprintf("address-%d", identifier) @@ -289,6 +285,7 @@ func createNodesCoordinator( dataComponents factory2.DataComponentsHolder, stateComponents factory2.StateComponentsHandler, nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, + maxNodesConfig []config.MaxNodesChangeConfig, ) nodesCoordinator.NodesCoordinator { validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) @@ -306,7 +303,7 @@ func createNodesCoordinator( peerAccount.ShardId = shardID peerAccount.BLSPublicKey = val.PubKey() peerAccount.List = string(common.EligibleList) - stateComponents.PeerAccounts().SaveAccount(peerAccount) + _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) allPubKeys = append(allPubKeys, val.PubKey()) } } @@ -318,7 +315,7 @@ func createNodesCoordinator( peerAccount.ShardId = shardID peerAccount.BLSPublicKey = val.PubKey() peerAccount.List = string(common.WaitingList) - stateComponents.PeerAccounts().SaveAccount(peerAccount) + _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) allPubKeys = append(allPubKeys, val.PubKey()) } } @@ -327,9 +324,6 @@ func createNodesCoordinator( registerValidatorKeys(stateComponents.AccountsAdapter(), []byte(string(pubKey)+strconv.Itoa(idx)), []byte(string(pubKey)+strconv.Itoa(idx)), [][]byte{pubKey}, big.NewInt(2000), coreComponents.InternalMarshalizer()) } - maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) - maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) - shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ NodesShard: numOfNodesPerShard, NodesMeta: numOfMetaNodes, @@ -452,73 +446,6 @@ func createGenesisMetaBlock() *block.MetaBlock { } } -func createFullArgumentsForSystemSCProcessing( - nc nodesCoordinator.NodesCoordinator, - coreComponents factory2.CoreComponentsHolder, - stateComponents factory2.StateComponentsHandler, - bootstrapComponents factory2.BootstrapComponentsHolder, - dataComponents factory2.DataComponentsHolder, -) (metachain.ArgsNewEpochStartSystemSCProcessing, process.BlockChainHookHandler, process.ValidatorStatisticsProcessor, process.VirtualMachinesContainerFactory) { - nodesSetup := &mock.NodesSetupStub{} - - validatorStatisticsProcessor := createValidatorStatisticsProcessor(dataComponents, coreComponents, nc, bootstrapComponents.ShardCoordinator(), stateComponents.PeerAccounts()) - - gasSchedule := arwenConfig.MakeGasMapForTests() - gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) - argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: gasScheduleNotifier, - MapDNSAddresses: make(map[string]struct{}), - Marshalizer: coreComponents.InternalMarshalizer(), - Accounts: stateComponents.AccountsAdapter(), - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - EpochNotifier: coreComponents.EpochNotifier(), - } - builtInFuncs, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) - - defaults.FillGasMapInternal(gasSchedule, 1) - blockChainHookImpl := createBlockChainHook(dataComponents, coreComponents, stateComponents.AccountsAdapter(), bootstrapComponents.ShardCoordinator(), builtInFuncs) - - metaVmFactory := createVMContainerFactory(coreComponents, gasScheduleNotifier, blockChainHookImpl, stateComponents.PeerAccounts(), bootstrapComponents.ShardCoordinator(), nc) - vmContainer, _ := metaVmFactory.Create() - systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") - - maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) - for i := 0; i < 444; i++ { - maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 24, NodesToShufflePerShard: 2}) - } - - args := metachain.ArgsNewEpochStartSystemSCProcessing{ - SystemVM: systemVM, - UserAccountsDB: stateComponents.AccountsAdapter(), - PeerAccountsDB: stateComponents.PeerAccounts(), - Marshalizer: coreComponents.InternalMarshalizer(), - StartRating: initialRating, - ValidatorInfoCreator: validatorStatisticsProcessor, - EndOfEpochCallerAddress: vm.EndOfEpochAddress, - StakingSCAddress: vm.StakingSCAddress, - ChanceComputer: &mock3.ChanceComputerStub{}, - EpochNotifier: coreComponents.EpochNotifier(), - GenesisNodesConfig: nodesSetup, - StakingDataProvider: stakingSCprovider, - NodesConfigProvider: nc, - ShardCoordinator: bootstrapComponents.ShardCoordinator(), - ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), - EpochConfig: config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 0, - ESDTEnableEpoch: 1000000, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, - MaxNodesChangeEnableEpoch: maxNodesConfig, - }, - }, - MaxNodesEnableConfig: maxNodesConfig, - } - - return args, blockChainHookImpl, validatorStatisticsProcessor, metaVmFactory -} - func createAccountsDB( hasher hashing.Hasher, marshalizer marshal.Marshalizer, @@ -659,22 +586,6 @@ func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserA return stakingSCAcc } -func prepareStakingContractWithData( - accountsDB state.AccountsAdapter, - stakedKey []byte, - waitingKey []byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - addStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) - saveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) - addValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) - - _, _ = accountsDB.Commit() - -} - func saveOneKeyToWaitingList( accountsDB state.AccountsAdapter, waitingKey []byte, From da98d43ee3e55736c8c2914c66284455b3b13257 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 8 Apr 2022 14:01:27 +0300 Subject: [PATCH 176/958] FIX: Refactor 5 --- .../vm/staking/componentsHolderCreator.go | 55 +++- .../vm/staking/nodesCoordiantorCreator.go | 162 +++++++++++ integrationTests/vm/staking/stakingV4_test.go | 2 +- .../vm/staking/systemSCCreator.go | 32 +-- .../vm/staking/testMetaProcessor.go | 253 +++++++----------- 5 files changed, 302 insertions(+), 202 deletions(-) create mode 100644 integrationTests/vm/staking/nodesCoordiantorCreator.go diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 92ac392fc4e..8cb25639dbe 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -9,7 +9,10 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/endProcess" "github.com/ElrondNetwork/elrond-go-core/data/typeConverters/uint64ByteSlice" + "github.com/ElrondNetwork/elrond-go-core/hashing" "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" @@ -21,7 +24,10 @@ import ( "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/state/factory" + "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" + "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" "github.com/ElrondNetwork/elrond-go/statusHandler" "github.com/ElrondNetwork/elrond-go/testscommon" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" @@ -64,10 +70,11 @@ func createCoreComponents() factory2.CoreComponentsHolder { } func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfShards uint32) factory2.DataComponentsHolder { - blockChain, _ := blockchain.NewMetaChain(coreComponents.StatusHandler()) genesisBlock := createGenesisMetaBlock() genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) + + blockChain, _ := blockchain.NewMetaChain(coreComponents.StatusHandler()) _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) blockChain.SetGenesisHeaderHash(genesisBlockHash) @@ -78,7 +85,8 @@ func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfSha chainStorer.AddStorer(dataRetriever.MiniBlockUnit, integrationTests.CreateMemUnit()) chainStorer.AddStorer(dataRetriever.BlockHeaderUnit, integrationTests.CreateMemUnit()) for i := uint32(0); i < numOfShards; i++ { - chainStorer.AddStorer(dataRetriever.ShardHdrNonceHashDataUnit+dataRetriever.UnitType(i), integrationTests.CreateMemUnit()) + unit := dataRetriever.ShardHdrNonceHashDataUnit + dataRetriever.UnitType(i) + chainStorer.AddStorer(unit, integrationTests.CreateMemUnit()) } return &factory3.DataComponentsMock{ @@ -89,9 +97,16 @@ func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfSha } } -func createBootstrapComponents(coreComponents factory2.CoreComponentsHolder, numOfShards uint32) factory2.BootstrapComponentsHolder { +func createBootstrapComponents( + coreComponents factory2.CoreComponentsHolder, + numOfShards uint32, +) factory2.BootstrapComponentsHolder { shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) - ncrf, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory(coreComponents.InternalMarshalizer(), coreComponents.EpochNotifier(), stakingV4EnableEpoch) + ncr, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( + coreComponents.InternalMarshalizer(), + coreComponents.EpochNotifier(), + stakingV4EnableEpoch, + ) return &mainFactoryMocks.BootstrapComponentsStub{ ShCoordinator: shardCoordinator, @@ -101,23 +116,39 @@ func createBootstrapComponents(coreComponents factory2.CoreComponentsHolder, num return &block.MetaBlock{Epoch: epoch} }, }, - NodesCoordinatorRegistryFactoryField: ncrf, + NodesCoordinatorRegistryFactoryField: ncr, + } +} + +func createStatusComponents() factory2.StatusComponentsHolder { + return &mock2.StatusComponentsStub{ + Outport: &testscommon.OutportStub{}, + AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, } } func createStateComponents(coreComponents factory2.CoreComponentsHolder) factory2.StateComponentsHandler { trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) - userAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewAccountCreator(), trieFactoryManager) - peerAccountsDB := createAccountsDB(coreComponents.Hasher(), coreComponents.InternalMarshalizer(), factory.NewPeerAccountCreator(), trieFactoryManager) + hasher := coreComponents.Hasher() + marshaller := coreComponents.InternalMarshalizer() + userAccountsDB := createAccountsDB(hasher, marshaller, factory.NewAccountCreator(), trieFactoryManager) + peerAccountsDB := createAccountsDB(hasher, marshaller, factory.NewPeerAccountCreator(), trieFactoryManager) + return &testscommon.StateComponentsMock{ PeersAcc: peerAccountsDB, Accounts: userAccountsDB, } } -func createStatusComponents() factory2.StatusComponentsHolder { - return &mock2.StatusComponentsStub{ - Outport: &testscommon.OutportStub{}, - AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, - } +func createAccountsDB( + hasher hashing.Hasher, + marshalizer marshal.Marshalizer, + accountFactory state.AccountFactory, + trieStorageManager common.StorageManager, +) *state.AccountsDB { + tr, _ := trie.NewTrie(trieStorageManager, marshalizer, hasher, 5) + ewl, _ := evictionWaitingList.NewEvictionWaitingList(10, testscommon.NewMemDbMock(), marshalizer) + spm, _ := storagePruningManager.NewStoragePruningManager(ewl, 10) + adb, _ := state.NewAccountsDB(tr, hasher, marshalizer, accountFactory, spm, common.Normal) + return adb } diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go new file mode 100644 index 00000000000..eb390f25a66 --- /dev/null +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -0,0 +1,162 @@ +package staking + +import ( + "fmt" + "math/big" + + "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/config" + factory2 "github.com/ElrondNetwork/elrond-go/factory" + mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/storage" + "github.com/ElrondNetwork/elrond-go/storage/lrucache" +) + +func createNodesCoordinator( + numOfMetaNodes uint32, + numOfShards uint32, + numOfEligibleNodesPerShard uint32, + numOfWaitingNodesPerShard uint32, + shardConsensusGroupSize int, + metaConsensusGroupSize int, + coreComponents factory2.CoreComponentsHolder, + bootStorer storage.Storer, + stateComponents factory2.StateComponentsHandler, + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, + maxNodesConfig []config.MaxNodesChangeConfig, +) nodesCoordinator.NodesCoordinator { + eligibleMap, waitingMap := createGenesisNodes( + numOfMetaNodes, + numOfShards, + numOfEligibleNodesPerShard, + numOfWaitingNodesPerShard, + coreComponents.InternalMarshalizer(), + stateComponents, + ) + + shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ + NodesShard: numOfEligibleNodesPerShard, + NodesMeta: numOfMetaNodes, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: maxNodesConfig, + StakingV4EnableEpoch: stakingV4EnableEpoch, + } + nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) + + cache, _ := lrucache.NewCache(10000) + argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + ShardIDAsObserver: core.MetachainShardId, + NbShards: numOfShards, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: eligibleMap[core.MetachainShardId][0].PubKey(), + ConsensusGroupCache: cache, + ShuffledOutHandler: &mock2.ShuffledOutHandlerStub{}, + ChanStopNode: coreComponents.ChanStopNodeProcess(), + IsFullArchive: false, + Shuffler: nodeShuffler, + BootStorer: bootStorer, + EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), + StakingV4EnableEpoch: stakingV4EnableEpoch, + NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + NodeTypeProvider: coreComponents.NodeTypeProvider(), + } + + baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) + if err != nil { + fmt.Println("error creating node coordinator") + } + + nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinatorWithRater(baseNodesCoordinator, coreComponents.Rater()) + if err != nil { + fmt.Println("error creating node coordinator") + } + + return nodesCoord +} + +func createGenesisNodes( + numOfMetaNodes uint32, + numOfShards uint32, + numOfNodesPerShard uint32, + numOfWaitingNodesPerShard uint32, + marshaller marshal.Marshalizer, + stateComponents factory2.StateComponentsHandler, +) (map[uint32][]nodesCoordinator.Validator, map[uint32][]nodesCoordinator.Validator) { + addressStartIdx := uint32(0) + eligibleGenesisNodes := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, addressStartIdx) + eligibleValidators, _ := nodesCoordinator.NodesInfoToValidators(eligibleGenesisNodes) + + addressStartIdx = numOfMetaNodes + numOfShards*numOfNodesPerShard + waitingGenesisNodes := generateGenesisNodeInfoMap(numOfWaitingNodesPerShard, numOfShards, numOfWaitingNodesPerShard, addressStartIdx) + waitingValidators, _ := nodesCoordinator.NodesInfoToValidators(waitingGenesisNodes) + + registerValidators(eligibleValidators, stateComponents, marshaller, common.EligibleList) + registerValidators(waitingValidators, stateComponents, marshaller, common.WaitingList) + + return eligibleValidators, waitingValidators +} + +func generateGenesisNodeInfoMap( + numOfMetaNodes uint32, + numOfShards uint32, + numOfNodesPerShard uint32, + addressStartIdx uint32, +) map[uint32][]nodesCoordinator.GenesisNodeInfoHandler { + validatorsMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) + id := addressStartIdx + for shardId := uint32(0); shardId < numOfShards; shardId++ { + for n := uint32(0); n < numOfNodesPerShard; n++ { + addr := generateUniqueKey(id) + validator := mock2.NewNodeInfo(addr, addr, shardId, initialRating) + validatorsMap[shardId] = append(validatorsMap[shardId], validator) + id++ + } + } + + for n := uint32(0); n < numOfMetaNodes; n++ { + addr := generateUniqueKey(id) + validator := mock2.NewNodeInfo(addr, addr, core.MetachainShardId, initialRating) + validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) + id++ + } + + return validatorsMap +} + +func registerValidators( + validators map[uint32][]nodesCoordinator.Validator, + stateComponents factory2.StateComponentsHolder, + marshaller marshal.Marshalizer, + list common.PeerType, +) { + for shardID, validatorsInShard := range validators { + for _, val := range validatorsInShard { + pubKey := val.PubKey() + peerAccount, _ := state.NewPeerAccount(pubKey) + peerAccount.SetTempRating(initialRating) + peerAccount.ShardId = shardID + peerAccount.BLSPublicKey = pubKey + peerAccount.List = string(list) + _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) + registerValidatorKeys( + stateComponents.AccountsAdapter(), + pubKey, + pubKey, + [][]byte{pubKey}, + big.NewInt(2000), + marshaller, + ) + } + } +} diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 066bebac675..0b8c51f0703 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -5,7 +5,7 @@ import ( ) func TestNewTestMetaProcessor(t *testing.T) { - node := NewTestMetaProcessor(3, 3, 3, 2, 2, 10, t) + node := NewTestMetaProcessor(3, 3, 3, 3, 2, 2, 2, 10, t) //logger.SetLogLevel("*:DEBUG,process:TRACE") //logger.SetLogLevel("*:DEBUG") diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 352fad22a1b..c18a6525778 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -29,34 +29,13 @@ func createSystemSCProcessor( nc nodesCoordinator.NodesCoordinator, coreComponents factory2.CoreComponentsHolder, stateComponents factory2.StateComponentsHandler, - bootstrapComponents factory2.BootstrapComponentsHolder, + shardCoordinator sharding.Coordinator, maxNodesConfig []config.MaxNodesChangeConfig, validatorStatisticsProcessor process.ValidatorStatisticsProcessor, vmContainer process.VirtualMachinesContainer, ) process.EpochStartSystemSCProcessor { - args := createFullArgumentsForSystemSCProcessing(nc, - coreComponents, - stateComponents, - bootstrapComponents, - maxNodesConfig, - validatorStatisticsProcessor, - vmContainer, - ) - s, _ := metachain.NewSystemSCProcessor(args) - return s -} - -func createFullArgumentsForSystemSCProcessing( - nc nodesCoordinator.NodesCoordinator, - coreComponents factory2.CoreComponentsHolder, - stateComponents factory2.StateComponentsHandler, - bootstrapComponents factory2.BootstrapComponentsHolder, - maxNodesConfig []config.MaxNodesChangeConfig, - validatorStatisticsProcessor process.ValidatorStatisticsProcessor, - vmContainer process.VirtualMachinesContainer, -) metachain.ArgsNewEpochStartSystemSCProcessing { systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCprovider, _ := metachain.NewStakingDataProvider(systemVM, "1000") + stakingSCProvider, _ := metachain.NewStakingDataProvider(systemVM, "1000") args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, @@ -70,9 +49,9 @@ func createFullArgumentsForSystemSCProcessing( ChanceComputer: &mock3.ChanceComputerStub{}, EpochNotifier: coreComponents.EpochNotifier(), GenesisNodesConfig: &mock.NodesSetupStub{}, - StakingDataProvider: stakingSCprovider, + StakingDataProvider: stakingSCProvider, NodesConfigProvider: nc, - ShardCoordinator: bootstrapComponents.ShardCoordinator(), + ShardCoordinator: shardCoordinator, ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ @@ -84,7 +63,8 @@ func createFullArgumentsForSystemSCProcessing( MaxNodesEnableConfig: maxNodesConfig, } - return args + systemSCProcessor, _ := metachain.NewSystemSCProcessor(args) + return systemSCProcessor } func createValidatorStatisticsProcessor( diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 26e866dd4cf..0a289b85e71 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,5 +1,6 @@ package staking +// nomindated proof of stake - polkadot import ( "fmt" "math/big" @@ -12,27 +13,19 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/hashing" "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" factory2 "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" - mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" "github.com/ElrondNetwork/elrond-go/process" economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" - "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" - "github.com/ElrondNetwork/elrond-go/storage/lrucache" - "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" - "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" @@ -60,28 +53,41 @@ type TestMetaProcessor struct { func NewTestMetaProcessor( numOfMetaNodes uint32, numOfShards uint32, - numOfNodesPerShard uint32, + numOfEligibleNodesPerShard uint32, + numOfWaitingNodesPerShard uint32, + numOfNodesToShufflePerShard uint32, shardConsensusGroupSize int, metaConsensusGroupSize int, numOfNodesInStakingQueue uint32, t *testing.T, ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(numOfShards) - epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) - maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) - maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{MaxNumNodes: 2 * (numOfMetaNodes + numOfShards*numOfNodesPerShard), NodesToShufflePerShard: 2}) + maxNodesConfig := createMaxNodesConfig( + numOfMetaNodes, + numOfShards, + numOfEligibleNodesPerShard, + numOfWaitingNodesPerShard, + numOfNodesToShufflePerShard, + ) createStakingQueue(numOfNodesInStakingQueue, coreComponents, stateComponents) - nc := createNodesCoordinator(numOfMetaNodes, numOfShards, numOfNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents, stateComponents, bootstrapComponents.NodesCoordinatorRegistryFactory(), maxNodesConfig) - - validatorStatisticsProcessor := createValidatorStatisticsProcessor(dataComponents, coreComponents, nc, bootstrapComponents.ShardCoordinator(), stateComponents.PeerAccounts()) - - gasSchedule := arwenConfig.MakeGasMapForTests() - defaults.FillGasMapInternal(gasSchedule, 1) - gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) + nc := createNodesCoordinator( + numOfMetaNodes, + numOfShards, + numOfEligibleNodesPerShard, + numOfWaitingNodesPerShard, + shardConsensusGroupSize, + metaConsensusGroupSize, + coreComponents, + dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), + stateComponents, + bootstrapComponents.NodesCoordinatorRegistryFactory(), + maxNodesConfig, + ) + gasScheduleNotifier := createGasScheduleNotifier() blockChainHook := createBlockChainHook( dataComponents, coreComponents, stateComponents.AccountsAdapter(), @@ -89,13 +95,49 @@ func NewTestMetaProcessor( gasScheduleNotifier, ) - metaVmFactory := createVMContainerFactory(coreComponents, gasScheduleNotifier, blockChainHook, stateComponents.PeerAccounts(), bootstrapComponents.ShardCoordinator(), nc) + metaVmFactory := createVMContainerFactory( + coreComponents, + gasScheduleNotifier, + blockChainHook, + stateComponents.PeerAccounts(), + bootstrapComponents.ShardCoordinator(), + nc, + ) vmContainer, _ := metaVmFactory.Create() - scp := createSystemSCProcessor(nc, coreComponents, stateComponents, bootstrapComponents, maxNodesConfig, validatorStatisticsProcessor, vmContainer) + validatorStatisticsProcessor := createValidatorStatisticsProcessor( + dataComponents, + coreComponents, + nc, + bootstrapComponents.ShardCoordinator(), + stateComponents.PeerAccounts(), + ) + scp := createSystemSCProcessor( + nc, + coreComponents, + stateComponents, + bootstrapComponents.ShardCoordinator(), + maxNodesConfig, + validatorStatisticsProcessor, + vmContainer, + ) + + epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) return &TestMetaProcessor{ - MetaBlockProcessor: createMetaBlockProcessor(nc, scp, coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, validatorStatisticsProcessor, blockChainHook, metaVmFactory, epochStartTrigger), + MetaBlockProcessor: createMetaBlockProcessor( + nc, + scp, + coreComponents, + dataComponents, + bootstrapComponents, + statusComponents, + stateComponents, + validatorStatisticsProcessor, + blockChainHook, + metaVmFactory, + epochStartTrigger, + ), NodesCoordinator: nc, ValidatorStatistics: validatorStatisticsProcessor, EpochStartTrigger: epochStartTrigger, @@ -103,6 +145,32 @@ func NewTestMetaProcessor( } } +func createMaxNodesConfig( + numOfMetaNodes uint32, + numOfShards uint32, + numOfEligibleNodesPerShard uint32, + numOfWaitingNodesPerShard uint32, + numOfNodesToShufflePerShard uint32, +) []config.MaxNodesChangeConfig { + totalEligible := numOfMetaNodes + numOfShards*numOfEligibleNodesPerShard + totalWaiting := (numOfShards + 1) * numOfWaitingNodesPerShard + + maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{ + MaxNumNodes: totalEligible + totalWaiting, + NodesToShufflePerShard: numOfNodesToShufflePerShard, + }, + ) + + return maxNodesConfig +} + +func createGasScheduleNotifier() core.GasScheduleNotifier { + gasSchedule := arwenConfig.MakeGasMapForTests() + defaults.FillGasMapInternal(gasSchedule, 1) + return mock.NewGasScheduleNotifierMock(gasSchedule) +} + func createStakingQueue( numOfNodesInStakingQueue uint32, coreComponents factory2.CoreComponentsHolder, @@ -120,8 +188,6 @@ func createStakingQueue( owner, owner) - _, _ = stateComponents.PeerAccounts().Commit() - addKeysToWaitingList(stateComponents.AccountsAdapter(), ownerWaitingNodes[1:], coreComponents.InternalMarshalizer(), @@ -274,132 +340,6 @@ func generateUniqueKey(identifier uint32) []byte { return []byte(strings.Repeat("0", neededLength-len(uniqueIdentifier)) + uniqueIdentifier) } -// TODO: MAYBE USE factory from mainFactory.CreateNodesCoordinator -func createNodesCoordinator( - numOfMetaNodes uint32, - numOfShards uint32, - numOfNodesPerShard uint32, - shardConsensusGroupSize int, - metaConsensusGroupSize int, - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, - stateComponents factory2.StateComponentsHandler, - nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, - maxNodesConfig []config.MaxNodesChangeConfig, -) nodesCoordinator.NodesCoordinator { - validatorsMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, 0) - validatorsMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(validatorsMap) - - waitingMap := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, numOfMetaNodes+numOfShards*numOfNodesPerShard) - waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) - - // TODO: HERE SAVE ALL ACCOUNTS - var allPubKeys [][]byte - - for shardID, vals := range validatorsMapForNodesCoordinator { - for _, val := range vals { - peerAccount, _ := state.NewPeerAccount(val.PubKey()) - peerAccount.SetTempRating(initialRating) - peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = val.PubKey() - peerAccount.List = string(common.EligibleList) - _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) - allPubKeys = append(allPubKeys, val.PubKey()) - } - } - - for shardID, vals := range waitingMapForNodesCoordinator { - for _, val := range vals { - peerAccount, _ := state.NewPeerAccount(val.PubKey()) - peerAccount.SetTempRating(initialRating) - peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = val.PubKey() - peerAccount.List = string(common.WaitingList) - _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) - allPubKeys = append(allPubKeys, val.PubKey()) - } - } - - for idx, pubKey := range allPubKeys { - registerValidatorKeys(stateComponents.AccountsAdapter(), []byte(string(pubKey)+strconv.Itoa(idx)), []byte(string(pubKey)+strconv.Itoa(idx)), [][]byte{pubKey}, big.NewInt(2000), coreComponents.InternalMarshalizer()) - } - - shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: numOfNodesPerShard, - NodesMeta: numOfMetaNodes, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: maxNodesConfig, - WaitingListFixEnableEpoch: 0, - BalanceWaitingListsEnableEpoch: 0, - StakingV4EnableEpoch: stakingV4EnableEpoch, - } - nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) - - cache, _ := lrucache.NewCache(10000) - argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - ShardIDAsObserver: core.MetachainShardId, - NbShards: numOfShards, - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: waitingMapForNodesCoordinator, - SelfPublicKey: validatorsMap[core.MetachainShardId][0].PubKeyBytes(), - ConsensusGroupCache: cache, - ShuffledOutHandler: &mock2.ShuffledOutHandlerStub{}, - ChanStopNode: coreComponents.ChanStopNodeProcess(), - IsFullArchive: false, - Shuffler: nodeShuffler, - BootStorer: dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), - EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - StakingV4EnableEpoch: stakingV4EnableEpoch, - NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - NodeTypeProvider: coreComponents.NodeTypeProvider(), - } - - baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) - if err != nil { - fmt.Println("error creating node coordinator") - } - - nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinatorWithRater(baseNodesCoordinator, coreComponents.Rater()) - if err != nil { - fmt.Println("error creating node coordinator") - } - - return nodesCoord -} - -func generateGenesisNodeInfoMap( - numOfMetaNodes uint32, - numOfShards uint32, - numOfNodesPerShard uint32, - startIdx uint32, -) map[uint32][]nodesCoordinator.GenesisNodeInfoHandler { - validatorsMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - id := startIdx - for shardId := uint32(0); shardId < numOfShards; shardId++ { - for n := uint32(0); n < numOfNodesPerShard; n++ { - addr := generateUniqueKey(id) - validator := mock2.NewNodeInfo(addr, addr, shardId, initialRating) - validatorsMap[shardId] = append(validatorsMap[shardId], validator) - id++ - } - } - - for n := uint32(0); n < numOfMetaNodes; n++ { - addr := generateUniqueKey(id) - validator := mock2.NewNodeInfo(addr, addr, core.MetachainShardId, initialRating) - validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) - id++ - } - - return validatorsMap -} - func createGenesisBlocks(shardCoordinator sharding.Coordinator) map[uint32]data.HeaderHandler { genesisBlocks := make(map[uint32]data.HeaderHandler) for ShardID := uint32(0); ShardID < shardCoordinator.NumberOfShards(); ShardID++ { @@ -446,19 +386,6 @@ func createGenesisMetaBlock() *block.MetaBlock { } } -func createAccountsDB( - hasher hashing.Hasher, - marshalizer marshal.Marshalizer, - accountFactory state.AccountFactory, - trieStorageManager common.StorageManager, -) *state.AccountsDB { - tr, _ := trie.NewTrie(trieStorageManager, marshalizer, hasher, 5) - ewl, _ := evictionWaitingList.NewEvictionWaitingList(10, testscommon.NewMemDbMock(), marshalizer) - spm, _ := storagePruningManager.NewStoragePruningManager(ewl, 10) - adb, _ := state.NewAccountsDB(tr, hasher, marshalizer, accountFactory, spm, common.Normal) - return adb -} - func createEconomicsData() process.EconomicsDataHandler { maxGasLimitPerBlock := strconv.FormatUint(1500000000, 10) minGasPrice := strconv.FormatUint(10, 10) From 0869a57803471d9de247de110b30f376a769fe64 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 8 Apr 2022 15:13:36 +0300 Subject: [PATCH 177/958] FIX: Refactor6 --- epochStart/metachain/systemSCs_test.go | 297 ++-------------- .../vm/staking/componentsHolderCreator.go | 2 +- .../vm/staking/metaBlockProcessorCreator.go | 53 ++- .../vm/staking/nodesCoordiantorCreator.go | 11 +- integrationTests/vm/staking/stakingV4_test.go | 2 +- .../vm/staking/testMetaProcessor.go | 335 ++---------------- testscommon/stakingCommon.go | 251 +++++++++++++ 7 files changed, 367 insertions(+), 584 deletions(-) create mode 100644 testscommon/stakingCommon.go diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 8a05765e46f..1c7d76f0e1c 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -8,7 +8,6 @@ import ( "math" "math/big" "os" - "strconv" "strings" "testing" @@ -29,8 +28,6 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" - "github.com/ElrondNetwork/elrond-go/process" - economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" "github.com/ElrondNetwork/elrond-go/process/peer" @@ -226,7 +223,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s _ = s.userAccountsDB.SaveAccount(stakingScAcc) _, _ = s.userAccountsDB.Commit() - addValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) + testscommon.AddValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.SetValidatorsInShard(0, jailed) @@ -687,127 +684,14 @@ func prepareStakingContractWithData( rewardAddress []byte, ownerAddress []byte, ) { - addStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) - saveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) - addValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) + testscommon.AddStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) + testscommon.SaveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) + testscommon.AddValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) _, err := accountsDB.Commit() log.LogIfError(err) } -func saveOneKeyToWaitingList( - accountsDB state.AccountsAdapter, - waitingKey []byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) - - waitingKeyInList := []byte("w_" + string(waitingKey)) - waitingListHead := &systemSmartContracts.WaitingList{ - FirstKey: waitingKeyInList, - LastKey: waitingKeyInList, - Length: 1, - } - marshaledData, _ = marshalizer.Marshal(waitingListHead) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - - waitingListElement := &systemSmartContracts.ElementInList{ - BLSPublicKey: waitingKey, - PreviousKey: waitingKeyInList, - NextKey: make([]byte, 0), - } - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - -func addKeysToWaitingList( - accountsDB state.AccountsAdapter, - waitingKeys [][]byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - - for _, waitingKey := range waitingKeys { - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) - } - - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) - waitingListHead := &systemSmartContracts.WaitingList{} - _ = marshalizer.Unmarshal(waitingListHead, marshaledData) - - waitingListAlreadyHasElements := waitingListHead.Length > 0 - waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey - - waitingListHead.Length += uint32(len(waitingKeys)) - lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) - waitingListHead.LastKey = lastKeyInList - - marshaledData, _ = marshalizer.Marshal(waitingListHead) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - - numWaitingKeys := len(waitingKeys) - previousKey := waitingListHead.LastKey - for i, waitingKey := range waitingKeys { - - waitingKeyInList := []byte("w_" + string(waitingKey)) - waitingListElement := &systemSmartContracts.ElementInList{ - BLSPublicKey: waitingKey, - PreviousKey: previousKey, - NextKey: make([]byte, 0), - } - - if i < numWaitingKeys-1 { - nextKey := []byte("w_" + string(waitingKeys[i+1])) - waitingListElement.NextKey = nextKey - } - - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - - previousKey = waitingKeyInList - } - - if waitingListAlreadyHasElements { - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) - } else { - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) - } - - waitingListElement := &systemSmartContracts.ElementInList{} - _ = marshalizer.Unmarshal(waitingListElement, marshaledData) - waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) - marshaledData, _ = marshalizer.Marshal(waitingListElement) - - if waitingListAlreadyHasElements { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) - } else { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) - } - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - func createAccountsDB( hasher hashing.Hasher, marshalizer marshal.Marshalizer, @@ -889,7 +773,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ BlockChainHook: blockChainHookImpl, PubkeyConv: argsHook.PubkeyConv, - Economics: createEconomicsData(), + Economics: testscommon.CreateEconomicsData(), MessageSignVerifier: signVerifer, GasSchedule: gasScheduleNotifier, NodesConfigProvider: nodesSetup, @@ -995,59 +879,6 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS return args, metaVmFactory.SystemSmartContractContainer() } -func createEconomicsData() process.EconomicsDataHandler { - maxGasLimitPerBlock := strconv.FormatUint(1500000000, 10) - minGasPrice := strconv.FormatUint(10, 10) - minGasLimit := strconv.FormatUint(10, 10) - - argsNewEconomicsData := economicsHandler.ArgsNewEconomicsData{ - Economics: &config.EconomicsConfig{ - GlobalSettings: config.GlobalSettings{ - GenesisTotalSupply: "2000000000000000000000", - MinimumInflation: 0, - YearSettings: []*config.YearSetting{ - { - Year: 0, - MaximumInflation: 0.01, - }, - }, - }, - RewardsSettings: config.RewardsSettings{ - RewardsConfigByEpoch: []config.EpochRewardSettings{ - { - LeaderPercentage: 0.1, - DeveloperPercentage: 0.1, - ProtocolSustainabilityPercentage: 0.1, - ProtocolSustainabilityAddress: "protocol", - TopUpGradientPoint: "300000000000000000000", - TopUpFactor: 0.25, - }, - }, - }, - FeeSettings: config.FeeSettings{ - GasLimitSettings: []config.GasLimitSetting{ - { - MaxGasLimitPerBlock: maxGasLimitPerBlock, - MaxGasLimitPerMiniBlock: maxGasLimitPerBlock, - MaxGasLimitPerMetaBlock: maxGasLimitPerBlock, - MaxGasLimitPerMetaMiniBlock: maxGasLimitPerBlock, - MaxGasLimitPerTx: maxGasLimitPerBlock, - MinGasLimit: minGasLimit, - }, - }, - MinGasPrice: minGasPrice, - GasPerDataByte: "1", - GasPriceModifier: 1.0, - }, - }, - PenalizedTooMuchGasEnableEpoch: 0, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - } - economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) - return economicsData -} - func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testing.T) { t.Parallel() @@ -1306,7 +1137,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t []byte("rewardAddress"), []byte("rewardAddress"), ) - registerValidatorKeys(args.UserAccountsDB, + testscommon.RegisterValidatorKeys(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, @@ -1378,7 +1209,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor []byte("rewardAddress"), ) - addStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, args.Marshalizer) + testscommon.AddStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, args.Marshalizer) addValidatorDataWithUnStakedKey(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, big.NewInt(1000), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1448,14 +1279,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra delegationAddr, ) - addStakingData(args.UserAccountsDB, + testscommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) allKeys := [][]byte{[]byte("stakedPubKey0"), []byte("waitingPubKey"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")} - addValidatorData(args.UserAccountsDB, delegationAddr, allKeys, big.NewInt(3000), args.Marshalizer) + testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allKeys, big.NewInt(3000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1540,11 +1371,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional delegationAddr, ) - addStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer) + testscommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer) listOfKeysInWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} allStakedKeys := append(listOfKeysInWaiting, []byte("waitingPubKey"), []byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")) - addKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr, delegationAddr) - addValidatorData(args.UserAccountsDB, delegationAddr, allStakedKeys, big.NewInt(4000), args.Marshalizer) + testscommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr, delegationAddr) + testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allStakedKeys, big.NewInt(4000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allStakedKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1624,14 +1455,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( delegationAddr, ) - addStakingData(args.UserAccountsDB, + testscommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) - addValidatorData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(10000), args.Marshalizer) + testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(10000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1641,8 +1472,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( _ = scContainer.Add(delegationAddr2, contract) listOfKeysInWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} - addKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr2, delegationAddr2) - addValidatorData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, big.NewInt(2000), args.Marshalizer) + testscommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr2, delegationAddr2) + testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, big.NewInt(2000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1806,14 +1637,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T args.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 s, _ := NewSystemSCProcessor(args) - addStakingData(args.UserAccountsDB, + testscommon.AddStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) - saveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) - addValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) + testscommon.SaveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) + testscommon.AddValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap() @@ -1893,18 +1724,18 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) // Owner1 has 2 staked nodes (one eligible, one waiting) in shard0 + 3 nodes in staking queue. // It has enough stake so that all his staking queue nodes will be selected in the auction list - addKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting[1:], args.Marshalizer, owner1, owner1) - addValidatorData(args.UserAccountsDB, owner1, owner1AllPubKeys[1:], big.NewInt(5000), args.Marshalizer) + testscommon.AddKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting[1:], args.Marshalizer, owner1, owner1) + testscommon.AddValidatorData(args.UserAccountsDB, owner1, owner1AllPubKeys[1:], big.NewInt(5000), args.Marshalizer) // Owner2 has 1 staked node (eligible) in shard1 + 2 nodes in staking queue. // It has enough stake for only ONE node from staking queue to be selected in the auction list - addKeysToWaitingList(args.UserAccountsDB, owner2ListPubKeysWaiting, args.Marshalizer, owner2, owner2) - addValidatorData(args.UserAccountsDB, owner2, owner2AllPubKeys, big.NewInt(1500), args.Marshalizer) + testscommon.AddKeysToWaitingList(args.UserAccountsDB, owner2ListPubKeysWaiting, args.Marshalizer, owner2, owner2) + testscommon.AddValidatorData(args.UserAccountsDB, owner2, owner2AllPubKeys, big.NewInt(1500), args.Marshalizer) // Owner3 has 0 staked node + 2 nodes in staking queue. // It has enough stake so that all his staking queue nodes will be selected in the auction list - addKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) - addValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) + testscommon.AddKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) + testscommon.AddValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) @@ -1950,7 +1781,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa owner := []byte("owner") ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} - registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) @@ -1984,7 +1815,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA owner := []byte("owner") ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} - registerValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) @@ -2011,8 +1842,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA owner1StakedKeys := [][]byte{[]byte("pubKey0")} owner2StakedKeys := [][]byte{[]byte("pubKey1")} - registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() @@ -2049,10 +1880,10 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner3StakedKeys := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} owner4StakedKeys := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} - registerValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(3000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) - registerValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(3000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) + testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) @@ -2126,68 +1957,6 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } -func registerValidatorKeys( - accountsDB state.AccountsAdapter, - ownerAddress []byte, - rewardAddress []byte, - stakedKeys [][]byte, - totalStake *big.Int, - marshaller marshal.Marshalizer, -) { - addValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) - addStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) - _, err := accountsDB.Commit() - log.LogIfError(err) -} - -func addValidatorData( - accountsDB state.AccountsAdapter, - ownerKey []byte, - registeredKeys [][]byte, - totalStake *big.Int, - marshaller marshal.Marshalizer, -) { - validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) - validatorData := &systemSmartContracts.ValidatorDataV2{ - RegisterNonce: 0, - Epoch: 0, - RewardAddress: ownerKey, - TotalStakeValue: totalStake, - LockedStake: big.NewInt(0), - TotalUnstaked: big.NewInt(0), - BlsPubKeys: registeredKeys, - NumRegistered: uint32(len(registeredKeys)), - } - - marshaledData, _ := marshaller.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) - - _ = accountsDB.SaveAccount(validatorSC) -} - -func addStakingData( - accountsDB state.AccountsAdapter, - ownerAddress []byte, - rewardAddress []byte, - stakedKeys [][]byte, - marshaller marshal.Marshalizer, -) { - stakedData := &systemSmartContracts.StakedDataV2_0{ - Staked: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshaller.Marshal(stakedData) - - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - for _, key := range stakedKeys { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) - } - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { for _, pubKey := range stakedPubKeys { topUpPerNode, err := s.GetNodeStakedTopUp(pubKey) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 8cb25639dbe..cbf09de7396 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -63,7 +63,7 @@ func createCoreComponents() factory2.CoreComponentsHolder { EpochNotifierField: forking.NewGenericEpochNotifier(), RaterField: &testscommon.RaterMock{Chance: 5}, AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, - EconomicsDataField: createEconomicsData(), + EconomicsDataField: testscommon.CreateEconomicsData(), ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), NodeTypeProviderField: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), } diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index cce662801bc..b1b3cd18063 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -1,6 +1,11 @@ package staking import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" @@ -52,7 +57,7 @@ func createMockMetaArguments( ) blproc.ArgMetaProcessor { shardCoordiantor := bootstrapComponents.ShardCoordinator() valInfoCreator := createValidatorInfoCreator(coreComponents, dataComponents, shardCoordiantor) - blockTracker := createBlockTracker(shardCoordiantor) + blockTracker := createBlockTracker(dataComponents.Blockchain().GetGenesisHeader(), shardCoordiantor) epochStartDataCreator := createEpochStartDataCreator(coreComponents, dataComponents, shardCoordiantor, epochStartHandler, blockTracker) accountsDb := make(map[state.AccountsDbIdentifier]state.AccountsAdapter) @@ -139,9 +144,49 @@ func createEpochStartDataCreator( return epochStartDataCreator } -func createBlockTracker(shardCoordinator sharding.Coordinator) process.BlockTracker { - startHeaders := createGenesisBlocks(shardCoordinator) - return mock.NewBlockTrackerMock(shardCoordinator, startHeaders) +func createBlockTracker(genesisMetaHeader data.HeaderHandler, shardCoordinator sharding.Coordinator) process.BlockTracker { + genesisBlocks := make(map[uint32]data.HeaderHandler) + for ShardID := uint32(0); ShardID < shardCoordinator.NumberOfShards(); ShardID++ { + genesisBlocks[ShardID] = createGenesisBlock(ShardID) + } + + genesisBlocks[core.MetachainShardId] = genesisMetaHeader + return mock.NewBlockTrackerMock(shardCoordinator, genesisBlocks) +} + +func createGenesisBlock(ShardID uint32) *block.Header { + rootHash := []byte("roothash") + return &block.Header{ + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + ShardID: ShardID, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + AccumulatedFees: big.NewInt(0), + DeveloperFees: big.NewInt(0), + } +} + +func createGenesisMetaBlock() *block.MetaBlock { + rootHash := []byte("roothash") + return &block.MetaBlock{ + Nonce: 0, + Round: 0, + Signature: rootHash, + RandSeed: rootHash, + PrevRandSeed: rootHash, + PubKeysBitmap: rootHash, + RootHash: rootHash, + PrevHash: rootHash, + AccumulatedFees: big.NewInt(0), + DeveloperFees: big.NewInt(0), + AccumulatedFeesInEpoch: big.NewInt(0), + DevFeesInEpoch: big.NewInt(0), + } } func createHeaderValidator(coreComponents factory2.CoreComponentsHolder) epochStart.HeaderValidator { diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index eb390f25a66..f2bd2185306 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -14,6 +14,15 @@ import ( "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage" "github.com/ElrondNetwork/elrond-go/storage/lrucache" + "github.com/ElrondNetwork/elrond-go/testscommon" +) + +// shuffler constants +const ( + shuffleBetweenShards = false + adaptivity = false + hysteresis = float32(0.2) + initialRating = 5 ) func createNodesCoordinator( @@ -149,7 +158,7 @@ func registerValidators( peerAccount.BLSPublicKey = pubKey peerAccount.List = string(list) _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) - registerValidatorKeys( + testscommon.RegisterValidatorKeys( stateComponents.AccountsAdapter(), pubKey, pubKey, diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 0b8c51f0703..7590e8f7c01 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -5,7 +5,7 @@ import ( ) func TestNewTestMetaProcessor(t *testing.T) { - node := NewTestMetaProcessor(3, 3, 3, 3, 2, 2, 2, 10, t) + node := NewTestMetaProcessor(3, 3, 3, 3, 2, 2, 2, 10) //logger.SetLogLevel("*:DEBUG,process:TRACE") //logger.SetLogLevel("*:DEBUG") diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 0a289b85e71..6d6a775b3b8 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -20,14 +20,10 @@ import ( factory2 "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/process" - economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" + "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/require" ) @@ -59,7 +55,6 @@ func NewTestMetaProcessor( shardConsensusGroupSize int, metaConsensusGroupSize int, numOfNodesInStakingQueue uint32, - t *testing.T, ) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(numOfShards) @@ -71,7 +66,7 @@ func NewTestMetaProcessor( numOfNodesToShufflePerShard, ) - createStakingQueue(numOfNodesInStakingQueue, coreComponents, stateComponents) + createStakingQueue(numOfNodesInStakingQueue, coreComponents.InternalMarshalizer(), stateComponents.AccountsAdapter()) nc := createNodesCoordinator( numOfMetaNodes, @@ -173,8 +168,8 @@ func createGasScheduleNotifier() core.GasScheduleNotifier { func createStakingQueue( numOfNodesInStakingQueue uint32, - coreComponents factory2.CoreComponentsHolder, - stateComponents factory2.StateComponentsHolder, + marshaller marshal.Marshalizer, + accountsAdapter state.AccountsAdapter, ) { owner := generateUniqueKey(50) ownerWaitingNodes := make([][]byte, 0) @@ -182,19 +177,27 @@ func createStakingQueue( ownerWaitingNodes = append(ownerWaitingNodes, generateUniqueKey(i)) } - saveOneKeyToWaitingList(stateComponents.AccountsAdapter(), + testscommon.SaveOneKeyToWaitingList( + accountsAdapter, ownerWaitingNodes[0], - coreComponents.InternalMarshalizer(), + marshaller, owner, - owner) - - addKeysToWaitingList(stateComponents.AccountsAdapter(), + owner, + ) + testscommon.AddKeysToWaitingList( + accountsAdapter, ownerWaitingNodes[1:], - coreComponents.InternalMarshalizer(), - owner, owner) - addValidatorData(stateComponents.AccountsAdapter(), owner, ownerWaitingNodes, big.NewInt(500000), coreComponents.InternalMarshalizer()) - - _, _ = stateComponents.AccountsAdapter().Commit() + marshaller, + owner, + owner, + ) + testscommon.AddValidatorData( + accountsAdapter, + owner, + ownerWaitingNodes, + big.NewInt(50000), + marshaller, + ) } func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { @@ -326,302 +329,8 @@ func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32) { } } -// shuffler constants -const ( - shuffleBetweenShards = false - adaptivity = false - hysteresis = float32(0.2) - initialRating = 5 -) - func generateUniqueKey(identifier uint32) []byte { neededLength := 15 //192 uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", neededLength-len(uniqueIdentifier)) + uniqueIdentifier) } - -func createGenesisBlocks(shardCoordinator sharding.Coordinator) map[uint32]data.HeaderHandler { - genesisBlocks := make(map[uint32]data.HeaderHandler) - for ShardID := uint32(0); ShardID < shardCoordinator.NumberOfShards(); ShardID++ { - genesisBlocks[ShardID] = createGenesisBlock(ShardID) - } - - genesisBlocks[core.MetachainShardId] = createGenesisMetaBlock() - - return genesisBlocks -} - -func createGenesisBlock(ShardID uint32) *block.Header { - rootHash := []byte("roothash") - return &block.Header{ - Nonce: 0, - Round: 0, - Signature: rootHash, - RandSeed: rootHash, - PrevRandSeed: rootHash, - ShardID: ShardID, - PubKeysBitmap: rootHash, - RootHash: rootHash, - PrevHash: rootHash, - AccumulatedFees: big.NewInt(0), - DeveloperFees: big.NewInt(0), - } -} - -func createGenesisMetaBlock() *block.MetaBlock { - rootHash := []byte("roothash") - return &block.MetaBlock{ - Nonce: 0, - Round: 0, - Signature: rootHash, - RandSeed: rootHash, - PrevRandSeed: rootHash, - PubKeysBitmap: rootHash, - RootHash: rootHash, - PrevHash: rootHash, - AccumulatedFees: big.NewInt(0), - DeveloperFees: big.NewInt(0), - AccumulatedFeesInEpoch: big.NewInt(0), - DevFeesInEpoch: big.NewInt(0), - } -} - -func createEconomicsData() process.EconomicsDataHandler { - maxGasLimitPerBlock := strconv.FormatUint(1500000000, 10) - minGasPrice := strconv.FormatUint(10, 10) - minGasLimit := strconv.FormatUint(10, 10) - - argsNewEconomicsData := economicsHandler.ArgsNewEconomicsData{ - Economics: &config.EconomicsConfig{ - GlobalSettings: config.GlobalSettings{ - GenesisTotalSupply: "2000000000000000000000", - MinimumInflation: 0, - YearSettings: []*config.YearSetting{ - { - Year: 0, - MaximumInflation: 0.01, - }, - }, - }, - RewardsSettings: config.RewardsSettings{ - RewardsConfigByEpoch: []config.EpochRewardSettings{ - { - LeaderPercentage: 0.1, - DeveloperPercentage: 0.1, - ProtocolSustainabilityPercentage: 0.1, - ProtocolSustainabilityAddress: "protocol", - TopUpGradientPoint: "300000000000000000000", - TopUpFactor: 0.25, - }, - }, - }, - FeeSettings: config.FeeSettings{ - GasLimitSettings: []config.GasLimitSetting{ - { - MaxGasLimitPerBlock: maxGasLimitPerBlock, - MaxGasLimitPerMiniBlock: maxGasLimitPerBlock, - MaxGasLimitPerMetaBlock: maxGasLimitPerBlock, - MaxGasLimitPerMetaMiniBlock: maxGasLimitPerBlock, - MaxGasLimitPerTx: maxGasLimitPerBlock, - MinGasLimit: minGasLimit, - }, - }, - MinGasPrice: minGasPrice, - GasPerDataByte: "1", - GasPriceModifier: 1.0, - }, - }, - PenalizedTooMuchGasEnableEpoch: 0, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - } - economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) - return economicsData -} - -// ###### - -func registerValidatorKeys( - accountsDB state.AccountsAdapter, - ownerAddress []byte, - rewardAddress []byte, - stakedKeys [][]byte, - totalStake *big.Int, - marshaller marshal.Marshalizer, -) { - addValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) - addStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) - _, err := accountsDB.Commit() - if err != nil { - fmt.Println("ERROR REGISTERING VALIDATORS ", err) - } - //log.LogIfError(err) -} - -func addValidatorData( - accountsDB state.AccountsAdapter, - ownerKey []byte, - registeredKeys [][]byte, - totalStake *big.Int, - marshaller marshal.Marshalizer, -) { - validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) - validatorData := &systemSmartContracts.ValidatorDataV2{ - RegisterNonce: 0, - Epoch: 0, - RewardAddress: ownerKey, - TotalStakeValue: totalStake, - LockedStake: big.NewInt(0), - TotalUnstaked: big.NewInt(0), - BlsPubKeys: registeredKeys, - NumRegistered: uint32(len(registeredKeys)), - } - - marshaledData, _ := marshaller.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) - - _ = accountsDB.SaveAccount(validatorSC) -} - -func addStakingData( - accountsDB state.AccountsAdapter, - ownerAddress []byte, - rewardAddress []byte, - stakedKeys [][]byte, - marshaller marshal.Marshalizer, -) { - stakedData := &systemSmartContracts.StakedDataV2_0{ - Staked: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshaller.Marshal(stakedData) - - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - for _, key := range stakedKeys { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) - } - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - -func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { - acc, _ := accountsDB.LoadAccount(address) - stakingSCAcc := acc.(state.UserAccountHandler) - - return stakingSCAcc -} - -func saveOneKeyToWaitingList( - accountsDB state.AccountsAdapter, - waitingKey []byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) - - waitingKeyInList := []byte("w_" + string(waitingKey)) - waitingListHead := &systemSmartContracts.WaitingList{ - FirstKey: waitingKeyInList, - LastKey: waitingKeyInList, - Length: 1, - } - marshaledData, _ = marshalizer.Marshal(waitingListHead) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - - waitingListElement := &systemSmartContracts.ElementInList{ - BLSPublicKey: waitingKey, - PreviousKey: waitingKeyInList, - NextKey: make([]byte, 0), - } - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - -func addKeysToWaitingList( - accountsDB state.AccountsAdapter, - waitingKeys [][]byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) - - for _, waitingKey := range waitingKeys { - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) - } - - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) - waitingListHead := &systemSmartContracts.WaitingList{} - _ = marshalizer.Unmarshal(waitingListHead, marshaledData) - - waitingListAlreadyHasElements := waitingListHead.Length > 0 - waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey - - waitingListHead.Length += uint32(len(waitingKeys)) - lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) - waitingListHead.LastKey = lastKeyInList - - marshaledData, _ = marshalizer.Marshal(waitingListHead) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - - numWaitingKeys := len(waitingKeys) - previousKey := waitingListHead.LastKey - for i, waitingKey := range waitingKeys { - - waitingKeyInList := []byte("w_" + string(waitingKey)) - waitingListElement := &systemSmartContracts.ElementInList{ - BLSPublicKey: waitingKey, - PreviousKey: previousKey, - NextKey: make([]byte, 0), - } - - if i < numWaitingKeys-1 { - nextKey := []byte("w_" + string(waitingKeys[i+1])) - waitingListElement.NextKey = nextKey - } - - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - - previousKey = waitingKeyInList - } - - if waitingListAlreadyHasElements { - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) - } else { - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) - } - - waitingListElement := &systemSmartContracts.ElementInList{} - _ = marshalizer.Unmarshal(waitingListElement, marshaledData) - waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) - marshaledData, _ = marshalizer.Marshal(waitingListElement) - - if waitingListAlreadyHasElements { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) - } else { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) - } - - _ = accountsDB.SaveAccount(stakingSCAcc) -} diff --git a/testscommon/stakingCommon.go b/testscommon/stakingCommon.go new file mode 100644 index 00000000000..5c5fc6236c0 --- /dev/null +++ b/testscommon/stakingCommon.go @@ -0,0 +1,251 @@ +package testscommon + +import ( + "math/big" + "strconv" + + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/process" + economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" + "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" +) + +func RegisterValidatorKeys( + accountsDB state.AccountsAdapter, + ownerAddress []byte, + rewardAddress []byte, + stakedKeys [][]byte, + totalStake *big.Int, + marshaller marshal.Marshalizer, +) { + AddValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) + AddStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) + _, err := accountsDB.Commit() + log.LogIfError(err) +} + +func AddValidatorData( + accountsDB state.AccountsAdapter, + ownerKey []byte, + registeredKeys [][]byte, + totalStake *big.Int, + marshaller marshal.Marshalizer, +) { + validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) + validatorData := &systemSmartContracts.ValidatorDataV2{ + RegisterNonce: 0, + Epoch: 0, + RewardAddress: ownerKey, + TotalStakeValue: totalStake, + LockedStake: big.NewInt(0), + TotalUnstaked: big.NewInt(0), + BlsPubKeys: registeredKeys, + NumRegistered: uint32(len(registeredKeys)), + } + + marshaledData, _ := marshaller.Marshal(validatorData) + _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) + + _ = accountsDB.SaveAccount(validatorSC) +} + +func AddStakingData( + accountsDB state.AccountsAdapter, + ownerAddress []byte, + rewardAddress []byte, + stakedKeys [][]byte, + marshaller marshal.Marshalizer, +) { + stakedData := &systemSmartContracts.StakedDataV2_0{ + Staked: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshaller.Marshal(stakedData) + + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + for _, key := range stakedKeys { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) + } + + _ = accountsDB.SaveAccount(stakingSCAcc) +} + +func AddKeysToWaitingList( + accountsDB state.AccountsAdapter, + waitingKeys [][]byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + + for _, waitingKey := range waitingKeys { + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) + } + + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + waitingListHead := &systemSmartContracts.WaitingList{} + _ = marshalizer.Unmarshal(waitingListHead, marshaledData) + + waitingListAlreadyHasElements := waitingListHead.Length > 0 + waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey + + waitingListHead.Length += uint32(len(waitingKeys)) + lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) + waitingListHead.LastKey = lastKeyInList + + marshaledData, _ = marshalizer.Marshal(waitingListHead) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) + + numWaitingKeys := len(waitingKeys) + previousKey := waitingListHead.LastKey + for i, waitingKey := range waitingKeys { + + waitingKeyInList := []byte("w_" + string(waitingKey)) + waitingListElement := &systemSmartContracts.ElementInList{ + BLSPublicKey: waitingKey, + PreviousKey: previousKey, + NextKey: make([]byte, 0), + } + + if i < numWaitingKeys-1 { + nextKey := []byte("w_" + string(waitingKeys[i+1])) + waitingListElement.NextKey = nextKey + } + + marshaledData, _ = marshalizer.Marshal(waitingListElement) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) + + previousKey = waitingKeyInList + } + + if waitingListAlreadyHasElements { + marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) + } else { + marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) + } + + waitingListElement := &systemSmartContracts.ElementInList{} + _ = marshalizer.Unmarshal(waitingListElement, marshaledData) + waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) + marshaledData, _ = marshalizer.Marshal(waitingListElement) + + if waitingListAlreadyHasElements { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) + } else { + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) + } + + _ = accountsDB.SaveAccount(stakingSCAcc) +} + +func SaveOneKeyToWaitingList( + accountsDB state.AccountsAdapter, + waitingKey []byte, + marshalizer marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, +) { + stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ := marshalizer.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) + + waitingKeyInList := []byte("w_" + string(waitingKey)) + waitingListHead := &systemSmartContracts.WaitingList{ + FirstKey: waitingKeyInList, + LastKey: waitingKeyInList, + Length: 1, + } + marshaledData, _ = marshalizer.Marshal(waitingListHead) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) + + waitingListElement := &systemSmartContracts.ElementInList{ + BLSPublicKey: waitingKey, + PreviousKey: waitingKeyInList, + NextKey: make([]byte, 0), + } + marshaledData, _ = marshalizer.Marshal(waitingListElement) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) + + _ = accountsDB.SaveAccount(stakingSCAcc) +} + +func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { + acc, _ := accountsDB.LoadAccount(address) + stakingSCAcc := acc.(state.UserAccountHandler) + + return stakingSCAcc +} + +func CreateEconomicsData() process.EconomicsDataHandler { + maxGasLimitPerBlock := strconv.FormatUint(1500000000, 10) + minGasPrice := strconv.FormatUint(10, 10) + minGasLimit := strconv.FormatUint(10, 10) + + argsNewEconomicsData := economicsHandler.ArgsNewEconomicsData{ + Economics: &config.EconomicsConfig{ + GlobalSettings: config.GlobalSettings{ + GenesisTotalSupply: "2000000000000000000000", + MinimumInflation: 0, + YearSettings: []*config.YearSetting{ + { + Year: 0, + MaximumInflation: 0.01, + }, + }, + }, + RewardsSettings: config.RewardsSettings{ + RewardsConfigByEpoch: []config.EpochRewardSettings{ + { + LeaderPercentage: 0.1, + DeveloperPercentage: 0.1, + ProtocolSustainabilityPercentage: 0.1, + ProtocolSustainabilityAddress: "protocol", + TopUpGradientPoint: "300000000000000000000", + TopUpFactor: 0.25, + }, + }, + }, + FeeSettings: config.FeeSettings{ + GasLimitSettings: []config.GasLimitSetting{ + { + MaxGasLimitPerBlock: maxGasLimitPerBlock, + MaxGasLimitPerMiniBlock: maxGasLimitPerBlock, + MaxGasLimitPerMetaBlock: maxGasLimitPerBlock, + MaxGasLimitPerMetaMiniBlock: maxGasLimitPerBlock, + MaxGasLimitPerTx: maxGasLimitPerBlock, + MinGasLimit: minGasLimit, + }, + }, + MinGasPrice: minGasPrice, + GasPerDataByte: "1", + GasPriceModifier: 1.0, + }, + }, + PenalizedTooMuchGasEnableEpoch: 0, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, + } + economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) + return economicsData +} From 4226a2d92960f8c3c0f0b500a355108564e5c278 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 8 Apr 2022 16:04:59 +0300 Subject: [PATCH 178/958] FIX: Refactor 7 --- .../vm/staking/metaBlockProcessorCreator.go | 54 +++---- .../vm/staking/nodesCoordiantorCreator.go | 12 +- .../vm/staking/systemSCCreator.go | 1 - .../vm/staking/testMetaProcessor.go | 152 ++++++++++-------- 4 files changed, 111 insertions(+), 108 deletions(-) diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index b1b3cd18063..a924bea5d69 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -35,39 +35,31 @@ func createMetaBlockProcessor( blockChainHook process.BlockChainHookHandler, metaVMFactory process.VirtualMachinesContainerFactory, epochStartHandler process.EpochStartTriggerHandler, + vmContainer process.VirtualMachinesContainer, ) process.BlockProcessor { - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents, nc, systemSCProcessor, stateComponents, validatorsInfoCreator, blockChainHook, metaVMFactory, epochStartHandler) - - metaProc, _ := blproc.NewMetaProcessor(arguments) - return metaProc -} - -func createMockMetaArguments( - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, - bootstrapComponents factory2.BootstrapComponentsHolder, - statusComponents factory2.StatusComponentsHolder, - nodesCoord nodesCoordinator.NodesCoordinator, - systemSCProcessor process.EpochStartSystemSCProcessor, - stateComponents factory2.StateComponentsHandler, - validatorsInfoCreator process.ValidatorStatisticsProcessor, - blockChainHook process.BlockChainHookHandler, - metaVMFactory process.VirtualMachinesContainerFactory, - epochStartHandler process.EpochStartTriggerHandler, -) blproc.ArgMetaProcessor { shardCoordiantor := bootstrapComponents.ShardCoordinator() - valInfoCreator := createValidatorInfoCreator(coreComponents, dataComponents, shardCoordiantor) + blockTracker := createBlockTracker(dataComponents.Blockchain().GetGenesisHeader(), shardCoordiantor) - epochStartDataCreator := createEpochStartDataCreator(coreComponents, dataComponents, shardCoordiantor, epochStartHandler, blockTracker) + epochStartDataCreator := createEpochStartDataCreator( + coreComponents, + dataComponents, + shardCoordiantor, + epochStartHandler, + blockTracker, + ) accountsDb := make(map[state.AccountsDbIdentifier]state.AccountsAdapter) accountsDb[state.UserAccountsState] = stateComponents.AccountsAdapter() accountsDb[state.PeerAccountsState] = stateComponents.PeerAccounts() - bootStorer, _ := bootstrapStorage.NewBootstrapStorer(coreComponents.InternalMarshalizer(), dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit)) + bootStorer, _ := bootstrapStorage.NewBootstrapStorer( + coreComponents.InternalMarshalizer(), + dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), + ) + headerValidator := createHeaderValidator(coreComponents) - vmContainer, _ := metaVMFactory.Create() - return blproc.ArgMetaProcessor{ + valInfoCreator := createValidatorInfoCreator(coreComponents, dataComponents, shardCoordiantor) + args := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ CoreComponents: coreComponents, DataComponents: dataComponents, @@ -75,7 +67,7 @@ func createMockMetaArguments( StatusComponents: statusComponents, AccountsDB: accountsDb, ForkDetector: &mock2.ForkDetectorStub{}, - NodesCoordinator: nodesCoord, + NodesCoordinator: nc, FeeHandler: postprocess.NewFeeAccumulator(), RequestHandler: &testscommon.RequestHandlerStub{}, BlockChainHook: blockChainHook, @@ -103,6 +95,9 @@ func createMockMetaArguments( ValidatorStatisticsProcessor: validatorsInfoCreator, EpochSystemSCProcessor: systemSCProcessor, } + + metaProc, _ := blproc.NewMetaProcessor(args) + return metaProc } func createValidatorInfoCreator( @@ -144,7 +139,10 @@ func createEpochStartDataCreator( return epochStartDataCreator } -func createBlockTracker(genesisMetaHeader data.HeaderHandler, shardCoordinator sharding.Coordinator) process.BlockTracker { +func createBlockTracker( + genesisMetaHeader data.HeaderHandler, + shardCoordinator sharding.Coordinator, +) process.BlockTracker { genesisBlocks := make(map[uint32]data.HeaderHandler) for ShardID := uint32(0); ShardID < shardCoordinator.NumberOfShards(); ShardID++ { genesisBlocks[ShardID] = createGenesisBlock(ShardID) @@ -154,7 +152,7 @@ func createBlockTracker(genesisMetaHeader data.HeaderHandler, shardCoordinator s return mock.NewBlockTrackerMock(shardCoordinator, genesisBlocks) } -func createGenesisBlock(ShardID uint32) *block.Header { +func createGenesisBlock(shardID uint32) *block.Header { rootHash := []byte("roothash") return &block.Header{ Nonce: 0, @@ -162,7 +160,7 @@ func createGenesisBlock(ShardID uint32) *block.Header { Signature: rootHash, RandSeed: rootHash, PrevRandSeed: rootHash, - ShardID: ShardID, + ShardID: shardID, PubKeysBitmap: rootHash, RootHash: rootHash, PrevHash: rootHash, diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index f2bd2185306..6ee234cf385 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -1,7 +1,6 @@ package staking import ( - "fmt" "math/big" "github.com/ElrondNetwork/elrond-go-core/core" @@ -81,15 +80,8 @@ func createNodesCoordinator( NodeTypeProvider: coreComponents.NodeTypeProvider(), } - baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) - if err != nil { - fmt.Println("error creating node coordinator") - } - - nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinatorWithRater(baseNodesCoordinator, coreComponents.Rater()) - if err != nil { - fmt.Println("error creating node coordinator") - } + baseNodesCoordinator, _ := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) + nodesCoord, _ := nodesCoordinator.NewIndexHashedNodesCoordinatorWithRater(baseNodesCoordinator, coreComponents.Rater()) return nodesCoord } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index c18a6525778..9bf5819f2ed 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -24,7 +24,6 @@ import ( "github.com/ElrondNetwork/elrond-go/vm" ) -// TODO: Pass epoch config func createSystemSCProcessor( nc nodesCoordinator.NodesCoordinator, coreComponents factory2.CoreComponentsHolder, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 6d6a775b3b8..d0eca00f824 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -31,11 +31,6 @@ import ( const stakingV4InitEpoch = 1 const stakingV4EnableEpoch = 2 -type HeaderInfo struct { - Hash []byte - Header data.HeaderHandler -} - // TestMetaProcessor - type TestMetaProcessor struct { MetaBlockProcessor process.BlockProcessor @@ -66,7 +61,11 @@ func NewTestMetaProcessor( numOfNodesToShufflePerShard, ) - createStakingQueue(numOfNodesInStakingQueue, coreComponents.InternalMarshalizer(), stateComponents.AccountsAdapter()) + createStakingQueue( + numOfNodesInStakingQueue, + coreComponents.InternalMarshalizer(), + stateComponents.AccountsAdapter(), + ) nc := createNodesCoordinator( numOfMetaNodes, @@ -132,6 +131,7 @@ func NewTestMetaProcessor( blockChainHook, metaVmFactory, epochStartTrigger, + vmContainer, ), NodesCoordinator: nc, ValidatorStatistics: validatorStatisticsProcessor, @@ -200,7 +200,75 @@ func createStakingQueue( ) } -func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block.MetaBlock { +func createEpochStartTrigger( + coreComponents factory2.CoreComponentsHolder, + storageService dataRetriever.StorageService, +) integrationTests.TestEpochStartTrigger { + argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ + GenesisTime: time.Now(), + Settings: &config.EpochStartConfig{ + MinRoundsBetweenEpochs: 10, + RoundsPerEpoch: 10, + }, + Epoch: 0, + EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), + Storage: storageService, + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + AppStatusHandler: coreComponents.StatusHandler(), + } + + epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) + testTrigger := &metachain.TestTrigger{} + testTrigger.SetTrigger(epochStartTrigger) + + return testTrigger +} + +func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint64) { + for r := fromRound; r < fromRound+numOfRounds; r++ { + currentHeader, currentHash := tmp.getCurrentHeaderInfo() + + fmt.Println(fmt.Sprintf("########################################### CREATING HEADER FOR EPOCH %v in round %v", + tmp.EpochStartTrigger.Epoch(), + r, + )) + + _, err := tmp.MetaBlockProcessor.CreateNewHeader(r, r) + require.Nil(t, err) + + header := createMetaBlockToCommit(tmp.EpochStartTrigger.Epoch(), r, currentHash, currentHeader.GetRandSeed()) + newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, func() bool { return true }) + require.Nil(t, err) + + err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) + require.Nil(t, err) + + time.Sleep(time.Millisecond * 40) + + tmp.displayNodesConfig(tmp.EpochStartTrigger.Epoch()) + tmp.displayValidatorsInfo() + } +} + +func (tmp *TestMetaProcessor) getCurrentHeaderInfo() (data.HeaderHandler, []byte) { + currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() + currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() + if currentHeader == nil { + currentHeader = tmp.BlockChainHandler.GetGenesisHeader() + currentHash = tmp.BlockChainHandler.GetGenesisHeaderHash() + } + + return currentHeader, currentHash +} + +func createMetaBlockToCommit( + epoch uint32, + round uint64, + prevHash []byte, + prevRandSeed []byte, +) *block.MetaBlock { + roundStr := strconv.Itoa(int(round)) hdr := block.MetaBlock{ Epoch: epoch, Nonce: round, @@ -211,8 +279,8 @@ func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block. RootHash: []byte("roothash"), ShardInfo: make([]block.ShardData, 0), TxCount: 1, - PrevRandSeed: []byte("roothash"), - RandSeed: []byte("roothash" + strconv.Itoa(int(round))), + PrevRandSeed: prevRandSeed, + RandSeed: []byte("roothash" + roundStr), AccumulatedFeesInEpoch: big.NewInt(0), AccumulatedFees: big.NewInt(0), DevFeesInEpoch: big.NewInt(0), @@ -221,7 +289,7 @@ func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block. shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: []byte("mb_hash" + strconv.Itoa(int(round))), + Hash: []byte("mb_hash" + roundStr), ReceiverShardID: 0, SenderShardID: 0, TxCount: 1, @@ -230,7 +298,7 @@ func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block. shardData := block.ShardData{ Nonce: round, ShardID: 0, - HeaderHash: []byte("hdr_hash" + strconv.Itoa(int(round))), + HeaderHash: []byte("hdr_hash" + roundStr), TxCount: 1, ShardMiniBlockHeaders: shardMiniBlockHeaders, DeveloperFees: big.NewInt(0), @@ -241,71 +309,17 @@ func createMetaBlockHeader2(epoch uint32, round uint64, prevHash []byte) *block. return &hdr } -func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint32) { - for r := fromRound; r < fromRound+numOfRounds; r++ { - currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() - currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() - if currentHeader == nil { - currentHeader = tmp.BlockChainHandler.GetGenesisHeader() - currentHash = tmp.BlockChainHandler.GetGenesisHeaderHash() - } - - prevRandomness := currentHeader.GetRandSeed() - fmt.Println(fmt.Sprintf("########################################### CREATEING HEADER FOR EPOCH %v in round %v", - tmp.EpochStartTrigger.Epoch(), - r, - )) - - newHdr := createMetaBlockHeader2(tmp.EpochStartTrigger.Epoch(), uint64(r), currentHash) - newHdr.PrevRandSeed = prevRandomness - createdHdr, _ := tmp.MetaBlockProcessor.CreateNewHeader(uint64(r), uint64(r)) - _ = newHdr.SetEpoch(createdHdr.GetEpoch()) - - newHdr2, newBodyHandler2, err := tmp.MetaBlockProcessor.CreateBlock(newHdr, func() bool { return true }) - require.Nil(t, err) - err = tmp.MetaBlockProcessor.CommitBlock(newHdr2, newBodyHandler2) - require.Nil(t, err) - - time.Sleep(time.Millisecond * 100) - - tmp.DisplayNodesConfig(tmp.EpochStartTrigger.Epoch()) - - rootHash, _ := tmp.ValidatorStatistics.RootHash() - allValidatorsInfo, err := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - require.Nil(t, err) - displayValidatorsInfo(allValidatorsInfo) - } - -} +func (tmp *TestMetaProcessor) displayValidatorsInfo() { + rootHash, _ := tmp.ValidatorStatistics.RootHash() + validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) -func displayValidatorsInfo(validatorsInfoMap state.ShardValidatorsInfoMapHandler) { fmt.Println("#######################DISPLAYING VALIDATORS INFO") for _, validators := range validatorsInfoMap.GetAllValidatorsInfo() { fmt.Println("PUBKEY: ", string(validators.GetPublicKey()), " SHARDID: ", validators.GetShardId(), " LIST: ", validators.GetList()) } } -func createEpochStartTrigger(coreComponents factory2.CoreComponentsHolder, storageService dataRetriever.StorageService) integrationTests.TestEpochStartTrigger { - argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ - GenesisTime: time.Now(), - Settings: &config.EpochStartConfig{ - MinRoundsBetweenEpochs: 10, - RoundsPerEpoch: 10, - }, - Epoch: 0, - EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - Storage: storageService, - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - AppStatusHandler: coreComponents.StatusHandler(), - } - epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) - testTrigger := &metachain.TestTrigger{} - testTrigger.SetTrigger(epochStartTrigger) - return testTrigger -} - -func (tmp *TestMetaProcessor) DisplayNodesConfig(epoch uint32) { +func (tmp *TestMetaProcessor) displayNodesConfig(epoch uint32) { eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) From 16efa27f234e214f27553fa03a249856fbedd738 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 11 Apr 2022 14:46:31 +0300 Subject: [PATCH 179/958] FIX: Refactor 8 --- .../vm/staking/nodesCoordiantorCreator.go | 6 +- integrationTests/vm/staking/stakingV4_test.go | 53 ++++- .../vm/staking/systemSCCreator.go | 7 +- .../vm/staking/testMetaProcessor.go | 225 +++++++++++++----- 4 files changed, 228 insertions(+), 63 deletions(-) diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 6ee234cf385..5eacc5ec336 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -118,7 +118,7 @@ func generateGenesisNodeInfoMap( id := addressStartIdx for shardId := uint32(0); shardId < numOfShards; shardId++ { for n := uint32(0); n < numOfNodesPerShard; n++ { - addr := generateUniqueKey(id) + addr := generateAddress(id) validator := mock2.NewNodeInfo(addr, addr, shardId, initialRating) validatorsMap[shardId] = append(validatorsMap[shardId], validator) id++ @@ -126,7 +126,7 @@ func generateGenesisNodeInfoMap( } for n := uint32(0); n < numOfMetaNodes; n++ { - addr := generateUniqueKey(id) + addr := generateAddress(id) validator := mock2.NewNodeInfo(addr, addr, core.MetachainShardId, initialRating) validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) id++ @@ -155,7 +155,7 @@ func registerValidators( pubKey, pubKey, [][]byte{pubKey}, - big.NewInt(2000), + big.NewInt(2*nodePrice), marshaller, ) } diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 7590e8f7c01..2029386f207 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1,15 +1,62 @@ package staking import ( + "bytes" "testing" + + "github.com/stretchr/testify/require" ) -func TestNewTestMetaProcessor(t *testing.T) { - node := NewTestMetaProcessor(3, 3, 3, 3, 2, 2, 2, 10) +func requireSameSliceDifferentOrder(t *testing.T, s1, s2 [][]byte) { + require.Equal(t, len(s1), len(s2)) + + for _, elemInS1 := range s1 { + require.Contains(t, s2, elemInS1) + } +} + +func searchInMap(validatorMap map[uint32][][]byte, pk []byte) bool { + for _, validatorsInShard := range validatorMap { + for _, val := range validatorsInShard { + if bytes.Equal(val, pk) { + return true + } + } + } + return false +} + +func requireMapContains(t *testing.T, m map[uint32][][]byte, s [][]byte) { + for _, elemInSlice := range s { + found := searchInMap(m, elemInSlice) + require.True(t, found) + } +} + +func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { + allValidators := make([][]byte, 0) + for _, validatorsInShard := range validatorsMap { + allValidators = append(allValidators, validatorsInShard...) + } + + return allValidators +} +func TestNewTestMetaProcessor(t *testing.T) { + node := NewTestMetaProcessor(3, 3, 3, 3, 2, 2, 2, 2) + initialNodes := node.NodesConfig //logger.SetLogLevel("*:DEBUG,process:TRACE") //logger.SetLogLevel("*:DEBUG") node.EpochStartTrigger.SetRoundsPerEpoch(4) - node.Process(t, 1, 56) + node.Process(t, 5) + + eligibleAfterStakingV4Init := node.NodesConfig.eligible + require.Empty(t, node.NodesConfig.queue) + requireSameSliceDifferentOrder(t, initialNodes.queue, node.NodesConfig.auction) + + node.Process(t, 6) + requireMapContains(t, node.NodesConfig.shuffledOut, node.NodesConfig.auction) + requireMapContains(t, node.NodesConfig.waiting, initialNodes.queue) + requireMapContains(t, eligibleAfterStakingV4Init, node.NodesConfig.auction) //todo: check size } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 9bf5819f2ed..e7ee6ed9ab4 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -2,6 +2,7 @@ package staking import ( "bytes" + "strconv" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go/config" @@ -34,7 +35,7 @@ func createSystemSCProcessor( vmContainer process.VirtualMachinesContainer, ) process.EpochStartSystemSCProcessor { systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCProvider, _ := metachain.NewStakingDataProvider(systemVM, "1000") + stakingSCProvider, _ := metachain.NewStakingDataProvider(systemVM, strconv.Itoa(nodePrice)) args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, @@ -166,7 +167,7 @@ func createVMContainerFactory( FirstWhitelistedAddress: "3132333435363738393031323334353637383930313233343536373839303234", }, StakingSystemSCConfig: config.StakingSystemSCConfig{ - GenesisNodePrice: "1000", + GenesisNodePrice: strconv.Itoa(nodePrice), UnJailValue: "10", MinStepValue: "10", MinStakeValue: "1", @@ -191,7 +192,7 @@ func createVMContainerFactory( }, }, ValidatorAccountsDB: peerAccounts, - ChanceComputer: &mock3.ChanceComputerStub{}, + ChanceComputer: coreComponents.Rater(), EpochNotifier: coreComponents.EpochNotifier(), EpochConfig: &config.EpochConfig{ EnableEpochs: config.EnableEpochs{ diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index d0eca00f824..5299f2c2328 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,6 +1,5 @@ package staking -// nomindated proof of stake - polkadot import ( "fmt" "math/big" @@ -14,6 +13,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" @@ -24,12 +24,27 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/require" ) -const stakingV4InitEpoch = 1 -const stakingV4EnableEpoch = 2 +const ( + stakingV4InitEpoch = 1 + stakingV4EnableEpoch = 2 + addressLength = 15 + nodePrice = 1000 +) + +type NodesConfig struct { + eligible map[uint32][][]byte + waiting map[uint32][][]byte + leaving map[uint32][][]byte + shuffledOut map[uint32][][]byte + queue [][]byte + auction [][]byte +} // TestMetaProcessor - type TestMetaProcessor struct { @@ -38,6 +53,10 @@ type TestMetaProcessor struct { ValidatorStatistics process.ValidatorStatisticsProcessor EpochStartTrigger integrationTests.TestEpochStartTrigger BlockChainHandler data.ChainHandler + NodesConfig NodesConfig + CurrentRound uint64 + AccountsAdapter state.AccountsAdapter + Marshaller marshal.Marshalizer } // NewTestMetaProcessor - @@ -61,8 +80,9 @@ func NewTestMetaProcessor( numOfNodesToShufflePerShard, ) - createStakingQueue( + queue := createStakingQueue( numOfNodesInStakingQueue, + maxNodesConfig[0].MaxNumNodes, coreComponents.InternalMarshalizer(), stateComponents.AccountsAdapter(), ) @@ -118,7 +138,20 @@ func NewTestMetaProcessor( epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) + eligible, _ := nc.GetAllEligibleValidatorsPublicKeys(0) + waiting, _ := nc.GetAllWaitingValidatorsPublicKeys(0) + shuffledOut, _ := nc.GetAllShuffledOutValidatorsPublicKeys(0) + return &TestMetaProcessor{ + AccountsAdapter: stateComponents.AccountsAdapter(), + Marshaller: coreComponents.InternalMarshalizer(), + NodesConfig: NodesConfig{ + eligible: eligible, + waiting: waiting, + shuffledOut: shuffledOut, + queue: queue, + auction: make([][]byte, 0), + }, MetaBlockProcessor: createMetaBlockProcessor( nc, scp, @@ -133,6 +166,7 @@ func NewTestMetaProcessor( epochStartTrigger, vmContainer, ), + CurrentRound: 1, NodesCoordinator: nc, ValidatorStatistics: validatorStatisticsProcessor, EpochStartTrigger: epochStartTrigger, @@ -168,13 +202,15 @@ func createGasScheduleNotifier() core.GasScheduleNotifier { func createStakingQueue( numOfNodesInStakingQueue uint32, + totalNumOfNodes uint32, marshaller marshal.Marshalizer, accountsAdapter state.AccountsAdapter, -) { - owner := generateUniqueKey(50) +) [][]byte { + owner := generateAddress(totalNumOfNodes) + totalNumOfNodes += 1 ownerWaitingNodes := make([][]byte, 0) - for i := uint32(51); i < 51+numOfNodesInStakingQueue; i++ { - ownerWaitingNodes = append(ownerWaitingNodes, generateUniqueKey(i)) + for i := totalNumOfNodes; i < totalNumOfNodes+numOfNodesInStakingQueue; i++ { + ownerWaitingNodes = append(ownerWaitingNodes, generateAddress(i)) } testscommon.SaveOneKeyToWaitingList( @@ -195,9 +231,11 @@ func createStakingQueue( accountsAdapter, owner, ownerWaitingNodes, - big.NewInt(50000), + big.NewInt(int64(2*nodePrice*numOfNodesInStakingQueue)), marshaller, ) + + return ownerWaitingNodes } func createEpochStartTrigger( @@ -225,18 +263,18 @@ func createEpochStartTrigger( return testTrigger } -func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint64) { - for r := fromRound; r < fromRound+numOfRounds; r++ { +func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { + for r := tmp.CurrentRound; r < tmp.CurrentRound+numOfRounds; r++ { currentHeader, currentHash := tmp.getCurrentHeaderInfo() - fmt.Println(fmt.Sprintf("########################################### CREATING HEADER FOR EPOCH %v in round %v", + _, err := tmp.MetaBlockProcessor.CreateNewHeader(r, r) + require.Nil(t, err) + + fmt.Println(fmt.Sprintf("############## CREATING HEADER FOR EPOCH %v in round %v ##############", tmp.EpochStartTrigger.Epoch(), r, )) - _, err := tmp.MetaBlockProcessor.CreateNewHeader(r, r) - require.Nil(t, err) - header := createMetaBlockToCommit(tmp.EpochStartTrigger.Epoch(), r, currentHash, currentHeader.GetRandSeed()) newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, func() bool { return true }) require.Nil(t, err) @@ -246,9 +284,123 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, fromRound, numOfRounds uint6 time.Sleep(time.Millisecond * 40) - tmp.displayNodesConfig(tmp.EpochStartTrigger.Epoch()) - tmp.displayValidatorsInfo() + tmp.updateNodesConfig(tmp.EpochStartTrigger.Epoch()) + } + + tmp.CurrentRound += numOfRounds +} + +func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { + eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) + waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) + leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) + shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) + auction := make([][]byte, 0) + + for shard := range eligible { + for _, pk := range eligible[shard] { + fmt.Println("eligible", "pk", string(pk), "shardID", shard) + } + for _, pk := range waiting[shard] { + fmt.Println("waiting", "pk", string(pk), "shardID", shard) + } + for _, pk := range leaving[shard] { + fmt.Println("leaving", "pk", string(pk), "shardID", shard) + } + for _, pk := range shuffledOut[shard] { + fmt.Println("shuffled out", "pk", string(pk), "shardID", shard) + } + } + + rootHash, _ := tmp.ValidatorStatistics.RootHash() + validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + + fmt.Println("####### Auction list") + for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { + if validator.GetList() == string(common.AuctionList) { + auction = append(auction, validator.GetPublicKey()) + fmt.Println("auction pk", string(validator.GetPublicKey())) + } + } + + queue := tmp.searchPreviousFromHead() + fmt.Println("##### STAKING QUEUE") + for _, nodeInQueue := range queue { + fmt.Println(string(nodeInQueue)) } + + tmp.NodesConfig.eligible = eligible + tmp.NodesConfig.waiting = waiting + tmp.NodesConfig.shuffledOut = shuffledOut + tmp.NodesConfig.leaving = leaving + tmp.NodesConfig.auction = auction + tmp.NodesConfig.queue = queue +} + +func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { + acc, _ := accountsDB.LoadAccount(address) + stakingSCAcc := acc.(state.UserAccountHandler) + + return stakingSCAcc +} + +func (tmp *TestMetaProcessor) searchPreviousFromHead() [][]byte { + stakingSCAcc := loadSCAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + + waitingList := &systemSmartContracts.WaitingList{ + FirstKey: make([]byte, 0), + LastKey: make([]byte, 0), + Length: 0, + LastJailedKey: make([]byte, 0), + } + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + if len(marshaledData) == 0 { + return nil + } + + err := tmp.Marshaller.Unmarshal(waitingList, marshaledData) + if err != nil { + return nil + } + + index := uint32(1) + nextKey := make([]byte, len(waitingList.FirstKey)) + copy(nextKey, waitingList.FirstKey) + + allPubKeys := make([][]byte, 0) + for len(nextKey) != 0 && index <= waitingList.Length { + allPubKeys = append(allPubKeys, nextKey) + + element, errGet := tmp.getWaitingListElement(nextKey) + if errGet != nil { + return nil + } + + nextKey = make([]byte, len(element.NextKey)) + if len(element.NextKey) == 0 { + break + } + index++ + copy(nextKey, element.NextKey) + } + return allPubKeys +} + +func (tmp *TestMetaProcessor) getWaitingListElement(key []byte) (*systemSmartContracts.ElementInList, error) { + stakingSCAcc := loadSCAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) + if len(marshaledData) == 0 { + return nil, vm.ErrElementNotFound + } + + element := &systemSmartContracts.ElementInList{} + err := tmp.Marshaller.Unmarshal(element, marshaledData) + if err != nil { + return nil, err + } + + return element, nil } func (tmp *TestMetaProcessor) getCurrentHeaderInfo() (data.HeaderHandler, []byte) { @@ -309,42 +461,7 @@ func createMetaBlockToCommit( return &hdr } -func (tmp *TestMetaProcessor) displayValidatorsInfo() { - rootHash, _ := tmp.ValidatorStatistics.RootHash() - validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - - fmt.Println("#######################DISPLAYING VALIDATORS INFO") - for _, validators := range validatorsInfoMap.GetAllValidatorsInfo() { - fmt.Println("PUBKEY: ", string(validators.GetPublicKey()), " SHARDID: ", validators.GetShardId(), " LIST: ", validators.GetList()) - } -} - -func (tmp *TestMetaProcessor) displayNodesConfig(epoch uint32) { - eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) - waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) - leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) - shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) - - fmt.Println("############### Displaying nodes config in epoch " + strconv.Itoa(int(epoch))) - - for shard := range eligible { - for _, pk := range eligible[shard] { - fmt.Println("eligible", "pk", string(pk), "shardID", shard) - } - for _, pk := range waiting[shard] { - fmt.Println("waiting", "pk", string(pk), "shardID", shard) - } - for _, pk := range leaving[shard] { - fmt.Println("leaving", "pk", string(pk), "shardID", shard) - } - for _, pk := range shuffledOut[shard] { - fmt.Println("shuffled out", "pk", string(pk), "shardID", shard) - } - } -} - -func generateUniqueKey(identifier uint32) []byte { - neededLength := 15 //192 +func generateAddress(identifier uint32) []byte { uniqueIdentifier := fmt.Sprintf("address-%d", identifier) - return []byte(strings.Repeat("0", neededLength-len(uniqueIdentifier)) + uniqueIdentifier) + return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) } From 11f7dc5ed670750d8bca92b9d4b0fa6460f62966 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 11 Apr 2022 18:01:31 +0300 Subject: [PATCH 180/958] FIX: Refactor 9 --- epochStart/metachain/systemSCs.go | 13 +++- integrationTests/vm/staking/stakingV4_test.go | 61 +++++++++++++++---- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 595caaff85c..5c34965c8f8 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -147,9 +147,20 @@ func (s *systemSCProcessor) processWithNewFlags( return nil } +func (s *systemSCProcessor) calcShuffledOutNodes() uint32 { + maxNodesConfigLen := len(s.maxNodesEnableConfig) + if maxNodesConfigLen == 0 { + return 0 + } + + nodesToShufflePerShard := s.maxNodesEnableConfig[maxNodesConfigLen-1].NodesToShufflePerShard + return nodesToShufflePerShard * s.shardCoordinator.NumberOfShards() +} + func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) - numOfValidators -= 2 * 4 + numOfShuffledNodes := s.calcShuffledOutNodes() + numOfValidators -= numOfShuffledNodes availableSlots, err := safeSub(s.maxNodes, numOfValidators) log.Info("systemSCProcessor.selectNodesFromAuctionList", "max nodes", s.maxNodes, diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 2029386f207..4ae7526dfe7 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -28,9 +28,9 @@ func searchInMap(validatorMap map[uint32][][]byte, pk []byte) bool { func requireMapContains(t *testing.T, m map[uint32][][]byte, s [][]byte) { for _, elemInSlice := range s { - found := searchInMap(m, elemInSlice) - require.True(t, found) + require.True(t, searchInMap(m, elemInSlice)) } + } func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { @@ -43,20 +43,55 @@ func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { } func TestNewTestMetaProcessor(t *testing.T) { - node := NewTestMetaProcessor(3, 3, 3, 3, 2, 2, 2, 2) - initialNodes := node.NodesConfig - //logger.SetLogLevel("*:DEBUG,process:TRACE") - //logger.SetLogLevel("*:DEBUG") + numOfMetaNodes := uint32(10) + numOfShards := uint32(3) + numOfEligibleNodesPerShard := uint32(10) + numOfWaitingNodesPerShard := uint32(10) + numOfNodesToShufflePerShard := uint32(3) + shardConsensusGroupSize := 3 + metaConsensusGroupSize := 3 + numOfNodesInStakingQueue := uint32(4) + + totalEligible := int(numOfEligibleNodesPerShard*numOfShards) + int(numOfMetaNodes) + totalWaiting := int(numOfWaitingNodesPerShard*numOfShards) + int(numOfMetaNodes) + + node := NewTestMetaProcessor( + numOfMetaNodes, + numOfShards, + numOfEligibleNodesPerShard, + numOfWaitingNodesPerShard, + numOfNodesToShufflePerShard, + shardConsensusGroupSize, + metaConsensusGroupSize, + numOfNodesInStakingQueue, + ) node.EpochStartTrigger.SetRoundsPerEpoch(4) - node.Process(t, 5) + initialNodes := node.NodesConfig + require.Len(t, getAllPubKeys(initialNodes.eligible), totalEligible) + require.Len(t, getAllPubKeys(initialNodes.waiting), totalWaiting) + require.Len(t, initialNodes.queue, int(numOfNodesInStakingQueue)) + require.Empty(t, initialNodes.shuffledOut) + require.Empty(t, initialNodes.auction) - eligibleAfterStakingV4Init := node.NodesConfig.eligible - require.Empty(t, node.NodesConfig.queue) - requireSameSliceDifferentOrder(t, initialNodes.queue, node.NodesConfig.auction) + node.Process(t, 5) + nodesConfigStakingV4Init := node.NodesConfig + require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) + require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) + require.Empty(t, nodesConfigStakingV4Init.queue) + require.Empty(t, nodesConfigStakingV4Init.shuffledOut) + requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) node.Process(t, 6) - requireMapContains(t, node.NodesConfig.shuffledOut, node.NodesConfig.auction) - requireMapContains(t, node.NodesConfig.waiting, initialNodes.queue) - requireMapContains(t, eligibleAfterStakingV4Init, node.NodesConfig.auction) //todo: check size + nodesConfigStakingV4 := node.NodesConfig + require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) + require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), totalWaiting-int((numOfShards+1)*numOfNodesToShufflePerShard)+len(nodesConfigStakingV4Init.auction)) + + requireMapContains(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) // all current waiting are from the previous auction + requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) // all current auction are from previous eligible + + //requireMapContains(t, node.NodesConfig.shuffledOut, node.NodesConfig.auction, uint32(len(node.NodesConfig.shuffledOut))) + //requireMapContains(t, eligibleAfterStakingV4Init, node.NodesConfig.auction, 8) //todo: check size + + //node.Process(t, 20) } From cd02f3a4c056959924f72809dbd746d4b7d2e14f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 12 Apr 2022 14:35:03 +0300 Subject: [PATCH 181/958] FIX: Refactor 10 --- integrationTests/vm/staking/stakingV4_test.go | 55 ++++++++++++---- .../vm/staking/testMetaProcessor.go | 63 +++++++++++-------- 2 files changed, 80 insertions(+), 38 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 4ae7526dfe7..20c276176fa 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -43,14 +43,14 @@ func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { } func TestNewTestMetaProcessor(t *testing.T) { - numOfMetaNodes := uint32(10) + numOfMetaNodes := uint32(400) numOfShards := uint32(3) - numOfEligibleNodesPerShard := uint32(10) - numOfWaitingNodesPerShard := uint32(10) - numOfNodesToShufflePerShard := uint32(3) - shardConsensusGroupSize := 3 - metaConsensusGroupSize := 3 - numOfNodesInStakingQueue := uint32(4) + numOfEligibleNodesPerShard := uint32(400) + numOfWaitingNodesPerShard := uint32(400) + numOfNodesToShufflePerShard := uint32(80) + shardConsensusGroupSize := 266 + metaConsensusGroupSize := 266 + numOfNodesInStakingQueue := uint32(60) totalEligible := int(numOfEligibleNodesPerShard*numOfShards) + int(numOfMetaNodes) totalWaiting := int(numOfWaitingNodesPerShard*numOfShards) + int(numOfMetaNodes) @@ -67,6 +67,7 @@ func TestNewTestMetaProcessor(t *testing.T) { ) node.EpochStartTrigger.SetRoundsPerEpoch(4) + // 1. Check initial config is correct initialNodes := node.NodesConfig require.Len(t, getAllPubKeys(initialNodes.eligible), totalEligible) require.Len(t, getAllPubKeys(initialNodes.waiting), totalWaiting) @@ -74,6 +75,7 @@ func TestNewTestMetaProcessor(t *testing.T) { require.Empty(t, initialNodes.shuffledOut) require.Empty(t, initialNodes.auction) + // 2. Check config after staking v4 initialization node.Process(t, 5) nodesConfigStakingV4Init := node.NodesConfig require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) @@ -82,16 +84,43 @@ func TestNewTestMetaProcessor(t *testing.T) { require.Empty(t, nodesConfigStakingV4Init.shuffledOut) requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) + // 3. Check config after first staking v4 epoch node.Process(t, 6) nodesConfigStakingV4 := node.NodesConfig require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) - require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), totalWaiting-int((numOfShards+1)*numOfNodesToShufflePerShard)+len(nodesConfigStakingV4Init.auction)) - requireMapContains(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) // all current waiting are from the previous auction - requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) // all current auction are from previous eligible + numOfShuffledOut := int((numOfShards + 1) * numOfNodesToShufflePerShard) + newWaiting := totalWaiting - numOfShuffledOut + len(nodesConfigStakingV4Init.auction) + require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), newWaiting) - //requireMapContains(t, node.NodesConfig.shuffledOut, node.NodesConfig.auction, uint32(len(node.NodesConfig.shuffledOut))) - //requireMapContains(t, eligibleAfterStakingV4Init, node.NodesConfig.auction, 8) //todo: check size + // All shuffled out are in auction + require.Len(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), numOfShuffledOut) + requireSameSliceDifferentOrder(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), nodesConfigStakingV4.auction) - //node.Process(t, 20) + // All current waiting are from the previous auction + requireMapContains(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) + // All current auction are from previous eligible + requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) + + rounds := 0 + prevConfig := nodesConfigStakingV4 + prevNumOfWaiting := newWaiting + for rounds < 10 { + node.Process(t, 5) + newNodeConfig := node.NodesConfig + + newWaiting = prevNumOfWaiting - numOfShuffledOut + len(prevConfig.auction) + require.Len(t, getAllPubKeys(newNodeConfig.waiting), newWaiting) + require.Len(t, getAllPubKeys(newNodeConfig.eligible), totalEligible) + + require.Len(t, getAllPubKeys(newNodeConfig.shuffledOut), numOfShuffledOut) + requireSameSliceDifferentOrder(t, getAllPubKeys(newNodeConfig.shuffledOut), newNodeConfig.auction) + + requireMapContains(t, newNodeConfig.waiting, prevConfig.auction) + requireMapContains(t, prevConfig.eligible, newNodeConfig.auction) + + prevConfig = newNodeConfig + prevNumOfWaiting = newWaiting + rounds++ + } } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 5299f2c2328..4ddb52e49c6 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -57,6 +57,8 @@ type TestMetaProcessor struct { CurrentRound uint64 AccountsAdapter state.AccountsAdapter Marshaller marshal.Marshalizer + + metaConsensusGroupSize uint32 } // NewTestMetaProcessor - @@ -166,11 +168,12 @@ func NewTestMetaProcessor( epochStartTrigger, vmContainer, ), - CurrentRound: 1, - NodesCoordinator: nc, - ValidatorStatistics: validatorStatisticsProcessor, - EpochStartTrigger: epochStartTrigger, - BlockChainHandler: dataComponents.Blockchain(), + CurrentRound: 1, + NodesCoordinator: nc, + metaConsensusGroupSize: uint32(metaConsensusGroupSize), + ValidatorStatistics: validatorStatisticsProcessor, + EpochStartTrigger: epochStartTrigger, + BlockChainHandler: dataComponents.Blockchain(), } } @@ -275,7 +278,13 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { r, )) - header := createMetaBlockToCommit(tmp.EpochStartTrigger.Epoch(), r, currentHash, currentHeader.GetRandSeed()) + header := createMetaBlockToCommit( + tmp.EpochStartTrigger.Epoch(), + r, + currentHash, + currentHeader.GetRandSeed(), + tmp.metaConsensusGroupSize/8+1, + ) newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, func() bool { return true }) require.Nil(t, err) @@ -290,44 +299,47 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { tmp.CurrentRound += numOfRounds } +func displayValidators(list string, pubKeys [][]byte, shardID uint32) { + pubKeysToDisplay := pubKeys + if len(pubKeys) > 6 { + pubKeysToDisplay = make([][]byte, 0) + pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[:3]...) + pubKeysToDisplay = append(pubKeysToDisplay, [][]byte{[]byte("...")}...) + pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[len(pubKeys)-3:]...) + } + + for _, pk := range pubKeysToDisplay { + fmt.Println(list, "pk", string(pk), "shardID", shardID) + } +} + func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) - auction := make([][]byte, 0) for shard := range eligible { - for _, pk := range eligible[shard] { - fmt.Println("eligible", "pk", string(pk), "shardID", shard) - } - for _, pk := range waiting[shard] { - fmt.Println("waiting", "pk", string(pk), "shardID", shard) - } - for _, pk := range leaving[shard] { - fmt.Println("leaving", "pk", string(pk), "shardID", shard) - } - for _, pk := range shuffledOut[shard] { - fmt.Println("shuffled out", "pk", string(pk), "shardID", shard) - } + displayValidators("eligible", eligible[shard], shard) + displayValidators("waiting", waiting[shard], shard) + displayValidators("leaving", leaving[shard], shard) + displayValidators("shuffled", shuffledOut[shard], shard) } rootHash, _ := tmp.ValidatorStatistics.RootHash() validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + auction := make([][]byte, 0) fmt.Println("####### Auction list") for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { if validator.GetList() == string(common.AuctionList) { auction = append(auction, validator.GetPublicKey()) - fmt.Println("auction pk", string(validator.GetPublicKey())) } } - + displayValidators("auction", auction, 0) queue := tmp.searchPreviousFromHead() fmt.Println("##### STAKING QUEUE") - for _, nodeInQueue := range queue { - fmt.Println(string(nodeInQueue)) - } + displayValidators("queue", queue, 0) tmp.NodesConfig.eligible = eligible tmp.NodesConfig.waiting = waiting @@ -419,6 +431,7 @@ func createMetaBlockToCommit( round uint64, prevHash []byte, prevRandSeed []byte, + consensusSize uint32, ) *block.MetaBlock { roundStr := strconv.Itoa(int(round)) hdr := block.MetaBlock{ @@ -427,7 +440,7 @@ func createMetaBlockToCommit( Round: round, PrevHash: prevHash, Signature: []byte("signature"), - PubKeysBitmap: []byte("pubKeysBitmap"), + PubKeysBitmap: []byte(strings.Repeat("f", int(consensusSize))), RootHash: []byte("roothash"), ShardInfo: make([]block.ShardData, 0), TxCount: 1, From f1bd22bd1c4d457164fa9a957fc7bfdb19ec615f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 12 Apr 2022 19:10:35 +0300 Subject: [PATCH 182/958] FIX: Refactor 11 --- epochStart/metachain/legacySystemSCs.go | 2 + epochStart/metachain/systemSCs.go | 21 +- epochStart/metachain/systemSCs_test.go | 27 +-- .../vm/staking/configDisplayer.go | 74 +++++++ .../vm/staking/nodesCoordiantorCreator.go | 1 - integrationTests/vm/staking/stakingQueue.go | 110 +++++++++++ integrationTests/vm/staking/stakingV4_test.go | 8 +- .../vm/staking/testMetaProcessor.go | 180 +++--------------- testscommon/stakingCommon.go | 14 +- 9 files changed, 241 insertions(+), 196 deletions(-) create mode 100644 integrationTests/vm/staking/configDisplayer.go create mode 100644 integrationTests/vm/staking/stakingQueue.go diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 4e3d0c425c3..485c0e0b06a 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -45,6 +45,7 @@ type legacySystemSCProcessor struct { mapNumSwitchedPerShard map[uint32]uint32 mapNumSwitchablePerShard map[uint32]uint32 maxNodesEnableConfig []config.MaxNodesChangeConfig + currentNodesEnableConfig config.MaxNodesChangeConfig maxNodes uint32 switchEnableEpoch uint32 @@ -1365,6 +1366,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { if epoch == maxNodesConfig.EpochEnable { s.flagChangeMaxNodesEnabled.SetValue(true) s.maxNodes = maxNodesConfig.MaxNumNodes + s.currentNodesEnableConfig = maxNodesConfig break } } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 5c34965c8f8..931bd3933f7 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -148,24 +148,22 @@ func (s *systemSCProcessor) processWithNewFlags( } func (s *systemSCProcessor) calcShuffledOutNodes() uint32 { - maxNodesConfigLen := len(s.maxNodesEnableConfig) - if maxNodesConfigLen == 0 { - return 0 - } - - nodesToShufflePerShard := s.maxNodesEnableConfig[maxNodesConfigLen-1].NodesToShufflePerShard - return nodesToShufflePerShard * s.shardCoordinator.NumberOfShards() + nodesToShufflePerShard := s.currentNodesEnableConfig.NodesToShufflePerShard + return nodesToShufflePerShard * (s.shardCoordinator.NumberOfShards() + 1) // TODO: THIS IS NOT OK; meta does not shuffle the sam num of nodes } func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { - auctionList, numOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) + auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) numOfShuffledNodes := s.calcShuffledOutNodes() - numOfValidators -= numOfShuffledNodes + numOfValidators := currNumOfValidators - numOfShuffledNodes availableSlots, err := safeSub(s.maxNodes, numOfValidators) + auctionListSize := uint32(len(auctionList)) log.Info("systemSCProcessor.selectNodesFromAuctionList", "max nodes", s.maxNodes, - "num of validators", numOfValidators, - "auction list size", len(auctionList), + "current number of validators", currNumOfValidators, + "num of nodes which will be shuffled", numOfShuffledNodes, + "num of validators after shuffling", numOfValidators, + "auction list size", auctionListSize, "available slots", availableSlots, ) // todo: change to log.debug @@ -179,7 +177,6 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S return err } - auctionListSize := uint32(len(auctionList)) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) s.displayAuctionList(auctionList, numOfAvailableNodeSlots) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 1c7d76f0e1c..28bf0285ca3 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -215,7 +215,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s numEligible := 9 numWaiting := 5 numJailed := 8 - stakingScAcc := loadSCAccount(args.UserAccountsDB, vm.StakingSCAddress) + stakingScAcc := testscommon.LoadUserAccount(args.UserAccountsDB, vm.StakingSCAddress) createEligibleNodes(numEligible, stakingScAcc, args.Marshalizer) _ = createWaitingNodes(numWaiting, stakingScAcc, args.UserAccountsDB, args.Marshalizer) jailed := createJailedNodes(numJailed, stakingScAcc, args.UserAccountsDB, args.PeerAccountsDB, args.Marshalizer) @@ -512,13 +512,6 @@ func doUnStake(t *testing.T, systemVm vmcommon.VMExecutionHandler, accountsDB st saveOutputAccounts(t, accountsDB, vmOutput) } -func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { - acc, _ := accountsDB.LoadAccount(address) - stakingSCAcc := acc.(state.UserAccountHandler) - - return stakingSCAcc -} - func createEligibleNodes(numNodes int, stakingSCAcc state.UserAccountHandler, marshalizer marshal.Marshalizer) { for i := 0; i < numNodes; i++ { stakedData := &systemSmartContracts.StakedDataV2_0{ @@ -574,8 +567,8 @@ func addValidatorDataWithUnStakedKey( nodePrice *big.Int, marshalizer marshal.Marshalizer, ) { - stakingAccount := loadSCAccount(accountsDB, vm.StakingSCAddress) - validatorAccount := loadSCAccount(accountsDB, vm.ValidatorSCAddress) + stakingAccount := testscommon.LoadUserAccount(accountsDB, vm.StakingSCAddress) + validatorAccount := testscommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) validatorData := &systemSmartContracts.ValidatorDataV2{ RegisterNonce: 0, @@ -1239,7 +1232,7 @@ func addDelegationData( stakedKeys [][]byte, marshalizer marshal.Marshalizer, ) { - delegatorSC := loadSCAccount(accountsDB, delegation) + delegatorSC := testscommon.LoadUserAccount(accountsDB, delegation) dStatus := &systemSmartContracts.DelegationContractStatus{ StakedKeys: make([]*systemSmartContracts.NodesData, 0), NotStakedKeys: make([]*systemSmartContracts.NodesData, 0), @@ -1332,7 +1325,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra assert.Equal(t, peerAcc.GetList(), string(common.LeavingList)) assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 4) - delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr) + delegationSC := testscommon.LoadUserAccount(args.UserAccountsDB, delegationAddr) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) assert.Nil(t, err) dStatus := &systemSmartContracts.DelegationContractStatus{ @@ -1417,7 +1410,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional assert.Equal(t, string(common.EligibleList), vInfo.GetList()) } - delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr) + delegationSC := testscommon.LoadUserAccount(args.UserAccountsDB, delegationAddr) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) assert.Nil(t, err) dStatus := &systemSmartContracts.DelegationContractStatus{ @@ -1510,7 +1503,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - delegationSC := loadSCAccount(args.UserAccountsDB, delegationAddr2) + delegationSC := testscommon.LoadUserAccount(args.UserAccountsDB, delegationAddr2) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) assert.Nil(t, err) dStatus := &systemSmartContracts.DelegationContractStatus{ @@ -1526,7 +1519,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( assert.Equal(t, []byte("waitingPubKe4"), dStatus.UnStakedKeys[0].BLSKey) assert.Equal(t, []byte("waitingPubKe3"), dStatus.UnStakedKeys[1].BLSKey) - stakingSCAcc := loadSCAccount(args.UserAccountsDB, vm.StakingSCAddress) + stakingSCAcc := testscommon.LoadUserAccount(args.UserAccountsDB, vm.StakingSCAddress) marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) waitingListHead := &systemSmartContracts.WaitingList{} _ = args.Marshalizer.Unmarshal(waitingListHead, marshaledData) @@ -1597,14 +1590,14 @@ func TestSystemSCProcessor_TogglePauseUnPause(t *testing.T) { err := s.ToggleUnStakeUnBond(true) assert.Nil(t, err) - validatorSC := loadSCAccount(s.userAccountsDB, vm.ValidatorSCAddress) + validatorSC := testscommon.LoadUserAccount(s.userAccountsDB, vm.ValidatorSCAddress) value, _ := validatorSC.DataTrie().Get([]byte("unStakeUnBondPause")) assert.True(t, value[0] == 1) err = s.ToggleUnStakeUnBond(false) assert.Nil(t, err) - validatorSC = loadSCAccount(s.userAccountsDB, vm.ValidatorSCAddress) + validatorSC = testscommon.LoadUserAccount(s.userAccountsDB, vm.ValidatorSCAddress) value, _ = validatorSC.DataTrie().Get([]byte("unStakeUnBondPause")) assert.True(t, value[0] == 0) } diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go new file mode 100644 index 00000000000..379f2516127 --- /dev/null +++ b/integrationTests/vm/staking/configDisplayer.go @@ -0,0 +1,74 @@ +package staking + +import ( + "fmt" + "strconv" + + "github.com/ElrondNetwork/elrond-go-core/display" +) + +const ( + delimiter = "#" + maxPubKeysListLen = 6 +) + +// TODO: Make a subcomponent which will register to epoch notifier to display config only upon epoch change + +func getShortPubKeysList(pubKeys [][]byte) [][]byte { + pubKeysToDisplay := pubKeys + if len(pubKeys) > maxPubKeysListLen { + pubKeysToDisplay = make([][]byte, 0) + pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[:maxPubKeysListLen/2]...) + pubKeysToDisplay = append(pubKeysToDisplay, [][]byte{[]byte("...")}...) + pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[len(pubKeys)-maxPubKeysListLen/2:]...) + } + + return pubKeysToDisplay +} + +func displayConfig(config nodesConfig) { + lines := make([]*display.LineData, 0) + + for shard := range config.eligible { + lines = append(lines, getDisplayableValidatorsInShard("eligible", config.eligible[shard], shard)...) + lines = append(lines, getDisplayableValidatorsInShard("waiting", config.waiting[shard], shard)...) + lines = append(lines, getDisplayableValidatorsInShard("leaving", config.leaving[shard], shard)...) + lines = append(lines, getDisplayableValidatorsInShard("shuffled", config.shuffledOut[shard], shard)...) + lines = append(lines, display.NewLineData(true, []string{})) + } + + tableHeader := []string{"List", "Pub key", "Shard ID"} + table, _ := display.CreateTableString(tableHeader, lines) + headline := display.Headline("Nodes config", "", delimiter) + fmt.Println(fmt.Sprintf("%s\n%s", headline, table)) + + displayValidators("Auction", config.auction) + displayValidators("Queue", config.queue) +} + +func getDisplayableValidatorsInShard(list string, pubKeys [][]byte, shardID uint32) []*display.LineData { + pubKeysToDisplay := getShortPubKeysList(pubKeys) + + lines := make([]*display.LineData, 0) + for idx, pk := range pubKeysToDisplay { + horizontalLine := idx == len(pubKeysToDisplay)-1 + line := display.NewLineData(horizontalLine, []string{list, string(pk), strconv.Itoa(int(shardID))}) + lines = append(lines, line) + } + + return lines +} + +func displayValidators(list string, pubKeys [][]byte) { + pubKeysToDisplay := getShortPubKeysList(pubKeys) + + lines := make([]*display.LineData, 0) + tableHeader := []string{"List", "Pub key"} + for _, pk := range pubKeysToDisplay { + lines = append(lines, display.NewLineData(false, []string{list, string(pk)})) + } + + headline := display.Headline(fmt.Sprintf("%s list", list), "", delimiter) + table, _ := display.CreateTableString(tableHeader, lines) + fmt.Println(fmt.Sprintf("%s \n%s", headline, table)) +} diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 5eacc5ec336..fc370eea741 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -16,7 +16,6 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" ) -// shuffler constants const ( shuffleBetweenShards = false adaptivity = false diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go new file mode 100644 index 00000000000..98cc143aac4 --- /dev/null +++ b/integrationTests/vm/staking/stakingQueue.go @@ -0,0 +1,110 @@ +package staking + +import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" +) + +func createStakingQueue( + numOfNodesInStakingQueue uint32, + totalNumOfNodes uint32, + marshaller marshal.Marshalizer, + accountsAdapter state.AccountsAdapter, +) [][]byte { + owner := generateAddress(totalNumOfNodes) + totalNumOfNodes += 1 + ownerWaitingNodes := make([][]byte, 0) + for i := totalNumOfNodes; i < totalNumOfNodes+numOfNodesInStakingQueue; i++ { + ownerWaitingNodes = append(ownerWaitingNodes, generateAddress(i)) + } + + // We need to save one key and then add keys to waiting list because there is a bug in those functions + // TODO: FIX bug in testscommon.AddKeysToWaitingList to also init staking queue if there are no keys in list + testscommon.SaveOneKeyToWaitingList( + accountsAdapter, + ownerWaitingNodes[0], + marshaller, + owner, + owner, + ) + testscommon.AddKeysToWaitingList( + accountsAdapter, + ownerWaitingNodes[1:], + marshaller, + owner, + owner, + ) + testscommon.AddValidatorData( + accountsAdapter, + owner, + ownerWaitingNodes, + big.NewInt(int64(2*nodePrice*numOfNodesInStakingQueue)), + marshaller, + ) + + return ownerWaitingNodes +} + +func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { + stakingSCAcc := testscommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + + waitingList := &systemSmartContracts.WaitingList{ + FirstKey: make([]byte, 0), + LastKey: make([]byte, 0), + Length: 0, + LastJailedKey: make([]byte, 0), + } + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + if len(marshaledData) == 0 { + return nil + } + + err := tmp.Marshaller.Unmarshal(waitingList, marshaledData) + if err != nil { + return nil + } + + index := uint32(1) + nextKey := make([]byte, len(waitingList.FirstKey)) + copy(nextKey, waitingList.FirstKey) + + allPubKeys := make([][]byte, 0) + for len(nextKey) != 0 && index <= waitingList.Length { + allPubKeys = append(allPubKeys, nextKey) + + element, errGet := tmp.getWaitingListElement(nextKey) + if errGet != nil { + return nil + } + + nextKey = make([]byte, len(element.NextKey)) + if len(element.NextKey) == 0 { + break + } + index++ + copy(nextKey, element.NextKey) + } + return allPubKeys +} + +func (tmp *TestMetaProcessor) getWaitingListElement(key []byte) (*systemSmartContracts.ElementInList, error) { + stakingSCAcc := testscommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) + if len(marshaledData) == 0 { + return nil, vm.ErrElementNotFound + } + + element := &systemSmartContracts.ElementInList{} + err := tmp.Marshaller.Unmarshal(element, marshaledData) + if err != nil { + return nil, err + } + + return element, nil +} diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 20c276176fa..7fdd15a48bf 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -76,7 +76,7 @@ func TestNewTestMetaProcessor(t *testing.T) { require.Empty(t, initialNodes.auction) // 2. Check config after staking v4 initialization - node.Process(t, 5) + node.Process(t, 6) nodesConfigStakingV4Init := node.NodesConfig require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) @@ -102,10 +102,10 @@ func TestNewTestMetaProcessor(t *testing.T) { // All current auction are from previous eligible requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) - rounds := 0 + epochs := 0 prevConfig := nodesConfigStakingV4 prevNumOfWaiting := newWaiting - for rounds < 10 { + for epochs < 10 { node.Process(t, 5) newNodeConfig := node.NodesConfig @@ -121,6 +121,6 @@ func TestNewTestMetaProcessor(t *testing.T) { prevConfig = newNodeConfig prevNumOfWaiting = newWaiting - rounds++ + epochs++ } } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 4ddb52e49c6..768e8443e12 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -12,6 +12,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" @@ -23,9 +24,6 @@ import ( "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/require" ) @@ -37,7 +35,7 @@ const ( nodePrice = 1000 ) -type NodesConfig struct { +type nodesConfig struct { eligible map[uint32][][]byte waiting map[uint32][][]byte leaving map[uint32][][]byte @@ -53,12 +51,10 @@ type TestMetaProcessor struct { ValidatorStatistics process.ValidatorStatisticsProcessor EpochStartTrigger integrationTests.TestEpochStartTrigger BlockChainHandler data.ChainHandler - NodesConfig NodesConfig + NodesConfig nodesConfig CurrentRound uint64 AccountsAdapter state.AccountsAdapter Marshaller marshal.Marshalizer - - metaConsensusGroupSize uint32 } // NewTestMetaProcessor - @@ -147,7 +143,7 @@ func NewTestMetaProcessor( return &TestMetaProcessor{ AccountsAdapter: stateComponents.AccountsAdapter(), Marshaller: coreComponents.InternalMarshalizer(), - NodesConfig: NodesConfig{ + NodesConfig: nodesConfig{ eligible: eligible, waiting: waiting, shuffledOut: shuffledOut, @@ -168,12 +164,11 @@ func NewTestMetaProcessor( epochStartTrigger, vmContainer, ), - CurrentRound: 1, - NodesCoordinator: nc, - metaConsensusGroupSize: uint32(metaConsensusGroupSize), - ValidatorStatistics: validatorStatisticsProcessor, - EpochStartTrigger: epochStartTrigger, - BlockChainHandler: dataComponents.Blockchain(), + CurrentRound: 1, + NodesCoordinator: nc, + ValidatorStatistics: validatorStatisticsProcessor, + EpochStartTrigger: epochStartTrigger, + BlockChainHandler: dataComponents.Blockchain(), } } @@ -203,44 +198,6 @@ func createGasScheduleNotifier() core.GasScheduleNotifier { return mock.NewGasScheduleNotifierMock(gasSchedule) } -func createStakingQueue( - numOfNodesInStakingQueue uint32, - totalNumOfNodes uint32, - marshaller marshal.Marshalizer, - accountsAdapter state.AccountsAdapter, -) [][]byte { - owner := generateAddress(totalNumOfNodes) - totalNumOfNodes += 1 - ownerWaitingNodes := make([][]byte, 0) - for i := totalNumOfNodes; i < totalNumOfNodes+numOfNodesInStakingQueue; i++ { - ownerWaitingNodes = append(ownerWaitingNodes, generateAddress(i)) - } - - testscommon.SaveOneKeyToWaitingList( - accountsAdapter, - ownerWaitingNodes[0], - marshaller, - owner, - owner, - ) - testscommon.AddKeysToWaitingList( - accountsAdapter, - ownerWaitingNodes[1:], - marshaller, - owner, - owner, - ) - testscommon.AddValidatorData( - accountsAdapter, - owner, - ownerWaitingNodes, - big.NewInt(int64(2*nodePrice*numOfNodesInStakingQueue)), - marshaller, - ) - - return ownerWaitingNodes -} - func createEpochStartTrigger( coreComponents factory2.CoreComponentsHolder, storageService dataRetriever.StorageService, @@ -266,24 +223,22 @@ func createEpochStartTrigger( return testTrigger } +// Process - func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { for r := tmp.CurrentRound; r < tmp.CurrentRound+numOfRounds; r++ { currentHeader, currentHash := tmp.getCurrentHeaderInfo() - _, err := tmp.MetaBlockProcessor.CreateNewHeader(r, r) require.Nil(t, err) - fmt.Println(fmt.Sprintf("############## CREATING HEADER FOR EPOCH %v in round %v ##############", - tmp.EpochStartTrigger.Epoch(), - r, - )) + epoch := tmp.EpochStartTrigger.Epoch() + printNewHeaderRoundEpoch(r, epoch) header := createMetaBlockToCommit( - tmp.EpochStartTrigger.Epoch(), + epoch, r, currentHash, currentHeader.GetRandSeed(), - tmp.metaConsensusGroupSize/8+1, + tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), ) newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, func() bool { return true }) require.Nil(t, err) @@ -292,25 +247,20 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { require.Nil(t, err) time.Sleep(time.Millisecond * 40) - - tmp.updateNodesConfig(tmp.EpochStartTrigger.Epoch()) + tmp.updateNodesConfig(epoch) + displayConfig(tmp.NodesConfig) } tmp.CurrentRound += numOfRounds } -func displayValidators(list string, pubKeys [][]byte, shardID uint32) { - pubKeysToDisplay := pubKeys - if len(pubKeys) > 6 { - pubKeysToDisplay = make([][]byte, 0) - pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[:3]...) - pubKeysToDisplay = append(pubKeysToDisplay, [][]byte{[]byte("...")}...) - pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[len(pubKeys)-3:]...) - } - - for _, pk := range pubKeysToDisplay { - fmt.Println(list, "pk", string(pk), "shardID", shardID) - } +func printNewHeaderRoundEpoch(round uint64, epoch uint32) { + headline := display.Headline( + fmt.Sprintf("Commiting header in epoch %v round %v", epoch, round), + "", + delimiter, + ) + fmt.Println(headline) } func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { @@ -319,100 +269,22 @@ func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) - for shard := range eligible { - displayValidators("eligible", eligible[shard], shard) - displayValidators("waiting", waiting[shard], shard) - displayValidators("leaving", leaving[shard], shard) - displayValidators("shuffled", shuffledOut[shard], shard) - } - rootHash, _ := tmp.ValidatorStatistics.RootHash() validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) auction := make([][]byte, 0) - fmt.Println("####### Auction list") for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { if validator.GetList() == string(common.AuctionList) { auction = append(auction, validator.GetPublicKey()) } } - displayValidators("auction", auction, 0) - queue := tmp.searchPreviousFromHead() - fmt.Println("##### STAKING QUEUE") - displayValidators("queue", queue, 0) tmp.NodesConfig.eligible = eligible tmp.NodesConfig.waiting = waiting tmp.NodesConfig.shuffledOut = shuffledOut tmp.NodesConfig.leaving = leaving tmp.NodesConfig.auction = auction - tmp.NodesConfig.queue = queue -} - -func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { - acc, _ := accountsDB.LoadAccount(address) - stakingSCAcc := acc.(state.UserAccountHandler) - - return stakingSCAcc -} - -func (tmp *TestMetaProcessor) searchPreviousFromHead() [][]byte { - stakingSCAcc := loadSCAccount(tmp.AccountsAdapter, vm.StakingSCAddress) - - waitingList := &systemSmartContracts.WaitingList{ - FirstKey: make([]byte, 0), - LastKey: make([]byte, 0), - Length: 0, - LastJailedKey: make([]byte, 0), - } - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) - if len(marshaledData) == 0 { - return nil - } - - err := tmp.Marshaller.Unmarshal(waitingList, marshaledData) - if err != nil { - return nil - } - - index := uint32(1) - nextKey := make([]byte, len(waitingList.FirstKey)) - copy(nextKey, waitingList.FirstKey) - - allPubKeys := make([][]byte, 0) - for len(nextKey) != 0 && index <= waitingList.Length { - allPubKeys = append(allPubKeys, nextKey) - - element, errGet := tmp.getWaitingListElement(nextKey) - if errGet != nil { - return nil - } - - nextKey = make([]byte, len(element.NextKey)) - if len(element.NextKey) == 0 { - break - } - index++ - copy(nextKey, element.NextKey) - } - return allPubKeys -} - -func (tmp *TestMetaProcessor) getWaitingListElement(key []byte) (*systemSmartContracts.ElementInList, error) { - stakingSCAcc := loadSCAccount(tmp.AccountsAdapter, vm.StakingSCAddress) - - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) - if len(marshaledData) == 0 { - return nil, vm.ErrElementNotFound - } - - element := &systemSmartContracts.ElementInList{} - err := tmp.Marshaller.Unmarshal(element, marshaledData) - if err != nil { - return nil, err - } - - return element, nil + tmp.NodesConfig.queue = tmp.getWaitingListKeys() } func (tmp *TestMetaProcessor) getCurrentHeaderInfo() (data.HeaderHandler, []byte) { @@ -431,7 +303,7 @@ func createMetaBlockToCommit( round uint64, prevHash []byte, prevRandSeed []byte, - consensusSize uint32, + consensusSize int, ) *block.MetaBlock { roundStr := strconv.Itoa(int(round)) hdr := block.MetaBlock{ @@ -440,7 +312,7 @@ func createMetaBlockToCommit( Round: round, PrevHash: prevHash, Signature: []byte("signature"), - PubKeysBitmap: []byte(strings.Repeat("f", int(consensusSize))), + PubKeysBitmap: []byte(strings.Repeat("f", consensusSize)), RootHash: []byte("roothash"), ShardInfo: make([]block.ShardData, 0), TxCount: 1, diff --git a/testscommon/stakingCommon.go b/testscommon/stakingCommon.go index 5c5fc6236c0..da9c8388d01 100644 --- a/testscommon/stakingCommon.go +++ b/testscommon/stakingCommon.go @@ -36,7 +36,7 @@ func AddValidatorData( totalStake *big.Int, marshaller marshal.Marshalizer, ) { - validatorSC := loadSCAccount(accountsDB, vm.ValidatorSCAddress) + validatorSC := LoadUserAccount(accountsDB, vm.ValidatorSCAddress) validatorData := &systemSmartContracts.ValidatorDataV2{ RegisterNonce: 0, Epoch: 0, @@ -69,7 +69,7 @@ func AddStakingData( } marshaledData, _ := marshaller.Marshal(stakedData) - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) for _, key := range stakedKeys { _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) } @@ -84,7 +84,7 @@ func AddKeysToWaitingList( rewardAddress []byte, ownerAddress []byte, ) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) for _, waitingKey := range waitingKeys { stakedData := &systemSmartContracts.StakedDataV2_0{ @@ -160,7 +160,7 @@ func SaveOneKeyToWaitingList( rewardAddress []byte, ownerAddress []byte, ) { - stakingSCAcc := loadSCAccount(accountsDB, vm.StakingSCAddress) + stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) stakedData := &systemSmartContracts.StakedDataV2_0{ Waiting: true, RewardAddress: rewardAddress, @@ -190,11 +190,9 @@ func SaveOneKeyToWaitingList( _ = accountsDB.SaveAccount(stakingSCAcc) } -func loadSCAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { +func LoadUserAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { acc, _ := accountsDB.LoadAccount(address) - stakingSCAcc := acc.(state.UserAccountHandler) - - return stakingSCAcc + return acc.(state.UserAccountHandler) } func CreateEconomicsData() process.EconomicsDataHandler { From 82a4a3a57bc4f589adc24d19098224545b277495 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 13 Apr 2022 10:13:43 +0300 Subject: [PATCH 183/958] FIX: Import cycle --- epochStart/metachain/systemSCs_test.go | 87 ++++++++++--------- .../vm/staking/componentsHolderCreator.go | 3 +- .../vm/staking/nodesCoordiantorCreator.go | 4 +- integrationTests/vm/staking/stakingQueue.go | 12 +-- integrationTests/vm/staking/stakingV4_test.go | 2 +- .../vm/staking/testMetaProcessor.go | 2 +- .../{ => stakingcommon}/stakingCommon.go | 5 +- 7 files changed, 58 insertions(+), 57 deletions(-) rename testscommon/{ => stakingcommon}/stakingCommon.go (99%) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 28bf0285ca3..4cbb08ca0d7 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -45,6 +45,7 @@ import ( dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" @@ -215,7 +216,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s numEligible := 9 numWaiting := 5 numJailed := 8 - stakingScAcc := testscommon.LoadUserAccount(args.UserAccountsDB, vm.StakingSCAddress) + stakingScAcc := stakingcommon.LoadUserAccount(args.UserAccountsDB, vm.StakingSCAddress) createEligibleNodes(numEligible, stakingScAcc, args.Marshalizer) _ = createWaitingNodes(numWaiting, stakingScAcc, args.UserAccountsDB, args.Marshalizer) jailed := createJailedNodes(numJailed, stakingScAcc, args.UserAccountsDB, args.PeerAccountsDB, args.Marshalizer) @@ -223,7 +224,7 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s _ = s.userAccountsDB.SaveAccount(stakingScAcc) _, _ = s.userAccountsDB.Commit() - testscommon.AddValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) + stakingcommon.AddValidatorData(args.UserAccountsDB, []byte("ownerForAll"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, big.NewInt(900000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.SetValidatorsInShard(0, jailed) @@ -567,8 +568,8 @@ func addValidatorDataWithUnStakedKey( nodePrice *big.Int, marshalizer marshal.Marshalizer, ) { - stakingAccount := testscommon.LoadUserAccount(accountsDB, vm.StakingSCAddress) - validatorAccount := testscommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) + stakingAccount := stakingcommon.LoadUserAccount(accountsDB, vm.StakingSCAddress) + validatorAccount := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) validatorData := &systemSmartContracts.ValidatorDataV2{ RegisterNonce: 0, @@ -677,9 +678,9 @@ func prepareStakingContractWithData( rewardAddress []byte, ownerAddress []byte, ) { - testscommon.AddStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) - testscommon.SaveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) - testscommon.AddValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) + stakingcommon.AddStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) + stakingcommon.SaveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) + stakingcommon.AddValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) _, err := accountsDB.Commit() log.LogIfError(err) @@ -766,7 +767,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ BlockChainHook: blockChainHookImpl, PubkeyConv: argsHook.PubkeyConv, - Economics: testscommon.CreateEconomicsData(), + Economics: stakingcommon.CreateEconomicsData(), MessageSignVerifier: signVerifer, GasSchedule: gasScheduleNotifier, NodesConfigProvider: nodesSetup, @@ -1130,7 +1131,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeOneNodeStakeOthers(t []byte("rewardAddress"), []byte("rewardAddress"), ) - testscommon.RegisterValidatorKeys(args.UserAccountsDB, + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, @@ -1202,7 +1203,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeTheOnlyNodeShouldWor []byte("rewardAddress"), ) - testscommon.AddStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, args.Marshalizer) + stakingcommon.AddStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, args.Marshalizer) addValidatorDataWithUnStakedKey(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey1")}, big.NewInt(1000), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1232,7 +1233,7 @@ func addDelegationData( stakedKeys [][]byte, marshalizer marshal.Marshalizer, ) { - delegatorSC := testscommon.LoadUserAccount(accountsDB, delegation) + delegatorSC := stakingcommon.LoadUserAccount(accountsDB, delegation) dStatus := &systemSmartContracts.DelegationContractStatus{ StakedKeys: make([]*systemSmartContracts.NodesData, 0), NotStakedKeys: make([]*systemSmartContracts.NodesData, 0), @@ -1272,14 +1273,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra delegationAddr, ) - testscommon.AddStakingData(args.UserAccountsDB, + stakingcommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) allKeys := [][]byte{[]byte("stakedPubKey0"), []byte("waitingPubKey"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")} - testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allKeys, big.NewInt(3000), args.Marshalizer) + stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allKeys, big.NewInt(3000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1325,7 +1326,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra assert.Equal(t, peerAcc.GetList(), string(common.LeavingList)) assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 4) - delegationSC := testscommon.LoadUserAccount(args.UserAccountsDB, delegationAddr) + delegationSC := stakingcommon.LoadUserAccount(args.UserAccountsDB, delegationAddr) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) assert.Nil(t, err) dStatus := &systemSmartContracts.DelegationContractStatus{ @@ -1364,11 +1365,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional delegationAddr, ) - testscommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer) + stakingcommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer) listOfKeysInWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} allStakedKeys := append(listOfKeysInWaiting, []byte("waitingPubKey"), []byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")) - testscommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr, delegationAddr) - testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allStakedKeys, big.NewInt(4000), args.Marshalizer) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr, delegationAddr) + stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allStakedKeys, big.NewInt(4000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allStakedKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1410,7 +1411,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional assert.Equal(t, string(common.EligibleList), vInfo.GetList()) } - delegationSC := testscommon.LoadUserAccount(args.UserAccountsDB, delegationAddr) + delegationSC := stakingcommon.LoadUserAccount(args.UserAccountsDB, delegationAddr) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) assert.Nil(t, err) dStatus := &systemSmartContracts.DelegationContractStatus{ @@ -1448,14 +1449,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( delegationAddr, ) - testscommon.AddStakingData(args.UserAccountsDB, + stakingcommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) - testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(10000), args.Marshalizer) + stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(10000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1465,8 +1466,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( _ = scContainer.Add(delegationAddr2, contract) listOfKeysInWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} - testscommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr2, delegationAddr2) - testscommon.AddValidatorData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, big.NewInt(2000), args.Marshalizer) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr2, delegationAddr2) + stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, big.NewInt(2000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr2, listOfKeysInWaiting, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1503,7 +1504,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - delegationSC := testscommon.LoadUserAccount(args.UserAccountsDB, delegationAddr2) + delegationSC := stakingcommon.LoadUserAccount(args.UserAccountsDB, delegationAddr2) marshalledData, err := delegationSC.DataTrie().Get([]byte("delegationStatus")) assert.Nil(t, err) dStatus := &systemSmartContracts.DelegationContractStatus{ @@ -1519,7 +1520,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromAdditionalQueue( assert.Equal(t, []byte("waitingPubKe4"), dStatus.UnStakedKeys[0].BLSKey) assert.Equal(t, []byte("waitingPubKe3"), dStatus.UnStakedKeys[1].BLSKey) - stakingSCAcc := testscommon.LoadUserAccount(args.UserAccountsDB, vm.StakingSCAddress) + stakingSCAcc := stakingcommon.LoadUserAccount(args.UserAccountsDB, vm.StakingSCAddress) marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) waitingListHead := &systemSmartContracts.WaitingList{} _ = args.Marshalizer.Unmarshal(waitingListHead, marshaledData) @@ -1590,14 +1591,14 @@ func TestSystemSCProcessor_TogglePauseUnPause(t *testing.T) { err := s.ToggleUnStakeUnBond(true) assert.Nil(t, err) - validatorSC := testscommon.LoadUserAccount(s.userAccountsDB, vm.ValidatorSCAddress) + validatorSC := stakingcommon.LoadUserAccount(s.userAccountsDB, vm.ValidatorSCAddress) value, _ := validatorSC.DataTrie().Get([]byte("unStakeUnBondPause")) assert.True(t, value[0] == 1) err = s.ToggleUnStakeUnBond(false) assert.Nil(t, err) - validatorSC = testscommon.LoadUserAccount(s.userAccountsDB, vm.ValidatorSCAddress) + validatorSC = stakingcommon.LoadUserAccount(s.userAccountsDB, vm.ValidatorSCAddress) value, _ = validatorSC.DataTrie().Get([]byte("unStakeUnBondPause")) assert.True(t, value[0] == 0) } @@ -1630,14 +1631,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T args.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 s, _ := NewSystemSCProcessor(args) - testscommon.AddStakingData(args.UserAccountsDB, + stakingcommon.AddStakingData(args.UserAccountsDB, []byte("ownerKey"), []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) - testscommon.SaveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) - testscommon.AddValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) + stakingcommon.SaveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) + stakingcommon.AddValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() validatorsInfo := state.NewShardValidatorsInfoMap() @@ -1717,18 +1718,18 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) // Owner1 has 2 staked nodes (one eligible, one waiting) in shard0 + 3 nodes in staking queue. // It has enough stake so that all his staking queue nodes will be selected in the auction list - testscommon.AddKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting[1:], args.Marshalizer, owner1, owner1) - testscommon.AddValidatorData(args.UserAccountsDB, owner1, owner1AllPubKeys[1:], big.NewInt(5000), args.Marshalizer) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting[1:], args.Marshalizer, owner1, owner1) + stakingcommon.AddValidatorData(args.UserAccountsDB, owner1, owner1AllPubKeys[1:], big.NewInt(5000), args.Marshalizer) // Owner2 has 1 staked node (eligible) in shard1 + 2 nodes in staking queue. // It has enough stake for only ONE node from staking queue to be selected in the auction list - testscommon.AddKeysToWaitingList(args.UserAccountsDB, owner2ListPubKeysWaiting, args.Marshalizer, owner2, owner2) - testscommon.AddValidatorData(args.UserAccountsDB, owner2, owner2AllPubKeys, big.NewInt(1500), args.Marshalizer) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner2ListPubKeysWaiting, args.Marshalizer, owner2, owner2) + stakingcommon.AddValidatorData(args.UserAccountsDB, owner2, owner2AllPubKeys, big.NewInt(1500), args.Marshalizer) // Owner3 has 0 staked node + 2 nodes in staking queue. // It has enough stake so that all his staking queue nodes will be selected in the auction list - testscommon.AddKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) - testscommon.AddValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) + stakingcommon.AddValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) @@ -1774,7 +1775,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa owner := []byte("owner") ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) @@ -1808,7 +1809,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA owner := []byte("owner") ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) @@ -1835,8 +1836,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA owner1StakedKeys := [][]byte{[]byte("pubKey0")} owner2StakedKeys := [][]byte{[]byte("pubKey1")} - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() @@ -1873,10 +1874,10 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner3StakedKeys := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} owner4StakedKeys := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6000), args.Marshalizer) - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(3000), args.Marshalizer) - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) - testscommon.RegisterValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(3000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index cbf09de7396..bd8eaf9f17f 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -32,6 +32,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" ) @@ -63,7 +64,7 @@ func createCoreComponents() factory2.CoreComponentsHolder { EpochNotifierField: forking.NewGenericEpochNotifier(), RaterField: &testscommon.RaterMock{Chance: 5}, AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, - EconomicsDataField: testscommon.CreateEconomicsData(), + EconomicsDataField: stakingcommon.CreateEconomicsData(), ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), NodeTypeProviderField: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), } diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index fc370eea741..ae363e6c75f 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -13,7 +13,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage" "github.com/ElrondNetwork/elrond-go/storage/lrucache" - "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" ) const ( @@ -149,7 +149,7 @@ func registerValidators( peerAccount.BLSPublicKey = pubKey peerAccount.List = string(list) _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) - testscommon.RegisterValidatorKeys( + stakingcommon.RegisterValidatorKeys( stateComponents.AccountsAdapter(), pubKey, pubKey, diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 98cc143aac4..b0fd5bc2bc7 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -5,7 +5,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" ) @@ -25,21 +25,21 @@ func createStakingQueue( // We need to save one key and then add keys to waiting list because there is a bug in those functions // TODO: FIX bug in testscommon.AddKeysToWaitingList to also init staking queue if there are no keys in list - testscommon.SaveOneKeyToWaitingList( + stakingcommon.SaveOneKeyToWaitingList( accountsAdapter, ownerWaitingNodes[0], marshaller, owner, owner, ) - testscommon.AddKeysToWaitingList( + stakingcommon.AddKeysToWaitingList( accountsAdapter, ownerWaitingNodes[1:], marshaller, owner, owner, ) - testscommon.AddValidatorData( + stakingcommon.AddValidatorData( accountsAdapter, owner, ownerWaitingNodes, @@ -51,7 +51,7 @@ func createStakingQueue( } func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { - stakingSCAcc := testscommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + stakingSCAcc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) waitingList := &systemSmartContracts.WaitingList{ FirstKey: make([]byte, 0), @@ -93,7 +93,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { } func (tmp *TestMetaProcessor) getWaitingListElement(key []byte) (*systemSmartContracts.ElementInList, error) { - stakingSCAcc := testscommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + stakingSCAcc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) if len(marshaledData) == 0 { diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 7fdd15a48bf..bd686518a0e 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -76,7 +76,7 @@ func TestNewTestMetaProcessor(t *testing.T) { require.Empty(t, initialNodes.auction) // 2. Check config after staking v4 initialization - node.Process(t, 6) + node.Process(t, 5) nodesConfigStakingV4Init := node.NodesConfig require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 768e8443e12..367217810e2 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -246,7 +246,7 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) require.Nil(t, err) - time.Sleep(time.Millisecond * 40) + time.Sleep(time.Millisecond * 500) tmp.updateNodesConfig(epoch) displayConfig(tmp.NodesConfig) } diff --git a/testscommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go similarity index 99% rename from testscommon/stakingCommon.go rename to testscommon/stakingcommon/stakingCommon.go index da9c8388d01..d43a6ef1647 100644 --- a/testscommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -1,4 +1,4 @@ -package testscommon +package stakingcommon import ( "math/big" @@ -25,8 +25,7 @@ func RegisterValidatorKeys( ) { AddValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) AddStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) - _, err := accountsDB.Commit() - log.LogIfError(err) + _, _ = accountsDB.Commit() } func AddValidatorData( From a0e443a2718b3916b240847ed15da5893132f0d8 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 13 Apr 2022 13:26:10 +0300 Subject: [PATCH 184/958] FIX: Race condition + add StakingV4DistributeAuctionToWaiting enable epoch --- cmd/node/config/enableEpochs.toml | 3 + config/epochConfig.go | 1 + factory/coreComponents.go | 18 +-- .../vm/staking/nodesCoordiantorCreator.go | 15 +- integrationTests/vm/staking/stakingV4_test.go | 94 ++++++------ .../vm/staking/testMetaProcessor.go | 26 +++- process/block/displayMetaBlock.go | 8 +- .../nodesCoordinator/hashValidatorShuffler.go | 136 ++++++++++-------- .../hashValidatorShuffler_test.go | 79 +++++----- 9 files changed, 213 insertions(+), 167 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index dbd12c46f89..8fa006e4f10 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -203,6 +203,9 @@ # StakingV4EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4InitEnableEpoch StakingV4EnableEpoch = 5 + # StakingV4DistributeAuctionToWaiting represents the epoch in which selected nodes from auction will be distributed to waiting list + StakingV4DistributeAuctionToWaiting = 6 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, diff --git a/config/epochConfig.go b/config/epochConfig.go index 7566b42e023..0d9ab50118f 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -80,6 +80,7 @@ type EnableEpochs struct { StakeLimitsEnableEpoch uint32 StakingV4InitEnableEpoch uint32 StakingV4EnableEpoch uint32 + StakingV4DistributeAuctionToWaiting uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/factory/coreComponents.go b/factory/coreComponents.go index 80a0e6fe6ff..c04bda0c8ce 100644 --- a/factory/coreComponents.go +++ b/factory/coreComponents.go @@ -310,14 +310,16 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) { } argsNodesShuffler := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: genesisNodesConfig.MinNumberOfShardNodes(), - NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(), - Hysteresis: genesisNodesConfig.GetHysteresis(), - Adaptivity: genesisNodesConfig.GetAdaptivity(), - ShuffleBetweenShards: true, - MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, - BalanceWaitingListsEnableEpoch: ccf.epochConfig.EnableEpochs.BalanceWaitingListsEnableEpoch, - WaitingListFixEnableEpoch: ccf.epochConfig.EnableEpochs.WaitingListFixEnableEpoch, + NodesShard: genesisNodesConfig.MinNumberOfShardNodes(), + NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(), + Hysteresis: genesisNodesConfig.GetHysteresis(), + Adaptivity: genesisNodesConfig.GetAdaptivity(), + ShuffleBetweenShards: true, + MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, + BalanceWaitingListsEnableEpoch: ccf.epochConfig.EnableEpochs.BalanceWaitingListsEnableEpoch, + WaitingListFixEnableEpoch: ccf.epochConfig.EnableEpochs.WaitingListFixEnableEpoch, + StakingV4EnableEpoch: ccf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + StakingV4DistributeAuctionToWaiting: ccf.epochConfig.EnableEpochs.StakingV4DistributeAuctionToWaiting, } nodesShuffler, err := nodesCoordinator.NewHashValidatorsShuffler(argsNodesShuffler) diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index ae363e6c75f..16af57434cc 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -46,13 +46,14 @@ func createNodesCoordinator( ) shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: numOfEligibleNodesPerShard, - NodesMeta: numOfMetaNodes, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: maxNodesConfig, - StakingV4EnableEpoch: stakingV4EnableEpoch, + NodesShard: numOfEligibleNodesPerShard, + NodesMeta: numOfMetaNodes, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: maxNodesConfig, + StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4DistributeAuctionToWaiting: stakingV4DistributeAuctionToWaiting, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index bd686518a0e..529bc233d18 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -76,51 +76,51 @@ func TestNewTestMetaProcessor(t *testing.T) { require.Empty(t, initialNodes.auction) // 2. Check config after staking v4 initialization - node.Process(t, 5) - nodesConfigStakingV4Init := node.NodesConfig - require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) - require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) - require.Empty(t, nodesConfigStakingV4Init.queue) - require.Empty(t, nodesConfigStakingV4Init.shuffledOut) - requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) - - // 3. Check config after first staking v4 epoch - node.Process(t, 6) - nodesConfigStakingV4 := node.NodesConfig - require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) - - numOfShuffledOut := int((numOfShards + 1) * numOfNodesToShufflePerShard) - newWaiting := totalWaiting - numOfShuffledOut + len(nodesConfigStakingV4Init.auction) - require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), newWaiting) - - // All shuffled out are in auction - require.Len(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), numOfShuffledOut) - requireSameSliceDifferentOrder(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), nodesConfigStakingV4.auction) - - // All current waiting are from the previous auction - requireMapContains(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) - // All current auction are from previous eligible - requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) - - epochs := 0 - prevConfig := nodesConfigStakingV4 - prevNumOfWaiting := newWaiting - for epochs < 10 { - node.Process(t, 5) - newNodeConfig := node.NodesConfig - - newWaiting = prevNumOfWaiting - numOfShuffledOut + len(prevConfig.auction) - require.Len(t, getAllPubKeys(newNodeConfig.waiting), newWaiting) - require.Len(t, getAllPubKeys(newNodeConfig.eligible), totalEligible) - - require.Len(t, getAllPubKeys(newNodeConfig.shuffledOut), numOfShuffledOut) - requireSameSliceDifferentOrder(t, getAllPubKeys(newNodeConfig.shuffledOut), newNodeConfig.auction) - - requireMapContains(t, newNodeConfig.waiting, prevConfig.auction) - requireMapContains(t, prevConfig.eligible, newNodeConfig.auction) - - prevConfig = newNodeConfig - prevNumOfWaiting = newWaiting - epochs++ - } + node.Process(t, 35) + //nodesConfigStakingV4Init := node.NodesConfig + //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) + //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) + //require.Empty(t, nodesConfigStakingV4Init.queue) + //require.Empty(t, nodesConfigStakingV4Init.shuffledOut) + //requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) + // + //// 3. Check config after first staking v4 epoch + //node.Process(t, 6) + //nodesConfigStakingV4 := node.NodesConfig + //require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) + // + //numOfShuffledOut := int((numOfShards + 1) * numOfNodesToShufflePerShard) + //newWaiting := totalWaiting - numOfShuffledOut + len(nodesConfigStakingV4Init.auction) + //require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), newWaiting) + // + //// All shuffled out are in auction + //require.Len(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), numOfShuffledOut) + //requireSameSliceDifferentOrder(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), nodesConfigStakingV4.auction) + // + //// All current waiting are from the previous auction + //requireMapContains(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) + //// All current auction are from previous eligible + //requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) + // + //epochs := 0 + //prevConfig := nodesConfigStakingV4 + //prevNumOfWaiting := newWaiting + //for epochs < 10 { + // node.Process(t, 5) + // newNodeConfig := node.NodesConfig + // + // newWaiting = prevNumOfWaiting - numOfShuffledOut + len(prevConfig.auction) + // require.Len(t, getAllPubKeys(newNodeConfig.waiting), newWaiting) + // require.Len(t, getAllPubKeys(newNodeConfig.eligible), totalEligible) + // + // require.Len(t, getAllPubKeys(newNodeConfig.shuffledOut), numOfShuffledOut) + // requireSameSliceDifferentOrder(t, getAllPubKeys(newNodeConfig.shuffledOut), newNodeConfig.auction) + // + // requireMapContains(t, newNodeConfig.waiting, prevConfig.auction) + // requireMapContains(t, prevConfig.eligible, newNodeConfig.auction) + // + // prevConfig = newNodeConfig + // prevNumOfWaiting = newWaiting + // epochs++ + //} } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 367217810e2..9f0455f7ff8 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,6 +1,7 @@ package staking import ( + "encoding/hex" "fmt" "math/big" "strconv" @@ -29,10 +30,11 @@ import ( ) const ( - stakingV4InitEpoch = 1 - stakingV4EnableEpoch = 2 - addressLength = 15 - nodePrice = 1000 + stakingV4InitEpoch = 1 + stakingV4EnableEpoch = 2 + stakingV4DistributeAuctionToWaiting = 3 + addressLength = 15 + nodePrice = 1000 ) type nodesConfig struct { @@ -181,10 +183,19 @@ func createMaxNodesConfig( ) []config.MaxNodesChangeConfig { totalEligible := numOfMetaNodes + numOfShards*numOfEligibleNodesPerShard totalWaiting := (numOfShards + 1) * numOfWaitingNodesPerShard + totalNodes := totalEligible + totalWaiting maxNodesConfig := make([]config.MaxNodesChangeConfig, 0) maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{ - MaxNumNodes: totalEligible + totalWaiting, + EpochEnable: 0, + MaxNumNodes: totalNodes, + NodesToShufflePerShard: numOfNodesToShufflePerShard, + }, + ) + + maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{ + EpochEnable: stakingV4DistributeAuctionToWaiting, + MaxNumNodes: totalNodes - numOfNodesToShufflePerShard*(numOfShards+1), NodesToShufflePerShard: numOfNodesToShufflePerShard, }, ) @@ -246,9 +257,12 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) require.Nil(t, err) - time.Sleep(time.Millisecond * 500) + time.Sleep(time.Millisecond * 50) tmp.updateNodesConfig(epoch) displayConfig(tmp.NodesConfig) + + rootHash, _ := tmp.ValidatorStatistics.RootHash() + fmt.Println("##########################################ROOOT HASH", hex.EncodeToString(rootHash)) } tmp.CurrentRound += numOfRounds diff --git a/process/block/displayMetaBlock.go b/process/block/displayMetaBlock.go index 0e8231079c6..3c74f36fbe5 100644 --- a/process/block/displayMetaBlock.go +++ b/process/block/displayMetaBlock.go @@ -2,9 +2,10 @@ package block import ( "fmt" - "github.com/ElrondNetwork/elrond-go-core/data" "sync" + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-logger" @@ -13,6 +14,7 @@ import ( type headersCounter struct { shardMBHeaderCounterMutex sync.RWMutex + peakTPSMutex sync.RWMutex shardMBHeadersCurrentBlockProcessed uint64 shardMBHeadersTotalProcessed uint64 peakTPS uint64 @@ -23,6 +25,7 @@ type headersCounter struct { func NewHeaderCounter() *headersCounter { return &headersCounter{ shardMBHeaderCounterMutex: sync.RWMutex{}, + peakTPSMutex: sync.RWMutex{}, shardMBHeadersCurrentBlockProcessed: 0, shardMBHeadersTotalProcessed: 0, peakTPS: 0, @@ -90,6 +93,8 @@ func (hc *headersCounter) displayLogInfo( numTxs := getNumTxs(header, body) tps := numTxs / roundDuration + + hc.peakTPSMutex.Lock() if tps > hc.peakTPS { hc.peakTPS = tps } @@ -101,6 +106,7 @@ func (hc *headersCounter) displayLogInfo( "num txs", numTxs, "tps", tps, "peak tps", hc.peakTPS) + hc.peakTPSMutex.Unlock() blockTracker.DisplayTrackedHeaders() } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index c7cc625020b..aeefdd5d741 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -16,33 +16,35 @@ var _ NodesShuffler = (*randHashShuffler)(nil) // NodesShufflerArgs defines the arguments required to create a nodes shuffler type NodesShufflerArgs struct { - NodesShard uint32 - NodesMeta uint32 - Hysteresis float32 - Adaptivity bool - ShuffleBetweenShards bool - MaxNodesEnableConfig []config.MaxNodesChangeConfig - BalanceWaitingListsEnableEpoch uint32 - WaitingListFixEnableEpoch uint32 - StakingV4EnableEpoch uint32 + NodesShard uint32 + NodesMeta uint32 + Hysteresis float32 + Adaptivity bool + ShuffleBetweenShards bool + MaxNodesEnableConfig []config.MaxNodesChangeConfig + BalanceWaitingListsEnableEpoch uint32 + WaitingListFixEnableEpoch uint32 + StakingV4EnableEpoch uint32 + StakingV4DistributeAuctionToWaiting uint32 } type shuffleNodesArg struct { - eligible map[uint32][]Validator - waiting map[uint32][]Validator - unstakeLeaving []Validator - additionalLeaving []Validator - newNodes []Validator - auction []Validator - randomness []byte - distributor ValidatorsDistributor - nodesMeta uint32 - nodesPerShard uint32 - nbShards uint32 - maxNodesToSwapPerShard uint32 - flagBalanceWaitingLists bool - flagWaitingListFix bool - flagStakingV4 bool + eligible map[uint32][]Validator + waiting map[uint32][]Validator + unstakeLeaving []Validator + additionalLeaving []Validator + newNodes []Validator + auction []Validator + randomness []byte + distributor ValidatorsDistributor + nodesMeta uint32 + nodesPerShard uint32 + nbShards uint32 + maxNodesToSwapPerShard uint32 + flagBalanceWaitingLists bool + flagWaitingListFix bool + flagStakingV4 bool + flagStakingV4DistributeAuctionToWaiting bool } // TODO: Decide if transaction load statistics will be used for limiting the number of shards @@ -51,21 +53,23 @@ type randHashShuffler struct { // when reinitialization of node in new shard is implemented shuffleBetweenShards bool - adaptivity bool - nodesShard uint32 - nodesMeta uint32 - shardHysteresis uint32 - metaHysteresis uint32 - activeNodesConfig config.MaxNodesChangeConfig - availableNodesConfigs []config.MaxNodesChangeConfig - mutShufflerParams sync.RWMutex - validatorDistributor ValidatorsDistributor - balanceWaitingListsEnableEpoch uint32 - flagBalanceWaitingLists atomic.Flag - waitingListFixEnableEpoch uint32 - flagWaitingListFix atomic.Flag - stakingV4EnableEpoch uint32 - flagStakingV4 atomic.Flag + adaptivity bool + nodesShard uint32 + nodesMeta uint32 + shardHysteresis uint32 + metaHysteresis uint32 + activeNodesConfig config.MaxNodesChangeConfig + availableNodesConfigs []config.MaxNodesChangeConfig + mutShufflerParams sync.RWMutex + validatorDistributor ValidatorsDistributor + balanceWaitingListsEnableEpoch uint32 + flagBalanceWaitingLists atomic.Flag + waitingListFixEnableEpoch uint32 + flagWaitingListFix atomic.Flag + stakingV4DistributeAuctionToWaiting uint32 + flagStakingV4DistributeAuctionToWaiting atomic.Flag + stakingV4EnableEpoch uint32 + flagStakingV4 atomic.Flag } // NewHashValidatorsShuffler creates a validator shuffler that uses a hash between validator key and a given @@ -79,6 +83,9 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro log.Debug("hashValidatorShuffler: enable epoch for max nodes change", "epoch", args.MaxNodesEnableConfig) log.Debug("hashValidatorShuffler: enable epoch for balance waiting lists", "epoch", args.BalanceWaitingListsEnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.StakingV4EnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.StakingV4DistributeAuctionToWaiting) + if args.MaxNodesEnableConfig != nil { configs = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(configs, args.MaxNodesEnableConfig) @@ -86,15 +93,17 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro log.Debug("Shuffler created", "shuffleBetweenShards", args.ShuffleBetweenShards) rxs := &randHashShuffler{ - shuffleBetweenShards: args.ShuffleBetweenShards, - availableNodesConfigs: configs, - balanceWaitingListsEnableEpoch: args.BalanceWaitingListsEnableEpoch, - waitingListFixEnableEpoch: args.WaitingListFixEnableEpoch, - stakingV4EnableEpoch: args.StakingV4EnableEpoch, + shuffleBetweenShards: args.ShuffleBetweenShards, + availableNodesConfigs: configs, + balanceWaitingListsEnableEpoch: args.BalanceWaitingListsEnableEpoch, + waitingListFixEnableEpoch: args.WaitingListFixEnableEpoch, + stakingV4DistributeAuctionToWaiting: args.StakingV4DistributeAuctionToWaiting, + stakingV4EnableEpoch: args.StakingV4EnableEpoch, } log.Debug("randHashShuffler: enable epoch for balance waiting list", "epoch", rxs.balanceWaitingListsEnableEpoch) log.Debug("randHashShuffler: enable epoch for waiting waiting list", "epoch", rxs.waitingListFixEnableEpoch) + log.Debug("randHashShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", rxs.stakingV4DistributeAuctionToWaiting) log.Debug("randHashShuffler: enable epoch for staking v4", "epoch", rxs.stakingV4EnableEpoch) rxs.UpdateParams(args.NodesShard, args.NodesMeta, args.Hysteresis, args.Adaptivity) @@ -178,21 +187,22 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo } return shuffleNodes(shuffleNodesArg{ - eligible: eligibleAfterReshard, - waiting: waitingAfterReshard, - unstakeLeaving: args.UnStakeLeaving, - additionalLeaving: args.AdditionalLeaving, - newNodes: args.NewNodes, - auction: args.Auction, - randomness: args.Rand, - nodesMeta: nodesMeta, - nodesPerShard: nodesPerShard, - nbShards: args.NbShards, - distributor: rhs.validatorDistributor, - maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, - flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), - flagWaitingListFix: rhs.flagWaitingListFix.IsSet(), - flagStakingV4: rhs.flagStakingV4.IsSet(), + eligible: eligibleAfterReshard, + waiting: waitingAfterReshard, + unstakeLeaving: args.UnStakeLeaving, + additionalLeaving: args.AdditionalLeaving, + newNodes: args.NewNodes, + auction: args.Auction, + randomness: args.Rand, + nodesMeta: nodesMeta, + nodesPerShard: nodesPerShard, + nbShards: args.NbShards, + distributor: rhs.validatorDistributor, + maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, + flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), + flagWaitingListFix: rhs.flagWaitingListFix.IsSet(), + flagStakingV4: rhs.flagStakingV4.IsSet(), + flagStakingV4DistributeAuctionToWaiting: rhs.flagStakingV4DistributeAuctionToWaiting.IsSet(), }) } @@ -297,13 +307,14 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - if arg.flagStakingV4 { + if arg.flagStakingV4DistributeAuctionToWaiting { // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) if err != nil { log.Warn("distributeValidators auction list failed", "error", err) } - } else { + } + if !arg.flagStakingV4 { // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) if err != nil { @@ -802,6 +813,9 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { rhs.flagWaitingListFix.SetValue(epoch >= rhs.waitingListFixEnableEpoch) log.Debug("waiting list fix", "enabled", rhs.flagWaitingListFix.IsSet()) + rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4DistributeAuctionToWaiting) + log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4DistributeAuctionToWaiting.IsSet()) + rhs.flagStakingV4.SetValue(epoch >= rhs.stakingV4EnableEpoch) log.Debug("staking v4", "enabled", rhs.flagStakingV4.IsSet()) } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index ee58cd3ff06..6844ad8a4ba 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -186,13 +186,14 @@ func testShuffledOut( func createHashShufflerInter() (*randHashShuffler, error) { shufflerArgs := &NodesShufflerArgs{ - NodesShard: eligiblePerShard, - NodesMeta: eligiblePerShard, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: true, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 444, + NodesShard: eligiblePerShard, + NodesMeta: eligiblePerShard, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: true, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaiting: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -202,13 +203,14 @@ func createHashShufflerInter() (*randHashShuffler, error) { func createHashShufflerIntraShards() (*randHashShuffler, error) { shufflerArgs := &NodesShufflerArgs{ - NodesShard: eligiblePerShard, - NodesMeta: eligiblePerShard, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 444, + NodesShard: eligiblePerShard, + NodesMeta: eligiblePerShard, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaiting: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1184,15 +1186,16 @@ func TestRandHashShuffler_UpdateParams(t *testing.T) { require.Nil(t, err) shuffler2 := &randHashShuffler{ - nodesShard: 200, - nodesMeta: 200, - shardHysteresis: 0, - metaHysteresis: 0, - adaptivity: true, - shuffleBetweenShards: true, - validatorDistributor: &CrossShardValidatorDistributor{}, - availableNodesConfigs: nil, - stakingV4EnableEpoch: 444, + nodesShard: 200, + nodesMeta: 200, + shardHysteresis: 0, + metaHysteresis: 0, + adaptivity: true, + shuffleBetweenShards: true, + validatorDistributor: &CrossShardValidatorDistributor{}, + availableNodesConfigs: nil, + stakingV4EnableEpoch: 443, + stakingV4DistributeAuctionToWaiting: 444, } shuffler.UpdateParams( @@ -2376,13 +2379,14 @@ func TestRandHashShuffler_UpdateNodeLists_All(t *testing.T) { unstakeLeavingList, additionalLeavingList := prepareListsFromMaps(unstakeLeaving, additionalLeaving) shufflerArgs := &NodesShufflerArgs{ - NodesShard: uint32(eligiblePerShard), - NodesMeta: uint32(eligiblePerShard), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 444, + NodesShard: uint32(eligiblePerShard), + NodesMeta: uint32(eligiblePerShard), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaiting: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) @@ -2724,13 +2728,14 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t } shufflerArgs := &NodesShufflerArgs{ - NodesShard: uint32(numEligiblePerShard), - NodesMeta: uint32(numEligiblePerShard), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 444, + NodesShard: uint32(numEligiblePerShard), + NodesMeta: uint32(numEligiblePerShard), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaiting: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) From e0d68a77eb273155c535651e5f99a9a055774c51 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 13 Apr 2022 16:48:26 +0300 Subject: [PATCH 185/958] FIX: Staking v4 complete test --- cmd/node/config/enableEpochs.toml | 7 +- epochStart/metachain/systemSCs.go | 38 ++-- .../vm/staking/configDisplayer.go | 24 ++- integrationTests/vm/staking/stakingV4_test.go | 162 ++++++++++++------ .../vm/staking/testMetaProcessor.go | 2 +- 5 files changed, 157 insertions(+), 76 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 8fa006e4f10..ca21150b2fa 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -209,7 +209,12 @@ # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, - { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 } + { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 }, + # Staking v4 configuration, where: + # - Enable epoch = StakingV4DistributeAuctionToWaiting + # - MaxNumNodes = (MaxNumNodes - (numOfShards+1)*NodesToShufflePerShard) from previous entry in MaxNodesChangeEnableEpoch + # - NodesToShufflePerShard = same as previous entry in MaxNodesChangeEnableEpoch + { EpochEnable = 6, MaxNumNodes = 48, NodesToShufflePerShard = 2 }, ] [GasSchedule] diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 931bd3933f7..6f870918f96 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -147,31 +147,41 @@ func (s *systemSCProcessor) processWithNewFlags( return nil } -func (s *systemSCProcessor) calcShuffledOutNodes() uint32 { - nodesToShufflePerShard := s.currentNodesEnableConfig.NodesToShufflePerShard - return nodesToShufflePerShard * (s.shardCoordinator.NumberOfShards() + 1) // TODO: THIS IS NOT OK; meta does not shuffle the sam num of nodes -} - +// TODO: Staking v4: perhaps create a subcomponent which handles selection, which would be also very useful in tests func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) - numOfShuffledNodes := s.calcShuffledOutNodes() - numOfValidators := currNumOfValidators - numOfShuffledNodes - availableSlots, err := safeSub(s.maxNodes, numOfValidators) + numOfShuffledNodes := s.currentNodesEnableConfig.NodesToShufflePerShard * (s.shardCoordinator.NumberOfShards() + 1) + + numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) + if err != nil { + log.Warn(fmt.Sprintf("%v error when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes); skip selecting nodes from auction list", + err, + currNumOfValidators, + numOfShuffledNodes, + )) + numOfValidatorsAfterShuffling = 0 + } + + availableSlots, err := safeSub(s.maxNodes, numOfValidatorsAfterShuffling) + if availableSlots == 0 || err != nil { + log.Info(fmt.Sprintf("%v error or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", + err, + s.maxNodes, + numOfValidatorsAfterShuffling, + )) + return nil + } + auctionListSize := uint32(len(auctionList)) log.Info("systemSCProcessor.selectNodesFromAuctionList", "max nodes", s.maxNodes, "current number of validators", currNumOfValidators, "num of nodes which will be shuffled", numOfShuffledNodes, - "num of validators after shuffling", numOfValidators, + "num of validators after shuffling", numOfValidatorsAfterShuffling, "auction list size", auctionListSize, "available slots", availableSlots, ) // todo: change to log.debug - if availableSlots == 0 || err != nil { - log.Info("not enough available slots for auction nodes; skip selecting nodes from auction list") - return nil - } - err = s.sortAuctionList(auctionList, randomness) if err != nil { return err diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index 379f2516127..d65b94154d4 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -14,6 +14,15 @@ const ( // TODO: Make a subcomponent which will register to epoch notifier to display config only upon epoch change +func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { + allValidators := make([][]byte, 0) + for _, validatorsInShard := range validatorsMap { + allValidators = append(allValidators, validatorsInShard...) + } + + return allValidators +} + func getShortPubKeysList(pubKeys [][]byte) [][]byte { pubKeysToDisplay := pubKeys if len(pubKeys) > maxPubKeysListLen { @@ -36,6 +45,10 @@ func displayConfig(config nodesConfig) { lines = append(lines, getDisplayableValidatorsInShard("shuffled", config.shuffledOut[shard], shard)...) lines = append(lines, display.NewLineData(true, []string{})) } + lines = append(lines, display.NewLineData(true, []string{"eligible", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.eligible))), "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"waiting", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.waiting))), "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"leaving", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.leaving))), "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"shuffled", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.shuffledOut))), "All shards"})) tableHeader := []string{"List", "Pub key", "Shard ID"} table, _ := display.CreateTableString(tableHeader, lines) @@ -51,10 +64,11 @@ func getDisplayableValidatorsInShard(list string, pubKeys [][]byte, shardID uint lines := make([]*display.LineData, 0) for idx, pk := range pubKeysToDisplay { - horizontalLine := idx == len(pubKeysToDisplay)-1 - line := display.NewLineData(horizontalLine, []string{list, string(pk), strconv.Itoa(int(shardID))}) + horizontalLineAfter := idx == len(pubKeysToDisplay)-1 + line := display.NewLineData(horizontalLineAfter, []string{list, string(pk), strconv.Itoa(int(shardID))}) lines = append(lines, line) } + lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys)), strconv.Itoa(int(shardID))})) return lines } @@ -64,9 +78,11 @@ func displayValidators(list string, pubKeys [][]byte) { lines := make([]*display.LineData, 0) tableHeader := []string{"List", "Pub key"} - for _, pk := range pubKeysToDisplay { - lines = append(lines, display.NewLineData(false, []string{list, string(pk)})) + for idx, pk := range pubKeysToDisplay { + horizontalLineAfter := idx == len(pubKeysToDisplay)-1 + lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk)})) } + lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys))})) headline := display.Headline(fmt.Sprintf("%s list", list), "", delimiter) table, _ := display.CreateTableString(tableHeader, lines) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 529bc233d18..1432b96e09b 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -7,6 +7,23 @@ import ( "github.com/stretchr/testify/require" ) +func requireSliceContains(t *testing.T, s1, s2 [][]byte) { + for _, elemInS2 := range s2 { + require.Contains(t, s1, elemInS2) + } +} + +func requireSliceContainsNumOfElements(t *testing.T, s1, s2 [][]byte, numOfElements int) { + foundCt := 0 + for _, elemInS2 := range s2 { + if searchInSlice(s1, elemInS2) { + foundCt++ + } + } + + require.Equal(t, numOfElements, foundCt) +} + func requireSameSliceDifferentOrder(t *testing.T, s1, s2 [][]byte) { require.Equal(t, len(s1), len(s2)) @@ -15,6 +32,16 @@ func requireSameSliceDifferentOrder(t *testing.T, s1, s2 [][]byte) { } } +func searchInSlice(s1 [][]byte, s2 []byte) bool { + for _, elemInS1 := range s1 { + if bytes.Equal(elemInS1, s2) { + return true + } + } + + return false +} + func searchInMap(validatorMap map[uint32][][]byte, pk []byte) bool { for _, validatorsInShard := range validatorMap { for _, val := range validatorsInShard { @@ -30,18 +57,16 @@ func requireMapContains(t *testing.T, m map[uint32][][]byte, s [][]byte) { for _, elemInSlice := range s { require.True(t, searchInMap(m, elemInSlice)) } - } -func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { - allValidators := make([][]byte, 0) - for _, validatorsInShard := range validatorsMap { - allValidators = append(allValidators, validatorsInShard...) +func requireMapDoesNotContain(t *testing.T, m map[uint32][][]byte, s [][]byte) { + for _, elemInSlice := range s { + require.False(t, searchInMap(m, elemInSlice)) } - - return allValidators } +// TODO: Staking v4: more tests to check exactly which nodes have been selected/unselected from previous nodes config auction + func TestNewTestMetaProcessor(t *testing.T) { numOfMetaNodes := uint32(400) numOfShards := uint32(3) @@ -52,8 +77,8 @@ func TestNewTestMetaProcessor(t *testing.T) { metaConsensusGroupSize := 266 numOfNodesInStakingQueue := uint32(60) - totalEligible := int(numOfEligibleNodesPerShard*numOfShards) + int(numOfMetaNodes) - totalWaiting := int(numOfWaitingNodesPerShard*numOfShards) + int(numOfMetaNodes) + totalEligible := int(numOfEligibleNodesPerShard*numOfShards) + int(numOfMetaNodes) // 1600 + totalWaiting := int(numOfWaitingNodesPerShard*numOfShards) + int(numOfMetaNodes) // 1600 node := NewTestMetaProcessor( numOfMetaNodes, @@ -76,51 +101,76 @@ func TestNewTestMetaProcessor(t *testing.T) { require.Empty(t, initialNodes.auction) // 2. Check config after staking v4 initialization - node.Process(t, 35) - //nodesConfigStakingV4Init := node.NodesConfig - //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) - //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) - //require.Empty(t, nodesConfigStakingV4Init.queue) - //require.Empty(t, nodesConfigStakingV4Init.shuffledOut) - //requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) - // - //// 3. Check config after first staking v4 epoch - //node.Process(t, 6) - //nodesConfigStakingV4 := node.NodesConfig - //require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) - // - //numOfShuffledOut := int((numOfShards + 1) * numOfNodesToShufflePerShard) - //newWaiting := totalWaiting - numOfShuffledOut + len(nodesConfigStakingV4Init.auction) - //require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), newWaiting) - // - //// All shuffled out are in auction - //require.Len(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), numOfShuffledOut) - //requireSameSliceDifferentOrder(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), nodesConfigStakingV4.auction) - // - //// All current waiting are from the previous auction - //requireMapContains(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) - //// All current auction are from previous eligible - //requireMapContains(t, nodesConfigStakingV4Init.eligible, nodesConfigStakingV4.auction) - // - //epochs := 0 - //prevConfig := nodesConfigStakingV4 - //prevNumOfWaiting := newWaiting - //for epochs < 10 { - // node.Process(t, 5) - // newNodeConfig := node.NodesConfig - // - // newWaiting = prevNumOfWaiting - numOfShuffledOut + len(prevConfig.auction) - // require.Len(t, getAllPubKeys(newNodeConfig.waiting), newWaiting) - // require.Len(t, getAllPubKeys(newNodeConfig.eligible), totalEligible) - // - // require.Len(t, getAllPubKeys(newNodeConfig.shuffledOut), numOfShuffledOut) - // requireSameSliceDifferentOrder(t, getAllPubKeys(newNodeConfig.shuffledOut), newNodeConfig.auction) - // - // requireMapContains(t, newNodeConfig.waiting, prevConfig.auction) - // requireMapContains(t, prevConfig.eligible, newNodeConfig.auction) - // - // prevConfig = newNodeConfig - // prevNumOfWaiting = newWaiting - // epochs++ - //} + node.Process(t, 5) + nodesConfigStakingV4Init := node.NodesConfig + require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) + require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) + require.Empty(t, nodesConfigStakingV4Init.queue) + require.Empty(t, nodesConfigStakingV4Init.shuffledOut) + requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) + + // 3. Check config after first staking v4 epoch, WITHOUT distribution from auction -> waiting + node.Process(t, 6) + nodesConfigStakingV4 := node.NodesConfig + require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) // 1600 + + numOfShuffledOut := int((numOfShards + 1) * numOfNodesToShufflePerShard) // 320 + require.Len(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), numOfShuffledOut) + + newWaiting := totalWaiting - numOfShuffledOut // 1280 (1600 - 320) + require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), newWaiting) + + // 380 (320 from shuffled out + 60 from initial staking queue -> auction from stakingV4 init) + auctionListSize := numOfShuffledOut + len(nodesConfigStakingV4Init.auction) + require.Len(t, nodesConfigStakingV4.auction, auctionListSize) + requireSliceContains(t, nodesConfigStakingV4.auction, nodesConfigStakingV4Init.auction) + + require.Empty(t, nodesConfigStakingV4.queue) + require.Empty(t, nodesConfigStakingV4.leaving) + + // 320 nodes which are now in eligible are from previous waiting list + requireSliceContainsNumOfElements(t, getAllPubKeys(nodesConfigStakingV4.eligible), getAllPubKeys(nodesConfigStakingV4Init.waiting), numOfShuffledOut) + + // All shuffled out are from previous staking v4 init eligible + requireMapContains(t, nodesConfigStakingV4Init.eligible, getAllPubKeys(nodesConfigStakingV4.shuffledOut)) + + // All shuffled out are in auction + requireSliceContains(t, nodesConfigStakingV4.auction, getAllPubKeys(nodesConfigStakingV4.shuffledOut)) + + // No auction node from previous epoch have been moved to waiting + requireMapDoesNotContain(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) + + epochs := 0 + prevConfig := nodesConfigStakingV4 + numOfSelectedNodesFromAuction := numOfShuffledOut // 320, since we will always fill shuffled out nodes with this config + numOfUnselectedNodesFromAuction := auctionListSize - numOfShuffledOut // 60 = 380 - 320 + for epochs < 10 { + node.Process(t, 5) + newNodeConfig := node.NodesConfig + + require.Len(t, getAllPubKeys(newNodeConfig.eligible), totalEligible) // 1600 + require.Len(t, getAllPubKeys(newNodeConfig.waiting), newWaiting) // 1280 + require.Len(t, getAllPubKeys(newNodeConfig.shuffledOut), numOfShuffledOut) // 320 + require.Len(t, newNodeConfig.auction, auctionListSize) // 380 + require.Empty(t, newNodeConfig.queue) + require.Empty(t, newNodeConfig.leaving) + + // 320 nodes which are now in eligible are from previous waiting list + requireSliceContainsNumOfElements(t, getAllPubKeys(newNodeConfig.eligible), getAllPubKeys(prevConfig.waiting), numOfShuffledOut) + + // New auction list also contains unselected nodes from previous auction list + requireSliceContainsNumOfElements(t, newNodeConfig.auction, prevConfig.auction, numOfUnselectedNodesFromAuction) + + // All shuffled out are from previous config + requireMapContains(t, prevConfig.eligible, getAllPubKeys(newNodeConfig.shuffledOut)) + + // All shuffled out are from previous config are now in auction + requireSliceContains(t, newNodeConfig.auction, getAllPubKeys(newNodeConfig.shuffledOut)) + + // 320 nodes which have been selected from previous auction list are now in waiting + requireSliceContainsNumOfElements(t, getAllPubKeys(newNodeConfig.waiting), prevConfig.auction, numOfSelectedNodesFromAuction) + + prevConfig = newNodeConfig + epochs++ + } } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 9f0455f7ff8..920e5bf52ed 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -214,7 +214,7 @@ func createEpochStartTrigger( storageService dataRetriever.StorageService, ) integrationTests.TestEpochStartTrigger { argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ - GenesisTime: time.Now(), + GenesisTime: time.Unix(0, 0), Settings: &config.EpochStartConfig{ MinRoundsBetweenEpochs: 10, RoundsPerEpoch: 10, From 9d5cee28731659e4934f0e59812482a35e585709 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 14 Apr 2022 15:28:21 +0300 Subject: [PATCH 186/958] FIX: Roothash mismatch --- epochStart/metachain/systemSCs.go | 32 ++++++++++--- integrationTests/vm/staking/stakingQueue.go | 22 +++++---- integrationTests/vm/staking/stakingV4_test.go | 47 ++++++++++++++++++- .../vm/staking/testMetaProcessor.go | 5 -- 4 files changed, 86 insertions(+), 20 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6f870918f96..a092cc95cca 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -266,14 +266,34 @@ func (s *systemSCProcessor) getValidatorTopUpMap(validators []state.ValidatorInf } func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { - minLen := core.MinInt(len(pubKey1), len(randomness)) + lenPubKey := len(pubKey1) + lenRand := len(randomness) - key1Xor := make([]byte, minLen) - key2Xor := make([]byte, minLen) + minLen := core.MinInt(lenPubKey, lenRand) + maxLen := core.MaxInt(lenPubKey, lenRand) + repeatedCt := maxLen/minLen + 1 - for idx := 0; idx < minLen; idx++ { - key1Xor[idx] = pubKey1[idx] ^ randomness[idx] - key2Xor[idx] = pubKey2[idx] ^ randomness[idx] + rnd := randomness + pk1 := pubKey1 + pk2 := pubKey2 + + if lenPubKey > lenRand { + rnd = bytes.Repeat(randomness, repeatedCt) + rnd = rnd[:maxLen] + } else { + pk1 = bytes.Repeat(pk1, repeatedCt) + pk2 = bytes.Repeat(pk2, repeatedCt) + + pk1 = pk1[:maxLen] + pk2 = pk2[:maxLen] + } + + key1Xor := make([]byte, maxLen) + key2Xor := make([]byte, maxLen) + + for idx := 0; idx < maxLen; idx++ { + key1Xor[idx] = pk1[idx] ^ rnd[idx] + key2Xor[idx] = pk2[idx] ^ rnd[idx] } return bytes.Compare(key1Xor, key2Xor) == 1 diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index b0fd5bc2bc7..65cb0f07693 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -16,9 +16,13 @@ func createStakingQueue( marshaller marshal.Marshalizer, accountsAdapter state.AccountsAdapter, ) [][]byte { + ownerWaitingNodes := make([][]byte, 0) + if numOfNodesInStakingQueue == 0 { + return ownerWaitingNodes + } + owner := generateAddress(totalNumOfNodes) totalNumOfNodes += 1 - ownerWaitingNodes := make([][]byte, 0) for i := totalNumOfNodes; i < totalNumOfNodes+numOfNodesInStakingQueue; i++ { ownerWaitingNodes = append(ownerWaitingNodes, generateAddress(i)) } @@ -32,13 +36,15 @@ func createStakingQueue( owner, owner, ) - stakingcommon.AddKeysToWaitingList( - accountsAdapter, - ownerWaitingNodes[1:], - marshaller, - owner, - owner, - ) + if numOfNodesInStakingQueue > 1 { + stakingcommon.AddKeysToWaitingList( + accountsAdapter, + ownerWaitingNodes[1:], + marshaller, + owner, + owner, + ) + } stakingcommon.AddValidatorData( accountsAdapter, owner, diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 1432b96e09b..638e455f3c8 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -67,7 +67,7 @@ func requireMapDoesNotContain(t *testing.T, m map[uint32][][]byte, s [][]byte) { // TODO: Staking v4: more tests to check exactly which nodes have been selected/unselected from previous nodes config auction -func TestNewTestMetaProcessor(t *testing.T) { +func TestStakingV4(t *testing.T) { numOfMetaNodes := uint32(400) numOfShards := uint32(3) numOfEligibleNodesPerShard := uint32(400) @@ -174,3 +174,48 @@ func TestNewTestMetaProcessor(t *testing.T) { epochs++ } } + +func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootHash(t *testing.T) { + numOfMetaNodes := uint32(6) + numOfShards := uint32(3) + numOfEligibleNodesPerShard := uint32(6) + numOfWaitingNodesPerShard := uint32(6) + numOfNodesToShufflePerShard := uint32(2) + shardConsensusGroupSize := 2 + metaConsensusGroupSize := 2 + numOfNodesInStakingQueue := uint32(2) + + nodes := make([]*TestMetaProcessor, 0, numOfMetaNodes) + for i := uint32(0); i < numOfMetaNodes; i++ { + nodes = append(nodes, NewTestMetaProcessor( + numOfMetaNodes, + numOfShards, + numOfEligibleNodesPerShard, + numOfWaitingNodesPerShard, + numOfNodesToShufflePerShard, + shardConsensusGroupSize, + metaConsensusGroupSize, + numOfNodesInStakingQueue, + )) + nodes[i].EpochStartTrigger.SetRoundsPerEpoch(4) + } + + numOfEpochs := uint32(15) + rootHashes := make(map[uint32][][]byte) + for currEpoch := uint32(1); currEpoch <= numOfEpochs; currEpoch++ { + for _, node := range nodes { + rootHash, _ := node.ValidatorStatistics.RootHash() + rootHashes[currEpoch] = append(rootHashes[currEpoch], rootHash) + + node.Process(t, 5) + require.Equal(t, currEpoch, node.EpochStartTrigger.Epoch()) + } + } + + for _, rootHashesInEpoch := range rootHashes { + firstNodeRootHashInEpoch := rootHashesInEpoch[0] + for _, rootHash := range rootHashesInEpoch { + require.Equal(t, firstNodeRootHashInEpoch, rootHash) + } + } +} diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 920e5bf52ed..0bb20f7c59c 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,7 +1,6 @@ package staking import ( - "encoding/hex" "fmt" "math/big" "strconv" @@ -214,7 +213,6 @@ func createEpochStartTrigger( storageService dataRetriever.StorageService, ) integrationTests.TestEpochStartTrigger { argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ - GenesisTime: time.Unix(0, 0), Settings: &config.EpochStartConfig{ MinRoundsBetweenEpochs: 10, RoundsPerEpoch: 10, @@ -260,9 +258,6 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { time.Sleep(time.Millisecond * 50) tmp.updateNodesConfig(epoch) displayConfig(tmp.NodesConfig) - - rootHash, _ := tmp.ValidatorStatistics.RootHash() - fmt.Println("##########################################ROOOT HASH", hex.EncodeToString(rootHash)) } tmp.CurrentRound += numOfRounds From 9de7aec6e01f52b671446376d165d3e837bfcf49 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 14 Apr 2022 17:11:22 +0300 Subject: [PATCH 187/958] FIX: Minor fixes --- cmd/node/config/enableEpochs.toml | 2 +- epochStart/metachain/systemSCs.go | 24 +++---- .../vm/staking/componentsHolderCreator.go | 2 +- .../vm/staking/nodesCoordiantorCreator.go | 2 + integrationTests/vm/staking/stakingQueue.go | 6 +- integrationTests/vm/staking/stakingV4_test.go | 6 +- .../vm/staking/testMetaProcessor.go | 64 ++++++++++--------- 7 files changed, 55 insertions(+), 51 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index ca21150b2fa..0ddbeaed265 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -212,8 +212,8 @@ { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 }, # Staking v4 configuration, where: # - Enable epoch = StakingV4DistributeAuctionToWaiting - # - MaxNumNodes = (MaxNumNodes - (numOfShards+1)*NodesToShufflePerShard) from previous entry in MaxNodesChangeEnableEpoch # - NodesToShufflePerShard = same as previous entry in MaxNodesChangeEnableEpoch + # - MaxNumNodes = (MaxNumNodesFromPreviousEpochEnable - (numOfShards+1)*NodesToShufflePerShard) { EpochEnable = 6, MaxNumNodes = 48, NodesToShufflePerShard = 2 }, ] diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index a092cc95cca..0bf425018b2 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -14,6 +14,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -154,7 +155,7 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { - log.Warn(fmt.Sprintf("%v error when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes); skip selecting nodes from auction list", + log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", err, currNumOfValidators, numOfShuffledNodes, @@ -164,7 +165,7 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S availableSlots, err := safeSub(s.maxNodes, numOfValidatorsAfterShuffling) if availableSlots == 0 || err != nil { - log.Info(fmt.Sprintf("%v error or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", + log.Info(fmt.Sprintf("%v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", err, s.maxNodes, numOfValidatorsAfterShuffling, @@ -176,11 +177,11 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S log.Info("systemSCProcessor.selectNodesFromAuctionList", "max nodes", s.maxNodes, "current number of validators", currNumOfValidators, - "num of nodes which will be shuffled", numOfShuffledNodes, + "num of nodes which will be shuffled out", numOfShuffledNodes, "num of validators after shuffling", numOfValidatorsAfterShuffling, "auction list size", auctionListSize, - "available slots", availableSlots, - ) // todo: change to log.debug + fmt.Sprintf("available slots (%v -%v)", s.maxNodes, numOfValidatorsAfterShuffling), availableSlots, + ) err = s.sortAuctionList(auctionList, randomness) if err != nil { @@ -202,6 +203,7 @@ func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.S return nil } +// TODO: Move this in elrond-go-core func safeSub(a, b uint32) (uint32, error) { if a < b { return 0, core.ErrSubtractionOverflow @@ -300,9 +302,9 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - //if log.GetLevel() > logger.LogDebug { - // return - //} + if log.GetLevel() > logger.LogDebug { + return + } tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -318,8 +320,8 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo horizontalLine = uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ - string([]byte(owner)), - string(pubKey), + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(pubKey), topUp.String(), }) lines = append(lines, line) @@ -332,7 +334,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Error(message) + log.Debug(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index bd8eaf9f17f..635d9a6f44e 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -55,7 +55,7 @@ func createComponentHolders(numOfShards uint32) ( func createCoreComponents() factory2.CoreComponentsHolder { return &mock2.CoreComponentsStub{ - InternalMarshalizerField: &testscommon.MarshalizerMock{}, + InternalMarshalizerField: &marshal.GogoProtoMarshalizer{}, HasherField: sha256.NewSha256(), Uint64ByteSliceConverterField: uint64ByteSlice.NewBigEndianConverter(), StatusHandlerField: statusHandler.NewStatusMetrics(), diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 16af57434cc..ff45f552a8f 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -144,12 +144,14 @@ func registerValidators( for shardID, validatorsInShard := range validators { for _, val := range validatorsInShard { pubKey := val.PubKey() + peerAccount, _ := state.NewPeerAccount(pubKey) peerAccount.SetTempRating(initialRating) peerAccount.ShardId = shardID peerAccount.BLSPublicKey = pubKey peerAccount.List = string(list) _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) + stakingcommon.RegisterValidatorKeys( stateComponents.AccountsAdapter(), pubKey, diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 65cb0f07693..180eb4a020d 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -83,7 +83,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { for len(nextKey) != 0 && index <= waitingList.Length { allPubKeys = append(allPubKeys, nextKey) - element, errGet := tmp.getWaitingListElement(nextKey) + element, errGet := tmp.getWaitingListElement(stakingSCAcc, nextKey) if errGet != nil { return nil } @@ -98,9 +98,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { return allPubKeys } -func (tmp *TestMetaProcessor) getWaitingListElement(key []byte) (*systemSmartContracts.ElementInList, error) { - stakingSCAcc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) - +func (tmp *TestMetaProcessor) getWaitingListElement(stakingSCAcc state.UserAccountHandler, key []byte) (*systemSmartContracts.ElementInList, error) { marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) if len(marshaledData) == 0 { return nil, vm.ErrElementNotFound diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 638e455f3c8..5c59b81b51a 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -137,7 +137,7 @@ func TestStakingV4(t *testing.T) { // All shuffled out are in auction requireSliceContains(t, nodesConfigStakingV4.auction, getAllPubKeys(nodesConfigStakingV4.shuffledOut)) - // No auction node from previous epoch have been moved to waiting + // No auction node from previous epoch has been moved to waiting requireMapDoesNotContain(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) epochs := 0 @@ -161,10 +161,10 @@ func TestStakingV4(t *testing.T) { // New auction list also contains unselected nodes from previous auction list requireSliceContainsNumOfElements(t, newNodeConfig.auction, prevConfig.auction, numOfUnselectedNodesFromAuction) - // All shuffled out are from previous config + // All shuffled out are from previous eligible config requireMapContains(t, prevConfig.eligible, getAllPubKeys(newNodeConfig.shuffledOut)) - // All shuffled out are from previous config are now in auction + // All shuffled out are now in auction requireSliceContains(t, newNodeConfig.auction, getAllPubKeys(newNodeConfig.shuffledOut)) // 320 nodes which have been selected from previous auction list are now in waiting diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 0bb20f7c59c..4bf945a3913 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -53,9 +53,10 @@ type TestMetaProcessor struct { EpochStartTrigger integrationTests.TestEpochStartTrigger BlockChainHandler data.ChainHandler NodesConfig nodesConfig - CurrentRound uint64 AccountsAdapter state.AccountsAdapter Marshaller marshal.Marshalizer + + currentRound uint64 } // NewTestMetaProcessor - @@ -165,7 +166,7 @@ func NewTestMetaProcessor( epochStartTrigger, vmContainer, ), - CurrentRound: 1, + currentRound: 1, NodesCoordinator: nc, ValidatorStatistics: validatorStatisticsProcessor, EpochStartTrigger: epochStartTrigger, @@ -234,14 +235,14 @@ func createEpochStartTrigger( // Process - func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { - for r := tmp.CurrentRound; r < tmp.CurrentRound+numOfRounds; r++ { - currentHeader, currentHash := tmp.getCurrentHeaderInfo() + for r := tmp.currentRound; r < tmp.currentRound+numOfRounds; r++ { _, err := tmp.MetaBlockProcessor.CreateNewHeader(r, r) require.Nil(t, err) epoch := tmp.EpochStartTrigger.Epoch() printNewHeaderRoundEpoch(r, epoch) + currentHeader, currentHash := tmp.getCurrentHeaderInfo() header := createMetaBlockToCommit( epoch, r, @@ -249,6 +250,7 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { currentHeader.GetRandSeed(), tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), ) + newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, func() bool { return true }) require.Nil(t, err) @@ -260,7 +262,7 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { displayConfig(tmp.NodesConfig) } - tmp.CurrentRound += numOfRounds + tmp.currentRound += numOfRounds } func printNewHeaderRoundEpoch(round uint64, epoch uint32) { @@ -272,30 +274,6 @@ func printNewHeaderRoundEpoch(round uint64, epoch uint32) { fmt.Println(headline) } -func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { - eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) - waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) - leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) - shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) - - rootHash, _ := tmp.ValidatorStatistics.RootHash() - validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - - auction := make([][]byte, 0) - for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { - if validator.GetList() == string(common.AuctionList) { - auction = append(auction, validator.GetPublicKey()) - } - } - - tmp.NodesConfig.eligible = eligible - tmp.NodesConfig.waiting = waiting - tmp.NodesConfig.shuffledOut = shuffledOut - tmp.NodesConfig.leaving = leaving - tmp.NodesConfig.auction = auction - tmp.NodesConfig.queue = tmp.getWaitingListKeys() -} - func (tmp *TestMetaProcessor) getCurrentHeaderInfo() (data.HeaderHandler, []byte) { currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() @@ -322,11 +300,11 @@ func createMetaBlockToCommit( PrevHash: prevHash, Signature: []byte("signature"), PubKeysBitmap: []byte(strings.Repeat("f", consensusSize)), - RootHash: []byte("roothash"), + RootHash: []byte("roothash" + roundStr), ShardInfo: make([]block.ShardData, 0), TxCount: 1, PrevRandSeed: prevRandSeed, - RandSeed: []byte("roothash" + roundStr), + RandSeed: []byte("randseed" + roundStr), AccumulatedFeesInEpoch: big.NewInt(0), AccumulatedFees: big.NewInt(0), DevFeesInEpoch: big.NewInt(0), @@ -355,6 +333,30 @@ func createMetaBlockToCommit( return &hdr } +func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { + eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) + waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) + leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) + shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) + + rootHash, _ := tmp.ValidatorStatistics.RootHash() + validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + + auction := make([][]byte, 0) + for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { + if validator.GetList() == string(common.AuctionList) { + auction = append(auction, validator.GetPublicKey()) + } + } + + tmp.NodesConfig.eligible = eligible + tmp.NodesConfig.waiting = waiting + tmp.NodesConfig.shuffledOut = shuffledOut + tmp.NodesConfig.leaving = leaving + tmp.NodesConfig.auction = auction + tmp.NodesConfig.queue = tmp.getWaitingListKeys() +} + func generateAddress(identifier uint32) []byte { uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) From 149bd22b35592a58fe77d29922143e6d794e3fd3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 15 Apr 2022 10:36:13 +0300 Subject: [PATCH 188/958] FIX: Rename StakingV4DistributeAuctionToWaiting epoch --- cmd/node/config/enableEpochs.toml | 6 +- factory/coreComponents.go | 20 ++--- .../vm/staking/nodesCoordiantorCreator.go | 16 ++-- .../vm/staking/testMetaProcessor.go | 12 +-- .../nodesCoordinator/hashValidatorShuffler.go | 72 ++++++++-------- .../hashValidatorShuffler_test.go | 84 +++++++++---------- 6 files changed, 105 insertions(+), 105 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 0ddbeaed265..104b8f36fd4 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -203,15 +203,15 @@ # StakingV4EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4InitEnableEpoch StakingV4EnableEpoch = 5 - # StakingV4DistributeAuctionToWaiting represents the epoch in which selected nodes from auction will be distributed to waiting list - StakingV4DistributeAuctionToWaiting = 6 + # StakingV4DistributeAuctionToWaitingEpoch represents the epoch in which selected nodes from auction will be distributed to waiting list + StakingV4DistributeAuctionToWaitingEpoch = 6 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 }, # Staking v4 configuration, where: - # - Enable epoch = StakingV4DistributeAuctionToWaiting + # - Enable epoch = StakingV4DistributeAuctionToWaitingEpoch # - NodesToShufflePerShard = same as previous entry in MaxNodesChangeEnableEpoch # - MaxNumNodes = (MaxNumNodesFromPreviousEpochEnable - (numOfShards+1)*NodesToShufflePerShard) { EpochEnable = 6, MaxNumNodes = 48, NodesToShufflePerShard = 2 }, diff --git a/factory/coreComponents.go b/factory/coreComponents.go index c04bda0c8ce..7adff1aa730 100644 --- a/factory/coreComponents.go +++ b/factory/coreComponents.go @@ -310,16 +310,16 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) { } argsNodesShuffler := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: genesisNodesConfig.MinNumberOfShardNodes(), - NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(), - Hysteresis: genesisNodesConfig.GetHysteresis(), - Adaptivity: genesisNodesConfig.GetAdaptivity(), - ShuffleBetweenShards: true, - MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, - BalanceWaitingListsEnableEpoch: ccf.epochConfig.EnableEpochs.BalanceWaitingListsEnableEpoch, - WaitingListFixEnableEpoch: ccf.epochConfig.EnableEpochs.WaitingListFixEnableEpoch, - StakingV4EnableEpoch: ccf.epochConfig.EnableEpochs.StakingV4EnableEpoch, - StakingV4DistributeAuctionToWaiting: ccf.epochConfig.EnableEpochs.StakingV4DistributeAuctionToWaiting, + NodesShard: genesisNodesConfig.MinNumberOfShardNodes(), + NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(), + Hysteresis: genesisNodesConfig.GetHysteresis(), + Adaptivity: genesisNodesConfig.GetAdaptivity(), + ShuffleBetweenShards: true, + MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, + BalanceWaitingListsEnableEpoch: ccf.epochConfig.EnableEpochs.BalanceWaitingListsEnableEpoch, + WaitingListFixEnableEpoch: ccf.epochConfig.EnableEpochs.WaitingListFixEnableEpoch, + StakingV4EnableEpoch: ccf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: ccf.epochConfig.EnableEpochs.StakingV4DistributeAuctionToWaiting, } nodesShuffler, err := nodesCoordinator.NewHashValidatorsShuffler(argsNodesShuffler) diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index ff45f552a8f..34515124a09 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -46,14 +46,14 @@ func createNodesCoordinator( ) shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: numOfEligibleNodesPerShard, - NodesMeta: numOfMetaNodes, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: maxNodesConfig, - StakingV4EnableEpoch: stakingV4EnableEpoch, - StakingV4DistributeAuctionToWaiting: stakingV4DistributeAuctionToWaiting, + NodesShard: numOfEligibleNodesPerShard, + NodesMeta: numOfMetaNodes, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: maxNodesConfig, + StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 4bf945a3913..8caa532c1d7 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -29,11 +29,11 @@ import ( ) const ( - stakingV4InitEpoch = 1 - stakingV4EnableEpoch = 2 - stakingV4DistributeAuctionToWaiting = 3 - addressLength = 15 - nodePrice = 1000 + stakingV4InitEpoch = 1 + stakingV4EnableEpoch = 2 + stakingV4DistributeAuctionToWaitingEpoch = 3 + addressLength = 15 + nodePrice = 1000 ) type nodesConfig struct { @@ -194,7 +194,7 @@ func createMaxNodesConfig( ) maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{ - EpochEnable: stakingV4DistributeAuctionToWaiting, + EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, MaxNumNodes: totalNodes - numOfNodesToShufflePerShard*(numOfShards+1), NodesToShufflePerShard: numOfNodesToShufflePerShard, }, diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index aeefdd5d741..dba6e92b793 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -16,16 +16,16 @@ var _ NodesShuffler = (*randHashShuffler)(nil) // NodesShufflerArgs defines the arguments required to create a nodes shuffler type NodesShufflerArgs struct { - NodesShard uint32 - NodesMeta uint32 - Hysteresis float32 - Adaptivity bool - ShuffleBetweenShards bool - MaxNodesEnableConfig []config.MaxNodesChangeConfig - BalanceWaitingListsEnableEpoch uint32 - WaitingListFixEnableEpoch uint32 - StakingV4EnableEpoch uint32 - StakingV4DistributeAuctionToWaiting uint32 + NodesShard uint32 + NodesMeta uint32 + Hysteresis float32 + Adaptivity bool + ShuffleBetweenShards bool + MaxNodesEnableConfig []config.MaxNodesChangeConfig + BalanceWaitingListsEnableEpoch uint32 + WaitingListFixEnableEpoch uint32 + StakingV4EnableEpoch uint32 + StakingV4DistributeAuctionToWaitingEpoch uint32 } type shuffleNodesArg struct { @@ -53,23 +53,23 @@ type randHashShuffler struct { // when reinitialization of node in new shard is implemented shuffleBetweenShards bool - adaptivity bool - nodesShard uint32 - nodesMeta uint32 - shardHysteresis uint32 - metaHysteresis uint32 - activeNodesConfig config.MaxNodesChangeConfig - availableNodesConfigs []config.MaxNodesChangeConfig - mutShufflerParams sync.RWMutex - validatorDistributor ValidatorsDistributor - balanceWaitingListsEnableEpoch uint32 - flagBalanceWaitingLists atomic.Flag - waitingListFixEnableEpoch uint32 - flagWaitingListFix atomic.Flag - stakingV4DistributeAuctionToWaiting uint32 - flagStakingV4DistributeAuctionToWaiting atomic.Flag - stakingV4EnableEpoch uint32 - flagStakingV4 atomic.Flag + adaptivity bool + nodesShard uint32 + nodesMeta uint32 + shardHysteresis uint32 + metaHysteresis uint32 + activeNodesConfig config.MaxNodesChangeConfig + availableNodesConfigs []config.MaxNodesChangeConfig + mutShufflerParams sync.RWMutex + validatorDistributor ValidatorsDistributor + balanceWaitingListsEnableEpoch uint32 + flagBalanceWaitingLists atomic.Flag + waitingListFixEnableEpoch uint32 + flagWaitingListFix atomic.Flag + stakingV4DistributeAuctionToWaitingEpoch uint32 + flagStakingV4DistributeAuctionToWaiting atomic.Flag + stakingV4EnableEpoch uint32 + flagStakingV4 atomic.Flag } // NewHashValidatorsShuffler creates a validator shuffler that uses a hash between validator key and a given @@ -84,7 +84,7 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro log.Debug("hashValidatorShuffler: enable epoch for max nodes change", "epoch", args.MaxNodesEnableConfig) log.Debug("hashValidatorShuffler: enable epoch for balance waiting lists", "epoch", args.BalanceWaitingListsEnableEpoch) log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.StakingV4EnableEpoch) - log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.StakingV4DistributeAuctionToWaiting) + log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.StakingV4DistributeAuctionToWaitingEpoch) if args.MaxNodesEnableConfig != nil { configs = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) @@ -93,17 +93,17 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro log.Debug("Shuffler created", "shuffleBetweenShards", args.ShuffleBetweenShards) rxs := &randHashShuffler{ - shuffleBetweenShards: args.ShuffleBetweenShards, - availableNodesConfigs: configs, - balanceWaitingListsEnableEpoch: args.BalanceWaitingListsEnableEpoch, - waitingListFixEnableEpoch: args.WaitingListFixEnableEpoch, - stakingV4DistributeAuctionToWaiting: args.StakingV4DistributeAuctionToWaiting, - stakingV4EnableEpoch: args.StakingV4EnableEpoch, + shuffleBetweenShards: args.ShuffleBetweenShards, + availableNodesConfigs: configs, + balanceWaitingListsEnableEpoch: args.BalanceWaitingListsEnableEpoch, + waitingListFixEnableEpoch: args.WaitingListFixEnableEpoch, + stakingV4DistributeAuctionToWaitingEpoch: args.StakingV4DistributeAuctionToWaitingEpoch, + stakingV4EnableEpoch: args.StakingV4EnableEpoch, } log.Debug("randHashShuffler: enable epoch for balance waiting list", "epoch", rxs.balanceWaitingListsEnableEpoch) log.Debug("randHashShuffler: enable epoch for waiting waiting list", "epoch", rxs.waitingListFixEnableEpoch) - log.Debug("randHashShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", rxs.stakingV4DistributeAuctionToWaiting) + log.Debug("randHashShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", rxs.stakingV4DistributeAuctionToWaitingEpoch) log.Debug("randHashShuffler: enable epoch for staking v4", "epoch", rxs.stakingV4EnableEpoch) rxs.UpdateParams(args.NodesShard, args.NodesMeta, args.Hysteresis, args.Adaptivity) @@ -813,7 +813,7 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { rhs.flagWaitingListFix.SetValue(epoch >= rhs.waitingListFixEnableEpoch) log.Debug("waiting list fix", "enabled", rhs.flagWaitingListFix.IsSet()) - rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4DistributeAuctionToWaiting) + rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4DistributeAuctionToWaitingEpoch) log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4DistributeAuctionToWaiting.IsSet()) rhs.flagStakingV4.SetValue(epoch >= rhs.stakingV4EnableEpoch) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index 6844ad8a4ba..6f6398d5e56 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -186,14 +186,14 @@ func testShuffledOut( func createHashShufflerInter() (*randHashShuffler, error) { shufflerArgs := &NodesShufflerArgs{ - NodesShard: eligiblePerShard, - NodesMeta: eligiblePerShard, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: true, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaiting: 444, + NodesShard: eligiblePerShard, + NodesMeta: eligiblePerShard, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: true, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -203,14 +203,14 @@ func createHashShufflerInter() (*randHashShuffler, error) { func createHashShufflerIntraShards() (*randHashShuffler, error) { shufflerArgs := &NodesShufflerArgs{ - NodesShard: eligiblePerShard, - NodesMeta: eligiblePerShard, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaiting: 444, + NodesShard: eligiblePerShard, + NodesMeta: eligiblePerShard, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1186,16 +1186,16 @@ func TestRandHashShuffler_UpdateParams(t *testing.T) { require.Nil(t, err) shuffler2 := &randHashShuffler{ - nodesShard: 200, - nodesMeta: 200, - shardHysteresis: 0, - metaHysteresis: 0, - adaptivity: true, - shuffleBetweenShards: true, - validatorDistributor: &CrossShardValidatorDistributor{}, - availableNodesConfigs: nil, - stakingV4EnableEpoch: 443, - stakingV4DistributeAuctionToWaiting: 444, + nodesShard: 200, + nodesMeta: 200, + shardHysteresis: 0, + metaHysteresis: 0, + adaptivity: true, + shuffleBetweenShards: true, + validatorDistributor: &CrossShardValidatorDistributor{}, + availableNodesConfigs: nil, + stakingV4EnableEpoch: 443, + stakingV4DistributeAuctionToWaitingEpoch: 444, } shuffler.UpdateParams( @@ -2379,14 +2379,14 @@ func TestRandHashShuffler_UpdateNodeLists_All(t *testing.T) { unstakeLeavingList, additionalLeavingList := prepareListsFromMaps(unstakeLeaving, additionalLeaving) shufflerArgs := &NodesShufflerArgs{ - NodesShard: uint32(eligiblePerShard), - NodesMeta: uint32(eligiblePerShard), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaiting: 444, + NodesShard: uint32(eligiblePerShard), + NodesMeta: uint32(eligiblePerShard), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) @@ -2728,14 +2728,14 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t } shufflerArgs := &NodesShufflerArgs{ - NodesShard: uint32(numEligiblePerShard), - NodesMeta: uint32(numEligiblePerShard), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaiting: 444, + NodesShard: uint32(numEligiblePerShard), + NodesMeta: uint32(numEligiblePerShard), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) From 1cf4bb039851c0c8c4dd108e4205ab3e78fce515 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 15 Apr 2022 14:50:18 +0300 Subject: [PATCH 189/958] FIX: Package names --- .../vm/staking/componentsHolderCreator.go | 40 +++++++++---------- .../vm/staking/metaBlockProcessorCreator.go | 26 ++++++------ .../vm/staking/nodesCoordiantorCreator.go | 18 ++++----- .../vm/staking/systemSCCreator.go | 22 +++++----- .../vm/staking/testMetaProcessor.go | 4 +- 5 files changed, 55 insertions(+), 55 deletions(-) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 635d9a6f44e..f65a5fd84bd 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -17,15 +17,15 @@ import ( "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" - factory2 "github.com/ElrondNetwork/elrond-go/factory" + "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" - mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" - factory3 "github.com/ElrondNetwork/elrond-go/node/mock/factory" + integrationMocks "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + mockFactory "github.com/ElrondNetwork/elrond-go/node/mock/factory" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/state/factory" + stateFactory "github.com/ElrondNetwork/elrond-go/state/factory" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" "github.com/ElrondNetwork/elrond-go/statusHandler" @@ -38,11 +38,11 @@ import ( ) func createComponentHolders(numOfShards uint32) ( - factory2.CoreComponentsHolder, - factory2.DataComponentsHolder, - factory2.BootstrapComponentsHolder, - factory2.StatusComponentsHolder, - factory2.StateComponentsHandler, + factory.CoreComponentsHolder, + factory.DataComponentsHolder, + factory.BootstrapComponentsHolder, + factory.StatusComponentsHolder, + factory.StateComponentsHandler, ) { coreComponents := createCoreComponents() statusComponents := createStatusComponents() @@ -53,8 +53,8 @@ func createComponentHolders(numOfShards uint32) ( return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents } -func createCoreComponents() factory2.CoreComponentsHolder { - return &mock2.CoreComponentsStub{ +func createCoreComponents() factory.CoreComponentsHolder { + return &integrationMocks.CoreComponentsStub{ InternalMarshalizerField: &marshal.GogoProtoMarshalizer{}, HasherField: sha256.NewSha256(), Uint64ByteSliceConverterField: uint64ByteSlice.NewBigEndianConverter(), @@ -70,7 +70,7 @@ func createCoreComponents() factory2.CoreComponentsHolder { } } -func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfShards uint32) factory2.DataComponentsHolder { +func createDataComponents(coreComponents factory.CoreComponentsHolder, numOfShards uint32) factory.DataComponentsHolder { genesisBlock := createGenesisMetaBlock() genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) @@ -90,7 +90,7 @@ func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfSha chainStorer.AddStorer(unit, integrationTests.CreateMemUnit()) } - return &factory3.DataComponentsMock{ + return &mockFactory.DataComponentsMock{ Store: chainStorer, DataPool: dataRetrieverMock.NewPoolsHolderMock(), BlockChain: blockChain, @@ -99,9 +99,9 @@ func createDataComponents(coreComponents factory2.CoreComponentsHolder, numOfSha } func createBootstrapComponents( - coreComponents factory2.CoreComponentsHolder, + coreComponents factory.CoreComponentsHolder, numOfShards uint32, -) factory2.BootstrapComponentsHolder { +) factory.BootstrapComponentsHolder { shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) ncr, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( coreComponents.InternalMarshalizer(), @@ -121,19 +121,19 @@ func createBootstrapComponents( } } -func createStatusComponents() factory2.StatusComponentsHolder { - return &mock2.StatusComponentsStub{ +func createStatusComponents() factory.StatusComponentsHolder { + return &integrationMocks.StatusComponentsStub{ Outport: &testscommon.OutportStub{}, AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, } } -func createStateComponents(coreComponents factory2.CoreComponentsHolder) factory2.StateComponentsHandler { +func createStateComponents(coreComponents factory.CoreComponentsHolder) factory.StateComponentsHandler { trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) hasher := coreComponents.Hasher() marshaller := coreComponents.InternalMarshalizer() - userAccountsDB := createAccountsDB(hasher, marshaller, factory.NewAccountCreator(), trieFactoryManager) - peerAccountsDB := createAccountsDB(hasher, marshaller, factory.NewPeerAccountCreator(), trieFactoryManager) + userAccountsDB := createAccountsDB(hasher, marshaller, stateFactory.NewAccountCreator(), trieFactoryManager) + peerAccountsDB := createAccountsDB(hasher, marshaller, stateFactory.NewPeerAccountCreator(), trieFactoryManager) return &testscommon.StateComponentsMock{ PeersAcc: peerAccountsDB, diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index a924bea5d69..10d5dfeb97a 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -9,8 +9,8 @@ import ( "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - factory2 "github.com/ElrondNetwork/elrond-go/factory" - mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + "github.com/ElrondNetwork/elrond-go/factory" + integrationMocks "github.com/ElrondNetwork/elrond-go/integrationTests/mock" "github.com/ElrondNetwork/elrond-go/process" blproc "github.com/ElrondNetwork/elrond-go/process/block" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" @@ -26,11 +26,11 @@ import ( func createMetaBlockProcessor( nc nodesCoordinator.NodesCoordinator, systemSCProcessor process.EpochStartSystemSCProcessor, - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, - bootstrapComponents factory2.BootstrapComponentsHolder, - statusComponents factory2.StatusComponentsHolder, - stateComponents factory2.StateComponentsHandler, + coreComponents factory.CoreComponentsHolder, + dataComponents factory.DataComponentsHolder, + bootstrapComponents factory.BootstrapComponentsHolder, + statusComponents factory.StatusComponentsHolder, + stateComponents factory.StateComponentsHandler, validatorsInfoCreator process.ValidatorStatisticsProcessor, blockChainHook process.BlockChainHookHandler, metaVMFactory process.VirtualMachinesContainerFactory, @@ -66,7 +66,7 @@ func createMetaBlockProcessor( BootstrapComponents: bootstrapComponents, StatusComponents: statusComponents, AccountsDB: accountsDb, - ForkDetector: &mock2.ForkDetectorStub{}, + ForkDetector: &integrationMocks.ForkDetectorStub{}, NodesCoordinator: nc, FeeHandler: postprocess.NewFeeAccumulator(), RequestHandler: &testscommon.RequestHandlerStub{}, @@ -101,8 +101,8 @@ func createMetaBlockProcessor( } func createValidatorInfoCreator( - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, + coreComponents factory.CoreComponentsHolder, + dataComponents factory.DataComponentsHolder, shardCoordinator sharding.Coordinator, ) process.EpochStartValidatorInfoCreator { args := metachain.ArgsNewValidatorInfoCreator{ @@ -118,8 +118,8 @@ func createValidatorInfoCreator( } func createEpochStartDataCreator( - coreComponents factory2.CoreComponentsHolder, - dataComponents factory2.DataComponentsHolder, + coreComponents factory.CoreComponentsHolder, + dataComponents factory.DataComponentsHolder, shardCoordinator sharding.Coordinator, epochStartTrigger process.EpochStartTriggerHandler, blockTracker process.BlockTracker, @@ -187,7 +187,7 @@ func createGenesisMetaBlock() *block.MetaBlock { } } -func createHeaderValidator(coreComponents factory2.CoreComponentsHolder) epochStart.HeaderValidator { +func createHeaderValidator(coreComponents factory.CoreComponentsHolder) epochStart.HeaderValidator { argsHeaderValidator := blproc.ArgsHeaderValidator{ Hasher: coreComponents.Hasher(), Marshalizer: coreComponents.InternalMarshalizer(), diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 34515124a09..1fdd224a132 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -7,8 +7,8 @@ import ( "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" - factory2 "github.com/ElrondNetwork/elrond-go/factory" - mock2 "github.com/ElrondNetwork/elrond-go/integrationTests/mock" + "github.com/ElrondNetwork/elrond-go/factory" + integrationMocks "github.com/ElrondNetwork/elrond-go/integrationTests/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage" @@ -30,9 +30,9 @@ func createNodesCoordinator( numOfWaitingNodesPerShard uint32, shardConsensusGroupSize int, metaConsensusGroupSize int, - coreComponents factory2.CoreComponentsHolder, + coreComponents factory.CoreComponentsHolder, bootStorer storage.Storer, - stateComponents factory2.StateComponentsHandler, + stateComponents factory.StateComponentsHandler, nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, maxNodesConfig []config.MaxNodesChangeConfig, ) nodesCoordinator.NodesCoordinator { @@ -69,7 +69,7 @@ func createNodesCoordinator( WaitingNodes: waitingMap, SelfPublicKey: eligibleMap[core.MetachainShardId][0].PubKey(), ConsensusGroupCache: cache, - ShuffledOutHandler: &mock2.ShuffledOutHandlerStub{}, + ShuffledOutHandler: &integrationMocks.ShuffledOutHandlerStub{}, ChanStopNode: coreComponents.ChanStopNodeProcess(), IsFullArchive: false, Shuffler: nodeShuffler, @@ -92,7 +92,7 @@ func createGenesisNodes( numOfNodesPerShard uint32, numOfWaitingNodesPerShard uint32, marshaller marshal.Marshalizer, - stateComponents factory2.StateComponentsHandler, + stateComponents factory.StateComponentsHandler, ) (map[uint32][]nodesCoordinator.Validator, map[uint32][]nodesCoordinator.Validator) { addressStartIdx := uint32(0) eligibleGenesisNodes := generateGenesisNodeInfoMap(numOfMetaNodes, numOfShards, numOfNodesPerShard, addressStartIdx) @@ -119,7 +119,7 @@ func generateGenesisNodeInfoMap( for shardId := uint32(0); shardId < numOfShards; shardId++ { for n := uint32(0); n < numOfNodesPerShard; n++ { addr := generateAddress(id) - validator := mock2.NewNodeInfo(addr, addr, shardId, initialRating) + validator := integrationMocks.NewNodeInfo(addr, addr, shardId, initialRating) validatorsMap[shardId] = append(validatorsMap[shardId], validator) id++ } @@ -127,7 +127,7 @@ func generateGenesisNodeInfoMap( for n := uint32(0); n < numOfMetaNodes; n++ { addr := generateAddress(id) - validator := mock2.NewNodeInfo(addr, addr, core.MetachainShardId, initialRating) + validator := integrationMocks.NewNodeInfo(addr, addr, core.MetachainShardId, initialRating) validatorsMap[core.MetachainShardId] = append(validatorsMap[core.MetachainShardId], validator) id++ } @@ -137,7 +137,7 @@ func generateGenesisNodeInfoMap( func registerValidators( validators map[uint32][]nodesCoordinator.Validator, - stateComponents factory2.StateComponentsHolder, + stateComponents factory.StateComponentsHolder, marshaller marshal.Marshalizer, list common.PeerType, ) { diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index e7ee6ed9ab4..48ecc0ba312 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -7,8 +7,8 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - mock3 "github.com/ElrondNetwork/elrond-go/epochStart/mock" - factory2 "github.com/ElrondNetwork/elrond-go/factory" + epochStartMock "github.com/ElrondNetwork/elrond-go/epochStart/mock" + "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" @@ -27,8 +27,8 @@ import ( func createSystemSCProcessor( nc nodesCoordinator.NodesCoordinator, - coreComponents factory2.CoreComponentsHolder, - stateComponents factory2.StateComponentsHandler, + coreComponents factory.CoreComponentsHolder, + stateComponents factory.StateComponentsHandler, shardCoordinator sharding.Coordinator, maxNodesConfig []config.MaxNodesChangeConfig, validatorStatisticsProcessor process.ValidatorStatisticsProcessor, @@ -46,7 +46,7 @@ func createSystemSCProcessor( ValidatorInfoCreator: validatorStatisticsProcessor, EndOfEpochCallerAddress: vm.EndOfEpochAddress, StakingSCAddress: vm.StakingSCAddress, - ChanceComputer: &mock3.ChanceComputerStub{}, + ChanceComputer: &epochStartMock.ChanceComputerStub{}, EpochNotifier: coreComponents.EpochNotifier(), GenesisNodesConfig: &mock.NodesSetupStub{}, StakingDataProvider: stakingSCProvider, @@ -68,8 +68,8 @@ func createSystemSCProcessor( } func createValidatorStatisticsProcessor( - dataComponents factory2.DataComponentsHolder, - coreComponents factory2.CoreComponentsHolder, + dataComponents factory.DataComponentsHolder, + coreComponents factory.CoreComponentsHolder, nc nodesCoordinator.NodesCoordinator, shardCoordinator sharding.Coordinator, peerAccounts state.AccountsAdapter, @@ -83,7 +83,7 @@ func createValidatorStatisticsProcessor( PubkeyConv: coreComponents.AddressPubKeyConverter(), PeerAdapter: peerAccounts, Rater: coreComponents.Rater(), - RewardsHandler: &mock3.RewardsHandlerStub{}, + RewardsHandler: &epochStartMock.RewardsHandlerStub{}, NodesSetup: &mock.NodesSetupStub{}, MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, @@ -96,8 +96,8 @@ func createValidatorStatisticsProcessor( } func createBlockChainHook( - dataComponents factory2.DataComponentsHolder, - coreComponents factory2.CoreComponentsHolder, + dataComponents factory.DataComponentsHolder, + coreComponents factory.CoreComponentsHolder, accountsAdapter state.AccountsAdapter, shardCoordinator sharding.Coordinator, gasScheduleNotifier core.GasScheduleNotifier, @@ -133,7 +133,7 @@ func createBlockChainHook( } func createVMContainerFactory( - coreComponents factory2.CoreComponentsHolder, + coreComponents factory.CoreComponentsHolder, gasScheduleNotifier core.GasScheduleNotifier, blockChainHook process.BlockChainHookHandler, peerAccounts state.AccountsAdapter, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 8caa532c1d7..db717874975 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -18,7 +18,7 @@ import ( "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - factory2 "github.com/ElrondNetwork/elrond-go/factory" + "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/process/mock" @@ -210,7 +210,7 @@ func createGasScheduleNotifier() core.GasScheduleNotifier { } func createEpochStartTrigger( - coreComponents factory2.CoreComponentsHolder, + coreComponents factory.CoreComponentsHolder, storageService dataRetriever.StorageService, ) integrationTests.TestEpochStartTrigger { argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ From c000cff896d90e55d1405df5581cfe3bf735a7ce Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 15 Apr 2022 16:27:47 +0300 Subject: [PATCH 190/958] FEAT: Move unjailed and new staked nodes to auction --- factory/blockProcessorCreator.go | 21 ++++++------- integrationTests/testProcessorNode.go | 19 ++++++------ process/scToProtocol/stakingToPeer.go | 24 +++++++++++---- process/scToProtocol/stakingToPeer_test.go | 34 +++++++++++++++------- 4 files changed, 64 insertions(+), 34 deletions(-) diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 61abeebc35a..19622ac7e58 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -654,16 +654,17 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( scheduledTxsExecutionHandler.SetTransactionCoordinator(txCoordinator) argsStaking := scToProtocol.ArgStakingToPeer{ - PubkeyConv: pcf.coreData.ValidatorPubKeyConverter(), - Hasher: pcf.coreData.Hasher(), - Marshalizer: pcf.coreData.InternalMarshalizer(), - PeerState: pcf.state.PeerAccounts(), - BaseState: pcf.state.AccountsAdapter(), - ArgParser: argsParser, - CurrTxs: pcf.data.Datapool().CurrentBlockTxs(), - RatingsData: pcf.coreData.RatingsData(), - EpochNotifier: pcf.coreData.EpochNotifier(), - StakeEnableEpoch: pcf.epochConfig.EnableEpochs.StakeEnableEpoch, + PubkeyConv: pcf.coreData.ValidatorPubKeyConverter(), + Hasher: pcf.coreData.Hasher(), + Marshalizer: pcf.coreData.InternalMarshalizer(), + PeerState: pcf.state.PeerAccounts(), + BaseState: pcf.state.AccountsAdapter(), + ArgParser: argsParser, + CurrTxs: pcf.data.Datapool().CurrentBlockTxs(), + RatingsData: pcf.coreData.RatingsData(), + EpochNotifier: pcf.coreData.EpochNotifier(), + StakeEnableEpoch: pcf.epochConfig.EnableEpochs.StakeEnableEpoch, + StakingV4InitEpoch: pcf.epochConfig.EnableEpochs.StakingV4InitEnableEpoch, } smartContractToProtocol, err := scToProtocol.NewStakingToPeer(argsStaking) if err != nil { diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index a0b5bba7238..e0f7f0dd901 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2126,15 +2126,16 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { argumentsBase.TxCoordinator = tpn.TxCoordinator argsStakingToPeer := scToProtocol.ArgStakingToPeer{ - PubkeyConv: TestValidatorPubkeyConverter, - Hasher: TestHasher, - Marshalizer: TestMarshalizer, - PeerState: tpn.PeerState, - BaseState: tpn.AccntState, - ArgParser: tpn.ArgsParser, - CurrTxs: tpn.DataPool.CurrentBlockTxs(), - RatingsData: tpn.RatingsData, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, + PubkeyConv: TestValidatorPubkeyConverter, + Hasher: TestHasher, + Marshalizer: TestMarshalizer, + PeerState: tpn.PeerState, + BaseState: tpn.AccntState, + ArgParser: tpn.ArgsParser, + CurrTxs: tpn.DataPool.CurrentBlockTxs(), + RatingsData: tpn.RatingsData, + StakingV4InitEpoch: StakingV4Epoch - 1, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, } scToProtocolInstance, _ := scToProtocol.NewStakingToPeer(argsStakingToPeer) diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index 9efc4fd2360..fab486551c0 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -3,6 +3,7 @@ package scToProtocol import ( "bytes" "encoding/hex" + "fmt" "math" "github.com/ElrondNetwork/elrond-go-core/core" @@ -36,9 +37,10 @@ type ArgStakingToPeer struct { ArgParser process.ArgumentsParser CurrTxs dataRetriever.TransactionCacher RatingsData process.RatingsInfoHandler + EpochNotifier process.EpochNotifier StakeEnableEpoch uint32 ValidatorToDelegationEnableEpoch uint32 - EpochNotifier process.EpochNotifier + StakingV4InitEpoch uint32 } // stakingToPeer defines the component which will translate changes from staking SC state @@ -58,6 +60,8 @@ type stakingToPeer struct { flagStaking atomic.Flag validatorToDelegationEnableEpoch uint32 flagValidatorToDelegation atomic.Flag + stakingV4InitEpoch uint32 + flagStakingV4Init atomic.Flag } // NewStakingToPeer creates the component which moves from staking sc state to peer state @@ -80,8 +84,10 @@ func NewStakingToPeer(args ArgStakingToPeer) (*stakingToPeer, error) { jailRating: args.RatingsData.MinRating(), stakeEnableEpoch: args.StakeEnableEpoch, validatorToDelegationEnableEpoch: args.ValidatorToDelegationEnableEpoch, + stakingV4InitEpoch: args.StakingV4InitEpoch, } log.Debug("stakingToPeer: enable epoch for stake", "epoch", st.stakeEnableEpoch) + log.Debug("stakingToPeer: enable epoch for staking v4 init", "epoch", st.stakingV4InitEpoch) args.EpochNotifier.RegisterNotifyHandler(st) @@ -332,11 +338,16 @@ func (stp *stakingToPeer) updatePeerState( } } + newNodesList := common.NewList + if stp.flagStakingV4Init.IsSet() { + newNodesList = common.AuctionList + } + isValidator := account.GetList() == string(common.EligibleList) || account.GetList() == string(common.WaitingList) if !stakingData.Jailed { if stakingData.StakedNonce == nonce && !isValidator { - log.Debug("node is staked, changed status to new", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce)) + log.Debug(fmt.Sprintf("node is staked, changed status to %s list", newNodesList), "blsKey", blsPubKey) + account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.StakedNonce)) account.SetTempRating(stp.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) } @@ -356,8 +367,8 @@ func (stp *stakingToPeer) updatePeerState( isNewValidator := !isValidator && stakingData.Staked if isNewValidator { - log.Debug("node is unJailed and staked, changing status to new list", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.UnJailedNonce)) + log.Debug(fmt.Sprintf("node is unJailed and staked, changing status to %s list", newNodesList), "blsKey", blsPubKey) + account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.UnJailedNonce)) } if account.GetList() == string(common.JailedList) { @@ -428,6 +439,9 @@ func (stp *stakingToPeer) EpochConfirmed(epoch uint32, _ uint64) { stp.flagValidatorToDelegation.SetValue(epoch >= stp.validatorToDelegationEnableEpoch) log.Debug("stakingToPeer: validator to delegation", "enabled", stp.flagValidatorToDelegation.IsSet()) + + stp.flagStakingV4Init.SetValue(epoch >= stp.stakingV4InitEpoch) + log.Debug("stakingToPeer: staking v4 init", "enabled", stp.flagStakingV4Init.IsSet()) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/process/scToProtocol/stakingToPeer_test.go b/process/scToProtocol/stakingToPeer_test.go index e862b100ed6..bf31291f369 100644 --- a/process/scToProtocol/stakingToPeer_test.go +++ b/process/scToProtocol/stakingToPeer_test.go @@ -18,9 +18,9 @@ import ( "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/state" - stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" + stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -29,15 +29,16 @@ import ( func createMockArgumentsNewStakingToPeer() ArgStakingToPeer { return ArgStakingToPeer{ - PubkeyConv: mock.NewPubkeyConverterMock(32), - Hasher: &hashingMocks.HasherMock{}, - Marshalizer: &mock.MarshalizerStub{}, - PeerState: &stateMock.AccountsStub{}, - BaseState: &stateMock.AccountsStub{}, - ArgParser: &mock.ArgumentParserMock{}, - CurrTxs: &mock.TxForCurrentBlockStub{}, - RatingsData: &mock.RatingsInfoMock{}, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, + PubkeyConv: mock.NewPubkeyConverterMock(32), + Hasher: &hashingMocks.HasherMock{}, + Marshalizer: &mock.MarshalizerStub{}, + PeerState: &stateMock.AccountsStub{}, + BaseState: &stateMock.AccountsStub{}, + ArgParser: &mock.ArgumentParserMock{}, + CurrTxs: &mock.TxForCurrentBlockStub{}, + RatingsData: &mock.RatingsInfoMock{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + StakingV4InitEpoch: 444, } } @@ -668,6 +669,14 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.NewList), peerAccount.GetList()) + stp.EpochConfirmed(arguments.StakingV4InitEpoch, 0) + err = stp.updatePeerState(stakingData, blsPubKey, nonce) + assert.NoError(t, err) + assert.True(t, bytes.Equal(blsPubKey, peerAccount.GetBLSPublicKey())) + assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) + assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) + stp.EpochConfirmed(0, 0) + stakingData.UnStakedNonce = 11 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) assert.Equal(t, string(common.LeavingList), peerAccount.GetList()) @@ -686,6 +695,11 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.Equal(t, string(common.NewList), peerAccount.GetList()) + stp.EpochConfirmed(arguments.StakingV4InitEpoch, 0) + _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) + assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) + stp.EpochConfirmed(0, 0) + stakingData.UnStakedNonce = 15 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) assert.Equal(t, string(common.LeavingList), peerAccount.GetList()) From 751d213b0648cafa86642c9dbc622ec1af51b1bf Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 15 Apr 2022 16:32:23 +0300 Subject: [PATCH 191/958] FIX: Check for no error --- process/scToProtocol/stakingToPeer_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process/scToProtocol/stakingToPeer_test.go b/process/scToProtocol/stakingToPeer_test.go index bf31291f369..9252425221d 100644 --- a/process/scToProtocol/stakingToPeer_test.go +++ b/process/scToProtocol/stakingToPeer_test.go @@ -696,7 +696,8 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { assert.Equal(t, string(common.NewList), peerAccount.GetList()) stp.EpochConfirmed(arguments.StakingV4InitEpoch, 0) - _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) + err = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) + assert.NoError(t, err) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) stp.EpochConfirmed(0, 0) From cbe5cb1ba81d1a13b6c056ab21b7884832728d34 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 18 Apr 2022 12:48:29 +0300 Subject: [PATCH 192/958] FEAT: Refactor code in stakingDataProvider and systemScs --- epochStart/errors.go | 3 + epochStart/interface.go | 1 + epochStart/metachain/legacySystemSCs.go | 9 +++ epochStart/metachain/stakingDataProvider.go | 67 +++++++++++++++---- .../metachain/stakingDataProvider_test.go | 36 +++++++--- epochStart/metachain/systemSCs.go | 4 -- epochStart/metachain/systemSCs_test.go | 4 +- epochStart/mock/stakingDataProviderStub.go | 4 ++ factory/blockProcessorCreator.go | 7 +- integrationTests/testProcessorNode.go | 2 +- .../vm/staking/systemSCCreator.go | 7 +- 11 files changed, 111 insertions(+), 33 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 4032928d016..a3c4ab09a74 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -337,3 +337,6 @@ var ErrCouldNotInitLiquidStakingSystemSC = errors.New("could not init liquid sta // ErrSortAuctionList signals that an error occurred while trying to sort auction list var ErrSortAuctionList = errors.New("error while trying to sort auction list") + +// ErrReceivedNewListNodeInStakingV4 signals that a new node has been assigned in common.NewList instead of common.AuctionList after staking v4 +var ErrReceivedNewListNodeInStakingV4 = errors.New("new node has been assigned in common.NewList instead of common.AuctionList after staking v4") diff --git a/epochStart/interface.go b/epochStart/interface.go index 5fc31ce340d..900e759712c 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -155,6 +155,7 @@ type StakingDataProvider interface { ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) Clean() + EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool } diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 485c0e0b06a..d4e4241010b 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -69,6 +69,7 @@ type legacySystemSCProcessor struct { flagESDTEnabled atomic.Flag flagSaveJailedAlwaysEnabled atomic.Flag flagStakingQueueEnabled atomic.Flag + flagStakingV4Enabled atomic.Flag } func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*legacySystemSCProcessor, error) { @@ -315,6 +316,11 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( validatorInfo := validatorsInfoMap.GetValidator(blsKey) if validatorInfo == nil { + if s.flagStakingV4Enabled.IsSet() { + return 0, fmt.Errorf( + "%w in legacySystemSCProcessor.unStakeNodesWithNotEnoughFunds because validator might be in additional queue after staking v4", + epochStart.ErrNilValidatorInfo) + } nodesUnStakedFromAdditionalQueue++ log.Debug("unStaked node which was in additional queue", "blsKey", blsKey) continue @@ -1401,4 +1407,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) log.Debug("legacySystemSC: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) + + s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) + log.Debug("systemProcessor: staking v4", "enabled", s.flagStakingV4Enabled.IsSet()) } diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 0d249fd6172..8db0a88ae48 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -7,9 +7,11 @@ import ( "math/big" "sync" + "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -33,6 +35,8 @@ type stakingDataProvider struct { totalEligibleStake *big.Int totalEligibleTopUpStake *big.Int minNodePrice *big.Int + stakingV4EnableEpoch uint32 + flagStakingV4Enable atomic.Flag } // NewStakingDataProvider will create a new instance of a staking data provider able to aid in the final rewards @@ -40,10 +44,15 @@ type stakingDataProvider struct { func NewStakingDataProvider( systemVM vmcommon.VMExecutionHandler, minNodePrice string, + stakingV4EnableEpoch uint32, + epochNotifier process.EpochNotifier, ) (*stakingDataProvider, error) { if check.IfNil(systemVM) { return nil, epochStart.ErrNilSystemVmInstance } + if check.IfNil(epochNotifier) { + return nil, epochStart.ErrNilEpochStartNotifier + } nodePrice, ok := big.NewInt(0).SetString(minNodePrice, 10) if !ok || nodePrice.Cmp(big.NewInt(0)) <= 0 { @@ -56,7 +65,10 @@ func NewStakingDataProvider( minNodePrice: nodePrice, totalEligibleStake: big.NewInt(0), totalEligibleTopUpStake: big.NewInt(0), + stakingV4EnableEpoch: stakingV4EnableEpoch, } + log.Debug("stakingDataProvider: enable epoch for staking v4", "epoch", sdp.stakingV4EnableEpoch) + epochNotifier.RegisterNotifyHandler(sdp) return sdp, nil } @@ -289,23 +301,27 @@ 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 state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { +func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { sdp.mutStakingData.Lock() defer sdp.mutStakingData.Unlock() mapOwnersKeys := make(map[string][][]byte) keysToUnStake := make([][]byte, 0) - mapBLSKeyStatus := createMapBLSKeyStatus(validatorInfos) + mapBLSKeyStatus, err := sdp.createMapBLSKeyStatus(validatorsInfo) + if err != nil { + return nil, nil, err + } + for ownerAddress, stakingInfo := range sdp.cache { maxQualified := big.NewInt(0).Div(stakingInfo.totalStaked, sdp.minNodePrice) if maxQualified.Int64() >= stakingInfo.numStakedNodes { continue } - sortedKeys := arrangeBlsKeysByStatus(mapBLSKeyStatus, stakingInfo.blsKeys) + sortedKeys := sdp.arrangeBlsKeysByStatus(mapBLSKeyStatus, stakingInfo.blsKeys) numKeysToUnStake := stakingInfo.numStakedNodes - maxQualified.Int64() - selectedKeys := selectKeysToUnStake(sortedKeys, numKeysToUnStake) + selectedKeys := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) if len(selectedKeys) == 0 { continue } @@ -319,19 +335,25 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorInfos state.Sha return keysToUnStake, mapOwnersKeys, nil } -func createMapBLSKeyStatus(validatorInfos state.ShardValidatorsInfoMapHandler) map[string]string { +func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.ShardValidatorsInfoMapHandler) (map[string]string, error) { mapBLSKeyStatus := make(map[string]string) - for _, validatorInfo := range validatorInfos.GetAllValidatorsInfo() { - mapBLSKeyStatus[string(validatorInfo.GetPublicKey())] = validatorInfo.GetList() + for _, validatorInfo := range validatorsInfo.GetAllValidatorsInfo() { + list := validatorInfo.GetList() + if sdp.flagStakingV4Enable.IsSet() && list == string(common.NewList) { + return nil, epochStart.ErrReceivedNewListNodeInStakingV4 + } + mapBLSKeyStatus[string(validatorInfo.GetPublicKey())] = list } - return mapBLSKeyStatus + return mapBLSKeyStatus, nil } -func selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) [][]byte { +func (sdp *stakingDataProvider) selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) [][]byte { selectedKeys := make([][]byte, 0) - newKeys := sortedKeys[string(common.NewList)] + newNodesList := sdp.getNewNodesList() + + newKeys := sortedKeys[newNodesList] if len(newKeys) > 0 { selectedKeys = append(selectedKeys, newKeys...) } @@ -361,12 +383,14 @@ func selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) [][] return selectedKeys } -func arrangeBlsKeysByStatus(mapBlsKeyStatus map[string]string, blsKeys [][]byte) map[string][][]byte { +func (sdp *stakingDataProvider) arrangeBlsKeysByStatus(mapBlsKeyStatus map[string]string, blsKeys [][]byte) map[string][][]byte { sortedKeys := make(map[string][][]byte) + newNodesList := sdp.getNewNodesList() + for _, blsKey := range blsKeys { - blsKeyStatus, ok := mapBlsKeyStatus[string(blsKey)] - if !ok { - sortedKeys[string(common.NewList)] = append(sortedKeys[string(common.NewList)], blsKey) + blsKeyStatus, found := mapBlsKeyStatus[string(blsKey)] + if !found { + sortedKeys[newNodesList] = append(sortedKeys[newNodesList], blsKey) continue } @@ -376,6 +400,21 @@ func arrangeBlsKeysByStatus(mapBlsKeyStatus map[string]string, blsKeys [][]byte) return sortedKeys } +func (sdp *stakingDataProvider) getNewNodesList() string { + newNodesList := string(common.NewList) + if sdp.flagStakingV4Enable.IsSet() { + newNodesList = string(common.AuctionList) + } + + return newNodesList +} + +// EpochConfirmed is called whenever a new epoch is confirmed +func (sdp *stakingDataProvider) EpochConfirmed(epoch uint32, _ uint64) { + sdp.flagStakingV4Enable.SetValue(epoch >= sdp.stakingV4EnableEpoch) + log.Debug("stakingDataProvider: staking v4 enable epoch", "enabled", sdp.flagStakingV4Enable.IsSet()) +} + // IsInterfaceNil return true if underlying object is nil func (sdp *stakingDataProvider) IsInterfaceNil() bool { return sdp == nil diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 7c931071f27..d24ff1afd26 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -16,25 +16,35 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestNewStakingDataProvider_NilSystemVMShouldErr(t *testing.T) { +const stakingV4EnableEpoch = 444 + +func TestNewStakingDataProvider_NilInputPointersShouldErr(t *testing.T) { t.Parallel() - sdp, err := NewStakingDataProvider(nil, "100000") + t.Run("nil system vm", func(t *testing.T) { + sdp, err := NewStakingDataProvider(nil, "100000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) + assert.True(t, check.IfNil(sdp)) + assert.Equal(t, epochStart.ErrNilSystemVmInstance, err) + }) - assert.True(t, check.IfNil(sdp)) - assert.Equal(t, epochStart.ErrNilSystemVmInstance, err) + t.Run("nil epoch notifier", func(t *testing.T) { + sdp, err := NewStakingDataProvider(&mock.VMExecutionHandlerStub{}, "100000", stakingV4EnableEpoch, nil) + assert.True(t, check.IfNil(sdp)) + assert.Equal(t, epochStart.ErrNilEpochStartNotifier, err) + }) } func TestNewStakingDataProvider_ShouldWork(t *testing.T) { t.Parallel() - sdp, err := NewStakingDataProvider(&mock.VMExecutionHandlerStub{}, "100000") + sdp, err := NewStakingDataProvider(&mock.VMExecutionHandlerStub{}, "100000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) assert.False(t, check.IfNil(sdp)) assert.Nil(t, err) @@ -64,7 +74,9 @@ func TestStakingDataProvider_PrepareDataForBlsKeyGetBlsKeyOwnerErrorsShouldErr(t return nil, nil }, - }, "100000") + }, "100000", + stakingV4EnableEpoch, + &epochNotifier.EpochNotifierStub{}) err := sdp.loadDataForBlsKey([]byte("bls key")) assert.Equal(t, expectedErr, err) @@ -110,7 +122,9 @@ func TestStakingDataProvider_PrepareDataForBlsKeyLoadOwnerDataErrorsShouldErr(t } return nil, nil }, - }, "100000") + }, "100000", + stakingV4EnableEpoch, + &epochNotifier.EpochNotifierStub{}) err := sdp.loadDataForBlsKey([]byte("bls key")) assert.Equal(t, expectedErr, err) @@ -416,7 +430,9 @@ func createStakingDataProviderWithMockArgs( return nil, errors.New("unexpected call") }, - }, "100000") + }, "100000", + stakingV4EnableEpoch, + &epochNotifier.EpochNotifierStub{}) require.Nil(t, err) return sdp @@ -432,7 +448,7 @@ func createStakingDataProviderWithRealArgs(t *testing.T, owner []byte, blsKey [] doStake(t, s.systemVM, s.userAccountsDB, owner, big.NewInt(0).Add(big.NewInt(1000), topUpVal), blsKey) - sdp, _ := NewStakingDataProvider(s.systemVM, "100000") + sdp, _ := NewStakingDataProvider(s.systemVM, "100000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) return sdp } @@ -467,7 +483,7 @@ func createStakingDataProviderAndUpdateCache(t *testing.T, validatorsInfo state. args.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: 1, }) - sdp, _ := NewStakingDataProvider(args.SystemVM, "2500") + sdp, _ := NewStakingDataProvider(args.SystemVM, "2500", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) args.StakingDataProvider = sdp s, _ := NewSystemSCProcessor(args) require.NotNil(t, s) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 0bf425018b2..f23f0aedebf 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -57,7 +57,6 @@ type systemSCProcessor struct { flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag - flagStakingV4Enabled atomic.Flag flagInitStakingV4Enabled atomic.Flag } @@ -465,9 +464,6 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagBuiltInOnMetaEnabled.SetValue(epoch == s.builtInOnMetaEnableEpoch) log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) - s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) - log.Debug("systemProcessor: staking v4", "enabled", s.flagStakingV4Enabled.IsSet()) - s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) log.Debug("systemProcessor: init staking v4", "enabled", s.flagInitStakingV4Enabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 4cbb08ca0d7..afdfa0f4c7c 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -835,7 +835,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS vmContainer, _ := metaVmFactory.Create() systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCprovider, _ := NewStakingDataProvider(systemVM, "1000") + stakingSCProvider, _ := NewStakingDataProvider(systemVM, "1000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) args := ArgsNewEpochStartSystemSCProcessing{ @@ -850,7 +850,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ChanceComputer: &mock.ChanceComputerStub{}, EpochNotifier: en, GenesisNodesConfig: nodesSetup, - StakingDataProvider: stakingSCprovider, + StakingDataProvider: stakingSCProvider, NodesConfigProvider: &shardingMocks.NodesCoordinatorStub{ ConsensusGroupSizeCalled: func(shardID uint32) int { if shardID == core.MetachainShardId { diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 7b4fd4f0be6..52519110336 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -77,6 +77,10 @@ func (sdps *StakingDataProviderStub) GetBlsKeyOwner([]byte) (string, error) { return "", nil } +// EpochConfirmed - +func (sdps *StakingDataProviderStub) EpochConfirmed(uint32, uint64) { +} + // IsInterfaceNil - func (sdps *StakingDataProviderStub) IsInterfaceNil() bool { return sdps == nil diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 19622ac7e58..929dac4b285 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -713,7 +713,12 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( } // TODO: in case of changing the minimum node price, make sure to update the staking data provider - stakingDataProvider, err := metachainEpochStart.NewStakingDataProvider(systemVM, pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice) + stakingDataProvider, err := metachainEpochStart.NewStakingDataProvider( + systemVM, + pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, + pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + pcf.coreData.EpochNotifier(), + ) if err != nil { return nil, err } diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index e0f7f0dd901..ec494c7d594 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2168,7 +2168,7 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { if errGet != nil { log.Error("initBlockProcessor tpn.VMContainer.Get", "error", errGet) } - stakingDataProvider, errRsp := metachain.NewStakingDataProvider(systemVM, "1000") + stakingDataProvider, errRsp := metachain.NewStakingDataProvider(systemVM, "1000", StakingV4Epoch, coreComponents.EpochNotifier()) if errRsp != nil { log.Error("initBlockProcessor NewRewardsStakingProvider", "error", errRsp) } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 48ecc0ba312..cc524f19316 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -35,7 +35,12 @@ func createSystemSCProcessor( vmContainer process.VirtualMachinesContainer, ) process.EpochStartSystemSCProcessor { systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCProvider, _ := metachain.NewStakingDataProvider(systemVM, strconv.Itoa(nodePrice)) + stakingSCProvider, _ := metachain.NewStakingDataProvider( + systemVM, + strconv.Itoa(nodePrice), + stakingV4EnableEpoch, + coreComponents.EpochNotifier(), + ) args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, From 79d4fc456bac2c84f36d804aa4cda3be8f4c2b49 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 18 Apr 2022 14:44:04 +0300 Subject: [PATCH 193/958] FIX: Pointer bugs + refactor systemSCs.go --- epochStart/metachain/legacySystemSCs.go | 38 ++++++--------- epochStart/metachain/systemSCs.go | 46 ++++++++++++++++++- process/scToProtocol/stakingToPeer.go | 8 ++-- .../indexHashedNodesCoordinator.go | 4 ++ state/interface.go | 1 + state/validatorInfo.go | 10 ++++ state/validatorsInfoMap.go | 5 +- state/validatorsInfoMap_test.go | 5 +- 8 files changed, 85 insertions(+), 32 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index d4e4241010b..8a1b501966e 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -69,7 +69,6 @@ type legacySystemSCProcessor struct { flagESDTEnabled atomic.Flag flagSaveJailedAlwaysEnabled atomic.Flag flagStakingQueueEnabled atomic.Flag - flagStakingV4Enabled atomic.Flag } func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*legacySystemSCProcessor, error) { @@ -234,7 +233,12 @@ func (s *legacySystemSCProcessor) processLegacy( return err } - numUnStaked, err := s.unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap, epoch) + err = s.fillStakingDataForNonEligible(validatorsInfoMap) + if err != nil { + return err + } + + numUnStaked, err := s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) if err != nil { return err } @@ -316,17 +320,17 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( validatorInfo := validatorsInfoMap.GetValidator(blsKey) if validatorInfo == nil { - if s.flagStakingV4Enabled.IsSet() { - return 0, fmt.Errorf( - "%w in legacySystemSCProcessor.unStakeNodesWithNotEnoughFunds because validator might be in additional queue after staking v4", - epochStart.ErrNilValidatorInfo) - } nodesUnStakedFromAdditionalQueue++ log.Debug("unStaked node which was in additional queue", "blsKey", blsKey) continue } - validatorInfo.SetList(string(common.LeavingList)) + validatorLeaving := validatorInfo.ShallowClone() + validatorLeaving.SetList(string(common.LeavingList)) + err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) + if err != nil { + return 0, err + } } err = s.updateDelegationContracts(mapOwnersKeys) @@ -335,9 +339,7 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( } nodesToStakeFromQueue := uint32(len(nodesToUnStake)) - if s.flagCorrectNumNodesToStake.IsSet() { - nodesToStakeFromQueue -= nodesUnStakedFromAdditionalQueue - } + nodesToStakeFromQueue -= nodesUnStakedFromAdditionalQueue log.Debug("stake nodes from waiting list", "num", nodesToStakeFromQueue) return nodesToStakeFromQueue, nil @@ -478,15 +480,6 @@ func (s *legacySystemSCProcessor) prepareStakingDataForEligibleNodes(validatorsI return s.prepareStakingData(eligibleNodes) } -func (s *legacySystemSCProcessor) unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap state.ShardValidatorsInfoMapHandler, epoch uint32) (uint32, error) { - err := s.fillStakingDataForNonEligible(validatorsInfoMap) - if err != nil { - return 0, err - } - - return s.unStakeNodesWithNotEnoughFunds(validatorsInfoMap, epoch) -} - func (s *legacySystemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byte) error { sw := core.NewStopWatch() sw.Start("prepareStakingDataForRewards") @@ -1385,7 +1378,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { log.Debug("systemSCProcessor: delegation", "enabled", epoch >= s.delegationEnableEpoch) s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) - s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch < s.stakingV4InitEnableEpoch) + s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch <= s.stakingV4InitEnableEpoch) log.Debug("legacySystemSC: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) log.Debug("legacySystemSC: change of maximum number of nodes and/or shuffling percentage", "enabled", s.flagChangeMaxNodesEnabled.IsSet(), @@ -1407,7 +1400,4 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) log.Debug("legacySystemSC: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) - - s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) - log.Debug("systemProcessor: staking v4", "enabled", s.flagStakingV4Enabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index f23f0aedebf..b63f9bc2f0c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -58,6 +58,7 @@ type systemSCProcessor struct { flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag flagInitStakingV4Enabled atomic.Flag + flagStakingV4Enabled atomic.Flag } // NewSystemSCProcessor creates the end of epoch system smart contract processor @@ -133,7 +134,12 @@ func (s *systemSCProcessor) processWithNewFlags( return err } - _, err = s.unStakeNonEligibleNodesWithNotEnoughFunds(validatorsInfoMap, header.GetEpoch()) + err = s.fillStakingDataForNonEligible(validatorsInfoMap) + if err != nil { + return err + } + + err = s.unStakeNodesWithNotEnoughFundsWithStakingV4(validatorsInfoMap, header.GetEpoch()) if err != nil { return err } @@ -147,6 +153,41 @@ func (s *systemSCProcessor) processWithNewFlags( return nil } +func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + epoch uint32, +) error { + nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) + if err != nil { + return err + } + + log.Debug("unStake nodes with not enough funds", "num", len(nodesToUnStake)) + for _, blsKey := range nodesToUnStake { + log.Debug("unStake at end of epoch for node", "blsKey", blsKey) + err = s.unStakeOneNode(blsKey, epoch) + if err != nil { + return err + } + + validatorInfo := validatorsInfoMap.GetValidator(blsKey) + if validatorInfo == nil { + return fmt.Errorf( + "%w in systemSCProcessor.unStakeNodesWithNotEnoughFundsWithStakingV4 because validator might be in additional queue after staking v4", + epochStart.ErrNilValidatorInfo) + } + + validatorLeaving := validatorInfo.ShallowClone() + validatorLeaving.SetList(string(common.LeavingList)) + err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) + if err != nil { + return err + } + } + + return s.updateDelegationContracts(mapOwnersKeys) +} + // TODO: Staking v4: perhaps create a subcomponent which handles selection, which would be also very useful in tests func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) @@ -466,4 +507,7 @@ func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) log.Debug("systemProcessor: init staking v4", "enabled", s.flagInitStakingV4Enabled.IsSet()) + + s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) + log.Debug("systemProcessor: staking v4", "enabled", s.flagStakingV4Enabled.IsSet()) } diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index fab486551c0..24a25162168 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -61,7 +61,7 @@ type stakingToPeer struct { validatorToDelegationEnableEpoch uint32 flagValidatorToDelegation atomic.Flag stakingV4InitEpoch uint32 - flagStakingV4Init atomic.Flag + flagStakingV4 atomic.Flag } // NewStakingToPeer creates the component which moves from staking sc state to peer state @@ -339,7 +339,7 @@ func (stp *stakingToPeer) updatePeerState( } newNodesList := common.NewList - if stp.flagStakingV4Init.IsSet() { + if stp.flagStakingV4.IsSet() { newNodesList = common.AuctionList } @@ -440,8 +440,8 @@ func (stp *stakingToPeer) EpochConfirmed(epoch uint32, _ uint64) { stp.flagValidatorToDelegation.SetValue(epoch >= stp.validatorToDelegationEnableEpoch) log.Debug("stakingToPeer: validator to delegation", "enabled", stp.flagValidatorToDelegation.IsSet()) - stp.flagStakingV4Init.SetValue(epoch >= stp.stakingV4InitEpoch) - log.Debug("stakingToPeer: staking v4 init", "enabled", stp.flagStakingV4Init.IsSet()) + stp.flagStakingV4.SetValue(epoch >= stp.stakingV4InitEpoch) + log.Debug("stakingToPeer: staking v4 init", "enabled", stp.flagStakingV4.IsSet()) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index d021cf2fa3f..b9998949b88 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -17,6 +17,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/marshal" logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage" ) @@ -776,6 +777,9 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( currentValidator, validatorInfo.ShardId) case string(common.NewList): + if ihnc.flagStakingV4.IsSet() { + return nil, epochStart.ErrReceivedNewListNodeInStakingV4 + } log.Debug("new node registered", "pk", validatorInfo.PublicKey) newNodesList = append(newNodesList, currentValidator) case string(common.InactiveList): diff --git a/state/interface.go b/state/interface.go index 597e1851d98..d23f1b1a3f8 100644 --- a/state/interface.go +++ b/state/interface.go @@ -242,5 +242,6 @@ type ValidatorInfoHandler interface { SetTotalValidatorFailure(totalValidatorFailure uint32) SetTotalValidatorIgnoredSignatures(totalValidatorIgnoredSignatures uint32) + ShallowClone() ValidatorInfoHandler String() string } diff --git a/state/validatorInfo.go b/state/validatorInfo.go index 93980510347..44314350067 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -109,6 +109,16 @@ func (vi *ValidatorInfo) SetTotalValidatorIgnoredSignatures(totalValidatorIgnore vi.TotalValidatorIgnoredSignatures = totalValidatorIgnoredSignatures } +// ShallowClone returns a clone of the object +func (vi *ValidatorInfo) ShallowClone() ValidatorInfoHandler { + if vi == nil { + return nil + } + + validatorCopy := *vi + return &validatorCopy +} + // IsInterfaceNil returns true if there is no value under the interface func (svi *ShardValidatorInfo) IsInterfaceNil() bool { return svi == nil diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 18c04fb4663..5615adc169a 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -72,9 +72,12 @@ func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) error { // GetValidator returns a ValidatorInfoHandler copy with the provided blsKey, // if it is present in the map, otherwise returns nil func (vi *shardValidatorsInfoMap) GetValidator(blsKey []byte) ValidatorInfoHandler { + vi.mutex.RLock() + defer vi.mutex.RUnlock() + for _, validator := range vi.GetAllValidatorsInfo() { if bytes.Equal(validator.GetPublicKey(), blsKey) { - return validator + return validator.ShallowClone() } } diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index 8280589bc97..802f2f357cb 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -219,10 +219,11 @@ func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testi validators = append(validators, &ValidatorInfo{ShardId: 1, PublicKey: []byte("pk3")}) validator := vi.GetValidator([]byte("pk0")) + require.False(t, validator == v0) // require not same pointer validator.SetShardId(2) - require.Equal(t, []ValidatorInfoHandler{v0}, vi.GetShardValidatorsInfoMap()[0]) - require.Equal(t, []ValidatorInfoHandler{v1}, vi.GetShardValidatorsInfoMap()[1]) + require.True(t, vi.GetShardValidatorsInfoMap()[0][0] == v0) // check by pointer + require.True(t, vi.GetShardValidatorsInfoMap()[1][0] == v1) // check by pointer } func TestShardValidatorsInfoMap_Concurrency(t *testing.T) { From aa31e14cc0fbbc5912b8e025e1cb394ef2563643 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 18 Apr 2022 16:41:33 +0300 Subject: [PATCH 194/958] FEAT: Unit tests for stakingDataProvider.go with staking v4 --- epochStart/metachain/stakingDataProvider.go | 9 ++- .../metachain/stakingDataProvider_test.go | 65 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 8db0a88ae48..de7a325fae8 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -339,11 +339,16 @@ func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.Shard mapBLSKeyStatus := make(map[string]string) for _, validatorInfo := range validatorsInfo.GetAllValidatorsInfo() { list := validatorInfo.GetList() + pubKey := validatorInfo.GetPublicKey() + if sdp.flagStakingV4Enable.IsSet() && list == string(common.NewList) { - return nil, epochStart.ErrReceivedNewListNodeInStakingV4 + return nil, fmt.Errorf("%w, bls key = %s", + epochStart.ErrReceivedNewListNodeInStakingV4, + hex.EncodeToString(pubKey), + ) } - mapBLSKeyStatus[string(validatorInfo.GetPublicKey())] = list + mapBLSKeyStatus[string(pubKey)] = list } return mapBLSKeyStatus, nil diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index d24ff1afd26..46cef9c73c0 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -237,6 +237,71 @@ func TestStakingDataProvider_ComputeUnQualifiedNodes(t *testing.T) { require.Zero(t, len(ownersWithNotEnoughFunds)) } +func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4(t *testing.T) { + valInfo := state.NewShardValidatorsInfoMap() + v0 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey0"), + List: string(common.EligibleList), + RewardAddress: []byte("address0"), + } + v1 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey1"), + List: string(common.NewList), + RewardAddress: []byte("address0"), + } + v2 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey2"), + List: string(common.AuctionList), + RewardAddress: []byte("address1"), + } + _ = valInfo.Add(v0) + _ = valInfo.Add(v1) + _ = valInfo.Add(v2) + + sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), epochStart.ErrReceivedNewListNodeInStakingV4.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(v1.PublicKey))) + require.Empty(t, keysToUnStake) + require.Empty(t, ownersWithNotEnoughFunds) +} + +func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithStakingV4(t *testing.T) { + valInfo := state.NewShardValidatorsInfoMap() + + owner := "address0" + v0 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey0"), + List: string(common.EligibleList), + RewardAddress: []byte(owner), + } + v1 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey1"), + List: string(common.AuctionList), + RewardAddress: []byte(owner), + } + _ = valInfo.Add(v0) + _ = valInfo.Add(v1) + + sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + sdp.cache[owner].blsKeys = append(sdp.cache[owner].blsKeys, []byte("newKey")) + sdp.cache[owner].totalStaked = big.NewInt(2500) + sdp.cache[owner].numStakedNodes++ + + keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) + require.Nil(t, err) + + expectedUnStakedKeys := [][]byte{[]byte("blsKey1"), []byte("newKey")} + expectedOwnerWithNotEnoughFunds := map[string][][]byte{owner: expectedUnStakedKeys} + require.Equal(t, expectedUnStakedKeys, keysToUnStake) + require.Equal(t, expectedOwnerWithNotEnoughFunds, ownersWithNotEnoughFunds) +} + func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFunds(t *testing.T) { nbShards := uint32(3) nbEligible := make(map[uint32]uint32) From 8af8559b2cea4e4c5ed30059ebf28dccff920268 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 18 Apr 2022 16:51:13 +0300 Subject: [PATCH 195/958] FIX: Small fixes --- .../metachain/stakingDataProvider_test.go | 68 +++++++++---------- state/validatorsInfoMap.go | 3 - 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 46cef9c73c0..ffa3c0c3176 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -237,7 +237,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodes(t *testing.T) { require.Zero(t, len(ownersWithNotEnoughFunds)) } -func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4(t *testing.T) { +func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4ReceivedNewListNode(t *testing.T) { valInfo := state.NewShardValidatorsInfoMap() v0 := &state.ValidatorInfo{ PublicKey: []byte("blsKey0"), @@ -269,39 +269,6 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4(t *testing.T) require.Empty(t, ownersWithNotEnoughFunds) } -func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithStakingV4(t *testing.T) { - valInfo := state.NewShardValidatorsInfoMap() - - owner := "address0" - v0 := &state.ValidatorInfo{ - PublicKey: []byte("blsKey0"), - List: string(common.EligibleList), - RewardAddress: []byte(owner), - } - v1 := &state.ValidatorInfo{ - PublicKey: []byte("blsKey1"), - List: string(common.AuctionList), - RewardAddress: []byte(owner), - } - _ = valInfo.Add(v0) - _ = valInfo.Add(v1) - - sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) - - sdp.cache[owner].blsKeys = append(sdp.cache[owner].blsKeys, []byte("newKey")) - sdp.cache[owner].totalStaked = big.NewInt(2500) - sdp.cache[owner].numStakedNodes++ - - keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) - require.Nil(t, err) - - expectedUnStakedKeys := [][]byte{[]byte("blsKey1"), []byte("newKey")} - expectedOwnerWithNotEnoughFunds := map[string][][]byte{owner: expectedUnStakedKeys} - require.Equal(t, expectedUnStakedKeys, keysToUnStake) - require.Equal(t, expectedOwnerWithNotEnoughFunds, ownersWithNotEnoughFunds) -} - func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFunds(t *testing.T) { nbShards := uint32(3) nbEligible := make(map[uint32]uint32) @@ -337,6 +304,39 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFunds(t *t require.Equal(t, 1, len(ownersWithNotEnoughFunds)) } +func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithStakingV4(t *testing.T) { + valInfo := state.NewShardValidatorsInfoMap() + + owner := "address0" + v0 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey0"), + List: string(common.EligibleList), + RewardAddress: []byte(owner), + } + v1 := &state.ValidatorInfo{ + PublicKey: []byte("blsKey1"), + List: string(common.AuctionList), + RewardAddress: []byte(owner), + } + _ = valInfo.Add(v0) + _ = valInfo.Add(v1) + + sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + sdp.cache[owner].blsKeys = append(sdp.cache[owner].blsKeys, []byte("newKey")) + sdp.cache[owner].totalStaked = big.NewInt(2500) + sdp.cache[owner].numStakedNodes++ + + keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) + require.Nil(t, err) + + expectedUnStakedKeys := [][]byte{[]byte("blsKey1"), []byte("newKey")} + expectedOwnerWithNotEnoughFunds := map[string][][]byte{owner: expectedUnStakedKeys} + require.Equal(t, expectedUnStakedKeys, keysToUnStake) + require.Equal(t, expectedOwnerWithNotEnoughFunds, ownersWithNotEnoughFunds) +} + func TestStakingDataProvider_GetTotalStakeEligibleNodes(t *testing.T) { t.Parallel() diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 5615adc169a..4f39f7a23d0 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -72,9 +72,6 @@ func (vi *shardValidatorsInfoMap) Add(validator ValidatorInfoHandler) error { // GetValidator returns a ValidatorInfoHandler copy with the provided blsKey, // if it is present in the map, otherwise returns nil func (vi *shardValidatorsInfoMap) GetValidator(blsKey []byte) ValidatorInfoHandler { - vi.mutex.RLock() - defer vi.mutex.RUnlock() - for _, validator := range vi.GetAllValidatorsInfo() { if bytes.Equal(validator.GetPublicKey(), blsKey) { return validator.ShallowClone() From 1c1987c5ed460bb48801848dbc8ced6316c895e6 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 19 Apr 2022 10:51:53 +0300 Subject: [PATCH 196/958] FIX: Epoch flag name --- config/epochConfig.go | 2 +- factory/coreComponents.go | 2 +- node/nodeRunner.go | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config/epochConfig.go b/config/epochConfig.go index 0d9ab50118f..b348918f43c 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -80,7 +80,7 @@ type EnableEpochs struct { StakeLimitsEnableEpoch uint32 StakingV4InitEnableEpoch uint32 StakingV4EnableEpoch uint32 - StakingV4DistributeAuctionToWaiting uint32 + StakingV4DistributeAuctionToWaitingEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/factory/coreComponents.go b/factory/coreComponents.go index 7adff1aa730..e4cb32bf366 100644 --- a/factory/coreComponents.go +++ b/factory/coreComponents.go @@ -319,7 +319,7 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) { BalanceWaitingListsEnableEpoch: ccf.epochConfig.EnableEpochs.BalanceWaitingListsEnableEpoch, WaitingListFixEnableEpoch: ccf.epochConfig.EnableEpochs.WaitingListFixEnableEpoch, StakingV4EnableEpoch: ccf.epochConfig.EnableEpochs.StakingV4EnableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: ccf.epochConfig.EnableEpochs.StakingV4DistributeAuctionToWaiting, + StakingV4DistributeAuctionToWaitingEpoch: ccf.epochConfig.EnableEpochs.StakingV4DistributeAuctionToWaitingEpoch, } nodesShuffler, err := nodesCoordinator.NewHashValidatorsShuffler(argsNodesShuffler) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 0c660440d00..654cf93fb70 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -177,6 +177,9 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("scr size invariant check on built in"), "epoch", enableEpochs.SCRSizeInvariantOnBuiltInResultEnableEpoch) log.Debug(readEpochFor("fail execution on every wrong API call"), "epoch", enableEpochs.FailExecutionOnEveryAPIErrorEnableEpoch) log.Debug(readEpochFor("limit validators"), "epoch", enableEpochs.StakeLimitsEnableEpoch) + log.Debug(readEpochFor("staking v4 init"), "epoch", enableEpochs.StakingV4InitEnableEpoch) + log.Debug(readEpochFor("staking v4 enable"), "epoch", enableEpochs.StakingV4EnableEpoch) + log.Debug(readEpochFor("staking v4 distribute auction to waiting"), "epoch", enableEpochs.StakingV4DistributeAuctionToWaitingEpoch) gasSchedule := configs.EpochConfig.GasSchedule From 2ce0098f5cbb0a6dbf9bd637f79ee9b94c73bf59 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 19 Apr 2022 11:12:30 +0300 Subject: [PATCH 197/958] FIX: Pass staking v4 epoch in nodes coord --- epochStart/bootstrap/process.go | 1 + epochStart/bootstrap/storageProcess.go | 1 + epochStart/bootstrap/syncValidatorStatus.go | 2 ++ factory/shardingFactory.go | 2 ++ .../factory/consensusComponents/consensusComponents_test.go | 1 + .../factory/processComponents/processComponents_test.go | 1 + .../factory/statusComponents/statusComponents_test.go | 1 + integrationTests/testP2PNode.go | 1 + integrationTests/testProcessorNodeWithCoordinator.go | 1 + node/nodeRunner.go | 1 + 10 files changed, 12 insertions(+) diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index e8538dd7b1b..650846e0fca 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -714,6 +714,7 @@ func (e *epochStartBootstrap) processNodesConfig(pubKey []byte) error { NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), IsFullArchive: e.prefsConfig.FullArchive, NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: e.enableEpochs.StakingV4EnableEpoch, } e.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) diff --git a/epochStart/bootstrap/storageProcess.go b/epochStart/bootstrap/storageProcess.go index 5f59bc8d5f3..d6d15d072f4 100644 --- a/epochStart/bootstrap/storageProcess.go +++ b/epochStart/bootstrap/storageProcess.go @@ -416,6 +416,7 @@ func (sesb *storageEpochStartBootstrap) processNodesConfig(pubKey []byte) error NodeTypeProvider: sesb.coreComponentsHolder.NodeTypeProvider(), IsFullArchive: sesb.prefsConfig.FullArchive, NodesCoordinatorRegistryFactory: sesb.nodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: sesb.enableEpochs.StakingV4EnableEpoch, } sesb.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) if err != nil { diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index 850a8fc2802..5e90f87953d 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -44,6 +44,7 @@ type ArgsNewSyncValidatorStatus struct { PubKey []byte ShardIdAsObserver uint32 WaitingListFixEnableEpoch uint32 + StakingV4EnableEpoch uint32 ChanNodeStop chan endProcess.ArgEndProcess NodeTypeProvider NodeTypeProviderHandler IsFullArchive bool @@ -113,6 +114,7 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat NodeTypeProvider: args.NodeTypeProvider, IsFullArchive: args.IsFullArchive, NodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: args.StakingV4EnableEpoch, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/factory/shardingFactory.go b/factory/shardingFactory.go index abe32c3fd04..5e8c59fae09 100644 --- a/factory/shardingFactory.go +++ b/factory/shardingFactory.go @@ -106,6 +106,7 @@ func CreateNodesCoordinator( chanNodeStop chan endProcess.ArgEndProcess, nodeTypeProvider core.NodeTypeProviderHandler, nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, + stakingV4EnableEpoch uint32, ) (nodesCoordinator.NodesCoordinator, error) { if chanNodeStop == nil { return nil, nodesCoordinator.ErrNilNodeStopChannel @@ -196,6 +197,7 @@ func CreateNodesCoordinator( NodeTypeProvider: nodeTypeProvider, IsFullArchive: prefsConfig.FullArchive, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: stakingV4EnableEpoch, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/factory/consensusComponents/consensusComponents_test.go b/integrationTests/factory/consensusComponents/consensusComponents_test.go index 01744b81ea7..ae079b2023a 100644 --- a/integrationTests/factory/consensusComponents/consensusComponents_test.go +++ b/integrationTests/factory/consensusComponents/consensusComponents_test.go @@ -66,6 +66,7 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/processComponents/processComponents_test.go b/integrationTests/factory/processComponents/processComponents_test.go index 72188b0f106..265683ed599 100644 --- a/integrationTests/factory/processComponents/processComponents_test.go +++ b/integrationTests/factory/processComponents/processComponents_test.go @@ -67,6 +67,7 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/statusComponents/statusComponents_test.go b/integrationTests/factory/statusComponents/statusComponents_test.go index 71428179214..dbbecc5493d 100644 --- a/integrationTests/factory/statusComponents/statusComponents_test.go +++ b/integrationTests/factory/statusComponents/statusComponents_test.go @@ -67,6 +67,7 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index 52660ae7276..84eb1e68fb9 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -357,6 +357,7 @@ func CreateNodesWithTestP2PNodes( NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: StakingV4Epoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) diff --git a/integrationTests/testProcessorNodeWithCoordinator.go b/integrationTests/testProcessorNodeWithCoordinator.go index c0004578249..a61674da6e1 100644 --- a/integrationTests/testProcessorNodeWithCoordinator.go +++ b/integrationTests/testProcessorNodeWithCoordinator.go @@ -92,6 +92,7 @@ func CreateProcessorNodesWithNodesCoordinator( WaitingListFixEnabledEpoch: 0, ChanStopNode: endProcess.GetDummyEndProcessChannel(), IsFullArchive: false, + StakingV4EnableEpoch: StakingV4Epoch, } nodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 654cf93fb70..96139817e0e 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -334,6 +334,7 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( managedCoreComponents.ChanStopNodeProcess(), managedCoreComponents.NodeTypeProvider(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, ) if err != nil { return true, err From e37991f9990a0bbc11a16bf9974be0a0eebc8e02 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 19 Apr 2022 12:03:10 +0300 Subject: [PATCH 198/958] FIX: Merge conflict --- epochStart/metachain/legacySystemSCs.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 0a8bf08cc25..eab767cb7b2 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -2,6 +2,7 @@ package metachain import ( "bytes" + "context" "encoding/hex" "fmt" "math" @@ -1013,7 +1014,8 @@ func (s *legacySystemSCProcessor) getArgumentsForSetOwnerFunctionality(userValid return nil, err } - chLeaves, err := userValidatorAccount.DataTrie().GetAllLeavesOnChannel(rootHash) + chLeaves := make(chan core.KeyValueHolder, common.TrieLeavesChannelDefaultCapacity) + err = userValidatorAccount.DataTrie().GetAllLeavesOnChannel(chLeaves, context.Background(), rootHash) if err != nil { return nil, err } From 8d2f1d5b0c29a20a0c3ee997629ca8a0d23b547d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 19 Apr 2022 13:00:37 +0300 Subject: [PATCH 199/958] FIX: Build error --- integrationTests/consensus/testInitializer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationTests/consensus/testInitializer.go b/integrationTests/consensus/testInitializer.go index 7f601bdc7a2..fc45f5512c9 100644 --- a/integrationTests/consensus/testInitializer.go +++ b/integrationTests/consensus/testInitializer.go @@ -49,6 +49,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" + "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" From 6dc741849091c267c6ca81a1db0a985f64816988 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Tue, 19 Apr 2022 20:47:29 +0300 Subject: [PATCH 200/958] add feat branches for golangci + add temp issue --- .github/workflows/golangci-lint.yml | 2 +- vm/systemSmartContracts/liquidStaking.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 962a0df83d4..da76c7970e0 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -4,7 +4,7 @@ on: branches: - master pull_request: - branches: [ master, development ] + branches: [ master, development, feat/* ] jobs: golangci: name: golangci linter diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 045d290d1af..e29daa85f4f 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -25,6 +25,7 @@ const attributesNoncePrefix = "a" type liquidStaking struct { eei vm.SystemEI sigVerifier vm.MessageSignVerifier + unusedPubKeyConverter core.PubkeyConverter liquidStakingSCAddress []byte gasCost vm.GasCost marshalizer marshal.Marshalizer From 13f2d621fc259ce80ea751fe2d8ec03c332f27f4 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Tue, 19 Apr 2022 20:53:38 +0300 Subject: [PATCH 201/958] fix intended linter issue --- vm/systemSmartContracts/liquidStaking.go | 1 - 1 file changed, 1 deletion(-) diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index e29daa85f4f..045d290d1af 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -25,7 +25,6 @@ const attributesNoncePrefix = "a" type liquidStaking struct { eei vm.SystemEI sigVerifier vm.MessageSignVerifier - unusedPubKeyConverter core.PubkeyConverter liquidStakingSCAddress []byte gasCost vm.GasCost marshalizer marshal.Marshalizer From 0f3e91a62d841498fe119634c85a0340d8d93078 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 20 Apr 2022 13:34:21 +0300 Subject: [PATCH 202/958] FIX: Delete error condition for maxNumNodes decrease --- epochStart/metachain/legacySystemSCs.go | 4 ---- integrationTests/vm/staking/systemSCCreator.go | 3 ++- integrationTests/vm/staking/testMetaProcessor.go | 1 + 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 071476d169c..fd3eef032ce 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -619,10 +619,6 @@ func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap state.ShardVa return err } - if maxNumberOfNodes < prevMaxNumberOfNodes { - return epochStart.ErrInvalidMaxNumberOfNodes - } - if s.flagStakingQueueEnabled.IsSet() { sw.Start("stakeNodesFromQueue") err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 48ecc0ba312..eeddff3d8c4 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -139,6 +139,7 @@ func createVMContainerFactory( peerAccounts state.AccountsAdapter, shardCoordinator sharding.Coordinator, nc nodesCoordinator.NodesCoordinator, + maxNumNodes uint32, ) process.VirtualMachinesContainerFactory { signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) @@ -175,7 +176,7 @@ func createVMContainerFactory( NumRoundsWithoutBleed: 1, MaximumPercentageToBleed: 1, BleedPercentagePerRound: 1, - MaxNumberOfNodesForStake: 24, // TODO HERE ADD MAX NUM NODES + MaxNumberOfNodesForStake: uint64(maxNumNodes), ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", StakeLimitPercentage: 100.0, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index db717874975..7eb47a98414 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -116,6 +116,7 @@ func NewTestMetaProcessor( stateComponents.PeerAccounts(), bootstrapComponents.ShardCoordinator(), nc, + maxNodesConfig[0].MaxNumNodes, ) vmContainer, _ := metaVmFactory.Create() From cb549f64ed96bf165a3b6271f011896d22056ded Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 20 Apr 2022 13:45:25 +0300 Subject: [PATCH 203/958] FIX: Delete error condition for maxNumNodes decrease --- epochStart/metachain/legacySystemSCs.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 367bea11f57..95a3714b4da 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -937,6 +937,7 @@ func (s *legacySystemSCProcessor) setMaxNumberOfNodes(maxNumNodes uint32) (uint3 log.Debug("setMaxNumberOfNodes called with", "maxNumNodes", maxNumNodes, + "current maxNumNodes in legacySystemSCProcessor", s.maxNodes, "returnMessage", vmOutput.ReturnMessage) if vmOutput.ReturnCode != vmcommon.Ok { @@ -1358,6 +1359,9 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) + // TODO: There is a bug: in case of node restart, state in legacySystemSC + // will be with epoch = startInEpoch after restart; these values are correctly + // stored only in sc state, so values printed and used here are obsolete s.flagChangeMaxNodesEnabled.SetValue(false) for _, maxNodesConfig := range s.maxNodesEnableConfig { if epoch == maxNodesConfig.EpochEnable { From 093817874d557777b07b1c8c609262f3e679f128 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 20 Apr 2022 14:12:44 +0300 Subject: [PATCH 204/958] FIX: Linter errors --- integrationTests/vm/delegation/liquidStaking_test.go | 2 +- state/validatorsInfoMap_test.go | 1 + vm/mock/systemEIStub.go | 1 - vm/systemSmartContracts/liquidStaking.go | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 4d7067d55b1..a343a1b9927 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -89,7 +89,7 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { } time.Sleep(time.Second) finalWait := 20 - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, finalWait, nonce, round, idxProposers) + _, _ = integrationTests.WaitOperationToBeDone(t, nodes, finalWait, nonce, round, idxProposers) time.Sleep(time.Second) for _, node := range nodes { diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index 8280589bc97..602f382cec4 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -223,6 +223,7 @@ func TestShardValidatorsInfoMap_GettersShouldReturnCopiesOfInternalData(t *testi require.Equal(t, []ValidatorInfoHandler{v0}, vi.GetShardValidatorsInfoMap()[0]) require.Equal(t, []ValidatorInfoHandler{v1}, vi.GetShardValidatorsInfoMap()[1]) + require.NotEqual(t, vi.GetAllValidatorsInfo(), validators) } func TestShardValidatorsInfoMap_Concurrency(t *testing.T) { diff --git a/vm/mock/systemEIStub.go b/vm/mock/systemEIStub.go index 78c900a7816..c91147135c4 100644 --- a/vm/mock/systemEIStub.go +++ b/vm/mock/systemEIStub.go @@ -196,7 +196,6 @@ func (s *SystemEIStub) Transfer(destination []byte, sender []byte, value *big.In if s.TransferCalled != nil { s.TransferCalled(destination, sender, value, input, gasLimit) } - return } // GetBalance - diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index 045d290d1af..bb49be1eb53 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -24,7 +24,6 @@ const attributesNoncePrefix = "a" type liquidStaking struct { eei vm.SystemEI - sigVerifier vm.MessageSignVerifier liquidStakingSCAddress []byte gasCost vm.GasCost marshalizer marshal.Marshalizer From e9b8e72055a8638e4108f5d3d138e84c28b7e750 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 20 Apr 2022 14:35:50 +0300 Subject: [PATCH 205/958] FIX: Linter errors --- integrationTests/vm/staking/configDisplayer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index d65b94154d4..2a6e55f4914 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -53,7 +53,7 @@ func displayConfig(config nodesConfig) { tableHeader := []string{"List", "Pub key", "Shard ID"} table, _ := display.CreateTableString(tableHeader, lines) headline := display.Headline("Nodes config", "", delimiter) - fmt.Println(fmt.Sprintf("%s\n%s", headline, table)) + fmt.Printf("%s\n%s\n", headline, table) displayValidators("Auction", config.auction) displayValidators("Queue", config.queue) @@ -86,5 +86,5 @@ func displayValidators(list string, pubKeys [][]byte) { headline := display.Headline(fmt.Sprintf("%s list", list), "", delimiter) table, _ := display.CreateTableString(tableHeader, lines) - fmt.Println(fmt.Sprintf("%s \n%s", headline, table)) + fmt.Printf("%s \n%s\n", headline, table) } From cf4c2f407c5752b373af16c4307d29dee6a6098c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 20 Apr 2022 16:36:02 +0300 Subject: [PATCH 206/958] FEAT: One more unit test --- .../indexHashedNodesCoordinator_test.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 40d423d43a2..0b14681a44b 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -19,6 +19,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/sharding/mock" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage/lrucache" @@ -2107,13 +2108,21 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * require.Equal(t, ErrReceivedAuctionValidatorsBeforeStakingV4, err) require.Nil(t, newNodesConfig) - nc.flagStakingV4.SetValue(true) + nc.updateEpochFlags(stakingV4Epoch) newNodesConfig, err = nc.computeNodesConfigFromList(previousConfig, validatorInfos) require.Nil(t, err) v1, _ := NewValidator([]byte("pk2"), 1, 2) v2, _ := NewValidator([]byte("pk1"), 1, 3) require.Equal(t, []Validator{v1, v2}, newNodesConfig.auctionList) + + validatorInfos = append(validatorInfos, &state.ShardValidatorInfo{ + PublicKey: []byte("pk3"), + List: string(common.NewList), + }) + newNodesConfig, err = nc.computeNodesConfigFromList(previousConfig, validatorInfos) + require.Equal(t, epochStart.ErrReceivedNewListNodeInStakingV4, err) + require.Nil(t, newNodesConfig) } func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix(t *testing.T) { From e4cd7f22da60c501295de5d7d2fbb2e95f29e130 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 20 Apr 2022 18:17:22 +0300 Subject: [PATCH 207/958] FIX: Hot fix for chicken-egg problem in CreateNodesCoordinatorRegistry --- .../indexHashedNodesCoordinator_test.go | 4 ++-- .../nodesCoordinatorRegistryFactory.go | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 0b14681a44b..1e27b70e3c7 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -81,7 +81,7 @@ func isStringSubgroup(a []string, b []string) bool { func createNodesCoordinatorRegistryFactory() NodesCoordinatorRegistryFactory { ncf, _ := NewNodesCoordinatorRegistryFactory( - &mock.MarshalizerMock{}, + &marshal.GogoProtoMarshalizer{}, &epochNotifier.EpochNotifierStub{}, stakingV4Epoch, ) @@ -109,7 +109,7 @@ func createArguments() ArgNodesCoordinator { arguments := ArgNodesCoordinator{ ShardConsensusGroupSize: 1, MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, + Marshalizer: &marshal.GogoProtoMarshalizer{}, Hasher: &hashingMocks.HasherMock{}, Shuffler: nodeShuffler, EpochStartNotifier: epochStartSubscriber, diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index e2e0e00d243..0927f81e8b9 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -42,9 +42,15 @@ func NewNodesCoordinatorRegistryFactory( // NodesCoordinatorRegistry with a json marshaller; while the new version(from staking v4) uses NodesCoordinatorRegistryWithAuction // with proto marshaller func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) { - if ncf.flagStakingV4.IsSet() { - return ncf.createRegistryWithAuction(buff) + //if ncf.flagStakingV4.IsSet() { + // return ncf.createRegistryWithAuction(buff) + //} + //return createOldRegistry(buff) + registry, err := ncf.createRegistryWithAuction(buff) + if err == nil { + return registry, nil } + return createOldRegistry(buff) } From 098bb938dbe10f037adc00f3bcca1686d21e56e6 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 27 Apr 2022 14:41:45 +0300 Subject: [PATCH 208/958] FIX: Bug in storageHandler when saving nodes coord registry --- epochStart/bootstrap/baseStorageHandler.go | 57 ++++++-- epochStart/bootstrap/metaStorageHandler.go | 48 +++---- .../bootstrap/metaStorageHandler_test.go | 97 +++++-------- epochStart/bootstrap/process.go | 48 ++++--- epochStart/bootstrap/process_test.go | 4 +- epochStart/bootstrap/shardStorageHandler.go | 48 +++---- .../bootstrap/shardStorageHandler_test.go | 129 +++++++----------- .../indexHashedNodesCoordinator.go | 1 + .../indexHashedNodesCoordinatorRegistry.go | 20 +-- ...ndexHashedNodesCoordinatorRegistry_test.go | 17 ++- sharding/nodesCoordinator/interface.go | 4 +- .../nodesCoordinatorRegistryFactory.go | 8 ++ .../nodesCoordRegistryFactoryMock.go | 37 +++++ 13 files changed, 252 insertions(+), 266 deletions(-) create mode 100644 testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go diff --git a/epochStart/bootstrap/baseStorageHandler.go b/epochStart/bootstrap/baseStorageHandler.go index dd971c36ddf..4229436e428 100644 --- a/epochStart/bootstrap/baseStorageHandler.go +++ b/epochStart/bootstrap/baseStorageHandler.go @@ -1,29 +1,67 @@ package bootstrap import ( - "encoding/json" - "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/typeConverters" "github.com/ElrondNetwork/elrond-go-core/hashing" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/storage" ) +// StorageHandlerArgs is a struct placeholder for all arguments required to create either a shard or a meta storage handler +type StorageHandlerArgs struct { + GeneralConfig config.Config + PreferencesConfig config.PreferencesConfig + ShardCoordinator sharding.Coordinator + PathManagerHandler storage.PathManagerHandler + Marshaller marshal.Marshalizer + Hasher hashing.Hasher + CurrentEpoch uint32 + Uint64Converter typeConverters.Uint64ByteSliceConverter + NodeTypeProvider NodeTypeProviderHandler + NodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory +} + +func checkNilArgs(args StorageHandlerArgs) error { + if check.IfNil(args.ShardCoordinator) { + return core.ErrNilShardCoordinator + } + if check.IfNil(args.PathManagerHandler) { + return dataRetriever.ErrNilPathManager + } + if check.IfNil(args.Marshaller) { + return core.ErrNilMarshalizer + } + if check.IfNil(args.Hasher) { + return core.ErrNilHasher + } + if check.IfNil(args.Uint64Converter) { + return dataRetriever.ErrNilUint64ByteSliceConverter + } + if check.IfNil(args.NodesCoordinatorRegistryFactory) { + return nodesCoordinator.ErrNilNodesCoordinatorRegistryFactory + } + return nil +} + // baseStorageHandler handles the storage functions for saving bootstrap data type baseStorageHandler struct { - storageService dataRetriever.StorageService - shardCoordinator sharding.Coordinator - marshalizer marshal.Marshalizer - hasher hashing.Hasher - currentEpoch uint32 - uint64Converter typeConverters.Uint64ByteSliceConverter + storageService dataRetriever.StorageService + shardCoordinator sharding.Coordinator + marshalizer marshal.Marshalizer + hasher hashing.Hasher + currentEpoch uint32 + uint64Converter typeConverters.Uint64ByteSliceConverter + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } func (bsh *baseStorageHandler) groupMiniBlocksByShard(miniBlocks map[string]*block.MiniBlock) ([]bootstrapStorage.PendingMiniBlocksInfo, error) { @@ -50,8 +88,7 @@ func (bsh *baseStorageHandler) saveNodesCoordinatorRegistry( ) ([]byte, error) { key := append([]byte(common.NodesCoordinatorRegistryKeyPrefix), metaBlock.GetPrevRandSeed()...) - // TODO: replace hardcoded json - although it is hardcoded in nodesCoordinator as well. - registryBytes, err := json.Marshal(nodesConfig) + registryBytes, err := bsh.nodesCoordinatorRegistryFactory.GetRegistryData(nodesConfig, metaBlock.GetEpoch()) if err != nil { return nil, err } diff --git a/epochStart/bootstrap/metaStorageHandler.go b/epochStart/bootstrap/metaStorageHandler.go index 1d7c63aa2f0..ee85dc67471 100644 --- a/epochStart/bootstrap/metaStorageHandler.go +++ b/epochStart/bootstrap/metaStorageHandler.go @@ -7,17 +7,11 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/typeConverters" - "github.com/ElrondNetwork/elrond-go-core/hashing" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/bootstrap/disabled" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/storage" "github.com/ElrondNetwork/elrond-go/storage/factory" ) @@ -26,26 +20,21 @@ type metaStorageHandler struct { } // NewMetaStorageHandler will return a new instance of metaStorageHandler -func NewMetaStorageHandler( - generalConfig config.Config, - prefsConfig config.PreferencesConfig, - shardCoordinator sharding.Coordinator, - pathManagerHandler storage.PathManagerHandler, - marshalizer marshal.Marshalizer, - hasher hashing.Hasher, - currentEpoch uint32, - uint64Converter typeConverters.Uint64ByteSliceConverter, - nodeTypeProvider NodeTypeProviderHandler, -) (*metaStorageHandler, error) { +func NewMetaStorageHandler(args StorageHandlerArgs) (*metaStorageHandler, error) { + err := checkNilArgs(args) + if err != nil { + return nil, err + } + epochStartNotifier := &disabled.EpochStartNotifier{} storageFactory, err := factory.NewStorageServiceFactory( - &generalConfig, - &prefsConfig, - shardCoordinator, - pathManagerHandler, + &args.GeneralConfig, + &args.PreferencesConfig, + args.ShardCoordinator, + args.PathManagerHandler, epochStartNotifier, - nodeTypeProvider, - currentEpoch, + args.NodeTypeProvider, + args.CurrentEpoch, false, ) if err != nil { @@ -58,12 +47,13 @@ func NewMetaStorageHandler( } base := &baseStorageHandler{ - storageService: storageService, - shardCoordinator: shardCoordinator, - marshalizer: marshalizer, - hasher: hasher, - currentEpoch: currentEpoch, - uint64Converter: uint64Converter, + storageService: storageService, + shardCoordinator: args.ShardCoordinator, + marshalizer: args.Marshaller, + hasher: args.Hasher, + currentEpoch: args.CurrentEpoch, + uint64Converter: args.Uint64Converter, + nodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, } return &metaStorageHandler{baseStorageHandler: base}, nil diff --git a/epochStart/bootstrap/metaStorageHandler_test.go b/epochStart/bootstrap/metaStorageHandler_test.go index a2561eecdab..b18875fb03f 100644 --- a/epochStart/bootstrap/metaStorageHandler_test.go +++ b/epochStart/bootstrap/metaStorageHandler_test.go @@ -14,20 +14,30 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" + "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" "github.com/stretchr/testify/assert" ) +func createStorageHandlerArgs() StorageHandlerArgs { + return StorageHandlerArgs{ + GeneralConfig: testscommon.GetGeneralConfig(), + PreferencesConfig: config.PreferencesConfig{}, + ShardCoordinator: &mock.ShardCoordinatorStub{}, + PathManagerHandler: &testscommon.PathManagerStub{}, + Marshaller: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + CurrentEpoch: 0, + Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, + } +} + func TestNewMetaStorageHandler_InvalidConfigErr(t *testing.T) { - gCfg := config.Config{} - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, err := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) + args := createStorageHandlerArgs() + args.GeneralConfig = config.Config{} + + mtStrHandler, err := NewMetaStorageHandler(args) assert.True(t, check.IfNil(mtStrHandler)) assert.NotNil(t, err) } @@ -37,16 +47,8 @@ func TestNewMetaStorageHandler_CreateForMetaErr(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - gCfg := testscommon.GetGeneralConfig() - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, err := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) + args := createStorageHandlerArgs() + mtStrHandler, err := NewMetaStorageHandler(args) assert.False(t, check.IfNil(mtStrHandler)) assert.Nil(t, err) } @@ -56,20 +58,11 @@ func TestMetaStorageHandler_saveLastHeader(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - gCfg := testscommon.GetGeneralConfig() - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, _ := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) - + args := createStorageHandlerArgs() + mtStrHandler, _ := NewMetaStorageHandler(args) header := &block.MetaBlock{Nonce: 0} - headerHash, _ := core.CalculateHash(marshalizer, hasher, header) + headerHash, _ := core.CalculateHash(args.Marshaller, args.Hasher, header) expectedBootInfo := bootstrapStorage.BootstrapHeaderInfo{ ShardId: core.MetachainShardId, Hash: headerHash, } @@ -84,21 +77,13 @@ func TestMetaStorageHandler_saveLastCrossNotarizedHeaders(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - gCfg := testscommon.GetGeneralConfig() - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, _ := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) + args := createStorageHandlerArgs() + mtStrHandler, _ := NewMetaStorageHandler(args) hdr1 := &block.Header{Nonce: 1} hdr2 := &block.Header{Nonce: 2} - hdrHash1, _ := core.CalculateHash(marshalizer, hasher, hdr1) - hdrHash2, _ := core.CalculateHash(marshalizer, hasher, hdr2) + hdrHash1, _ := core.CalculateHash(args.Marshaller, args.Hasher, hdr1) + hdrHash2, _ := core.CalculateHash(args.Marshaller, args.Hasher, hdr2) hdr3 := &block.MetaBlock{ Nonce: 3, @@ -118,16 +103,8 @@ func TestMetaStorageHandler_saveTriggerRegistry(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - gCfg := testscommon.GetGeneralConfig() - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, _ := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) + args := createStorageHandlerArgs() + mtStrHandler, _ := NewMetaStorageHandler(args) components := &ComponentsNeededForBootstrap{ EpochStartMetaBlock: &block.MetaBlock{Nonce: 3}, @@ -143,16 +120,8 @@ func TestMetaStorageHandler_saveDataToStorage(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - gCfg := testscommon.GetGeneralConfig() - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, _ := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) + args := createStorageHandlerArgs() + mtStrHandler, _ := NewMetaStorageHandler(args) components := &ComponentsNeededForBootstrap{ EpochStartMetaBlock: &block.MetaBlock{Nonce: 3}, diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index ef545dedae3..9f33b895fef 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -728,17 +728,19 @@ func (e *epochStartBootstrap) processNodesConfig(pubKey []byte) error { func (e *epochStartBootstrap) requestAndProcessForMeta() error { var err error - storageHandlerComponent, err := NewMetaStorageHandler( - e.generalConfig, - e.prefsConfig, - e.shardCoordinator, - e.coreComponentsHolder.PathHandler(), - e.coreComponentsHolder.InternalMarshalizer(), - e.coreComponentsHolder.Hasher(), - e.epochStartMeta.GetEpoch(), - e.coreComponentsHolder.Uint64ByteSliceConverter(), - e.coreComponentsHolder.NodeTypeProvider(), - ) + argsStorageHandler := StorageHandlerArgs{ + GeneralConfig: e.generalConfig, + PreferencesConfig: e.prefsConfig, + ShardCoordinator: e.shardCoordinator, + PathManagerHandler: e.coreComponentsHolder.PathHandler(), + Marshaller: e.coreComponentsHolder.InternalMarshalizer(), + Hasher: e.coreComponentsHolder.Hasher(), + CurrentEpoch: e.epochStartMeta.GetEpoch(), + Uint64Converter: e.coreComponentsHolder.Uint64ByteSliceConverter(), + NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), + NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, + } + storageHandlerComponent, err := NewMetaStorageHandler(argsStorageHandler) if err != nil { return err } @@ -862,17 +864,19 @@ func (e *epochStartBootstrap) requestAndProcessForShard() error { e.syncedHeaders[hash] = hdr } - storageHandlerComponent, err := NewShardStorageHandler( - e.generalConfig, - e.prefsConfig, - e.shardCoordinator, - e.coreComponentsHolder.PathHandler(), - e.coreComponentsHolder.InternalMarshalizer(), - e.coreComponentsHolder.Hasher(), - e.baseData.lastEpoch, - e.coreComponentsHolder.Uint64ByteSliceConverter(), - e.coreComponentsHolder.NodeTypeProvider(), - ) + argsStorageHandler := StorageHandlerArgs{ + GeneralConfig: e.generalConfig, + PreferencesConfig: e.prefsConfig, + ShardCoordinator: e.shardCoordinator, + PathManagerHandler: e.coreComponentsHolder.PathHandler(), + Marshaller: e.coreComponentsHolder.InternalMarshalizer(), + Hasher: e.coreComponentsHolder.Hasher(), + CurrentEpoch: e.epochStartMeta.GetEpoch(), + Uint64Converter: e.coreComponentsHolder.Uint64ByteSliceConverter(), + NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), + NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, + } + storageHandlerComponent, err := NewShardStorageHandler(argsStorageHandler) if err != nil { return err } diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index 0b41a2c872f..40605064ef3 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -15,6 +15,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/versioning" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" @@ -88,7 +89,7 @@ func createMockEpochStartBootstrapArgs( ) ArgsEpochStartBootstrap { generalCfg := testscommon.GetGeneralConfig() nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( - &testscommon.MarshalizerMock{}, + &marshal.GogoProtoMarshalizer{}, &epochNotifier.EpochNotifierStub{}, 444, ) @@ -189,6 +190,7 @@ func createMockEpochStartBootstrapArgs( return 1 }, }, + EnableEpochs: config.EnableEpochs{StakingV4EnableEpoch: 444}, GenesisNodesConfig: &mock.NodesSetupStub{}, GenesisShardCoordinator: mock.NewMultipleShardsCoordinatorMock(), Rater: &mock.RaterStub{}, diff --git a/epochStart/bootstrap/shardStorageHandler.go b/epochStart/bootstrap/shardStorageHandler.go index 3f09e7b7e02..c740ed70c65 100644 --- a/epochStart/bootstrap/shardStorageHandler.go +++ b/epochStart/bootstrap/shardStorageHandler.go @@ -10,17 +10,11 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/typeConverters" - "github.com/ElrondNetwork/elrond-go-core/hashing" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/bootstrap/disabled" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/storage" "github.com/ElrondNetwork/elrond-go/storage/factory" ) @@ -29,26 +23,21 @@ type shardStorageHandler struct { } // NewShardStorageHandler will return a new instance of shardStorageHandler -func NewShardStorageHandler( - generalConfig config.Config, - prefsConfig config.PreferencesConfig, - shardCoordinator sharding.Coordinator, - pathManagerHandler storage.PathManagerHandler, - marshalizer marshal.Marshalizer, - hasher hashing.Hasher, - currentEpoch uint32, - uint64Converter typeConverters.Uint64ByteSliceConverter, - nodeTypeProvider core.NodeTypeProviderHandler, -) (*shardStorageHandler, error) { +func NewShardStorageHandler(args StorageHandlerArgs) (*shardStorageHandler, error) { + err := checkNilArgs(args) + if err != nil { + return nil, err + } + epochStartNotifier := &disabled.EpochStartNotifier{} storageFactory, err := factory.NewStorageServiceFactory( - &generalConfig, - &prefsConfig, - shardCoordinator, - pathManagerHandler, + &args.GeneralConfig, + &args.PreferencesConfig, + args.ShardCoordinator, + args.PathManagerHandler, epochStartNotifier, - nodeTypeProvider, - currentEpoch, + args.NodeTypeProvider, + args.CurrentEpoch, false, ) if err != nil { @@ -61,12 +50,13 @@ func NewShardStorageHandler( } base := &baseStorageHandler{ - storageService: storageService, - shardCoordinator: shardCoordinator, - marshalizer: marshalizer, - hasher: hasher, - currentEpoch: currentEpoch, - uint64Converter: uint64Converter, + storageService: storageService, + shardCoordinator: args.ShardCoordinator, + marshalizer: args.Marshaller, + hasher: args.Hasher, + currentEpoch: args.CurrentEpoch, + uint64Converter: args.Uint64Converter, + nodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, } return &shardStorageHandler{baseStorageHandler: base}, nil diff --git a/epochStart/bootstrap/shardStorageHandler_test.go b/epochStart/bootstrap/shardStorageHandler_test.go index b572f9cbe37..094e6e3dad5 100644 --- a/epochStart/bootstrap/shardStorageHandler_test.go +++ b/epochStart/bootstrap/shardStorageHandler_test.go @@ -12,20 +12,11 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/typeConverters" - "github.com/ElrondNetwork/elrond-go-core/hashing" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" - "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/storage" "github.com/ElrondNetwork/elrond-go/testscommon" epochStartMocks "github.com/ElrondNetwork/elrond-go/testscommon/bootstrapMocks/epochStart" - "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" - "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -35,8 +26,8 @@ func TestNewShardStorageHandler_ShouldWork(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, err := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, err := NewShardStorageHandler(args) assert.False(t, check.IfNil(shardStorage)) assert.Nil(t, err) @@ -47,8 +38,8 @@ func TestShardStorageHandler_SaveDataToStorageShardDataNotFound(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) components := &ComponentsNeededForBootstrap{ EpochStartMetaBlock: &block.MetaBlock{Epoch: 1}, @@ -65,8 +56,8 @@ func TestShardStorageHandler_SaveDataToStorageMissingHeader(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) components := &ComponentsNeededForBootstrap{ EpochStartMetaBlock: &block.MetaBlock{ @@ -90,8 +81,8 @@ func TestShardStorageHandler_SaveDataToStorage(t *testing.T) { _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) hash1 := []byte("hash1") hdr1 := block.MetaBlock{ @@ -189,8 +180,8 @@ func TestShardStorageHandler_getCrossProcessedMbsDestMeByHeader(t *testing.T) { mbs := append(intraMbs, crossMbs...) - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shardHeader := &block.Header{ Nonce: 100, MiniBlockHeaders: mbs, @@ -207,8 +198,8 @@ func TestShardStorageHandler_getCrossProcessedMbsDestMeByHeader(t *testing.T) { func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduledErrorGettingProcessedAndPendingMbs(t *testing.T) { t.Parallel() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) meta := &block.MetaBlock{ Nonce: 100, EpochStart: block.EpochStart{}, @@ -225,8 +216,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduledErrorG func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduledNoScheduled(t *testing.T) { t.Parallel() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) scenario := createPendingAndProcessedMiniBlocksScenario() processedMiniBlocks, pendingMiniBlocks, err := shardStorage.getProcessedAndPendingMiniBlocksWithScheduled(scenario.metaBlock, scenario.headers, scenario.shardHeader, false) @@ -240,8 +231,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduledNoSche func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduledWrongHeaderType(t *testing.T) { t.Parallel() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) scenario := createPendingAndProcessedMiniBlocksScenario() wrongShardHeader := &block.MetaBlock{} @@ -262,8 +253,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduledWrongH func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithScheduled(t *testing.T) { t.Parallel() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) scenario := createPendingAndProcessedMiniBlocksScenario() processedMiniBlocks, pendingMiniBlocks, err := shardStorage.getProcessedAndPendingMiniBlocksWithScheduled(scenario.metaBlock, scenario.headers, scenario.shardHeader, true) @@ -399,8 +390,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksErrorGettingEpochSt _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) meta := &block.MetaBlock{ Nonce: 100, EpochStart: block.EpochStart{}, @@ -422,8 +413,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksMissingHeader(t *te }() lastFinishedMetaBlock := "last finished meta block" - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) meta := &block.MetaBlock{ Nonce: 100, EpochStart: block.EpochStart{ @@ -448,8 +439,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWrongHeader(t *test lastFinishedMetaBlockHash := "last finished meta block" firstPendingMeta := "first pending meta" - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) lastFinishedHeaders := createDefaultEpochStartShardData([]byte(lastFinishedMetaBlockHash), []byte("headerHash")) lastFinishedHeaders[0].FirstPendingMetaBlock = []byte(firstPendingMeta) meta := &block.MetaBlock{ @@ -479,8 +470,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksNilMetaBlock(t *tes lastFinishedMetaBlockHash := "last finished meta block" firstPendingMeta := "first pending meta" - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) lastFinishedHeaders := createDefaultEpochStartShardData([]byte(lastFinishedMetaBlockHash), []byte("headerHash")) lastFinishedHeaders[0].FirstPendingMetaBlock = []byte(firstPendingMeta) meta := &block.MetaBlock{ @@ -512,8 +503,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksNoProcessedNoPendin lastFinishedMetaBlockHash := "last finished meta block" firstPendingMeta := "first pending meta" - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) lastFinishedHeaders := createDefaultEpochStartShardData([]byte(lastFinishedMetaBlockHash), []byte("headerHash")) lastFinishedHeaders[0].FirstPendingMetaBlock = []byte(firstPendingMeta) lastFinishedHeaders[0].PendingMiniBlockHeaders = nil @@ -541,8 +532,8 @@ func TestShardStorageHandler_getProcessedAndPendingMiniBlocksNoProcessedNoPendin func TestShardStorageHandler_getProcessedAndPendingMiniBlocksWithProcessedAndPendingMbs(t *testing.T) { t.Parallel() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) scenario := createPendingAndProcessedMiniBlocksScenario() processedMiniBlocks, pendingMiniBlocks, firstPendingMetaBlockHash, err := shardStorage.getProcessedAndPendingMiniBlocks(scenario.metaBlock, scenario.headers) @@ -559,8 +550,8 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithoutScheduledGetSha _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) headers := map[string]data.HeaderHandler{} meta := &block.MetaBlock{ @@ -580,8 +571,8 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithoutScheduledMissin _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shard0HeaderHash := "shard0 header hash" lastFinishedMetaBlock := "last finished meta block" @@ -609,8 +600,8 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithoutScheduledWrongT _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shard0HeaderHash := "shard0 header hash" lastFinishedMetaBlock := "last finished meta block" @@ -640,13 +631,12 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithoutScheduledErrorW _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() + args := createStorageHandlerArgs() expectedErr := fmt.Errorf("expected error") - // Simulate an error when writing to storage with a mock marshaller - args.marshalizer = &testscommon.MarshalizerStub{MarshalCalled: func(obj interface{}) ([]byte, error) { + args.Marshaller = &testscommon.MarshalizerStub{MarshalCalled: func(obj interface{}) ([]byte, error) { return nil, expectedErr }} - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + shardStorage, _ := NewShardStorageHandler(args) shard0HeaderHash := "shard0 header hash" lastFinishedMetaBlock := "last finished meta block" @@ -676,8 +666,8 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithoutScheduled(t *te _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shard0HeaderHash := "shard0 header hash" lastFinishedMetaBlock := "last finished meta block" @@ -712,8 +702,8 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithScheduledErrorUpda _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shard0HeaderHash := "shard0 header hash" lastFinishedMetaBlock := "last finished meta block" @@ -742,8 +732,8 @@ func TestShardStorageHandler_saveLastCrossNotarizedHeadersWithScheduled(t *testi _ = os.RemoveAll("./Epoch_0") }() - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shard0HeaderHash := "shard0 header hash" lastFinishedMetaBlock := "last finished meta block" prevMetaHash := "prev metaHlock hash" @@ -955,32 +945,6 @@ func Test_getShardHeaderAndMetaHashes(t *testing.T) { require.Equal(t, metaHashes, headers[shardHdrKey].(data.ShardHeaderHandler).GetMetaBlockHashes()) } -type shardStorageArgs struct { - generalConfig config.Config - prefsConfig config.PreferencesConfig - shardCoordinator sharding.Coordinator - pathManagerHandler storage.PathManagerHandler - marshalizer marshal.Marshalizer - hasher hashing.Hasher - currentEpoch uint32 - uint64Converter typeConverters.Uint64ByteSliceConverter - nodeTypeProvider core.NodeTypeProviderHandler -} - -func createDefaultShardStorageArgs() shardStorageArgs { - return shardStorageArgs{ - generalConfig: testscommon.GetGeneralConfig(), - prefsConfig: config.PreferencesConfig{}, - shardCoordinator: &mock.ShardCoordinatorStub{}, - pathManagerHandler: &testscommon.PathManagerStub{}, - marshalizer: &mock.MarshalizerMock{}, - hasher: &hashingMocks.HasherMock{}, - currentEpoch: 0, - uint64Converter: &mock.Uint64ByteSliceConverterMock{}, - nodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - } -} - func createDefaultEpochStartShardData(lastFinishedMetaBlockHash []byte, shardHeaderHash []byte) []block.EpochStartShardData { return []block.EpochStartShardData{ { @@ -1050,7 +1014,6 @@ func createPendingAndProcessedMiniBlocksScenario() scenarioData { expectedPendingMbsWithScheduled := []bootstrapStorage.PendingMiniBlocksInfo{ {ShardID: 0, MiniBlocksHashes: [][]byte{crossMbHeaders[1].Hash, crossMbHeaders[2].Hash, crossMbHeaders[3].Hash, crossMbHeaders[4].Hash, crossMbHeaders[0].Hash}}, } - expectedProcessedMbsWithScheduled := []bootstrapStorage.MiniBlocksInMeta{} headers := map[string]data.HeaderHandler{ lastFinishedMetaBlockHash: &block.MetaBlock{ @@ -1091,7 +1054,7 @@ func createPendingAndProcessedMiniBlocksScenario() scenarioData { expectedPendingMbs: expectedPendingMiniBlocks, expectedProcessedMbs: expectedProcessedMiniBlocks, expectedPendingMbsWithScheduled: expectedPendingMbsWithScheduled, - expectedProcessedMbsWithScheduled: expectedProcessedMbsWithScheduled, + expectedProcessedMbsWithScheduled: []bootstrapStorage.MiniBlocksInMeta{}, } } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index b9998949b88..b49f3f9ddd6 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -122,6 +122,7 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed auctionList: make([]Validator, 0), } + // todo: if not genesis, use previous randomness from start of epoch meta block savedKey := arguments.Hasher.Compute(string(arguments.SelfPublicKey)) ihnc := &indexHashedNodesCoordinator{ diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go index 4224b7b9983..24d73e758aa 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go @@ -1,7 +1,6 @@ package nodesCoordinator import ( - "encoding/json" "fmt" "strconv" @@ -61,7 +60,8 @@ func displayNodesConfigInfo(config map[uint32]*epochNodesConfig) { } func (ihnc *indexHashedNodesCoordinator) saveState(key []byte) error { - data, err := ihnc.getRegistryData() + registry := ihnc.NodesCoordinatorToRegistry() + data, err := ihnc.nodesCoordinatorRegistryFactory.GetRegistryData(registry, ihnc.currentEpoch) if err != nil { return err } @@ -72,23 +72,9 @@ func (ihnc *indexHashedNodesCoordinator) saveState(key []byte) error { return ihnc.bootStorer.Put(ncInternalKey, data) } -func (ihnc *indexHashedNodesCoordinator) getRegistryData() ([]byte, error) { - var err error - var data []byte - - registry := ihnc.NodesCoordinatorToRegistry() - if ihnc.flagStakingV4.IsSet() { - data, err = ihnc.marshalizer.Marshal(registry) - } else { - data, err = json.Marshal(registry) - } - - return data, err -} - // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry func (ihnc *indexHashedNodesCoordinator) NodesCoordinatorToRegistry() NodesCoordinatorRegistryHandler { - if ihnc.flagStakingV4.IsSet() { + if ihnc.currentEpoch >= ihnc.stakingV4EnableEpoch { return ihnc.nodesCoordinatorToRegistryWithAuction() } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go index f5305806e68..3ff6825e9c8 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go @@ -101,13 +101,12 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing. t.Parallel() args := createArguments() - args.NodesCoordinatorRegistryFactory.EpochConfirmed(stakingV4Epoch, 0) + args.Epoch = stakingV4Epoch nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) - nodesCoordinator.updateEpochFlags(stakingV4Epoch) - nodesCoordinator.nodesConfig[0].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) - nodesCoordinator.nodesConfig[0].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) - expectedConfig := nodesCoordinator.nodesConfig[0] + nodesCoordinator.nodesConfig[stakingV4Epoch].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) + nodesCoordinator.nodesConfig[stakingV4Epoch].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) + expectedConfig := nodesCoordinator.nodesConfig[stakingV4Epoch] key := []byte("config") err := nodesCoordinator.saveState(key) @@ -117,7 +116,7 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing. err = nodesCoordinator.LoadState(key) assert.Nil(t, err) - actualConfig := nodesCoordinator.nodesConfig[0] + actualConfig := nodesCoordinator.nodesConfig[stakingV4Epoch] assert.Equal(t, expectedConfig.shardID, actualConfig.shardID) assert.Equal(t, expectedConfig.nbShards, actualConfig.nbShards) assert.True(t, sameValidatorsMaps(expectedConfig.eligibleMap, actualConfig.eligibleMap)) @@ -128,11 +127,11 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing. func TestIndexHashedNodesCoordinator_nodesCoordinatorToRegistryWithStakingV4(t *testing.T) { args := createArguments() + args.Epoch = stakingV4Epoch nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) - nodesCoordinator.flagStakingV4.SetValue(true) - nodesCoordinator.nodesConfig[0].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) - nodesCoordinator.nodesConfig[0].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) + nodesCoordinator.nodesConfig[stakingV4Epoch].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) + nodesCoordinator.nodesConfig[stakingV4Epoch].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) ncr := nodesCoordinator.NodesCoordinatorToRegistry() nc := nodesCoordinator.nodesConfig diff --git a/sharding/nodesCoordinator/interface.go b/sharding/nodesCoordinator/interface.go index 655777c84bd..4c747cd1d39 100644 --- a/sharding/nodesCoordinator/interface.go +++ b/sharding/nodesCoordinator/interface.go @@ -153,10 +153,10 @@ type NodesCoordinatorRegistryHandler interface { SetCurrentEpoch(epoch uint32) } -// NodesCoordinatorRegistryFactory defines a NodesCoordinatorRegistryHandler factory -// from the provided buffer +// NodesCoordinatorRegistryFactory handles NodesCoordinatorRegistryHandler marshall/unmarshall type NodesCoordinatorRegistryFactory interface { CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) + GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool } diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index 0927f81e8b9..aecef404e24 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -54,6 +54,14 @@ func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff return createOldRegistry(buff) } +func (ncf *nodesCoordinatorRegistryFactory) GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) { + if epoch >= ncf.stakingV4EnableEpoch { + return ncf.marshaller.Marshal(registry) + } + + return json.Marshal(registry) +} + func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { registry := &NodesCoordinatorRegistry{} err := json.Unmarshal(buff, registry) diff --git a/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go b/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go new file mode 100644 index 00000000000..b511b7434ee --- /dev/null +++ b/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go @@ -0,0 +1,37 @@ +package shardingMocks + +import ( + "encoding/json" + + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" +) + +// NodesCoordinatorRegistryFactoryMock - +type NodesCoordinatorRegistryFactoryMock struct { +} + +// CreateNodesCoordinatorRegistry - +func (ncr *NodesCoordinatorRegistryFactoryMock) CreateNodesCoordinatorRegistry(buff []byte) (nodesCoordinator.NodesCoordinatorRegistryHandler, error) { + registry := &nodesCoordinator.NodesCoordinatorRegistry{} + err := json.Unmarshal(buff, registry) + if err != nil { + return nil, err + } + + return registry, nil +} + +// GetRegistryData - +func (ncr *NodesCoordinatorRegistryFactoryMock) GetRegistryData(registry nodesCoordinator.NodesCoordinatorRegistryHandler, _ uint32) ([]byte, error) { + return json.Marshal(registry) +} + +// EpochConfirmed - +func (ncr *NodesCoordinatorRegistryFactoryMock) EpochConfirmed(_ uint32, _ uint64) { + +} + +// IsInterfaceNil - +func (ncr *NodesCoordinatorRegistryFactoryMock) IsInterfaceNil() bool { + return ncr == nil +} From f3fe6c5a2d7cd7ae7b62685778aabfd5affadcd5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 27 Apr 2022 17:24:26 +0300 Subject: [PATCH 209/958] FIX: Review findings --- config/epochConfig.go | 2 +- epochStart/metachain/systemSCs.go | 45 ++++++----- factory/coreComponents.go | 17 ++--- integrationTests/nodesCoordinatorFactory.go | 28 +++---- .../testProcessorNodeWithMultisigner.go | 14 ++-- .../vm/staking/metaBlockProcessorCreator.go | 15 ++-- .../vm/staking/nodesCoordiantorCreator.go | 18 +++-- .../nodesCoordinator/hashValidatorShuffler.go | 31 ++++---- .../hashValidatorShuffler_test.go | 76 ++++++++++--------- .../indexHashedNodesCoordinator_test.go | 6 +- testscommon/rewardsCreatorStub.go | 3 +- testscommon/stakingcommon/stakingCommon.go | 13 +++- 12 files changed, 143 insertions(+), 125 deletions(-) diff --git a/config/epochConfig.go b/config/epochConfig.go index 48b86ca44c0..e46870a8d85 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -79,7 +79,7 @@ type EnableEpochs struct { StakeLimitsEnableEpoch uint32 StakingV4InitEnableEpoch uint32 StakingV4EnableEpoch uint32 - StakingV4DistributeAuctionToWaiting uint32 + StakingV4DistributeAuctionToWaitingEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 0bf425018b2..a21bcc8b004 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -229,11 +229,17 @@ func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInf } func (s *systemSCProcessor) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { + if len(auctionList) == 0 { + return nil + } + validatorTopUpMap, err := s.getValidatorTopUpMap(auctionList) if err != nil { return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) } + pubKeyLen := len(auctionList[0].GetPublicKey()) + normRandomness := calcNormRand(randomness, pubKeyLen) sort.SliceStable(auctionList, func(i, j int) bool { pubKey1 := auctionList[i].GetPublicKey() pubKey2 := auctionList[j].GetPublicKey() @@ -242,7 +248,7 @@ func (s *systemSCProcessor) sortAuctionList(auctionList []state.ValidatorInfoHan nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { - return compareByXORWithRandomness(pubKey1, pubKey2, randomness) + return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) } return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 @@ -267,35 +273,32 @@ func (s *systemSCProcessor) getValidatorTopUpMap(validators []state.ValidatorInf return ret, nil } -func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { - lenPubKey := len(pubKey1) +func calcNormRand(randomness []byte, expectedLen int) []byte { lenRand := len(randomness) - - minLen := core.MinInt(lenPubKey, lenRand) - maxLen := core.MaxInt(lenPubKey, lenRand) - repeatedCt := maxLen/minLen + 1 + minLen := core.MinInt(expectedLen, lenRand) + maxLen := core.MaxInt(expectedLen, lenRand) rnd := randomness - pk1 := pubKey1 - pk2 := pubKey2 - - if lenPubKey > lenRand { + if expectedLen > lenRand { + repeatedCt := maxLen/minLen + 1 rnd = bytes.Repeat(randomness, repeatedCt) rnd = rnd[:maxLen] } else { - pk1 = bytes.Repeat(pk1, repeatedCt) - pk2 = bytes.Repeat(pk2, repeatedCt) - - pk1 = pk1[:maxLen] - pk2 = pk2[:maxLen] + rnd = rnd[:minLen] } - key1Xor := make([]byte, maxLen) - key2Xor := make([]byte, maxLen) + return rnd +} + +func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { + xorLen := len(randomness) + + key1Xor := make([]byte, xorLen) + key2Xor := make([]byte, xorLen) - for idx := 0; idx < maxLen; idx++ { - key1Xor[idx] = pk1[idx] ^ rnd[idx] - key2Xor[idx] = pk2[idx] ^ rnd[idx] + for idx := 0; idx < xorLen; idx++ { + key1Xor[idx] = pubKey1[idx] ^ randomness[idx] + key2Xor[idx] = pubKey2[idx] ^ randomness[idx] } return bytes.Compare(key1Xor, key2Xor) == 1 diff --git a/factory/coreComponents.go b/factory/coreComponents.go index 7adff1aa730..012d6d452e8 100644 --- a/factory/coreComponents.go +++ b/factory/coreComponents.go @@ -310,16 +310,13 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) { } argsNodesShuffler := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: genesisNodesConfig.MinNumberOfShardNodes(), - NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(), - Hysteresis: genesisNodesConfig.GetHysteresis(), - Adaptivity: genesisNodesConfig.GetAdaptivity(), - ShuffleBetweenShards: true, - MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, - BalanceWaitingListsEnableEpoch: ccf.epochConfig.EnableEpochs.BalanceWaitingListsEnableEpoch, - WaitingListFixEnableEpoch: ccf.epochConfig.EnableEpochs.WaitingListFixEnableEpoch, - StakingV4EnableEpoch: ccf.epochConfig.EnableEpochs.StakingV4EnableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: ccf.epochConfig.EnableEpochs.StakingV4DistributeAuctionToWaiting, + NodesShard: genesisNodesConfig.MinNumberOfShardNodes(), + NodesMeta: genesisNodesConfig.MinNumberOfMetaNodes(), + Hysteresis: genesisNodesConfig.GetHysteresis(), + Adaptivity: genesisNodesConfig.GetAdaptivity(), + ShuffleBetweenShards: true, + MaxNodesEnableConfig: ccf.epochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, + EnableEpochs: ccf.epochConfig.EnableEpochs, } nodesShuffler, err := nodesCoordinator.NewHashValidatorsShuffler(argsNodesShuffler) diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 000ddf90c3b..46d55924955 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -42,14 +42,12 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd pubKeyBytes, _ := keys.Pk.ToByteArray() nodeShufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: uint32(arg.nodesPerShard), - NodesMeta: uint32(arg.nbMetaNodes), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - WaitingListFixEnableEpoch: 0, - BalanceWaitingListsEnableEpoch: 0, + NodesShard: uint32(arg.nodesPerShard), + NodesMeta: uint32(arg.nbMetaNodes), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(nodeShufflerArgs) @@ -102,14 +100,12 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato pubKeyBytes, _ := keys.Pk.ToByteArray() shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: uint32(arg.nodesPerShard), - NodesMeta: uint32(arg.nbMetaNodes), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - BalanceWaitingListsEnableEpoch: 0, - WaitingListFixEnableEpoch: 0, + NodesShard: uint32(arg.nodesPerShard), + NodesMeta: uint32(arg.nbMetaNodes), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 8383965787a..4b240e080d1 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -477,14 +477,12 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( nodesMap := make(map[uint32][]*TestProcessorNode) shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: uint32(nodesPerShard), - NodesMeta: uint32(nbMetaNodes), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - WaitingListFixEnableEpoch: 0, - BalanceWaitingListsEnableEpoch: 0, + NodesShard: uint32(nodesPerShard), + NodesMeta: uint32(nbMetaNodes), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: nil, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) epochStartSubscriber := notifier.NewEpochStartSubscriptionHandler() diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 10d5dfeb97a..481ac9183a7 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -7,6 +7,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/dataRetriever/dataPool" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" @@ -86,11 +87,15 @@ func createMetaBlockProcessor( VMContainersFactory: metaVMFactory, VmContainer: vmContainer, }, - SCToProtocol: &mock.SCToProtocolStub{}, - PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, - EpochStartDataCreator: epochStartDataCreator, - EpochEconomics: &mock.EpochEconomicsStub{}, - EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, + SCToProtocol: &mock.SCToProtocolStub{}, + PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, + EpochStartDataCreator: epochStartDataCreator, + EpochEconomics: &mock.EpochEconomicsStub{}, + EpochRewardsCreator: &testscommon.RewardsCreatorStub{ + GetLocalTxCacheCalled: func() epochStart.TransactionCacher { + return dataPool.NewCurrentBlockPool() + }, + }, EpochValidatorInfoCreator: valInfoCreator, ValidatorStatisticsProcessor: validatorsInfoCreator, EpochSystemSCProcessor: systemSCProcessor, diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 1fdd224a132..2ceb047073b 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -46,14 +46,16 @@ func createNodesCoordinator( ) shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ - NodesShard: numOfEligibleNodesPerShard, - NodesMeta: numOfMetaNodes, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: maxNodesConfig, - StakingV4EnableEpoch: stakingV4EnableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, + NodesShard: numOfEligibleNodesPerShard, + NodesMeta: numOfMetaNodes, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + MaxNodesEnableConfig: maxNodesConfig, + EnableEpochs: config.EnableEpochs{ + StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, + }, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index dba6e92b793..58603d31c02 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -16,16 +16,13 @@ var _ NodesShuffler = (*randHashShuffler)(nil) // NodesShufflerArgs defines the arguments required to create a nodes shuffler type NodesShufflerArgs struct { - NodesShard uint32 - NodesMeta uint32 - Hysteresis float32 - Adaptivity bool - ShuffleBetweenShards bool - MaxNodesEnableConfig []config.MaxNodesChangeConfig - BalanceWaitingListsEnableEpoch uint32 - WaitingListFixEnableEpoch uint32 - StakingV4EnableEpoch uint32 - StakingV4DistributeAuctionToWaitingEpoch uint32 + NodesShard uint32 + NodesMeta uint32 + Hysteresis float32 + Adaptivity bool + ShuffleBetweenShards bool + MaxNodesEnableConfig []config.MaxNodesChangeConfig + EnableEpochs config.EnableEpochs } type shuffleNodesArg struct { @@ -82,9 +79,9 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro var configs []config.MaxNodesChangeConfig log.Debug("hashValidatorShuffler: enable epoch for max nodes change", "epoch", args.MaxNodesEnableConfig) - log.Debug("hashValidatorShuffler: enable epoch for balance waiting lists", "epoch", args.BalanceWaitingListsEnableEpoch) - log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.StakingV4EnableEpoch) - log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.StakingV4DistributeAuctionToWaitingEpoch) + log.Debug("hashValidatorShuffler: enable epoch for balance waiting lists", "epoch", args.EnableEpochs.BalanceWaitingListsEnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.EnableEpochs.StakingV4EnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.EnableEpochs.StakingV4DistributeAuctionToWaitingEpoch) if args.MaxNodesEnableConfig != nil { configs = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) @@ -95,10 +92,10 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro rxs := &randHashShuffler{ shuffleBetweenShards: args.ShuffleBetweenShards, availableNodesConfigs: configs, - balanceWaitingListsEnableEpoch: args.BalanceWaitingListsEnableEpoch, - waitingListFixEnableEpoch: args.WaitingListFixEnableEpoch, - stakingV4DistributeAuctionToWaitingEpoch: args.StakingV4DistributeAuctionToWaitingEpoch, - stakingV4EnableEpoch: args.StakingV4EnableEpoch, + balanceWaitingListsEnableEpoch: args.EnableEpochs.BalanceWaitingListsEnableEpoch, + waitingListFixEnableEpoch: args.EnableEpochs.WaitingListFixEnableEpoch, + stakingV4DistributeAuctionToWaitingEpoch: args.EnableEpochs.StakingV4DistributeAuctionToWaitingEpoch, + stakingV4EnableEpoch: args.EnableEpochs.StakingV4EnableEpoch, } log.Debug("randHashShuffler: enable epoch for balance waiting list", "epoch", rxs.balanceWaitingListsEnableEpoch) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index 6f6398d5e56..92ec406bcc3 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -186,14 +186,15 @@ func testShuffledOut( func createHashShufflerInter() (*randHashShuffler, error) { shufflerArgs := &NodesShufflerArgs{ - NodesShard: eligiblePerShard, - NodesMeta: eligiblePerShard, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: true, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + NodesShard: eligiblePerShard, + NodesMeta: eligiblePerShard, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: true, + EnableEpochs: config.EnableEpochs{ + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, + }, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -203,14 +204,15 @@ func createHashShufflerInter() (*randHashShuffler, error) { func createHashShufflerIntraShards() (*randHashShuffler, error) { shufflerArgs := &NodesShufflerArgs{ - NodesShard: eligiblePerShard, - NodesMeta: eligiblePerShard, - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + NodesShard: eligiblePerShard, + NodesMeta: eligiblePerShard, + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + EnableEpochs: config.EnableEpochs{ + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, + }, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1333,7 +1335,9 @@ func testUpdateNodesAndCheckNumLeaving(t *testing.T, beforeFix bool) { NodesToShufflePerShard: uint32(numNodesToShuffle), }, }, - WaitingListFixEnableEpoch: uint32(waitingListFixEnableEpoch), + EnableEpochs: config.EnableEpochs{ + WaitingListFixEnableEpoch: uint32(waitingListFixEnableEpoch), + }, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1403,7 +1407,9 @@ func testUpdateNodeListsAndCheckWaitingList(t *testing.T, beforeFix bool) { NodesToShufflePerShard: uint32(numNodesToShuffle), }, }, - WaitingListFixEnableEpoch: uint32(waitingListFixEnableEpoch), + EnableEpochs: config.EnableEpochs{ + WaitingListFixEnableEpoch: uint32(waitingListFixEnableEpoch), + }, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -2379,14 +2385,15 @@ func TestRandHashShuffler_UpdateNodeLists_All(t *testing.T) { unstakeLeavingList, additionalLeavingList := prepareListsFromMaps(unstakeLeaving, additionalLeaving) shufflerArgs := &NodesShufflerArgs{ - NodesShard: uint32(eligiblePerShard), - NodesMeta: uint32(eligiblePerShard), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + NodesShard: uint32(eligiblePerShard), + NodesMeta: uint32(eligiblePerShard), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + EnableEpochs: config.EnableEpochs{ + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, + }, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) @@ -2728,14 +2735,15 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t } shufflerArgs := &NodesShufflerArgs{ - NodesShard: uint32(numEligiblePerShard), - NodesMeta: uint32(numEligiblePerShard), - Hysteresis: hysteresis, - Adaptivity: adaptivity, - ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + NodesShard: uint32(numEligiblePerShard), + NodesMeta: uint32(numEligiblePerShard), + Hysteresis: hysteresis, + Adaptivity: adaptivity, + ShuffleBetweenShards: shuffleBetweenShards, + EnableEpochs: config.EnableEpochs{ + StakingV4EnableEpoch: 443, + StakingV4DistributeAuctionToWaitingEpoch: 444, + }, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 40d423d43a2..ae3b82dda9c 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -19,6 +19,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/sharding/mock" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage/lrucache" @@ -97,8 +98,9 @@ func createArguments() ArgNodesCoordinator { Hysteresis: hysteresis, Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, - MaxNodesEnableConfig: nil, - StakingV4EnableEpoch: stakingV4Epoch, + EnableEpochs: config.EnableEpochs{ + StakingV4EnableEpoch: stakingV4Epoch, + }, } nodeShuffler, _ := NewHashValidatorsShuffler(shufflerArgs) diff --git a/testscommon/rewardsCreatorStub.go b/testscommon/rewardsCreatorStub.go index 787231f496f..662f5f76b55 100644 --- a/testscommon/rewardsCreatorStub.go +++ b/testscommon/rewardsCreatorStub.go @@ -5,7 +5,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/dataRetriever/dataPool" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" ) @@ -66,7 +65,7 @@ func (rcs *RewardsCreatorStub) GetLocalTxCache() epochStart.TransactionCacher { if rcs.GetLocalTxCacheCalled != nil { return rcs.GetLocalTxCacheCalled() } - return dataPool.NewCurrentBlockPool() + return nil } // CreateMarshalizedData - diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index d43a6ef1647..2bf8eed6547 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/ElrondNetwork/elrond-go-core/marshal" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/process" economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" @@ -15,6 +16,9 @@ import ( "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" ) +var log = logger.GetOrCreate("testscommon/stakingCommon") + +// RegisterValidatorKeys will register validator's staked key in the provided accounts db func RegisterValidatorKeys( accountsDB state.AccountsAdapter, ownerAddress []byte, @@ -25,9 +29,11 @@ func RegisterValidatorKeys( ) { AddValidatorData(accountsDB, ownerAddress, stakedKeys, totalStake, marshaller) AddStakingData(accountsDB, ownerAddress, rewardAddress, stakedKeys, marshaller) - _, _ = accountsDB.Commit() + _, err := accountsDB.Commit() + log.LogIfError(err) } +// AddValidatorData will add the validator's registered keys in the provided accounts db func AddValidatorData( accountsDB state.AccountsAdapter, ownerKey []byte, @@ -53,6 +59,7 @@ func AddValidatorData( _ = accountsDB.SaveAccount(validatorSC) } +// AddStakingData will add the owner's staked keys in the provided accounts db func AddStakingData( accountsDB state.AccountsAdapter, ownerAddress []byte, @@ -76,6 +83,7 @@ func AddStakingData( _ = accountsDB.SaveAccount(stakingSCAcc) } +// AddKeysToWaitingList will add the owner's provided bls keys in the staking queue list func AddKeysToWaitingList( accountsDB state.AccountsAdapter, waitingKeys [][]byte, @@ -152,6 +160,7 @@ func AddKeysToWaitingList( _ = accountsDB.SaveAccount(stakingSCAcc) } +// SaveOneKeyToWaitingList will add one bls key with its associated owner in the staking queue list func SaveOneKeyToWaitingList( accountsDB state.AccountsAdapter, waitingKey []byte, @@ -189,11 +198,13 @@ func SaveOneKeyToWaitingList( _ = accountsDB.SaveAccount(stakingSCAcc) } +// LoadUserAccount returns address's state.UserAccountHandler from the provided db func LoadUserAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { acc, _ := accountsDB.LoadAccount(address) return acc.(state.UserAccountHandler) } +// CreateEconomicsData returns an initialized process.EconomicsDataHandler func CreateEconomicsData() process.EconomicsDataHandler { maxGasLimitPerBlock := strconv.FormatUint(1500000000, 10) minGasPrice := strconv.FormatUint(10, 10) From 7ef95c4b6ad3c429d4bc14687bc985421c60b5f8 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 28 Apr 2022 11:59:35 +0300 Subject: [PATCH 210/958] FIX: saveState in indexHashedNodesCoordinator.go --- epochStart/bootstrap/interface.go | 2 +- epochStart/bootstrap/syncValidatorStatus.go | 2 +- .../nodesCoordinator/indexHashedNodesCoordinator.go | 6 +++--- .../indexHashedNodesCoordinatorRegistry.go | 12 +++++++----- .../indexHashedNodesCoordinatorRegistry_test.go | 12 ++++++------ .../nodesCoordinatorRegistryFactory.go | 6 ++++-- testscommon/shardingMocks/nodesCoordinatorStub.go | 2 +- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/epochStart/bootstrap/interface.go b/epochStart/bootstrap/interface.go index c6107f91826..77adc810bd2 100644 --- a/epochStart/bootstrap/interface.go +++ b/epochStart/bootstrap/interface.go @@ -25,7 +25,7 @@ type EpochStartMetaBlockInterceptorProcessor interface { // StartInEpochNodesCoordinator defines the methods to process and save nodesCoordinator information to storage type StartInEpochNodesCoordinator interface { EpochStartPrepare(metaHdr data.HeaderHandler, body data.BodyHandler) - NodesCoordinatorToRegistry() nodesCoordinator.NodesCoordinatorRegistryHandler + NodesCoordinatorToRegistry(epoch uint32) nodesCoordinator.NodesCoordinatorRegistryHandler ShardIdForEpoch(epoch uint32) (uint32, error) IsInterfaceNil() bool } diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index 5e90f87953d..6533f486a04 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -158,7 +158,7 @@ func (s *syncValidatorStatus) NodesConfigFromMetaBlock( return nil, 0, err } - nodesConfig := s.nodeCoordinator.NodesCoordinatorToRegistry() + nodesConfig := s.nodeCoordinator.NodesCoordinatorToRegistry(currMetaBlock.GetEpoch()) nodesConfig.SetCurrentEpoch(currMetaBlock.GetEpoch()) return nodesConfig, selfShardId, nil } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index b49f3f9ddd6..e5893d81ef0 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -161,7 +161,7 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed } ihnc.fillPublicKeyToValidatorMap() - err = ihnc.saveState(ihnc.savedStateKey) + err = ihnc.saveState(ihnc.savedStateKey, arguments.Epoch) if err != nil { log.Error("saving initial nodes coordinator config failed", "error", err.Error()) @@ -675,7 +675,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa } ihnc.fillPublicKeyToValidatorMap() - err = ihnc.saveState(randomness) + err = ihnc.saveState(randomness, newEpoch) if err != nil { log.Error("saving nodes coordinator config failed", "error", err.Error()) } @@ -861,7 +861,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartAction(hdr data.HeaderHandler needToRemove := epochToRemove >= 0 ihnc.currentEpoch = newEpoch - err := ihnc.saveState(ihnc.savedStateKey) + err := ihnc.saveState(ihnc.savedStateKey, newEpoch) if err != nil { log.Error("saving nodes coordinator config failed", "error", err.Error()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go index 24d73e758aa..12608327bd0 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go @@ -59,25 +59,27 @@ func displayNodesConfigInfo(config map[uint32]*epochNodesConfig) { } } -func (ihnc *indexHashedNodesCoordinator) saveState(key []byte) error { - registry := ihnc.NodesCoordinatorToRegistry() +func (ihnc *indexHashedNodesCoordinator) saveState(key []byte, epoch uint32) error { + registry := ihnc.NodesCoordinatorToRegistry(epoch) data, err := ihnc.nodesCoordinatorRegistryFactory.GetRegistryData(registry, ihnc.currentEpoch) if err != nil { return err } ncInternalKey := append([]byte(common.NodesCoordinatorRegistryKeyPrefix), key...) - log.Debug("saving nodes coordinator config", "key", ncInternalKey) + log.Debug("saving nodes coordinator config", "key", ncInternalKey, "epoch", epoch) return ihnc.bootStorer.Put(ncInternalKey, data) } // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry -func (ihnc *indexHashedNodesCoordinator) NodesCoordinatorToRegistry() NodesCoordinatorRegistryHandler { - if ihnc.currentEpoch >= ihnc.stakingV4EnableEpoch { +func (ihnc *indexHashedNodesCoordinator) NodesCoordinatorToRegistry(epoch uint32) NodesCoordinatorRegistryHandler { + if epoch >= ihnc.stakingV4EnableEpoch { + log.Debug("indexHashedNodesCoordinator.NodesCoordinatorToRegistry called with auction registry", "epoch", epoch) return ihnc.nodesCoordinatorToRegistryWithAuction() } + log.Debug("indexHashedNodesCoordinator.NodesCoordinatorToRegistry called with old registry", "epoch", epoch) return ihnc.nodesCoordinatorToOldRegistry() } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go index 3ff6825e9c8..de1b4f7a2f4 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go @@ -82,7 +82,7 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSave(t *testing.T) { expectedConfig := nodesCoordinator.nodesConfig[0] key := []byte("config") - err := nodesCoordinator.saveState(key) + err := nodesCoordinator.saveState(key, 0) assert.Nil(t, err) delete(nodesCoordinator.nodesConfig, 0) @@ -109,7 +109,7 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSaveWithStakingV4(t *testing. expectedConfig := nodesCoordinator.nodesConfig[stakingV4Epoch] key := []byte("config") - err := nodesCoordinator.saveState(key) + err := nodesCoordinator.saveState(key, stakingV4Epoch) assert.Nil(t, err) delete(nodesCoordinator.nodesConfig, 0) @@ -133,7 +133,7 @@ func TestIndexHashedNodesCoordinator_nodesCoordinatorToRegistryWithStakingV4(t * nodesCoordinator.nodesConfig[stakingV4Epoch].leavingMap = createDummyNodesMap(3, 0, string(common.LeavingList)) nodesCoordinator.nodesConfig[stakingV4Epoch].shuffledOutMap = createDummyNodesMap(3, 0, string(common.SelectedFromAuctionList)) - ncr := nodesCoordinator.NodesCoordinatorToRegistry() + ncr := nodesCoordinator.NodesCoordinatorToRegistry(stakingV4Epoch) nc := nodesCoordinator.nodesConfig assert.Equal(t, nodesCoordinator.currentEpoch, ncr.GetCurrentEpoch()) @@ -152,7 +152,7 @@ func TestIndexHashedNodesCoordinator_nodesCoordinatorToRegistry(t *testing.T) { args := createArguments() nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) - ncr := nodesCoordinator.NodesCoordinatorToRegistry() + ncr := nodesCoordinator.NodesCoordinatorToRegistry(args.Epoch) nc := nodesCoordinator.nodesConfig assert.Equal(t, nodesCoordinator.currentEpoch, ncr.GetCurrentEpoch()) @@ -167,7 +167,7 @@ func TestIndexHashedNodesCoordinator_nodesCoordinatorToRegistry(t *testing.T) { func TestIndexHashedNodesCoordinator_registryToNodesCoordinator(t *testing.T) { args := createArguments() nodesCoordinator1, _ := NewIndexHashedNodesCoordinator(args) - ncr := nodesCoordinator1.NodesCoordinatorToRegistry() + ncr := nodesCoordinator1.NodesCoordinatorToRegistry(args.Epoch) args = createArguments() nodesCoordinator2, _ := NewIndexHashedNodesCoordinator(args) @@ -201,7 +201,7 @@ func TestIndexHashedNodesCooridinator_nodesCoordinatorToRegistryLimitNumEpochsIn } } - ncr := nodesCoordinator.NodesCoordinatorToRegistry() + ncr := nodesCoordinator.NodesCoordinatorToRegistry(args.Epoch) nc := nodesCoordinator.nodesConfig require.Equal(t, nodesCoordinator.currentEpoch, ncr.GetCurrentEpoch()) diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index aecef404e24..4a988571547 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -48,17 +48,19 @@ func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff //return createOldRegistry(buff) registry, err := ncf.createRegistryWithAuction(buff) if err == nil { + log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created registry with auction") return registry, nil } - + log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created old registry") return createOldRegistry(buff) } func (ncf *nodesCoordinatorRegistryFactory) GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) { if epoch >= ncf.stakingV4EnableEpoch { + log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with auction", "epoch", epoch) return ncf.marshaller.Marshal(registry) } - + log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with old json", "epoch", epoch) return json.Marshal(registry) } diff --git a/testscommon/shardingMocks/nodesCoordinatorStub.go b/testscommon/shardingMocks/nodesCoordinatorStub.go index c7abf375cbc..70ea4b61577 100644 --- a/testscommon/shardingMocks/nodesCoordinatorStub.go +++ b/testscommon/shardingMocks/nodesCoordinatorStub.go @@ -20,7 +20,7 @@ type NodesCoordinatorStub struct { } // NodesCoordinatorToRegistry - -func (ncm *NodesCoordinatorStub) NodesCoordinatorToRegistry() nodesCoordinator.NodesCoordinatorRegistryHandler { +func (ncm *NodesCoordinatorStub) NodesCoordinatorToRegistry(uint32) nodesCoordinator.NodesCoordinatorRegistryHandler { return nil } From 063a1c35243f229bbcce5712240cec7c67a48568 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 28 Apr 2022 12:51:40 +0300 Subject: [PATCH 211/958] FIX: Simplify logic in calcNormRand --- epochStart/metachain/systemSCs.go | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index a21bcc8b004..3763893a29c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -274,20 +274,16 @@ func (s *systemSCProcessor) getValidatorTopUpMap(validators []state.ValidatorInf } func calcNormRand(randomness []byte, expectedLen int) []byte { - lenRand := len(randomness) - minLen := core.MinInt(expectedLen, lenRand) - maxLen := core.MaxInt(expectedLen, lenRand) + rand := randomness + randLen := len(rand) - rnd := randomness - if expectedLen > lenRand { - repeatedCt := maxLen/minLen + 1 - rnd = bytes.Repeat(randomness, repeatedCt) - rnd = rnd[:maxLen] - } else { - rnd = rnd[:minLen] + if expectedLen > randLen { + repeatedCt := expectedLen/randLen + 1 + rand = bytes.Repeat(randomness, repeatedCt) } - return rnd + rand = rand[:expectedLen] + return rand } func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { From c1f8aec7259e96c2f0f874b0018ab821f8b0513a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 28 Apr 2022 14:47:28 +0300 Subject: [PATCH 212/958] FIX: Merge conflict --- .../vm/staking/componentsHolderCreator.go | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index f65a5fd84bd..0c1a5f6349b 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -9,7 +9,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/endProcess" "github.com/ElrondNetwork/elrond-go-core/data/typeConverters/uint64ByteSlice" - "github.com/ElrondNetwork/elrond-go-core/hashing" "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" @@ -67,6 +66,7 @@ func createCoreComponents() factory.CoreComponentsHolder { EconomicsDataField: stakingcommon.CreateEconomicsData(), ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), NodeTypeProviderField: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), + ProcessStatusHandlerInternal: statusHandler.NewProcessStatusHandler(), } } @@ -130,10 +130,8 @@ func createStatusComponents() factory.StatusComponentsHolder { func createStateComponents(coreComponents factory.CoreComponentsHolder) factory.StateComponentsHandler { trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) - hasher := coreComponents.Hasher() - marshaller := coreComponents.InternalMarshalizer() - userAccountsDB := createAccountsDB(hasher, marshaller, stateFactory.NewAccountCreator(), trieFactoryManager) - peerAccountsDB := createAccountsDB(hasher, marshaller, stateFactory.NewPeerAccountCreator(), trieFactoryManager) + userAccountsDB := createAccountsDB(coreComponents, stateFactory.NewAccountCreator(), trieFactoryManager) + peerAccountsDB := createAccountsDB(coreComponents, stateFactory.NewPeerAccountCreator(), trieFactoryManager) return &testscommon.StateComponentsMock{ PeersAcc: peerAccountsDB, @@ -142,14 +140,23 @@ func createStateComponents(coreComponents factory.CoreComponentsHolder) factory. } func createAccountsDB( - hasher hashing.Hasher, - marshalizer marshal.Marshalizer, + coreComponents factory.CoreComponentsHolder, accountFactory state.AccountFactory, trieStorageManager common.StorageManager, ) *state.AccountsDB { - tr, _ := trie.NewTrie(trieStorageManager, marshalizer, hasher, 5) - ewl, _ := evictionWaitingList.NewEvictionWaitingList(10, testscommon.NewMemDbMock(), marshalizer) + tr, _ := trie.NewTrie(trieStorageManager, coreComponents.InternalMarshalizer(), coreComponents.Hasher(), 5) + ewl, _ := evictionWaitingList.NewEvictionWaitingList(10, testscommon.NewMemDbMock(), coreComponents.InternalMarshalizer()) spm, _ := storagePruningManager.NewStoragePruningManager(ewl, 10) - adb, _ := state.NewAccountsDB(tr, hasher, marshalizer, accountFactory, spm, common.Normal) + + argsAccountsDb := state.ArgsAccountsDB{ + Trie: tr, + Hasher: coreComponents.Hasher(), + Marshaller: coreComponents.InternalMarshalizer(), + AccountFactory: accountFactory, + StoragePruningManager: spm, + ProcessingMode: common.Normal, + ProcessStatusHandler: coreComponents.ProcessStatusHandler(), + } + adb, _ := state.NewAccountsDB(argsAccountsDb) return adb } From a98dceed5d33fc90648895294a16f1eb94a27946 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 29 Apr 2022 10:17:42 +0300 Subject: [PATCH 213/958] FIX: Build after merge --- process/block/postprocess/feeHandler_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/process/block/postprocess/feeHandler_test.go b/process/block/postprocess/feeHandler_test.go index d36f1d3b376..d3e80f713ce 100644 --- a/process/block/postprocess/feeHandler_test.go +++ b/process/block/postprocess/feeHandler_test.go @@ -88,7 +88,7 @@ func TestFeeHandler_RevertFees(t *testing.T) { func TestFeeHandler_CompleteRevertFeesUserTxs(t *testing.T) { t.Parallel() - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() userTxHashes := [][]byte{[]byte("txHash1"), []byte("txHash2"), []byte("txHash3")} originalTxHashes := [][]byte{[]byte("origTxHash1"), []byte("origTxHash2"), []byte("origTxHash3")} @@ -110,7 +110,7 @@ func TestFeeHandler_PartialRevertFeesUserTxs(t *testing.T) { originalTxHashes := [][]byte{[]byte("origTxHash1"), []byte("origTxHash2"), []byte("origTxHash3"), []byte("userTxHash4")} t.Run("revert partial originalTxs", func(t *testing.T) { - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(1000), big.NewInt(100), userTxHashes[0], originalTxHashes[0]) feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(100), big.NewInt(10), userTxHashes[1], originalTxHashes[1]) feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(10), big.NewInt(1), userTxHashes[2], originalTxHashes[2]) @@ -124,7 +124,7 @@ func TestFeeHandler_PartialRevertFeesUserTxs(t *testing.T) { require.Equal(t, big.NewInt(200), devFees) }) t.Run("revert all userTxs", func(t *testing.T) { - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(1000), big.NewInt(100), userTxHashes[0], originalTxHashes[0]) feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(100), big.NewInt(10), userTxHashes[1], originalTxHashes[1]) feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(10), big.NewInt(1), userTxHashes[2], originalTxHashes[2]) @@ -138,7 +138,7 @@ func TestFeeHandler_PartialRevertFeesUserTxs(t *testing.T) { require.Equal(t, big.NewInt(200), devFees) }) t.Run("revert partial userTxs", func(t *testing.T) { - feeHandler, _ := postprocess.NewFeeAccumulator() + feeHandler := postprocess.NewFeeAccumulator() feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(1000), big.NewInt(100), userTxHashes[0], originalTxHashes[0]) feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(100), big.NewInt(10), userTxHashes[1], originalTxHashes[1]) feeHandler.ProcessTransactionFeeRelayedUserTx(big.NewInt(10), big.NewInt(1), userTxHashes[2], originalTxHashes[2]) From 1574f53800e88fa50092c2f1eb7d0e9ef1ec5c4a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 29 Apr 2022 13:09:14 +0300 Subject: [PATCH 214/958] FIX: Bug in maxNumNodesUpdate in legacySystemSCs.go --- epochStart/metachain/legacySystemSCs.go | 6 +- epochStart/metachain/systemSCs_test.go | 94 +++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 95a3714b4da..f3620f186a3 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -1359,16 +1359,14 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) - // TODO: There is a bug: in case of node restart, state in legacySystemSC - // will be with epoch = startInEpoch after restart; these values are correctly - // stored only in sc state, so values printed and used here are obsolete s.flagChangeMaxNodesEnabled.SetValue(false) for _, maxNodesConfig := range s.maxNodesEnableConfig { if epoch == maxNodesConfig.EpochEnable { s.flagChangeMaxNodesEnabled.SetValue(true) + } + if epoch >= maxNodesConfig.EpochEnable { s.maxNodes = maxNodesConfig.MaxNumNodes s.currentNodesEnableConfig = maxNodesConfig - break } } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 939a381eeb1..e226c819f6e 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1961,6 +1961,100 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } +func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + nodesConfigEpoch0 := config.MaxNodesChangeConfig{ + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + } + nodesConfigEpoch1 := config.MaxNodesChangeConfig{ + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + } + nodesConfigEpoch6 := config.MaxNodesChangeConfig{ + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 1, + } + + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{ + nodesConfigEpoch0, + nodesConfigEpoch1, + nodesConfigEpoch6, + } + + validatorsInfoMap := state.NewShardValidatorsInfoMap() + s, _ := NewSystemSCProcessor(args) + + s.EpochConfirmed(0, 0) + require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) + err := s.processLegacy(validatorsInfoMap, 0, 0) + require.Nil(t, err) + require.Equal(t, nodesConfigEpoch0, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch0.MaxNumNodes, s.maxNodes) + + s.EpochConfirmed(1, 1) + require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, 1, 1) + require.Nil(t, err) + require.Equal(t, nodesConfigEpoch1, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) + + for epoch := uint32(2); epoch <= 5; epoch++ { + s.EpochConfirmed(epoch, uint64(epoch)) + require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, uint64(epoch), epoch) + require.Nil(t, err) + require.Equal(t, nodesConfigEpoch1, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) + } + + // simulate restart + s.EpochConfirmed(0, 0) + s.EpochConfirmed(5, 5) + require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, 5, 5) + require.Nil(t, err) + require.Equal(t, nodesConfigEpoch1, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) + + s.EpochConfirmed(6, 6) + require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, 6, 6) + require.Nil(t, err) + require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) + + // simulate restart + s.EpochConfirmed(0, 0) + s.EpochConfirmed(6, 6) + require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, 6, 6) + require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) + + for epoch := uint32(7); epoch <= 20; epoch++ { + s.EpochConfirmed(epoch, uint64(epoch)) + require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, uint64(epoch), epoch) + require.Nil(t, err) + require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) + } + + // simulate restart + s.EpochConfirmed(0, 0) + s.EpochConfirmed(21, 21) + require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) + err = s.processLegacy(validatorsInfoMap, 21, 21) + require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) + require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) +} + func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { for _, pubKey := range stakedPubKeys { topUpPerNode, err := s.GetNodeStakedTopUp(pubKey) From 0ade9ea703dfa3da1da7c7decc5fa5d2d6bda83e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 29 Apr 2022 14:48:23 +0300 Subject: [PATCH 215/958] FIX: Do some fixes --- epochStart/bootstrap/process_test.go | 1 - .../bootstrap/syncValidatorStatus_test.go | 2 - .../metachain/stakingDataProvider_test.go | 7 +-- epochStart/metachain/systemSCs_test.go | 2 +- factory/bootstrapComponents.go | 1 - integrationTests/consensus/testInitializer.go | 2 - .../startInEpoch/startInEpoch_test.go | 1 - integrationTests/nodesCoordinatorFactory.go | 3 -- integrationTests/testP2PNode.go | 2 - .../vm/staking/componentsHolderCreator.go | 7 ++- .../indexHashedNodesCoordinator_test.go | 4 +- sharding/nodesCoordinator/interface.go | 1 - .../nodesCoordinatorRegistryFactory.go | 53 ++++++------------- .../nodesCoordRegistryFactoryMock.go | 5 -- 14 files changed, 26 insertions(+), 65 deletions(-) diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index 10e46b67d4a..e60629914d1 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -92,7 +92,6 @@ func createMockEpochStartBootstrapArgs( generalCfg := testscommon.GetGeneralConfig() nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &marshal.GogoProtoMarshalizer{}, - &epochNotifier.EpochNotifierStub{}, 444, ) return ArgsEpochStartBootstrap{ diff --git a/epochStart/bootstrap/syncValidatorStatus_test.go b/epochStart/bootstrap/syncValidatorStatus_test.go index 1b1e09eeee6..ee1d3bb8500 100644 --- a/epochStart/bootstrap/syncValidatorStatus_test.go +++ b/epochStart/bootstrap/syncValidatorStatus_test.go @@ -15,7 +15,6 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" epochStartMocks "github.com/ElrondNetwork/elrond-go/testscommon/bootstrapMocks/epochStart" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" @@ -243,7 +242,6 @@ func TestSyncValidatorStatus_getPeerBlockBodyForMeta(t *testing.T) { func getSyncValidatorStatusArgs() ArgsNewSyncValidatorStatus { nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &mock.MarshalizerMock{}, - &epochNotifier.EpochNotifierStub{}, 444, ) diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index ffa3c0c3176..beb3a118ed1 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -238,7 +238,6 @@ func TestStakingDataProvider_ComputeUnQualifiedNodes(t *testing.T) { } func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4ReceivedNewListNode(t *testing.T) { - valInfo := state.NewShardValidatorsInfoMap() v0 := &state.ValidatorInfo{ PublicKey: []byte("blsKey0"), List: string(common.EligibleList), @@ -254,6 +253,8 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4ReceivedNewList List: string(common.AuctionList), RewardAddress: []byte("address1"), } + + valInfo := state.NewShardValidatorsInfoMap() _ = valInfo.Add(v0) _ = valInfo.Add(v1) _ = valInfo.Add(v2) @@ -305,8 +306,6 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFunds(t *t } func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithStakingV4(t *testing.T) { - valInfo := state.NewShardValidatorsInfoMap() - owner := "address0" v0 := &state.ValidatorInfo{ PublicKey: []byte("blsKey0"), @@ -318,6 +317,8 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithS List: string(common.AuctionList), RewardAddress: []byte(owner), } + + valInfo := state.NewShardValidatorsInfoMap() _ = valInfo.Add(v0) _ = valInfo.Add(v1) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e226c819f6e..2016f0c92eb 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2047,7 +2047,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar } // simulate restart - s.EpochConfirmed(0, 0) + s.EpochConfirmed(1, 1) s.EpochConfirmed(21, 21) require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 21, 21) diff --git a/factory/bootstrapComponents.go b/factory/bootstrapComponents.go index fe8e388a997..c5d7c5bbadb 100644 --- a/factory/bootstrapComponents.go +++ b/factory/bootstrapComponents.go @@ -164,7 +164,6 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory( bcf.coreComponents.InternalMarshalizer(), - bcf.coreComponents.EpochNotifier(), bcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, ) if err != nil { diff --git a/integrationTests/consensus/testInitializer.go b/integrationTests/consensus/testInitializer.go index ae9f61bc022..da966024d83 100644 --- a/integrationTests/consensus/testInitializer.go +++ b/integrationTests/consensus/testInitializer.go @@ -49,7 +49,6 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" @@ -513,7 +512,6 @@ func createNodes( nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - &epochNotifier.EpochNotifierStub{}, integrationTests.StakingV4Epoch, ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index c299de3dd7d..452236bc07b 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -211,7 +211,6 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - &epochNotifierMock.EpochNotifierStub{}, 444, ) argsBootstrapHandler := bootstrap.ArgsEpochStartBootstrap{ diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 46d55924955..bf140555046 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -9,7 +9,6 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/storage" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" ) @@ -53,7 +52,6 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(nodeShufflerArgs) nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( TestMarshalizer, - &epochNotifier.EpochNotifierStub{}, StakingV4Epoch, ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ @@ -111,7 +109,6 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( TestMarshalizer, - &epochNotifier.EpochNotifierStub{}, StakingV4Epoch, ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index 84eb1e68fb9..8c0ba72053f 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -28,7 +28,6 @@ import ( "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage/storageUnit" "github.com/ElrondNetwork/elrond-go/testscommon" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" @@ -332,7 +331,6 @@ func CreateNodesWithTestP2PNodes( cache, _ := storageUnit.NewCache(cacherCfg) nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - &epochNotifier.EpochNotifierStub{}, StakingV4Epoch, ) for shardId, validatorList := range validatorsMap { diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 0c1a5f6349b..9b383df5d42 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -47,7 +47,7 @@ func createComponentHolders(numOfShards uint32) ( statusComponents := createStatusComponents() stateComponents := createStateComponents(coreComponents) dataComponents := createDataComponents(coreComponents, numOfShards) - boostrapComponents := createBootstrapComponents(coreComponents, numOfShards) + boostrapComponents := createBootstrapComponents(coreComponents.InternalMarshalizer(), numOfShards) return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents } @@ -99,13 +99,12 @@ func createDataComponents(coreComponents factory.CoreComponentsHolder, numOfShar } func createBootstrapComponents( - coreComponents factory.CoreComponentsHolder, + marshaller marshal.Marshalizer, numOfShards uint32, ) factory.BootstrapComponentsHolder { shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) ncr, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( - coreComponents.InternalMarshalizer(), - coreComponents.EpochNotifier(), + marshaller, stakingV4EnableEpoch, ) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index d616a7c99c6..e52b86f0157 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -19,12 +19,11 @@ import ( "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/sharding/mock" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/storage/lrucache" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/stretchr/testify/assert" @@ -83,7 +82,6 @@ func isStringSubgroup(a []string, b []string) bool { func createNodesCoordinatorRegistryFactory() NodesCoordinatorRegistryFactory { ncf, _ := NewNodesCoordinatorRegistryFactory( &marshal.GogoProtoMarshalizer{}, - &epochNotifier.EpochNotifierStub{}, stakingV4Epoch, ) return ncf diff --git a/sharding/nodesCoordinator/interface.go b/sharding/nodesCoordinator/interface.go index 4c747cd1d39..04f1f2f86ce 100644 --- a/sharding/nodesCoordinator/interface.go +++ b/sharding/nodesCoordinator/interface.go @@ -157,7 +157,6 @@ type NodesCoordinatorRegistryHandler interface { type NodesCoordinatorRegistryFactory interface { CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) - EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool } diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index 4a988571547..8e7429a7409 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -3,49 +3,35 @@ package nodesCoordinator import ( "encoding/json" - "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/marshal" ) type nodesCoordinatorRegistryFactory struct { - stakingV4EnableEpoch uint32 - flagStakingV4 atomic.Flag marshaller marshal.Marshalizer + stakingV4EnableEpoch uint32 } // NewNodesCoordinatorRegistryFactory creates a nodes coordinator registry factory which will create a // NodesCoordinatorRegistryHandler from a buffer depending on the epoch func NewNodesCoordinatorRegistryFactory( marshaller marshal.Marshalizer, - notifier EpochNotifier, stakingV4EnableEpoch uint32, ) (*nodesCoordinatorRegistryFactory, error) { if check.IfNil(marshaller) { return nil, ErrNilMarshalizer } - if check.IfNil(notifier) { - return nil, ErrNilEpochNotifier - } - - log.Debug("nodesCoordinatorRegistryFactory: staking v4 enable epoch", "epoch", stakingV4EnableEpoch) - ncf := &nodesCoordinatorRegistryFactory{ + return &nodesCoordinatorRegistryFactory{ marshaller: marshaller, stakingV4EnableEpoch: stakingV4EnableEpoch, - } - notifier.RegisterNotifyHandler(ncf) - return ncf, nil + }, nil } // CreateNodesCoordinatorRegistry creates a NodesCoordinatorRegistryHandler depending on the buffer. Old version uses // NodesCoordinatorRegistry with a json marshaller; while the new version(from staking v4) uses NodesCoordinatorRegistryWithAuction // with proto marshaller func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) { - //if ncf.flagStakingV4.IsSet() { - // return ncf.createRegistryWithAuction(buff) - //} - //return createOldRegistry(buff) registry, err := ncf.createRegistryWithAuction(buff) if err == nil { log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created registry with auction") @@ -55,13 +41,14 @@ func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff return createOldRegistry(buff) } -func (ncf *nodesCoordinatorRegistryFactory) GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) { - if epoch >= ncf.stakingV4EnableEpoch { - log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with auction", "epoch", epoch) - return ncf.marshaller.Marshal(registry) +func (ncf *nodesCoordinatorRegistryFactory) createRegistryWithAuction(buff []byte) (*NodesCoordinatorRegistryWithAuction, error) { + registry := &NodesCoordinatorRegistryWithAuction{} + err := ncf.marshaller.Unmarshal(registry, buff) + if err != nil { + return nil, err } - log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with old json", "epoch", epoch) - return json.Marshal(registry) + + return registry, nil } func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { @@ -74,23 +61,17 @@ func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { return registry, nil } -func (ncf *nodesCoordinatorRegistryFactory) createRegistryWithAuction(buff []byte) (*NodesCoordinatorRegistryWithAuction, error) { - registry := &NodesCoordinatorRegistryWithAuction{} - err := ncf.marshaller.Unmarshal(registry, buff) - if err != nil { - return nil, err +// GetRegistryData returns the registry data as buffer. Old version uses json marshaller, while new version uses proto marshaller +func (ncf *nodesCoordinatorRegistryFactory) GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) { + if epoch >= ncf.stakingV4EnableEpoch { + log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with auction after staking v4", "epoch", epoch) + return ncf.marshaller.Marshal(registry) } - - return registry, nil + log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with old json before staking v4", "epoch", epoch) + return json.Marshal(registry) } // IsInterfaceNil checks if the underlying pointer is nil func (ncf *nodesCoordinatorRegistryFactory) IsInterfaceNil() bool { return ncf == nil } - -// EpochConfirmed is called whenever a new epoch is confirmed -func (ncf *nodesCoordinatorRegistryFactory) EpochConfirmed(epoch uint32, _ uint64) { - ncf.flagStakingV4.SetValue(epoch >= ncf.stakingV4EnableEpoch) - log.Debug("nodesCoordinatorRegistryFactory: staking v4", "enabled", ncf.flagStakingV4.IsSet()) -} diff --git a/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go b/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go index b511b7434ee..cceb0232680 100644 --- a/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go +++ b/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go @@ -26,11 +26,6 @@ func (ncr *NodesCoordinatorRegistryFactoryMock) GetRegistryData(registry nodesCo return json.Marshal(registry) } -// EpochConfirmed - -func (ncr *NodesCoordinatorRegistryFactoryMock) EpochConfirmed(_ uint32, _ uint64) { - -} - // IsInterfaceNil - func (ncr *NodesCoordinatorRegistryFactoryMock) IsInterfaceNil() bool { return ncr == nil From 4366a7d77aee1dc54f9d7e61dfe2dfdf04d1b788 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 29 Apr 2022 14:48:52 +0300 Subject: [PATCH 216/958] FIX: Add missed file --- integrationTests/testProcessorNodeWithMultisigner.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 4b240e080d1..3aadd1bcc4a 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -32,7 +32,6 @@ import ( "github.com/ElrondNetwork/elrond-go/storage/storageUnit" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" ) @@ -494,7 +493,6 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - &epochNotifier.EpochNotifierStub{}, StakingV4Epoch, ) completeNodesList := make([]Connectable, 0) @@ -599,7 +597,6 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - &epochNotifier.EpochNotifierStub{}, StakingV4Epoch, ) completeNodesList := make([]Connectable, 0) From 43162712380643bf3a3cd609016d0f96fcbde152 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 29 Apr 2022 15:37:10 +0300 Subject: [PATCH 217/958] FIX: Gas schedule --- cmd/node/config/gasSchedules/gasScheduleV1.toml | 2 +- cmd/node/config/gasSchedules/gasScheduleV4.toml | 1 + cmd/node/config/gasSchedules/gasScheduleV5.toml | 1 + cmd/node/config/gasSchedules/gasScheduleV6.toml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/node/config/gasSchedules/gasScheduleV1.toml b/cmd/node/config/gasSchedules/gasScheduleV1.toml index a6f147733f8..f1b637a2863 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV1.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV1.toml @@ -39,7 +39,7 @@ ValidatorToDelegation = 500000000 GetAllNodeStates = 100000000 FixWaitingListSize = 500000000 -LiquidStakingOps = 10000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV4.toml b/cmd/node/config/gasSchedules/gasScheduleV4.toml index 5b07be7b81a..dc6fef1092f 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV4.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV4.toml @@ -39,6 +39,7 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV5.toml b/cmd/node/config/gasSchedules/gasScheduleV5.toml index f2fbe2e463c..8101ecf38bc 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV5.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV5.toml @@ -39,6 +39,7 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV6.toml b/cmd/node/config/gasSchedules/gasScheduleV6.toml index 4e1cf9ff27b..4252a1b5ad8 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV6.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV6.toml @@ -39,6 +39,7 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 From 8338304428074c939c33dff3ce0ca0454324d4fb Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 2 May 2022 13:00:58 +0300 Subject: [PATCH 218/958] FIX: Flags inconsistency between systemSCs.go and staking.go --- epochStart/metachain/legacySystemSCs.go | 7 +- epochStart/metachain/systemSCs.go | 2 + vm/systemSmartContracts/staking.go | 12 ++-- vm/systemSmartContracts/stakingWaitingList.go | 8 +-- vm/systemSmartContracts/staking_test.go | 67 ++++++++++++++++--- 5 files changed, 74 insertions(+), 22 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index f3620f186a3..91d64a5363b 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -57,7 +57,6 @@ type legacySystemSCProcessor struct { esdtEnableEpoch uint32 saveJailedAlwaysEnableEpoch uint32 stakingV4InitEnableEpoch uint32 - stakingV4EnableEpoch uint32 flagSwitchJailedWaiting atomic.Flag flagHystNodesEnabled atomic.Flag @@ -103,7 +102,6 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, - stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("legacySystemSC: enable epoch for switch jail waiting", "epoch", legacy.switchEnableEpoch) @@ -114,7 +112,6 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega log.Debug("legacySystemSC: enable epoch for correct last unjailed", "epoch", legacy.correctLastUnJailEpoch) log.Debug("legacySystemSC: enable epoch for save jailed always", "epoch", legacy.saveJailedAlwaysEnableEpoch) log.Debug("legacySystemSC: enable epoch for initializing staking v4", "epoch", legacy.stakingV4InitEnableEpoch) - log.Debug("legacySystemSC: enable epoch for staking v4", "epoch", legacy.stakingV4EnableEpoch) legacy.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(legacy.maxNodesEnableConfig, args.MaxNodesEnableConfig) @@ -1353,7 +1350,7 @@ func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBloc } func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { - s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch && epoch < s.stakingV4InitEnableEpoch) + s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch && epoch <= s.stakingV4InitEnableEpoch) log.Debug("legacySystemSC: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers @@ -1389,7 +1386,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagCorrectLastUnjailedEnabled.SetValue(epoch == s.correctLastUnJailEpoch) log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) - s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch && epoch < s.stakingV4EnableEpoch) + s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch && epoch <= s.stakingV4InitEnableEpoch) log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) s.flagESDTEnabled.SetValue(epoch == s.esdtEnableEpoch) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 0a5d9a601de..fb700dba120 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -54,6 +54,7 @@ type systemSCProcessor struct { governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 + stakingV4EnableEpoch uint32 flagGovernanceEnabled atomic.Flag flagBuiltInOnMetaEnabled atomic.Flag @@ -76,6 +77,7 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr legacySystemSCProcessor: legacy, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, + stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, } log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index ea8f1058bec..b3502f1c097 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -47,11 +47,12 @@ type stakingSC struct { flagCorrectFirstQueued atomic.Flag flagCorrectJailedNotUnstakedEmptyQueue atomic.Flag flagStakingV4 atomic.Flag + flagStakingV4Init atomic.Flag correctJailedNotUnstakedEmptyQueueEpoch uint32 correctFirstQueuedEpoch uint32 correctLastUnjailedEpoch uint32 stakingV2Epoch uint32 - stakingV4Epoch uint32 + stakingV4InitEpoch uint32 walletAddressLen int mutExecution sync.RWMutex minNodePrice *big.Int @@ -131,7 +132,7 @@ func NewStakingSmartContract( validatorToDelegationEnableEpoch: args.EpochConfig.EnableEpochs.ValidatorToDelegationEnableEpoch, correctFirstQueuedEpoch: args.EpochConfig.EnableEpochs.CorrectFirstQueuedEpoch, correctJailedNotUnstakedEmptyQueueEpoch: args.EpochConfig.EnableEpochs.CorrectJailedNotUnstakedEmptyQueueEpoch, - stakingV4Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + stakingV4InitEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, } log.Debug("staking: enable epoch for stake", "epoch", reg.enableStakingEpoch) log.Debug("staking: enable epoch for staking v2", "epoch", reg.stakingV2Epoch) @@ -139,7 +140,7 @@ func NewStakingSmartContract( log.Debug("staking: enable epoch for validator to delegation", "epoch", reg.validatorToDelegationEnableEpoch) log.Debug("staking: enable epoch for correct first queued", "epoch", reg.correctFirstQueuedEpoch) log.Debug("staking: enable epoch for correct jailed not unstaked with empty queue", "epoch", reg.correctJailedNotUnstakedEmptyQueueEpoch) - log.Debug("staking: enable epoch for staking v4", "epoch", reg.stakingV4Epoch) + log.Debug("staking: enable epoch for staking v4 init", "epoch", reg.stakingV4InitEpoch) var conversionOk bool reg.stakeValue, conversionOk = big.NewInt(0).SetString(args.StakingSCConfig.GenesisNodePrice, conversionBase) @@ -1187,7 +1188,10 @@ func (s *stakingSC) EpochConfirmed(epoch uint32, _ uint64) { s.flagCorrectJailedNotUnstakedEmptyQueue.SetValue(epoch >= s.correctJailedNotUnstakedEmptyQueueEpoch) log.Debug("stakingSC: correct jailed not unstaked with empty queue", "enabled", s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet()) - s.flagStakingV4.SetValue(epoch >= s.stakingV4Epoch) + s.flagStakingV4Init.SetValue(epoch == s.stakingV4InitEpoch) + log.Debug("stakingSC: staking v4 init", "enabled", s.flagStakingV4Init.IsSet()) + + s.flagStakingV4.SetValue(epoch >= s.stakingV4InitEpoch) log.Debug("stakingSC: staking v4", "enabled", s.flagStakingV4.IsSet()) } diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index 577bf0ce020..a9909bebf87 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -458,7 +458,7 @@ func createWaitingListKey(blsKey []byte) []byte { } func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { + if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -642,7 +642,7 @@ func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) // backward compatibility return vmcommon.UserError } - if s.flagStakingV4.IsSet() { + if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -730,7 +730,7 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() { + if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -806,7 +806,7 @@ func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcom s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() { + if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 6e5de5dac74..442dc6452a0 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -57,9 +57,10 @@ func createMockStakingScArgumentsWithSystemScAddresses( EpochNotifier: &mock.EpochNotifierStub{}, EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 10, - StakeEnableEpoch: 0, - StakingV4EnableEpoch: 445, + StakingV2EnableEpoch: 10, + StakeEnableEpoch: 0, + StakingV4InitEnableEpoch: 444, + StakingV4EnableEpoch: 445, }, }, } @@ -1009,7 +1010,7 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("addr0"), []byte("addr0"), vmcommon.Ok) requireRegisteredNodes(t, stakingSmartContract, eei, 4, 5) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) for i := 5; i < 10; i++ { idxStr := strconv.Itoa(i) addr := []byte("addr" + idxStr) @@ -1047,7 +1048,7 @@ func TestStakingSc_UnStakeNodeFromWaitingListAfterStakingV4ShouldError(t *testin doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2")) requireRegisteredNodes(t, stakingSmartContract, eei, 2, 1) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) eei.returnMessage = "" doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2"), vmcommon.ExecutionFailed) @@ -3347,8 +3348,9 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { args.Eei = eei stakingSmartContract, _ := NewStakingSmartContract(args) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) + // Functions which are not allowed starting STAKING V4 INIT arguments := CreateVmContractCallInput() arguments.Function = "getQueueIndex" retCode := stakingSmartContract.Execute(arguments) @@ -3362,25 +3364,48 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() - arguments.Function = "switchJailedWithWaiting" + arguments.Function = "fixWaitingListQueueSize" retCode = stakingSmartContract.Execute(arguments) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() - arguments.Function = "resetLastUnJailedFromQueue" + arguments.Function = "addMissingNodeToQueue" retCode = stakingSmartContract.Execute(arguments) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + // Functions which are allowed to be called by systemSC at the end of the epoch in epoch = STAKING V4 INIT + eei.CleanCache() + arguments.Function = "switchJailedWithWaiting" + retCode = stakingSmartContract.Execute(arguments) + require.True(t, strings.Contains(eei.returnMessage, "function not allowed to be called by address")) + + eei.CleanCache() + arguments.Function = "resetLastUnJailedFromQueue" + retCode = stakingSmartContract.Execute(arguments) + require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) + eei.CleanCache() arguments.Function = "stakeNodesFromQueue" retCode = stakingSmartContract.Execute(arguments) + require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) + + eei.CleanCache() + arguments.Function = "cleanAdditionalQueue" + retCode = stakingSmartContract.Execute(arguments) + require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) + + stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + // All functions from above are not allowed anymore starting STAKING V4 epoch + eei.CleanCache() + arguments.Function = "getQueueIndex" + retCode = stakingSmartContract.Execute(arguments) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) eei.CleanCache() - arguments.Function = "cleanAdditionalQueue" + arguments.Function = "getQueueSize" retCode = stakingSmartContract.Execute(arguments) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) @@ -3396,6 +3421,30 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { retCode = stakingSmartContract.Execute(arguments) require.Equal(t, vmcommon.UserError, retCode) require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "switchJailedWithWaiting" + retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "resetLastUnJailedFromQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "stakeNodesFromQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) + + eei.CleanCache() + arguments.Function = "cleanAdditionalQueue" + retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, vm.ErrWaitingListDisabled.Error(), eei.returnMessage) } func requireRegisteredNodes(t *testing.T, stakingSC *stakingSC, eei *vmContext, stakedNodes int64, waitingListNodes uint32) { From 7d507b1e0ef66206e670e843785bf15205548869 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 2 May 2022 14:43:09 +0300 Subject: [PATCH 219/958] FIX: Broken tests --- .../vm/txsFee/validatorSC_test.go | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index 23fb232e542..0c355d6babf 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -28,6 +28,9 @@ const ( validatorStakeData = "stake@01@" + validatorBLSKey + "@0b823739887c40e9331f70c5a140623dfaf4558a9138b62f4473b26bbafdd4f58cb5889716a71c561c9e20e7a280e985@b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba" cannotUnBondTokensMessage = "cannot unBond tokens, the validator would remain without min deposit, nodes are still active" noTokensToUnBondMessage = "no tokens that can be unbond at this time" + delegationManagementKey = "delegationManagement" + stakingV4InitEpoch = 4443 + stakingV4EnableEpoch = 4444 ) var ( @@ -36,8 +39,6 @@ var ( value200EGLD, _ = big.NewInt(0).SetString("200000000000000000000", 10) ) -const delegationManagementKey = "delegationManagement" - func saveDelegationManagerConfig(testContext *vm.VMTestContext) { acc, _ := testContext.Accounts.LoadAccount(vmAddr.DelegationManagerSCAddress) userAcc, _ := acc.(state.UserAccountHandler) @@ -106,7 +107,13 @@ func checkReturnLog(t *testing.T, testContextMeta *vm.VMTestContext, subStr stri } func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *testing.T) { - testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{StakingV4EnableEpoch: 444}) + testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( + core.MetachainShardId, + config.EnableEpochs{ + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, + }, + ) require.Nil(t, err) defer testContextMeta.Close() @@ -139,13 +146,15 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes func TestValidatorsSC_DoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *testing.T) { argUnbondTokensV1 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 20000, - StakingV4EnableEpoch: 44444, + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV1) argUnbondTokensV2 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 0, - StakingV4EnableEpoch: 44444, + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV2) } @@ -179,7 +188,13 @@ func testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *t } func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens(t *testing.T) { - testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{StakingV4EnableEpoch: 4444}) + testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( + core.MetachainShardId, + config.EnableEpochs{ + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, + }, + ) require.Nil(t, err) defer testContextMeta.Close() @@ -226,7 +241,13 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens( } func TestValidatorsSC_ToStakePutInQueueUnStakeNodesAndUnBondNodesShouldRefund(t *testing.T) { - testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard(core.MetachainShardId, config.EnableEpochs{StakingV4EnableEpoch: 444}) + testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( + core.MetachainShardId, + config.EnableEpochs{ + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, + }, + ) require.Nil(t, err) defer testContextMeta.Close() From ef96899ea99b935aed576dec4738f50d6fdb66db Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 10:36:46 +0300 Subject: [PATCH 220/958] FEAT: Add initial placeholder file --- integrationTests/vm/staking/stakingV4_test.go | 24 ++++++ .../testMetaProcessorWithCustomNodesConfig.go | 73 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 5c59b81b51a..0b3b6998ec1 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -2,6 +2,7 @@ package staking import ( "bytes" + "math/big" "testing" "github.com/stretchr/testify/require" @@ -219,3 +220,26 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH } } } + +func TestStakingV4_CustomScenario(t *testing.T) { + owner1 := "owner1" + + owner1StakedKeys := map[uint32][][]byte{ + 0: {[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")}, + } + + owner1Stats := &OwnerStats{ + EligibleBlsKeys: owner1StakedKeys, + TotalStake: big.NewInt(5000), + } + + nodesConfig := &InitialNodesConfig{ + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + }, + } + + node := NewTestMetaProcessorWithCustomNodes(nodesConfig) + + _ = node +} diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go new file mode 100644 index 00000000000..cd8e9796767 --- /dev/null +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -0,0 +1,73 @@ +package staking + +import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" +) + +type OwnerStats struct { + EligibleBlsKeys map[uint32][][]byte + WaitingBlsKeys map[uint32][][]byte + StakingQueueKeys [][]byte + TotalStake *big.Int +} + +type InitialNodesConfig struct { + NumOfShards uint32 + Owners map[string]*OwnerStats + MaxNodesChangeConfig []config.MaxNodesChangeConfig +} + +func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaProcessor { + coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(config.NumOfShards) + + _ = dataComponents + _ = bootstrapComponents + _ = statusComponents + + queue := createStakingQueueCustomNodes( + config.Owners, + coreComponents.InternalMarshalizer(), + stateComponents.AccountsAdapter(), + ) + + return &TestMetaProcessor{ + NodesConfig: nodesConfig{ + queue: queue, + }, + } +} + +func createStakingQueueCustomNodes( + owners map[string]*OwnerStats, + marshaller marshal.Marshalizer, + accountsAdapter state.AccountsAdapter, +) [][]byte { + queue := make([][]byte, 0) + + for owner, ownerStats := range owners { + stakingcommon.AddKeysToWaitingList( + accountsAdapter, + ownerStats.StakingQueueKeys, + marshaller, + []byte(owner), + []byte(owner), + ) + + stakingcommon.AddValidatorData( + accountsAdapter, + []byte(owner), + ownerStats.StakingQueueKeys, + ownerStats.TotalStake, + marshaller, + ) + + queue = append(queue, ownerStats.StakingQueueKeys...) + } + + return queue +} From 3d4d3198bbc5ac33a1f0898b4bf329314e995da1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 11:00:12 +0300 Subject: [PATCH 221/958] FIX: Broken tests --- integrationTests/testProcessorNode.go | 6 ++++++ integrationTests/testProcessorNodeWithMultisigner.go | 11 +++++++++++ .../testProcessorNodeWithStateCheckpointModulus.go | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index d9177efffb9..345b785ee0b 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -205,9 +205,15 @@ const stateCheckpointModulus = 100 // StakingV2Epoch defines the epoch for integration tests when stakingV2 is enabled const StakingV2Epoch = 1000 +// StakingV4InitEpoch defines the epoch for integration tests when stakingV4 init is enabled +const StakingV4InitEpoch = 4443 + // StakingV4Epoch defines the epoch for integration tests when stakingV4 is enabled; should be greater than StakingV2Epoch const StakingV4Epoch = 4444 +// StakingV4DistributeAuctionToWaiting defines the epoch for integration tests when nodes distribution from auction to waiting list is enabled in staking v4 +const StakingV4DistributeAuctionToWaiting = 4445 + // ScheduledMiniBlocksEnableEpoch defines the epoch for integration tests when scheduled nini blocks are enabled const ScheduledMiniBlocksEnableEpoch = 1000 diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 3aadd1bcc4a..fbc1fa5727b 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -19,6 +19,7 @@ import ( mclmultisig "github.com/ElrondNetwork/elrond-go-crypto/signing/mcl/multisig" "github.com/ElrondNetwork/elrond-go-crypto/signing/multisig" "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/factory/peerSignatureHandler" "github.com/ElrondNetwork/elrond-go/integrationTests/mock" @@ -70,6 +71,11 @@ func NewTestProcessorNodeWithCustomNodesCoordinator( ArwenChangeLocker: &sync.RWMutex{}, TransactionLogProcessor: logsProcessor, Bootstrapper: mock.NewTestBootstrapperMock(), + EnableEpochs: config.EnableEpochs{ + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + }, } tpn.ScheduledMiniBlocksEnableEpoch = uint32(1000000) @@ -256,6 +262,11 @@ func CreateNodeWithBLSAndTxKeys( EpochNotifier: forking.NewGenericEpochNotifier(), ArwenChangeLocker: &sync.RWMutex{}, TransactionLogProcessor: logsProcessor, + EnableEpochs: config.EnableEpochs{ + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + }, } tpn.ScheduledMiniBlocksEnableEpoch = uint32(1000000) diff --git a/integrationTests/testProcessorNodeWithStateCheckpointModulus.go b/integrationTests/testProcessorNodeWithStateCheckpointModulus.go index 4f3ed545f24..28856f961e4 100644 --- a/integrationTests/testProcessorNodeWithStateCheckpointModulus.go +++ b/integrationTests/testProcessorNodeWithStateCheckpointModulus.go @@ -6,6 +6,7 @@ import ( arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/consensus/spos/sposFactory" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/integrationTests/mock" @@ -81,6 +82,11 @@ func NewTestProcessorNodeWithStateCheckpointModulus( EpochNotifier: forking.NewGenericEpochNotifier(), ArwenChangeLocker: &sync.RWMutex{}, TransactionLogProcessor: logsProcessor, + EnableEpochs: config.EnableEpochs{ + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + }, } tpn.NodesSetup = nodesSetup From 3557a4257910209712660be8fb2ba383a5e15e72 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 11:05:04 +0300 Subject: [PATCH 222/958] FIX: Review finding --- process/scToProtocol/stakingToPeer.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index 24a25162168..1817679e4e9 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -3,7 +3,6 @@ package scToProtocol import ( "bytes" "encoding/hex" - "fmt" "math" "github.com/ElrondNetwork/elrond-go-core/core" @@ -346,7 +345,7 @@ func (stp *stakingToPeer) updatePeerState( isValidator := account.GetList() == string(common.EligibleList) || account.GetList() == string(common.WaitingList) if !stakingData.Jailed { if stakingData.StakedNonce == nonce && !isValidator { - log.Debug(fmt.Sprintf("node is staked, changed status to %s list", newNodesList), "blsKey", blsPubKey) + log.Debug("node is staked, changed status to", "list", newNodesList, "blsKey", blsPubKey) account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.StakedNonce)) account.SetTempRating(stp.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) @@ -367,7 +366,7 @@ func (stp *stakingToPeer) updatePeerState( isNewValidator := !isValidator && stakingData.Staked if isNewValidator { - log.Debug(fmt.Sprintf("node is unJailed and staked, changing status to %s list", newNodesList), "blsKey", blsPubKey) + log.Debug("node is unJailed and staked, changing status to", "list", newNodesList, "blsKey", blsPubKey) account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.UnJailedNonce)) } From 7a3c479683285f042d9aec42c28837c14f4ae7d1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 11:16:51 +0300 Subject: [PATCH 223/958] FIX: Linter errors --- epochStart/metachain/systemSCs_test.go | 2 ++ vm/systemSmartContracts/staking_test.go | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 2016f0c92eb..f226f709699 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2034,6 +2034,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar s.EpochConfirmed(6, 6) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 6, 6) + require.Nil(t, err) require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) @@ -2051,6 +2052,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar s.EpochConfirmed(21, 21) require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 21, 21) + require.Nil(t, err) require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) } diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 442dc6452a0..eb2d0c5dbf4 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -3379,21 +3379,25 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { eei.CleanCache() arguments.Function = "switchJailedWithWaiting" retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "function not allowed to be called by address")) eei.CleanCache() arguments.Function = "resetLastUnJailedFromQueue" retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) eei.CleanCache() arguments.Function = "stakeNodesFromQueue" retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) eei.CleanCache() arguments.Function = "cleanAdditionalQueue" retCode = stakingSmartContract.Execute(arguments) + require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) From 0a13853189983aec384cb15f2900cca5cfcd3db1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 11:47:22 +0300 Subject: [PATCH 224/958] FIX: More tests --- integrationTests/multiShard/softfork/scDeploy_test.go | 11 +++++++---- integrationTests/testProcessorNode.go | 5 +++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/integrationTests/multiShard/softfork/scDeploy_test.go b/integrationTests/multiShard/softfork/scDeploy_test.go index a9afbfc4c44..376c31c73e3 100644 --- a/integrationTests/multiShard/softfork/scDeploy_test.go +++ b/integrationTests/multiShard/softfork/scDeploy_test.go @@ -33,10 +33,13 @@ func TestScDeploy(t *testing.T) { roundsPerEpoch := uint64(10) enableEpochs := config.EnableEpochs{ - BuiltInFunctionsEnableEpoch: builtinEnableEpoch, - SCDeployEnableEpoch: deployEnableEpoch, - RelayedTransactionsEnableEpoch: relayedTxEnableEpoch, - PenalizedTooMuchGasEnableEpoch: penalizedTooMuchGasEnableEpoch, + BuiltInFunctionsEnableEpoch: builtinEnableEpoch, + SCDeployEnableEpoch: deployEnableEpoch, + RelayedTransactionsEnableEpoch: relayedTxEnableEpoch, + PenalizedTooMuchGasEnableEpoch: penalizedTooMuchGasEnableEpoch, + StakingV4InitEnableEpoch: integrationTests.StakingV4InitEpoch, + StakingV4EnableEpoch: integrationTests.StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: integrationTests.StakingV4DistributeAuctionToWaiting, } shardNode := integrationTests.NewTestProcessorNodeWithEnableEpochs( diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 345b785ee0b..b9778a0fac6 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -428,6 +428,11 @@ func newBaseTestProcessorNode( ArwenChangeLocker: &sync.RWMutex{}, TransactionLogProcessor: logsProcessor, Bootstrapper: mock.NewTestBootstrapperMock(), + EnableEpochs: config.EnableEpochs{ + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + }, } tpn.ScheduledMiniBlocksEnableEpoch = uint32(1000000) From 1aec3bbfcfbc8f565c383299c5d8f61bca675821 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 13:40:46 +0300 Subject: [PATCH 225/958] FEAT: Add intermediary code --- integrationTests/vm/staking/stakingV4_test.go | 21 ++++++++++++++++--- .../testMetaProcessorWithCustomNodesConfig.go | 2 ++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 0b3b6998ec1..bdfd55d4bc5 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -227,19 +227,34 @@ func TestStakingV4_CustomScenario(t *testing.T) { owner1StakedKeys := map[uint32][][]byte{ 0: {[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")}, } - + owner1StakingQueueKeys := [][]byte{ + []byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5"), + } owner1Stats := &OwnerStats{ - EligibleBlsKeys: owner1StakedKeys, - TotalStake: big.NewInt(5000), + EligibleBlsKeys: owner1StakedKeys, + StakingQueueKeys: owner1StakingQueueKeys, + TotalStake: big.NewInt(5000), + } + + owner2 := "owner2" + owner2StakingQueueKeys := [][]byte{ + []byte("pubKey6"), []byte("pubKey7"), []byte("pubKey8"), + } + owner2Stats := &OwnerStats{ + StakingQueueKeys: owner2StakingQueueKeys, + TotalStake: big.NewInt(5000), } nodesConfig := &InitialNodesConfig{ Owners: map[string]*OwnerStats{ owner1: owner1Stats, + owner2: owner2Stats, }, } node := NewTestMetaProcessorWithCustomNodes(nodesConfig) + waiting := node.getWaitingListKeys() + _ = waiting _ = node } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index cd8e9796767..655354b434e 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -39,6 +39,8 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr NodesConfig: nodesConfig{ queue: queue, }, + AccountsAdapter: stateComponents.AccountsAdapter(), + Marshaller: coreComponents.InternalMarshalizer(), } } From e15b3ada8fef703327965e6bf4e6c87ba463af5f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 13:46:36 +0300 Subject: [PATCH 226/958] FIX: AddKeysToWaitingList in tests --- epochStart/metachain/systemSCs_test.go | 4 +- integrationTests/vm/staking/stakingQueue.go | 16 +--- testscommon/stakingcommon/stakingCommon.go | 90 ++++++--------------- 3 files changed, 29 insertions(+), 81 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f226f709699..1321c6cb56f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -679,7 +679,7 @@ func prepareStakingContractWithData( ownerAddress []byte, ) { stakingcommon.AddStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer) - stakingcommon.SaveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress) + stakingcommon.AddKeysToWaitingList(accountsDB, [][]byte{waitingKey}, marshalizer, rewardAddress, ownerAddress) stakingcommon.AddValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer) _, err := accountsDB.Commit() @@ -1647,7 +1647,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer, ) - stakingcommon.SaveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, [][]byte{[]byte("waitingPubKey")}, args.Marshalizer, []byte("ownerKey"), []byte("ownerKey")) stakingcommon.AddValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer) _, _ = args.UserAccountsDB.Commit() diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 180eb4a020d..79c53e02b72 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -27,24 +27,14 @@ func createStakingQueue( ownerWaitingNodes = append(ownerWaitingNodes, generateAddress(i)) } - // We need to save one key and then add keys to waiting list because there is a bug in those functions - // TODO: FIX bug in testscommon.AddKeysToWaitingList to also init staking queue if there are no keys in list - stakingcommon.SaveOneKeyToWaitingList( + stakingcommon.AddKeysToWaitingList( accountsAdapter, - ownerWaitingNodes[0], + ownerWaitingNodes, marshaller, owner, owner, ) - if numOfNodesInStakingQueue > 1 { - stakingcommon.AddKeysToWaitingList( - accountsAdapter, - ownerWaitingNodes[1:], - marshaller, - owner, - owner, - ) - } + stakingcommon.AddValidatorData( accountsAdapter, owner, diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 2bf8eed6547..88bdc833d3b 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -91,37 +91,32 @@ func AddKeysToWaitingList( rewardAddress []byte, ownerAddress []byte, ) { - stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) - - for _, waitingKey := range waitingKeys { - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) + if len(waitingKeys) == 0 { + return } + stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) waitingListHead := &systemSmartContracts.WaitingList{} _ = marshalizer.Unmarshal(waitingListHead, marshaledData) waitingListAlreadyHasElements := waitingListHead.Length > 0 waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey + var previousKey []byte + if !waitingListAlreadyHasElements { + waitingListHead.FirstKey = []byte("w_" + string(waitingKeys[0])) + previousKey = waitingListHead.FirstKey + } else { + previousKey = waitingListHead.LastKey + } + waitingListHead.LastKey = []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) waitingListHead.Length += uint32(len(waitingKeys)) - lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) - waitingListHead.LastKey = lastKeyInList marshaledData, _ = marshalizer.Marshal(waitingListHead) _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - numWaitingKeys := len(waitingKeys) - previousKey := waitingListHead.LastKey for i, waitingKey := range waitingKeys { - waitingKeyInList := []byte("w_" + string(waitingKey)) waitingListElement := &systemSmartContracts.ElementInList{ BLSPublicKey: waitingKey, @@ -129,6 +124,15 @@ func AddKeysToWaitingList( NextKey: make([]byte, 0), } + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + marshaledData, _ = marshalizer.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) + if i < numWaitingKeys-1 { nextKey := []byte("w_" + string(waitingKeys[i+1])) waitingListElement.NextKey = nextKey @@ -142,58 +146,12 @@ func AddKeysToWaitingList( if waitingListAlreadyHasElements { marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) - } else { - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey) - } - - waitingListElement := &systemSmartContracts.ElementInList{} - _ = marshalizer.Unmarshal(waitingListElement, marshaledData) - waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) - marshaledData, _ = marshalizer.Marshal(waitingListElement) - - if waitingListAlreadyHasElements { + waitingListElement := &systemSmartContracts.ElementInList{} + _ = marshalizer.Unmarshal(waitingListElement, marshaledData) + waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) + marshaledData, _ = marshalizer.Marshal(waitingListElement) _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) - } else { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData) - } - - _ = accountsDB.SaveAccount(stakingSCAcc) -} - -// SaveOneKeyToWaitingList will add one bls key with its associated owner in the staking queue list -func SaveOneKeyToWaitingList( - accountsDB state.AccountsAdapter, - waitingKey []byte, - marshalizer marshal.Marshalizer, - rewardAddress []byte, - ownerAddress []byte, -) { - stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ := marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) - - waitingKeyInList := []byte("w_" + string(waitingKey)) - waitingListHead := &systemSmartContracts.WaitingList{ - FirstKey: waitingKeyInList, - LastKey: waitingKeyInList, - Length: 1, - } - marshaledData, _ = marshalizer.Marshal(waitingListHead) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) - - waitingListElement := &systemSmartContracts.ElementInList{ - BLSPublicKey: waitingKey, - PreviousKey: waitingKeyInList, - NextKey: make([]byte, 0), } - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) _ = accountsDB.SaveAccount(stakingSCAcc) } From 9fef28f4f87e96bcd7a07a700ab0511f5dd9063c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 14:52:43 +0300 Subject: [PATCH 227/958] FIX: Refactor --- testscommon/stakingcommon/stakingCommon.go | 117 ++++++++++++++------- 1 file changed, 81 insertions(+), 36 deletions(-) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 88bdc833d3b..d5b6e6a5937 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -87,7 +87,7 @@ func AddStakingData( func AddKeysToWaitingList( accountsDB state.AccountsAdapter, waitingKeys [][]byte, - marshalizer marshal.Marshalizer, + marshaller marshal.Marshalizer, rewardAddress []byte, ownerAddress []byte, ) { @@ -96,66 +96,111 @@ func AddKeysToWaitingList( } stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) - waitingListHead := &systemSmartContracts.WaitingList{} - _ = marshalizer.Unmarshal(waitingListHead, marshaledData) + waitingList := getWaitingList(stakingSCAcc, marshaller) - waitingListAlreadyHasElements := waitingListHead.Length > 0 - waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey - var previousKey []byte + waitingListAlreadyHasElements := waitingList.Length > 0 + waitingListLastKeyBeforeAddingNewKeys := waitingList.LastKey + previousKey := waitingList.LastKey if !waitingListAlreadyHasElements { - waitingListHead.FirstKey = []byte("w_" + string(waitingKeys[0])) - previousKey = waitingListHead.FirstKey - } else { - previousKey = waitingListHead.LastKey + waitingList.FirstKey = []byte("w_" + string(waitingKeys[0])) + previousKey = waitingList.FirstKey } - waitingListHead.LastKey = []byte("w_" + string(waitingKeys[len(waitingKeys)-1])) - waitingListHead.Length += uint32(len(waitingKeys)) - - marshaledData, _ = marshalizer.Marshal(waitingListHead) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) numWaitingKeys := len(waitingKeys) + waitingList.LastKey = []byte("w_" + string(waitingKeys[numWaitingKeys-1])) + waitingList.Length += uint32(numWaitingKeys) + saveWaitingList(stakingSCAcc, marshaller, waitingList) + for i, waitingKey := range waitingKeys { - waitingKeyInList := []byte("w_" + string(waitingKey)) waitingListElement := &systemSmartContracts.ElementInList{ BLSPublicKey: waitingKey, PreviousKey: previousKey, NextKey: make([]byte, 0), } - stakedData := &systemSmartContracts.StakedDataV2_0{ - Waiting: true, - RewardAddress: rewardAddress, - OwnerAddress: ownerAddress, - StakeValue: big.NewInt(100), - } - marshaledData, _ = marshalizer.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData) - if i < numWaitingKeys-1 { nextKey := []byte("w_" + string(waitingKeys[i+1])) waitingListElement.NextKey = nextKey } - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - - previousKey = waitingKeyInList + saveStakedData(stakingSCAcc, marshaller, rewardAddress, ownerAddress, waitingKey) + previousKey = saveElemInList(stakingSCAcc, marshaller, waitingListElement, waitingKey) } if waitingListAlreadyHasElements { - marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys) - waitingListElement := &systemSmartContracts.ElementInList{} - _ = marshalizer.Unmarshal(waitingListElement, marshaledData) - waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0])) - marshaledData, _ = marshalizer.Marshal(waitingListElement) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData) + lastKeyWithoutPrefix := waitingListLastKeyBeforeAddingNewKeys[2:] + + lastElem := getElemInList(stakingSCAcc, marshaller, lastKeyWithoutPrefix) + lastElem.NextKey = []byte("w_" + string(waitingKeys[0])) + saveElemInList(stakingSCAcc, marshaller, lastElem, lastKeyWithoutPrefix) } _ = accountsDB.SaveAccount(stakingSCAcc) } +func getWaitingList( + stakingSCAcc state.UserAccountHandler, + marshaller marshal.Marshalizer, +) *systemSmartContracts.WaitingList { + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + waitingList := &systemSmartContracts.WaitingList{} + _ = marshaller.Unmarshal(waitingList, marshaledData) + + return waitingList +} + +func saveWaitingList( + stakingSCAcc state.UserAccountHandler, + marshaller marshal.Marshalizer, + waitingList *systemSmartContracts.WaitingList, +) { + marshaledData, _ := marshaller.Marshal(waitingList) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) +} + +func saveStakedData( + stakingSCAcc state.UserAccountHandler, + marshaller marshal.Marshalizer, + rewardAddress []byte, + ownerAddress []byte, + key []byte, +) { + stakedData := &systemSmartContracts.StakedDataV2_0{ + Waiting: true, + RewardAddress: rewardAddress, + OwnerAddress: ownerAddress, + StakeValue: big.NewInt(100), + } + + marshaledData, _ := marshaller.Marshal(stakedData) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) +} + +func saveElemInList( + stakingSCAcc state.UserAccountHandler, + marshaller marshal.Marshalizer, + elem *systemSmartContracts.ElementInList, + key []byte, +) []byte { + marshaledData, _ := marshaller.Marshal(elem) + waitingKeyInList := []byte("w_" + string(key)) + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) + + return waitingKeyInList +} + +func getElemInList( + stakingSCAcc state.UserAccountHandler, + marshaller marshal.Marshalizer, + key []byte, +) *systemSmartContracts.ElementInList { + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("w_" + string(key))) + waitingListElement := &systemSmartContracts.ElementInList{} + _ = marshaller.Unmarshal(waitingListElement, marshaledData) + + return waitingListElement +} + // LoadUserAccount returns address's state.UserAccountHandler from the provided db func LoadUserAccount(accountsDB state.AccountsAdapter, address []byte) state.UserAccountHandler { acc, _ := accountsDB.LoadAccount(address) From 4c1ab09d76d7b3715ef570196cd2dab9e11bbf09 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 15:35:44 +0300 Subject: [PATCH 228/958] FIX: Function name --- testscommon/stakingcommon/stakingCommon.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index d5b6e6a5937..ee3c8c32d2e 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -123,7 +123,7 @@ func AddKeysToWaitingList( waitingListElement.NextKey = nextKey } - saveStakedData(stakingSCAcc, marshaller, rewardAddress, ownerAddress, waitingKey) + saveStakedWaitingKey(stakingSCAcc, marshaller, rewardAddress, ownerAddress, waitingKey) previousKey = saveElemInList(stakingSCAcc, marshaller, waitingListElement, waitingKey) } @@ -158,7 +158,7 @@ func saveWaitingList( _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) } -func saveStakedData( +func saveStakedWaitingKey( stakingSCAcc state.UserAccountHandler, marshaller marshal.Marshalizer, rewardAddress []byte, From 5c51f42b1df51d90d15caa70be6899ee50f45e8a Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 16:18:41 +0300 Subject: [PATCH 229/958] FIX: Small refactor --- integrationTests/vm/staking/stakingQueue.go | 17 +------ testscommon/stakingcommon/stakingCommon.go | 50 ++++++++++++--------- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 79c53e02b72..c4c313c2c1b 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -73,7 +73,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { for len(nextKey) != 0 && index <= waitingList.Length { allPubKeys = append(allPubKeys, nextKey) - element, errGet := tmp.getWaitingListElement(stakingSCAcc, nextKey) + element, errGet := stakingcommon.GetWaitingListElement(stakingSCAcc, tmp.Marshaller, nextKey) if errGet != nil { return nil } @@ -87,18 +87,3 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { } return allPubKeys } - -func (tmp *TestMetaProcessor) getWaitingListElement(stakingSCAcc state.UserAccountHandler, key []byte) (*systemSmartContracts.ElementInList, error) { - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) - if len(marshaledData) == 0 { - return nil, vm.ErrElementNotFound - } - - element := &systemSmartContracts.ElementInList{} - err := tmp.Marshaller.Unmarshal(element, marshaledData) - if err != nil { - return nil, err - } - - return element, nil -} diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index ee3c8c32d2e..6fe84206a17 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -102,12 +102,12 @@ func AddKeysToWaitingList( waitingListLastKeyBeforeAddingNewKeys := waitingList.LastKey previousKey := waitingList.LastKey if !waitingListAlreadyHasElements { - waitingList.FirstKey = []byte("w_" + string(waitingKeys[0])) + waitingList.FirstKey = getPrefixedWaitingKey(waitingKeys[0]) previousKey = waitingList.FirstKey } numWaitingKeys := len(waitingKeys) - waitingList.LastKey = []byte("w_" + string(waitingKeys[numWaitingKeys-1])) + waitingList.LastKey = getPrefixedWaitingKey(waitingKeys[numWaitingKeys-1]) waitingList.Length += uint32(numWaitingKeys) saveWaitingList(stakingSCAcc, marshaller, waitingList) @@ -119,20 +119,21 @@ func AddKeysToWaitingList( } if i < numWaitingKeys-1 { - nextKey := []byte("w_" + string(waitingKeys[i+1])) + nextKey := getPrefixedWaitingKey(waitingKeys[i+1]) waitingListElement.NextKey = nextKey } + prefixedWaitingKey := getPrefixedWaitingKey(waitingKey) saveStakedWaitingKey(stakingSCAcc, marshaller, rewardAddress, ownerAddress, waitingKey) - previousKey = saveElemInList(stakingSCAcc, marshaller, waitingListElement, waitingKey) + saveElemInList(stakingSCAcc, marshaller, waitingListElement, prefixedWaitingKey) + + previousKey = prefixedWaitingKey } if waitingListAlreadyHasElements { - lastKeyWithoutPrefix := waitingListLastKeyBeforeAddingNewKeys[2:] - - lastElem := getElemInList(stakingSCAcc, marshaller, lastKeyWithoutPrefix) - lastElem.NextKey = []byte("w_" + string(waitingKeys[0])) - saveElemInList(stakingSCAcc, marshaller, lastElem, lastKeyWithoutPrefix) + lastElem, _ := GetWaitingListElement(stakingSCAcc, marshaller, waitingListLastKeyBeforeAddingNewKeys) + lastElem.NextKey = getPrefixedWaitingKey(waitingKeys[0]) + saveElemInList(stakingSCAcc, marshaller, lastElem, waitingListLastKeyBeforeAddingNewKeys) } _ = accountsDB.SaveAccount(stakingSCAcc) @@ -158,6 +159,10 @@ func saveWaitingList( _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) } +func getPrefixedWaitingKey(key []byte) []byte { + return []byte("w_" + string(key)) +} + func saveStakedWaitingKey( stakingSCAcc state.UserAccountHandler, marshaller marshal.Marshalizer, @@ -181,24 +186,29 @@ func saveElemInList( marshaller marshal.Marshalizer, elem *systemSmartContracts.ElementInList, key []byte, -) []byte { +) { marshaledData, _ := marshaller.Marshal(elem) - waitingKeyInList := []byte("w_" + string(key)) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData) - - return waitingKeyInList + _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) } -func getElemInList( +// GetWaitingListElement returns the element in waiting list saved at the provided key +func GetWaitingListElement( stakingSCAcc state.UserAccountHandler, marshaller marshal.Marshalizer, key []byte, -) *systemSmartContracts.ElementInList { - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("w_" + string(key))) - waitingListElement := &systemSmartContracts.ElementInList{} - _ = marshaller.Unmarshal(waitingListElement, marshaledData) +) (*systemSmartContracts.ElementInList, error) { + marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) + if len(marshaledData) == 0 { + return nil, vm.ErrElementNotFound + } + + element := &systemSmartContracts.ElementInList{} + err := marshaller.Unmarshal(element, marshaledData) + if err != nil { + return nil, err + } - return waitingListElement + return element, nil } // LoadUserAccount returns address's state.UserAccountHandler from the provided db From cee9d7e0a4d2bed38822c69d21376d62bec49d95 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 3 May 2022 17:35:36 +0300 Subject: [PATCH 230/958] FIX: Review findings --- epochStart/bootstrap/process_test.go | 7 +- epochStart/errors.go | 12 ---- epochStart/metachain/stakingDataProvider.go | 27 ++++---- .../metachain/stakingDataProvider_test.go | 64 ++++++++++++------- epochStart/metachain/systemSCs_test.go | 5 +- factory/blockProcessorCreator.go | 14 ++-- integrationTests/testProcessorNode.go | 9 ++- .../vm/staking/systemSCCreator.go | 13 ++-- state/validatorInfo_test.go | 15 ----- 9 files changed, 83 insertions(+), 83 deletions(-) delete mode 100644 state/validatorInfo_test.go diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index e60629914d1..f9efb9b0880 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -15,7 +15,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/versioning" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" @@ -90,16 +89,12 @@ func createMockEpochStartBootstrapArgs( cryptoMock *mock.CryptoComponentsMock, ) ArgsEpochStartBootstrap { generalCfg := testscommon.GetGeneralConfig() - nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( - &marshal.GogoProtoMarshalizer{}, - 444, - ) return ArgsEpochStartBootstrap{ ScheduledSCRsStorer: genericMocks.NewStorerMock("path", 0), CoreComponentsHolder: coreMock, CryptoComponentsHolder: cryptoMock, Messenger: &mock.MessengerStub{}, - NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, + NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, GeneralConfig: config.Config{ MiniBlocksStorage: generalCfg.MiniBlocksStorage, PeerBlockBodyStorage: generalCfg.PeerBlockBodyStorage, diff --git a/epochStart/errors.go b/epochStart/errors.go index a3c4ab09a74..2edb86f6e82 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -155,9 +155,6 @@ var ErrEpochStartDataForShardNotFound = errors.New("epoch start data for current // ErrMissingHeader signals that searched header is missing var ErrMissingHeader = errors.New("missing header") -// ErrMissingMiniBlock signals that the searched miniBlock is missing -var ErrMissingMiniBlock = errors.New("missing miniBlock") - // ErrNilPathManager signals that a nil path manager has been provided var ErrNilPathManager = errors.New("nil path manager") @@ -188,9 +185,6 @@ var ErrNilGenesisNodesConfig = errors.New("nil genesis nodes config") // ErrNilRater signals that a nil rater has been provided var ErrNilRater = errors.New("nil rater") -// ErrInvalidWorkingDir signals that an invalid working directory has been provided -var ErrInvalidWorkingDir = errors.New("invalid working directory") - // ErrTimeoutWaitingForMetaBlock signals that a timeout event was raised while waiting for the epoch start meta block var ErrTimeoutWaitingForMetaBlock = errors.New("timeout while waiting for epoch start meta block") @@ -272,12 +266,6 @@ var ErrNilDataTrie = errors.New("nil data trie") // ErrInvalidMinNodePrice signals that the minimum node price is invalid (e.g negative, not a number, etc) var ErrInvalidMinNodePrice = errors.New("minimum node price is invalid") -// ErrInvalidRewardsTopUpGradientPoint signals that the given point controlling the top-up gradient is invalid -var ErrInvalidRewardsTopUpGradientPoint = errors.New("top-up gradient point invalid") - -// ErrInvalidRewardsTopUpFactor signals that the factor for computing the top-up rewards out of the full rewards is invalid -var ErrInvalidRewardsTopUpFactor = errors.New("top-up factor invalid") - // ErrNilEconomicsDataProvider signals that the economics data provider is nil var ErrNilEconomicsDataProvider = errors.New("end of epoch economics data provider is nil") diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index de7a325fae8..952381aecdd 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -39,36 +39,39 @@ type stakingDataProvider struct { flagStakingV4Enable atomic.Flag } +// StakingDataProviderArgs is a struct placeholder for all arguments required to create a NewStakingDataProvider +type StakingDataProviderArgs struct { + EpochNotifier process.EpochNotifier + SystemVM vmcommon.VMExecutionHandler + MinNodePrice string + StakingV4EnableEpoch uint32 +} + // NewStakingDataProvider will create a new instance of a staking data provider able to aid in the final rewards // computation as this will retrieve the staking data from the system VM -func NewStakingDataProvider( - systemVM vmcommon.VMExecutionHandler, - minNodePrice string, - stakingV4EnableEpoch uint32, - epochNotifier process.EpochNotifier, -) (*stakingDataProvider, error) { - if check.IfNil(systemVM) { +func NewStakingDataProvider(args StakingDataProviderArgs) (*stakingDataProvider, error) { + if check.IfNil(args.SystemVM) { return nil, epochStart.ErrNilSystemVmInstance } - if check.IfNil(epochNotifier) { + if check.IfNil(args.EpochNotifier) { return nil, epochStart.ErrNilEpochStartNotifier } - nodePrice, ok := big.NewInt(0).SetString(minNodePrice, 10) + nodePrice, ok := big.NewInt(0).SetString(args.MinNodePrice, 10) if !ok || nodePrice.Cmp(big.NewInt(0)) <= 0 { return nil, epochStart.ErrInvalidMinNodePrice } sdp := &stakingDataProvider{ - systemVM: systemVM, + systemVM: args.SystemVM, cache: make(map[string]*ownerStats), minNodePrice: nodePrice, totalEligibleStake: big.NewInt(0), totalEligibleTopUpStake: big.NewInt(0), - stakingV4EnableEpoch: stakingV4EnableEpoch, + stakingV4EnableEpoch: args.StakingV4EnableEpoch, } log.Debug("stakingDataProvider: enable epoch for staking v4", "epoch", sdp.stakingV4EnableEpoch) - epochNotifier.RegisterNotifyHandler(sdp) + args.EpochNotifier.RegisterNotifyHandler(sdp) return sdp, nil } diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index beb3a118ed1..e1dd08be909 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -25,29 +25,40 @@ import ( const stakingV4EnableEpoch = 444 +func createStakingDataProviderArgs() StakingDataProviderArgs { + return StakingDataProviderArgs{ + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + SystemVM: &mock.VMExecutionHandlerStub{}, + MinNodePrice: "2500", + StakingV4EnableEpoch: stakingV4EnableEpoch, + } +} + func TestNewStakingDataProvider_NilInputPointersShouldErr(t *testing.T) { t.Parallel() t.Run("nil system vm", func(t *testing.T) { - sdp, err := NewStakingDataProvider(nil, "100000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) + args := createStakingDataProviderArgs() + args.SystemVM = nil + sdp, err := NewStakingDataProvider(args) assert.True(t, check.IfNil(sdp)) assert.Equal(t, epochStart.ErrNilSystemVmInstance, err) }) t.Run("nil epoch notifier", func(t *testing.T) { - sdp, err := NewStakingDataProvider(&mock.VMExecutionHandlerStub{}, "100000", stakingV4EnableEpoch, nil) + args := createStakingDataProviderArgs() + args.EpochNotifier = nil + sdp, err := NewStakingDataProvider(args) assert.True(t, check.IfNil(sdp)) assert.Equal(t, epochStart.ErrNilEpochStartNotifier, err) }) -} - -func TestNewStakingDataProvider_ShouldWork(t *testing.T) { - t.Parallel() - - sdp, err := NewStakingDataProvider(&mock.VMExecutionHandlerStub{}, "100000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) - assert.False(t, check.IfNil(sdp)) - assert.Nil(t, err) + t.Run("should work", func(t *testing.T) { + args := createStakingDataProviderArgs() + sdp, err := NewStakingDataProvider(args) + assert.False(t, check.IfNil(sdp)) + assert.Nil(t, err) + }) } func TestStakingDataProvider_PrepareDataForBlsKeyGetBlsKeyOwnerErrorsShouldErr(t *testing.T) { @@ -55,7 +66,8 @@ func TestStakingDataProvider_PrepareDataForBlsKeyGetBlsKeyOwnerErrorsShouldErr(t numCall := 0 expectedErr := errors.New("expected error") - sdp, _ := NewStakingDataProvider(&mock.VMExecutionHandlerStub{ + args := createStakingDataProviderArgs() + args.SystemVM = &mock.VMExecutionHandlerStub{ RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { numCall++ if numCall == 1 { @@ -74,9 +86,8 @@ func TestStakingDataProvider_PrepareDataForBlsKeyGetBlsKeyOwnerErrorsShouldErr(t return nil, nil }, - }, "100000", - stakingV4EnableEpoch, - &epochNotifier.EpochNotifierStub{}) + } + sdp, _ := NewStakingDataProvider(args) err := sdp.loadDataForBlsKey([]byte("bls key")) assert.Equal(t, expectedErr, err) @@ -98,7 +109,8 @@ func TestStakingDataProvider_PrepareDataForBlsKeyLoadOwnerDataErrorsShouldErr(t numCall := 0 owner := []byte("owner") expectedErr := errors.New("expected error") - sdp, _ := NewStakingDataProvider(&mock.VMExecutionHandlerStub{ + args := createStakingDataProviderArgs() + args.SystemVM = &mock.VMExecutionHandlerStub{ RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { if input.Function == "getOwner" { return &vmcommon.VMOutput{ @@ -122,9 +134,8 @@ func TestStakingDataProvider_PrepareDataForBlsKeyLoadOwnerDataErrorsShouldErr(t } return nil, nil }, - }, "100000", - stakingV4EnableEpoch, - &epochNotifier.EpochNotifierStub{}) + } + sdp, _ := NewStakingDataProvider(args) err := sdp.loadDataForBlsKey([]byte("bls key")) assert.Equal(t, expectedErr, err) @@ -472,7 +483,8 @@ func createStakingDataProviderWithMockArgs( stakingVal *big.Int, numRunContractCalls *int, ) *stakingDataProvider { - sdp, err := NewStakingDataProvider(&mock.VMExecutionHandlerStub{ + args := createStakingDataProviderArgs() + args.SystemVM = &mock.VMExecutionHandlerStub{ RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { *numRunContractCalls++ switch input.Function { @@ -496,9 +508,8 @@ func createStakingDataProviderWithMockArgs( return nil, errors.New("unexpected call") }, - }, "100000", - stakingV4EnableEpoch, - &epochNotifier.EpochNotifierStub{}) + } + sdp, err := NewStakingDataProvider(args) require.Nil(t, err) return sdp @@ -514,7 +525,9 @@ func createStakingDataProviderWithRealArgs(t *testing.T, owner []byte, blsKey [] doStake(t, s.systemVM, s.userAccountsDB, owner, big.NewInt(0).Add(big.NewInt(1000), topUpVal), blsKey) - sdp, _ := NewStakingDataProvider(s.systemVM, "100000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) + argsStakingDataProvider := createStakingDataProviderArgs() + argsStakingDataProvider.SystemVM = s.systemVM + sdp, _ := NewStakingDataProvider(argsStakingDataProvider) return sdp } @@ -549,7 +562,10 @@ func createStakingDataProviderAndUpdateCache(t *testing.T, validatorsInfo state. args.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: 1, }) - sdp, _ := NewStakingDataProvider(args.SystemVM, "2500", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) + + argsStakingDataProvider := createStakingDataProviderArgs() + argsStakingDataProvider.SystemVM = args.SystemVM + sdp, _ := NewStakingDataProvider(argsStakingDataProvider) args.StakingDataProvider = sdp s, _ := NewSystemSCProcessor(args) require.NotNil(t, s) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f226f709699..3696b2400d3 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -845,7 +845,10 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS vmContainer, _ := metaVmFactory.Create() systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCProvider, _ := NewStakingDataProvider(systemVM, "1000", stakingV4EnableEpoch, &epochNotifier.EpochNotifierStub{}) + argsStakingDataProvider := createStakingDataProviderArgs() + argsStakingDataProvider.SystemVM = systemVM + argsStakingDataProvider.MinNodePrice = "1000" + stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) args := ArgsNewEpochStartSystemSCProcessing{ diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 929dac4b285..a7bdec71826 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -712,13 +712,15 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } + argsStakingDataProvider := metachainEpochStart.StakingDataProviderArgs{ + EpochNotifier: pcf.coreData.EpochNotifier(), + SystemVM: systemVM, + MinNodePrice: pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, + StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + } + // TODO: in case of changing the minimum node price, make sure to update the staking data provider - stakingDataProvider, err := metachainEpochStart.NewStakingDataProvider( - systemVM, - pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, - pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, - pcf.coreData.EpochNotifier(), - ) + stakingDataProvider, err := metachainEpochStart.NewStakingDataProvider(argsStakingDataProvider) if err != nil { return nil, err } diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index b9778a0fac6..7514707a0c4 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2178,7 +2178,14 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { if errGet != nil { log.Error("initBlockProcessor tpn.VMContainer.Get", "error", errGet) } - stakingDataProvider, errRsp := metachain.NewStakingDataProvider(systemVM, "1000", StakingV4Epoch, coreComponents.EpochNotifier()) + + argsStakingDataProvider := metachain.StakingDataProviderArgs{ + EpochNotifier: coreComponents.EpochNotifier(), + SystemVM: systemVM, + MinNodePrice: "1000", + StakingV4EnableEpoch: StakingV4Epoch, + } + stakingDataProvider, errRsp := metachain.NewStakingDataProvider(argsStakingDataProvider) if errRsp != nil { log.Error("initBlockProcessor NewRewardsStakingProvider", "error", errRsp) } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 15fda090180..0ef240a12f1 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -35,12 +35,13 @@ func createSystemSCProcessor( vmContainer process.VirtualMachinesContainer, ) process.EpochStartSystemSCProcessor { systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - stakingSCProvider, _ := metachain.NewStakingDataProvider( - systemVM, - strconv.Itoa(nodePrice), - stakingV4EnableEpoch, - coreComponents.EpochNotifier(), - ) + argsStakingDataProvider := metachain.StakingDataProviderArgs{ + EpochNotifier: coreComponents.EpochNotifier(), + SystemVM: systemVM, + MinNodePrice: strconv.Itoa(nodePrice), + StakingV4EnableEpoch: stakingV4EnableEpoch, + } + stakingSCProvider, _ := metachain.NewStakingDataProvider(argsStakingDataProvider) args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, diff --git a/state/validatorInfo_test.go b/state/validatorInfo_test.go deleted file mode 100644 index 69bdbeb0748..00000000000 --- a/state/validatorInfo_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package state - -import ( - "testing" - - "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/stretchr/testify/assert" -) - -func TestValidatorInfo_IsInterfaceNile(t *testing.T) { - t.Parallel() - - vi := &ValidatorInfo{} - assert.False(t, check.IfNil(vi)) -} From e643b1ba8d478735c46c34cea332c64f201bf2b8 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 4 May 2022 12:20:48 +0300 Subject: [PATCH 231/958] FEAT: New baseMetaTestProcessor --- .../vm/staking/baseTestMetaProcessor.go | 109 ++++++++++++++++++ .../vm/staking/componentsHolderCreator.go | 4 +- .../vm/staking/nodesCoordiantorCreator.go | 46 ++++++-- integrationTests/vm/staking/stakingV4_test.go | 11 +- .../vm/staking/testMetaProcessor.go | 96 +++------------ .../testMetaProcessorWithCustomNodesConfig.go | 46 ++++++-- 6 files changed, 210 insertions(+), 102 deletions(-) create mode 100644 integrationTests/vm/staking/baseTestMetaProcessor.go diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go new file mode 100644 index 00000000000..e03822b2fc5 --- /dev/null +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -0,0 +1,109 @@ +package staking + +import ( + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/factory" + "github.com/ElrondNetwork/elrond-go/integrationTests" + "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" +) + +type baseMetaProcessor struct { + MetaBlockProcessor process.BlockProcessor + NodesCoordinator nodesCoordinator.NodesCoordinator + ValidatorStatistics process.ValidatorStatisticsProcessor + EpochStartTrigger integrationTests.TestEpochStartTrigger + BlockChainHandler data.ChainHandler + NodesConfig nodesConfig + AccountsAdapter state.AccountsAdapter + Marshaller marshal.Marshalizer + + currentRound uint64 +} + +func newBaseMetaProcessor( + coreComponents factory.CoreComponentsHolder, + dataComponents factory.DataComponentsHolder, + bootstrapComponents factory.BootstrapComponentsHolder, + statusComponents factory.StatusComponentsHolder, + stateComponents factory.StateComponentsHandler, + nc nodesCoordinator.NodesCoordinator, + maxNodesConfig []config.MaxNodesChangeConfig, + queue [][]byte, +) *baseMetaProcessor { + gasScheduleNotifier := createGasScheduleNotifier() + blockChainHook := createBlockChainHook( + dataComponents, coreComponents, + stateComponents.AccountsAdapter(), + bootstrapComponents.ShardCoordinator(), + gasScheduleNotifier, + ) + + metaVmFactory := createVMContainerFactory( + coreComponents, + gasScheduleNotifier, + blockChainHook, + stateComponents.PeerAccounts(), + bootstrapComponents.ShardCoordinator(), + nc, + maxNodesConfig[0].MaxNumNodes, + ) + vmContainer, _ := metaVmFactory.Create() + + validatorStatisticsProcessor := createValidatorStatisticsProcessor( + dataComponents, + coreComponents, + nc, + bootstrapComponents.ShardCoordinator(), + stateComponents.PeerAccounts(), + ) + scp := createSystemSCProcessor( + nc, + coreComponents, + stateComponents, + bootstrapComponents.ShardCoordinator(), + maxNodesConfig, + validatorStatisticsProcessor, + vmContainer, + ) + + epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) + + eligible, _ := nc.GetAllEligibleValidatorsPublicKeys(0) + waiting, _ := nc.GetAllWaitingValidatorsPublicKeys(0) + shuffledOut, _ := nc.GetAllShuffledOutValidatorsPublicKeys(0) + + return &baseMetaProcessor{ + AccountsAdapter: stateComponents.AccountsAdapter(), + Marshaller: coreComponents.InternalMarshalizer(), + NodesConfig: nodesConfig{ + eligible: eligible, + waiting: waiting, + shuffledOut: shuffledOut, + queue: queue, + auction: make([][]byte, 0), + }, + MetaBlockProcessor: createMetaBlockProcessor( + nc, + scp, + coreComponents, + dataComponents, + bootstrapComponents, + statusComponents, + stateComponents, + validatorStatisticsProcessor, + blockChainHook, + metaVmFactory, + epochStartTrigger, + vmContainer, + ), + currentRound: 1, + NodesCoordinator: nc, + ValidatorStatistics: validatorStatisticsProcessor, + EpochStartTrigger: epochStartTrigger, + BlockChainHandler: dataComponents.Blockchain(), + } +} diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 9b383df5d42..fe6084cee5a 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -47,9 +47,9 @@ func createComponentHolders(numOfShards uint32) ( statusComponents := createStatusComponents() stateComponents := createStateComponents(coreComponents) dataComponents := createDataComponents(coreComponents, numOfShards) - boostrapComponents := createBootstrapComponents(coreComponents.InternalMarshalizer(), numOfShards) + bootstrapComponents := createBootstrapComponents(coreComponents.InternalMarshalizer(), numOfShards) - return coreComponents, dataComponents, boostrapComponents, statusComponents, stateComponents + return coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents } func createCoreComponents() factory.CoreComponentsHolder { diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 2ceb047073b..42342f7c9f9 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -24,27 +24,18 @@ const ( ) func createNodesCoordinator( + eligibleMap map[uint32][]nodesCoordinator.Validator, + waitingMap map[uint32][]nodesCoordinator.Validator, numOfMetaNodes uint32, numOfShards uint32, numOfEligibleNodesPerShard uint32, - numOfWaitingNodesPerShard uint32, shardConsensusGroupSize int, metaConsensusGroupSize int, coreComponents factory.CoreComponentsHolder, bootStorer storage.Storer, - stateComponents factory.StateComponentsHandler, nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, maxNodesConfig []config.MaxNodesChangeConfig, ) nodesCoordinator.NodesCoordinator { - eligibleMap, waitingMap := createGenesisNodes( - numOfMetaNodes, - numOfShards, - numOfEligibleNodesPerShard, - numOfWaitingNodesPerShard, - coreComponents.InternalMarshalizer(), - stateComponents, - ) - shufflerArgs := &nodesCoordinator.NodesShufflerArgs{ NodesShard: numOfEligibleNodesPerShard, NodesMeta: numOfMetaNodes, @@ -110,6 +101,39 @@ func createGenesisNodes( return eligibleValidators, waitingValidators } +func createGenesisNodesWithCustomConfig( + owners map[string]*OwnerStats, + marshaller marshal.Marshalizer, + stateComponents factory.StateComponentsHandler, +) (map[uint32][]nodesCoordinator.Validator, map[uint32][]nodesCoordinator.Validator) { + eligibleGenesis := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) + waitingGenesis := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) + + for _, ownerStats := range owners { + for shardID, ownerEligibleKeys := range ownerStats.EligibleBlsKeys { + for _, eligibleKey := range ownerEligibleKeys { + validator := integrationMocks.NewNodeInfo(eligibleKey, eligibleKey, shardID, initialRating) + eligibleGenesis[shardID] = append(eligibleGenesis[shardID], validator) + } + } + + for shardID, ownerWaitingKeys := range ownerStats.WaitingBlsKeys { + for _, waitingKey := range ownerWaitingKeys { + validator := integrationMocks.NewNodeInfo(waitingKey, waitingKey, shardID, initialRating) + waitingGenesis[shardID] = append(waitingGenesis[shardID], validator) + } + } + } + + eligible, _ := nodesCoordinator.NodesInfoToValidators(eligibleGenesis) + waiting, _ := nodesCoordinator.NodesInfoToValidators(waitingGenesis) + + registerValidators(eligible, stateComponents, marshaller, common.EligibleList) + registerValidators(waiting, stateComponents, marshaller, common.WaitingList) + + return eligible, waiting +} + func generateGenesisNodeInfoMap( numOfMetaNodes uint32, numOfShards uint32, diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index bdfd55d4bc5..9412cbc5625 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -5,6 +5,8 @@ import ( "math/big" "testing" + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go/config" "github.com/stretchr/testify/require" ) @@ -225,7 +227,7 @@ func TestStakingV4_CustomScenario(t *testing.T) { owner1 := "owner1" owner1StakedKeys := map[uint32][][]byte{ - 0: {[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")}, + core.MetachainShardId: {[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")}, } owner1StakingQueueKeys := [][]byte{ []byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5"), @@ -250,6 +252,13 @@ func TestStakingV4_CustomScenario(t *testing.T) { owner1: owner1Stats, owner2: owner2Stats, }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 4, + NodesToShufflePerShard: 2, + }, + }, } node := NewTestMetaProcessorWithCustomNodes(nodesConfig) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 7eb47a98414..284ba030f5d 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -13,17 +13,13 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/display" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" - "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/require" ) @@ -47,16 +43,7 @@ type nodesConfig struct { // TestMetaProcessor - type TestMetaProcessor struct { - MetaBlockProcessor process.BlockProcessor - NodesCoordinator nodesCoordinator.NodesCoordinator - ValidatorStatistics process.ValidatorStatisticsProcessor - EpochStartTrigger integrationTests.TestEpochStartTrigger - BlockChainHandler data.ChainHandler - NodesConfig nodesConfig - AccountsAdapter state.AccountsAdapter - Marshaller marshal.Marshalizer - - currentRound uint64 + *baseMetaProcessor } // NewTestMetaProcessor - @@ -87,91 +74,40 @@ func NewTestMetaProcessor( stateComponents.AccountsAdapter(), ) - nc := createNodesCoordinator( + eligibleMap, waitingMap := createGenesisNodes( numOfMetaNodes, numOfShards, numOfEligibleNodesPerShard, numOfWaitingNodesPerShard, + coreComponents.InternalMarshalizer(), + stateComponents, + ) + + nc := createNodesCoordinator( + eligibleMap, + waitingMap, + numOfMetaNodes, + numOfShards, + numOfEligibleNodesPerShard, shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), - stateComponents, bootstrapComponents.NodesCoordinatorRegistryFactory(), maxNodesConfig, ) - gasScheduleNotifier := createGasScheduleNotifier() - blockChainHook := createBlockChainHook( - dataComponents, coreComponents, - stateComponents.AccountsAdapter(), - bootstrapComponents.ShardCoordinator(), - gasScheduleNotifier, - ) - - metaVmFactory := createVMContainerFactory( - coreComponents, - gasScheduleNotifier, - blockChainHook, - stateComponents.PeerAccounts(), - bootstrapComponents.ShardCoordinator(), - nc, - maxNodesConfig[0].MaxNumNodes, - ) - vmContainer, _ := metaVmFactory.Create() - - validatorStatisticsProcessor := createValidatorStatisticsProcessor( - dataComponents, - coreComponents, - nc, - bootstrapComponents.ShardCoordinator(), - stateComponents.PeerAccounts(), - ) - scp := createSystemSCProcessor( - nc, - coreComponents, - stateComponents, - bootstrapComponents.ShardCoordinator(), - maxNodesConfig, - validatorStatisticsProcessor, - vmContainer, - ) - - epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) - - eligible, _ := nc.GetAllEligibleValidatorsPublicKeys(0) - waiting, _ := nc.GetAllWaitingValidatorsPublicKeys(0) - shuffledOut, _ := nc.GetAllShuffledOutValidatorsPublicKeys(0) - return &TestMetaProcessor{ - AccountsAdapter: stateComponents.AccountsAdapter(), - Marshaller: coreComponents.InternalMarshalizer(), - NodesConfig: nodesConfig{ - eligible: eligible, - waiting: waiting, - shuffledOut: shuffledOut, - queue: queue, - auction: make([][]byte, 0), - }, - MetaBlockProcessor: createMetaBlockProcessor( - nc, - scp, + newBaseMetaProcessor( coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents, - validatorStatisticsProcessor, - blockChainHook, - metaVmFactory, - epochStartTrigger, - vmContainer, + nc, + maxNodesConfig, + queue, ), - currentRound: 1, - NodesCoordinator: nc, - ValidatorStatistics: validatorStatisticsProcessor, - EpochStartTrigger: epochStartTrigger, - BlockChainHandler: dataComponents.Blockchain(), } } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 655354b434e..410f49be726 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -5,6 +5,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" ) @@ -17,9 +18,13 @@ type OwnerStats struct { } type InitialNodesConfig struct { - NumOfShards uint32 - Owners map[string]*OwnerStats - MaxNodesChangeConfig []config.MaxNodesChangeConfig + Owners map[string]*OwnerStats + MaxNodesChangeConfig []config.MaxNodesChangeConfig + NumOfShards uint32 + MinNumberOfEligibleShardNodes uint32 + MinNumberOfEligibleMetaNodes uint32 + ShardConsensusGroupSize int + MetaConsensusGroupSize int } func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaProcessor { @@ -35,12 +40,37 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr stateComponents.AccountsAdapter(), ) + eligibleMap, waitingMap := createGenesisNodesWithCustomConfig( + config.Owners, + coreComponents.InternalMarshalizer(), + stateComponents, + ) + + nc := createNodesCoordinator( + eligibleMap, + waitingMap, + config.MinNumberOfEligibleMetaNodes, + config.NumOfShards, + config.MinNumberOfEligibleShardNodes, + config.ShardConsensusGroupSize, + config.MetaConsensusGroupSize, + coreComponents, + dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), + bootstrapComponents.NodesCoordinatorRegistryFactory(), + config.MaxNodesChangeConfig, + ) + return &TestMetaProcessor{ - NodesConfig: nodesConfig{ - queue: queue, - }, - AccountsAdapter: stateComponents.AccountsAdapter(), - Marshaller: coreComponents.InternalMarshalizer(), + newBaseMetaProcessor( + coreComponents, + dataComponents, + bootstrapComponents, + statusComponents, + stateComponents, + nc, + config.MaxNodesChangeConfig, + queue, + ), } } From 7ce5ebb2ca4be9f8b26fd3398c20b890d0ae58d0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 4 May 2022 12:35:01 +0300 Subject: [PATCH 232/958] FIX: Test + Process 1 epoch --- .../vm/staking/baseTestMetaProcessor.go | 24 ++---------- integrationTests/vm/staking/stakingV4_test.go | 7 +++- .../vm/staking/testMetaProcessor.go | 37 ++++++++++++------- .../testMetaProcessorWithCustomNodesConfig.go | 22 +++++------ 4 files changed, 43 insertions(+), 47 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index e03822b2fc5..d6d5672155b 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -1,30 +1,12 @@ package staking import ( - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/factory" - "github.com/ElrondNetwork/elrond-go/integrationTests" - "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" ) -type baseMetaProcessor struct { - MetaBlockProcessor process.BlockProcessor - NodesCoordinator nodesCoordinator.NodesCoordinator - ValidatorStatistics process.ValidatorStatisticsProcessor - EpochStartTrigger integrationTests.TestEpochStartTrigger - BlockChainHandler data.ChainHandler - NodesConfig nodesConfig - AccountsAdapter state.AccountsAdapter - Marshaller marshal.Marshalizer - - currentRound uint64 -} - -func newBaseMetaProcessor( +func newTestMetaProcessor( coreComponents factory.CoreComponentsHolder, dataComponents factory.DataComponentsHolder, bootstrapComponents factory.BootstrapComponentsHolder, @@ -33,7 +15,7 @@ func newBaseMetaProcessor( nc nodesCoordinator.NodesCoordinator, maxNodesConfig []config.MaxNodesChangeConfig, queue [][]byte, -) *baseMetaProcessor { +) *TestMetaProcessor { gasScheduleNotifier := createGasScheduleNotifier() blockChainHook := createBlockChainHook( dataComponents, coreComponents, @@ -76,7 +58,7 @@ func newBaseMetaProcessor( waiting, _ := nc.GetAllWaitingValidatorsPublicKeys(0) shuffledOut, _ := nc.GetAllShuffledOutValidatorsPublicKeys(0) - return &baseMetaProcessor{ + return &TestMetaProcessor{ AccountsAdapter: stateComponents.AccountsAdapter(), Marshaller: coreComponents.InternalMarshalizer(), NodesConfig: nodesConfig{ diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 9412cbc5625..f54181dbf25 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -248,6 +248,11 @@ func TestStakingV4_CustomScenario(t *testing.T) { } nodesConfig := &InitialNodesConfig{ + MetaConsensusGroupSize: 2, + ShardConsensusGroupSize: 1, + MinNumberOfEligibleShardNodes: 1, + MinNumberOfEligibleMetaNodes: 1, + NumOfShards: 2, Owners: map[string]*OwnerStats{ owner1: owner1Stats, owner2: owner2Stats, @@ -263,7 +268,7 @@ func TestStakingV4_CustomScenario(t *testing.T) { node := NewTestMetaProcessorWithCustomNodes(nodesConfig) waiting := node.getWaitingListKeys() - + node.Process(t, 1) _ = waiting _ = node } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 284ba030f5d..3a50ccc7dbd 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -13,13 +13,17 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/display" + "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" + "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/require" ) @@ -43,7 +47,16 @@ type nodesConfig struct { // TestMetaProcessor - type TestMetaProcessor struct { - *baseMetaProcessor + MetaBlockProcessor process.BlockProcessor + NodesCoordinator nodesCoordinator.NodesCoordinator + ValidatorStatistics process.ValidatorStatisticsProcessor + EpochStartTrigger integrationTests.TestEpochStartTrigger + BlockChainHandler data.ChainHandler + NodesConfig nodesConfig + AccountsAdapter state.AccountsAdapter + Marshaller marshal.Marshalizer + + currentRound uint64 } // NewTestMetaProcessor - @@ -97,18 +110,16 @@ func NewTestMetaProcessor( maxNodesConfig, ) - return &TestMetaProcessor{ - newBaseMetaProcessor( - coreComponents, - dataComponents, - bootstrapComponents, - statusComponents, - stateComponents, - nc, - maxNodesConfig, - queue, - ), - } + return newTestMetaProcessor( + coreComponents, + dataComponents, + bootstrapComponents, + statusComponents, + stateComponents, + nc, + maxNodesConfig, + queue, + ) } func createMaxNodesConfig( diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 410f49be726..0b65503791f 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -60,18 +60,16 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr config.MaxNodesChangeConfig, ) - return &TestMetaProcessor{ - newBaseMetaProcessor( - coreComponents, - dataComponents, - bootstrapComponents, - statusComponents, - stateComponents, - nc, - config.MaxNodesChangeConfig, - queue, - ), - } + return newTestMetaProcessor( + coreComponents, + dataComponents, + bootstrapComponents, + statusComponents, + stateComponents, + nc, + config.MaxNodesChangeConfig, + queue, + ) } func createStakingQueueCustomNodes( From defec49c713345d8f0a4bfe97ea951547d42702b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 4 May 2022 17:59:56 +0300 Subject: [PATCH 233/958] FIX: Bug in AddValidatorData --- epochStart/metachain/systemSCs.go | 8 +--- epochStart/metachain/systemSCs_test.go | 36 ++++----------- .../vm/staking/baseTestMetaProcessor.go | 37 +++++++++++++++ .../vm/staking/nodesCoordiantorCreator.go | 44 ++++++++++++++++-- integrationTests/vm/staking/stakingV4_test.go | 26 +++++------ .../vm/staking/testMetaProcessor.go | 45 +++++-------------- testscommon/stakingcommon/stakingCommon.go | 26 +++++++---- 7 files changed, 129 insertions(+), 93 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index fb700dba120..65f92989457 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -14,7 +14,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -320,7 +319,7 @@ func calcNormRand(randomness []byte, expectedLen int) []byte { randLen := len(rand) if expectedLen > randLen { - repeatedCt := expectedLen/randLen + 1 + repeatedCt := expectedLen/randLen + 1 // todo: fix possible div by 0 rand = bytes.Repeat(randomness, repeatedCt) } @@ -343,9 +342,6 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - if log.GetLevel() > logger.LogDebug { - return - } tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -375,7 +371,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Debug(message) + log.Info(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f4a22520eca..93448be71e9 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1293,7 +1293,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra args.Marshalizer, ) allKeys := [][]byte{[]byte("stakedPubKey0"), []byte("waitingPubKey"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")} - stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allKeys, big.NewInt(3000), args.Marshalizer) + stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allKeys[2:], big.NewInt(3000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1369,20 +1369,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractShouldUnStakeFromAdditional contract, _ := scContainer.Get(vm.FirstDelegationSCAddress) _ = scContainer.Add(delegationAddr, contract) - prepareStakingContractWithData( - args.UserAccountsDB, - []byte("stakedPubKey0"), - []byte("waitingPubKey"), - args.Marshalizer, - delegationAddr, - delegationAddr, - ) + listOfKeysInWaiting := [][]byte{[]byte("waitingPubKey"), []byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} + allStakedKeys := append(listOfKeysInWaiting, []byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")) - stakingcommon.AddStakingData(args.UserAccountsDB, delegationAddr, delegationAddr, [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, args.Marshalizer) - listOfKeysInWaiting := [][]byte{[]byte("waitingPubKe1"), []byte("waitingPubKe2"), []byte("waitingPubKe3"), []byte("waitingPubKe4")} - allStakedKeys := append(listOfKeysInWaiting, []byte("waitingPubKey"), []byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, delegationAddr, delegationAddr, allStakedKeys, big.NewInt(4000), args.Marshalizer) stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, listOfKeysInWaiting, args.Marshalizer, delegationAddr, delegationAddr) - stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allStakedKeys, big.NewInt(4000), args.Marshalizer) addDelegationData(args.UserAccountsDB, delegationAddr, allStakedKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() @@ -1712,7 +1703,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) owner1ListPubKeysWaiting := [][]byte{[]byte("waitingPubKe0"), []byte("waitingPubKe1"), []byte("waitingPubKe2")} owner1ListPubKeysStaked := [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1")} - owner1AllPubKeys := append(owner1ListPubKeysWaiting, owner1ListPubKeysWaiting...) + owner1AllPubKeys := append(owner1ListPubKeysWaiting, owner1ListPubKeysStaked...) owner2ListPubKeysWaiting := [][]byte{[]byte("waitingPubKe3"), []byte("waitingPubKe4")} owner2ListPubKeysStaked := [][]byte{[]byte("stakedPubKey2")} @@ -1720,29 +1711,20 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) owner3ListPubKeysWaiting := [][]byte{[]byte("waitingPubKe5"), []byte("waitingPubKe6")} - prepareStakingContractWithData( - args.UserAccountsDB, - owner1ListPubKeysStaked[0], - owner1ListPubKeysWaiting[0], - args.Marshalizer, - owner1, - owner1, - ) - // Owner1 has 2 staked nodes (one eligible, one waiting) in shard0 + 3 nodes in staking queue. // It has enough stake so that all his staking queue nodes will be selected in the auction list - stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting[1:], args.Marshalizer, owner1, owner1) - stakingcommon.AddValidatorData(args.UserAccountsDB, owner1, owner1AllPubKeys[1:], big.NewInt(5000), args.Marshalizer) + stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner1ListPubKeysWaiting, args.Marshalizer, owner1, owner1) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1AllPubKeys, big.NewInt(5000), args.Marshalizer) // Owner2 has 1 staked node (eligible) in shard1 + 2 nodes in staking queue. // It has enough stake for only ONE node from staking queue to be selected in the auction list stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner2ListPubKeysWaiting, args.Marshalizer, owner2, owner2) - stakingcommon.AddValidatorData(args.UserAccountsDB, owner2, owner2AllPubKeys, big.NewInt(1500), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2AllPubKeys, big.NewInt(2500), args.Marshalizer) // Owner3 has 0 staked node + 2 nodes in staking queue. // It has enough stake so that all his staking queue nodes will be selected in the auction list stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, owner3ListPubKeysWaiting, args.Marshalizer, owner3, owner3) - stakingcommon.AddValidatorData(args.UserAccountsDB, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index d6d5672155b..7ec2a8d56bc 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -1,9 +1,16 @@ package staking import ( + arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" + "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" + "github.com/ElrondNetwork/elrond-go/integrationTests" + "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" ) func newTestMetaProcessor( @@ -89,3 +96,33 @@ func newTestMetaProcessor( BlockChainHandler: dataComponents.Blockchain(), } } + +func createGasScheduleNotifier() core.GasScheduleNotifier { + gasSchedule := arwenConfig.MakeGasMapForTests() + defaults.FillGasMapInternal(gasSchedule, 1) + return mock.NewGasScheduleNotifierMock(gasSchedule) +} + +func createEpochStartTrigger( + coreComponents factory.CoreComponentsHolder, + storageService dataRetriever.StorageService, +) integrationTests.TestEpochStartTrigger { + argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ + Settings: &config.EpochStartConfig{ + MinRoundsBetweenEpochs: 10, + RoundsPerEpoch: 10, + }, + Epoch: 0, + EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), + Storage: storageService, + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + AppStatusHandler: coreComponents.StatusHandler(), + } + + epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) + testTrigger := &metachain.TestTrigger{} + testTrigger.SetTrigger(epochStartTrigger) + + return testTrigger +} diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 42342f7c9f9..b68966fee40 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -109,11 +109,30 @@ func createGenesisNodesWithCustomConfig( eligibleGenesis := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) waitingGenesis := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - for _, ownerStats := range owners { + for owner, ownerStats := range owners { for shardID, ownerEligibleKeys := range ownerStats.EligibleBlsKeys { for _, eligibleKey := range ownerEligibleKeys { validator := integrationMocks.NewNodeInfo(eligibleKey, eligibleKey, shardID, initialRating) eligibleGenesis[shardID] = append(eligibleGenesis[shardID], validator) + + pubKey := validator.PubKeyBytes() + + peerAccount, _ := state.NewPeerAccount(pubKey) + peerAccount.SetTempRating(initialRating) + peerAccount.ShardId = shardID + peerAccount.BLSPublicKey = pubKey + peerAccount.List = string(common.EligibleList) + _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) + + stakingcommon.RegisterValidatorKeys( + stateComponents.AccountsAdapter(), + []byte(owner), + []byte(owner), + [][]byte{pubKey}, + ownerStats.TotalStake, + marshaller, + ) + } } @@ -121,6 +140,25 @@ func createGenesisNodesWithCustomConfig( for _, waitingKey := range ownerWaitingKeys { validator := integrationMocks.NewNodeInfo(waitingKey, waitingKey, shardID, initialRating) waitingGenesis[shardID] = append(waitingGenesis[shardID], validator) + + pubKey := validator.PubKeyBytes() + + peerAccount, _ := state.NewPeerAccount(pubKey) + peerAccount.SetTempRating(initialRating) + peerAccount.ShardId = shardID + peerAccount.BLSPublicKey = pubKey + peerAccount.List = string(common.WaitingList) + _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) + + stakingcommon.RegisterValidatorKeys( + stateComponents.AccountsAdapter(), + []byte(owner), + []byte(owner), + [][]byte{pubKey}, + ownerStats.TotalStake, + marshaller, + ) + } } } @@ -128,8 +166,8 @@ func createGenesisNodesWithCustomConfig( eligible, _ := nodesCoordinator.NodesInfoToValidators(eligibleGenesis) waiting, _ := nodesCoordinator.NodesInfoToValidators(waitingGenesis) - registerValidators(eligible, stateComponents, marshaller, common.EligibleList) - registerValidators(waiting, stateComponents, marshaller, common.WaitingList) + //registerValidators(eligible, stateComponents, marshaller, common.EligibleList) + //registerValidators(waiting, stateComponents, marshaller, common.WaitingList) return eligible, waiting } diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index f54181dbf25..2ce32f4f17b 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/ElrondNetwork/elrond-go-core/core" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/config" "github.com/stretchr/testify/require" ) @@ -224,14 +225,15 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH } func TestStakingV4_CustomScenario(t *testing.T) { - owner1 := "owner1" + pubKeys := generateAddresses(0, 20) + owner1 := "owner1" + logger.SetLogLevel("*:DEBUG") owner1StakedKeys := map[uint32][][]byte{ - core.MetachainShardId: {[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")}, - } - owner1StakingQueueKeys := [][]byte{ - []byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5"), + core.MetachainShardId: {pubKeys[0], pubKeys[1], pubKeys[2]}, + 0: {pubKeys[3], pubKeys[4], pubKeys[5], pubKeys[6], pubKeys[7], pubKeys[8]}, } + owner1StakingQueueKeys := [][]byte{pubKeys[9], pubKeys[10], pubKeys[11]} owner1Stats := &OwnerStats{ EligibleBlsKeys: owner1StakedKeys, StakingQueueKeys: owner1StakingQueueKeys, @@ -239,9 +241,7 @@ func TestStakingV4_CustomScenario(t *testing.T) { } owner2 := "owner2" - owner2StakingQueueKeys := [][]byte{ - []byte("pubKey6"), []byte("pubKey7"), []byte("pubKey8"), - } + owner2StakingQueueKeys := [][]byte{pubKeys[12], pubKeys[13], pubKeys[14]} owner2Stats := &OwnerStats{ StakingQueueKeys: owner2StakingQueueKeys, TotalStake: big.NewInt(5000), @@ -265,10 +265,10 @@ func TestStakingV4_CustomScenario(t *testing.T) { }, }, } - + //todo; check that in epoch = staking v4 nodes with not enough stake will be unstaked node := NewTestMetaProcessorWithCustomNodes(nodesConfig) - waiting := node.getWaitingListKeys() - node.Process(t, 1) - _ = waiting - _ = node + node.EpochStartTrigger.SetRoundsPerEpoch(5) + + node.Process(t, 20) + } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 3a50ccc7dbd..357e212a7ac 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -8,7 +8,6 @@ import ( "testing" "time" - arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" @@ -17,14 +16,10 @@ import ( "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/require" ) @@ -151,36 +146,6 @@ func createMaxNodesConfig( return maxNodesConfig } -func createGasScheduleNotifier() core.GasScheduleNotifier { - gasSchedule := arwenConfig.MakeGasMapForTests() - defaults.FillGasMapInternal(gasSchedule, 1) - return mock.NewGasScheduleNotifierMock(gasSchedule) -} - -func createEpochStartTrigger( - coreComponents factory.CoreComponentsHolder, - storageService dataRetriever.StorageService, -) integrationTests.TestEpochStartTrigger { - argsEpochStart := &metachain.ArgsNewMetaEpochStartTrigger{ - Settings: &config.EpochStartConfig{ - MinRoundsBetweenEpochs: 10, - RoundsPerEpoch: 10, - }, - Epoch: 0, - EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - Storage: storageService, - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - AppStatusHandler: coreComponents.StatusHandler(), - } - - epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) - testTrigger := &metachain.TestTrigger{} - testTrigger.SetTrigger(epochStartTrigger) - - return testTrigger -} - // Process - func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { for r := tmp.currentRound; r < tmp.currentRound+numOfRounds; r++ { @@ -305,6 +270,16 @@ func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { tmp.NodesConfig.queue = tmp.getWaitingListKeys() } +func generateAddresses(startIdx, n uint32) [][]byte { + ret := make([][]byte, 0, n) + + for i := startIdx; i < n+startIdx; i++ { + ret = append(ret, generateAddress(i)) + } + + return ret +} + func generateAddress(identifier uint32) []byte { uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 6fe84206a17..1ffe56e9683 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -42,15 +42,23 @@ func AddValidatorData( marshaller marshal.Marshalizer, ) { validatorSC := LoadUserAccount(accountsDB, vm.ValidatorSCAddress) - validatorData := &systemSmartContracts.ValidatorDataV2{ - RegisterNonce: 0, - Epoch: 0, - RewardAddress: ownerKey, - TotalStakeValue: totalStake, - LockedStake: big.NewInt(0), - TotalUnstaked: big.NewInt(0), - BlsPubKeys: registeredKeys, - NumRegistered: uint32(len(registeredKeys)), + ownerStoredData, _ := validatorSC.DataTrieTracker().RetrieveValue(ownerKey) + validatorData := &systemSmartContracts.ValidatorDataV2{} + if len(ownerStoredData) != 0 { + _ = marshaller.Unmarshal(validatorData, ownerStoredData) + validatorData.BlsPubKeys = append(validatorData.BlsPubKeys, registeredKeys...) + validatorData.TotalStakeValue = totalStake + } else { + validatorData = &systemSmartContracts.ValidatorDataV2{ + RegisterNonce: 0, + Epoch: 0, + RewardAddress: ownerKey, + TotalStakeValue: totalStake, + LockedStake: big.NewInt(0), + TotalUnstaked: big.NewInt(0), + BlsPubKeys: registeredKeys, + NumRegistered: uint32(len(registeredKeys)), + } } marshaledData, _ := marshaller.Marshal(validatorData) From 0dd1fa28b19a858e915184ba980675a827b745ff Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 5 May 2022 10:58:05 +0300 Subject: [PATCH 234/958] FIX: Revert unwanted changes --- epochStart/metachain/systemSCs.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 65f92989457..9408e07d980 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -14,6 +14,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -342,6 +343,9 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { + if log.GetLevel() > logger.LogDebug { + return + } tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -371,7 +375,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Info(message) + log.Debug(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { From c8ad033bbc7561aa6522882f4ec6bfa8f76fd4a4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 5 May 2022 13:05:45 +0300 Subject: [PATCH 235/958] FIX: Some refactor --- .../vm/staking/nodesCoordiantorCreator.go | 122 +++++++++--------- integrationTests/vm/staking/stakingV4_test.go | 28 ++-- 2 files changed, 74 insertions(+), 76 deletions(-) diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index b68966fee40..163e312174d 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -110,65 +110,30 @@ func createGenesisNodesWithCustomConfig( waitingGenesis := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) for owner, ownerStats := range owners { - for shardID, ownerEligibleKeys := range ownerStats.EligibleBlsKeys { - for _, eligibleKey := range ownerEligibleKeys { - validator := integrationMocks.NewNodeInfo(eligibleKey, eligibleKey, shardID, initialRating) - eligibleGenesis[shardID] = append(eligibleGenesis[shardID], validator) - - pubKey := validator.PubKeyBytes() - - peerAccount, _ := state.NewPeerAccount(pubKey) - peerAccount.SetTempRating(initialRating) - peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = pubKey - peerAccount.List = string(common.EligibleList) - _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) - - stakingcommon.RegisterValidatorKeys( - stateComponents.AccountsAdapter(), - []byte(owner), - []byte(owner), - [][]byte{pubKey}, - ownerStats.TotalStake, - marshaller, - ) - - } - } - - for shardID, ownerWaitingKeys := range ownerStats.WaitingBlsKeys { - for _, waitingKey := range ownerWaitingKeys { - validator := integrationMocks.NewNodeInfo(waitingKey, waitingKey, shardID, initialRating) - waitingGenesis[shardID] = append(waitingGenesis[shardID], validator) - - pubKey := validator.PubKeyBytes() - - peerAccount, _ := state.NewPeerAccount(pubKey) - peerAccount.SetTempRating(initialRating) - peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = pubKey - peerAccount.List = string(common.WaitingList) - _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) - - stakingcommon.RegisterValidatorKeys( - stateComponents.AccountsAdapter(), - []byte(owner), - []byte(owner), - [][]byte{pubKey}, - ownerStats.TotalStake, - marshaller, - ) - - } - } + registerOwnerKeys( + []byte(owner), + ownerStats.EligibleBlsKeys, + ownerStats.TotalStake, + stateComponents, + marshaller, + common.EligibleList, + eligibleGenesis, + ) + + registerOwnerKeys( + []byte(owner), + ownerStats.WaitingBlsKeys, + ownerStats.TotalStake, + stateComponents, + marshaller, + common.WaitingList, + waitingGenesis, + ) } eligible, _ := nodesCoordinator.NodesInfoToValidators(eligibleGenesis) waiting, _ := nodesCoordinator.NodesInfoToValidators(waitingGenesis) - //registerValidators(eligible, stateComponents, marshaller, common.EligibleList) - //registerValidators(waiting, stateComponents, marshaller, common.WaitingList) - return eligible, waiting } @@ -199,6 +164,33 @@ func generateGenesisNodeInfoMap( return validatorsMap } +func registerOwnerKeys( + owner []byte, + ownerPubKeys map[uint32][][]byte, + totalStake *big.Int, + stateComponents factory.StateComponentsHolder, + marshaller marshal.Marshalizer, + list common.PeerType, + allNodes map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, +) { + for shardID, pubKeysInShard := range ownerPubKeys { + for _, pubKey := range pubKeysInShard { + validator := integrationMocks.NewNodeInfo(pubKey, pubKey, shardID, initialRating) + allNodes[shardID] = append(allNodes[shardID], validator) + + savePeerAcc(stateComponents, pubKey, shardID, list) + } + stakingcommon.RegisterValidatorKeys( + stateComponents.AccountsAdapter(), + owner, + owner, + pubKeysInShard, + totalStake, + marshaller, + ) + } +} + func registerValidators( validators map[uint32][]nodesCoordinator.Validator, stateComponents factory.StateComponentsHolder, @@ -208,13 +200,7 @@ func registerValidators( for shardID, validatorsInShard := range validators { for _, val := range validatorsInShard { pubKey := val.PubKey() - - peerAccount, _ := state.NewPeerAccount(pubKey) - peerAccount.SetTempRating(initialRating) - peerAccount.ShardId = shardID - peerAccount.BLSPublicKey = pubKey - peerAccount.List = string(list) - _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) + savePeerAcc(stateComponents, pubKey, shardID, list) stakingcommon.RegisterValidatorKeys( stateComponents.AccountsAdapter(), @@ -227,3 +213,17 @@ func registerValidators( } } } + +func savePeerAcc( + stateComponents factory.StateComponentsHolder, + pubKey []byte, + shardID uint32, + list common.PeerType, +) { + peerAccount, _ := state.NewPeerAccount(pubKey) + peerAccount.SetTempRating(initialRating) + peerAccount.ShardId = shardID + peerAccount.BLSPublicKey = pubKey + peerAccount.List = string(list) + _ = stateComponents.PeerAccounts().SaveAccount(peerAccount) +} diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 2ce32f4f17b..09415366322 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/ElrondNetwork/elrond-go-core/core" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/config" "github.com/stretchr/testify/require" ) @@ -227,16 +226,15 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH func TestStakingV4_CustomScenario(t *testing.T) { pubKeys := generateAddresses(0, 20) + //_ = logger.SetLogLevel("*:DEBUG") + owner1 := "owner1" - logger.SetLogLevel("*:DEBUG") - owner1StakedKeys := map[uint32][][]byte{ - core.MetachainShardId: {pubKeys[0], pubKeys[1], pubKeys[2]}, - 0: {pubKeys[3], pubKeys[4], pubKeys[5], pubKeys[6], pubKeys[7], pubKeys[8]}, - } - owner1StakingQueueKeys := [][]byte{pubKeys[9], pubKeys[10], pubKeys[11]} owner1Stats := &OwnerStats{ - EligibleBlsKeys: owner1StakedKeys, - StakingQueueKeys: owner1StakingQueueKeys, + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:3], + 0: pubKeys[3:6], + }, + StakingQueueKeys: pubKeys[6:9], TotalStake: big.NewInt(5000), } @@ -247,11 +245,11 @@ func TestStakingV4_CustomScenario(t *testing.T) { TotalStake: big.NewInt(5000), } - nodesConfig := &InitialNodesConfig{ + cfg := &InitialNodesConfig{ MetaConsensusGroupSize: 2, - ShardConsensusGroupSize: 1, - MinNumberOfEligibleShardNodes: 1, - MinNumberOfEligibleMetaNodes: 1, + ShardConsensusGroupSize: 2, + MinNumberOfEligibleShardNodes: 2, + MinNumberOfEligibleMetaNodes: 2, NumOfShards: 2, Owners: map[string]*OwnerStats{ owner1: owner1Stats, @@ -266,9 +264,9 @@ func TestStakingV4_CustomScenario(t *testing.T) { }, } //todo; check that in epoch = staking v4 nodes with not enough stake will be unstaked - node := NewTestMetaProcessorWithCustomNodes(nodesConfig) + node := NewTestMetaProcessorWithCustomNodes(cfg) node.EpochStartTrigger.SetRoundsPerEpoch(5) - node.Process(t, 20) + node.Process(t, 16) } From b48c536af1eec9c9860160cccad1ca62cf726383 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 6 May 2022 16:50:27 +0300 Subject: [PATCH 236/958] FEAT: First very ugly version of stake tx --- .../vm/staking/baseTestMetaProcessor.go | 10 +- .../vm/staking/componentsHolderCreator.go | 2 +- .../vm/staking/metaBlockProcessorCreator.go | 44 ++++-- integrationTests/vm/staking/stakingV4_test.go | 57 ++++++- .../vm/staking/systemSCCreator.go | 5 +- .../vm/staking/testMetaProcessor.go | 140 +++++++++++++++++- process/mock/transactionCoordinatorMock.go | 5 +- 7 files changed, 241 insertions(+), 22 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 7ec2a8d56bc..f040902e0b1 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -8,6 +8,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" + vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" @@ -41,6 +42,7 @@ func newTestMetaProcessor( maxNodesConfig[0].MaxNumNodes, ) vmContainer, _ := metaVmFactory.Create() + systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) validatorStatisticsProcessor := createValidatorStatisticsProcessor( dataComponents, @@ -56,9 +58,10 @@ func newTestMetaProcessor( bootstrapComponents.ShardCoordinator(), maxNodesConfig, validatorStatisticsProcessor, - vmContainer, + systemVM, ) + txCoordinator := &mock.TransactionCoordinatorMock{} epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) eligible, _ := nc.GetAllEligibleValidatorsPublicKeys(0) @@ -88,12 +91,17 @@ func newTestMetaProcessor( metaVmFactory, epochStartTrigger, vmContainer, + txCoordinator, ), currentRound: 1, NodesCoordinator: nc, ValidatorStatistics: validatorStatisticsProcessor, EpochStartTrigger: epochStartTrigger, BlockChainHandler: dataComponents.Blockchain(), + TxCacher: dataComponents.Datapool().CurrentBlockTxs(), + TxCoordinator: txCoordinator, + SystemVM: systemVM, + StateComponents: stateComponents, } } diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index fe6084cee5a..75ad541f378 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -62,7 +62,7 @@ func createCoreComponents() factory.CoreComponentsHolder { EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), EpochNotifierField: forking.NewGenericEpochNotifier(), RaterField: &testscommon.RaterMock{Chance: 5}, - AddressPubKeyConverterField: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverterField: testscommon.NewPubkeyConverterMock(addressLength), EconomicsDataField: stakingcommon.CreateEconomicsData(), ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), NodeTypeProviderField: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 481ac9183a7..126d5a90c13 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -7,7 +7,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/dataRetriever/dataPool" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" @@ -17,6 +16,8 @@ import ( "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" "github.com/ElrondNetwork/elrond-go/process/block/postprocess" "github.com/ElrondNetwork/elrond-go/process/mock" + "github.com/ElrondNetwork/elrond-go/process/scToProtocol" + "github.com/ElrondNetwork/elrond-go/process/smartContract" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" @@ -37,14 +38,16 @@ func createMetaBlockProcessor( metaVMFactory process.VirtualMachinesContainerFactory, epochStartHandler process.EpochStartTriggerHandler, vmContainer process.VirtualMachinesContainer, + txCoordinator process.TransactionCoordinator, ) process.BlockProcessor { - shardCoordiantor := bootstrapComponents.ShardCoordinator() - - blockTracker := createBlockTracker(dataComponents.Blockchain().GetGenesisHeader(), shardCoordiantor) + blockTracker := createBlockTracker( + dataComponents.Blockchain().GetGenesisHeader(), + bootstrapComponents.ShardCoordinator(), + ) epochStartDataCreator := createEpochStartDataCreator( coreComponents, dataComponents, - shardCoordiantor, + bootstrapComponents.ShardCoordinator(), epochStartHandler, blockTracker, ) @@ -59,7 +62,9 @@ func createMetaBlockProcessor( ) headerValidator := createHeaderValidator(coreComponents) - valInfoCreator := createValidatorInfoCreator(coreComponents, dataComponents, shardCoordiantor) + valInfoCreator := createValidatorInfoCreator(coreComponents, dataComponents, bootstrapComponents.ShardCoordinator()) + stakingToPeer := createSCToProtocol(coreComponents, stateComponents, dataComponents.Datapool().CurrentBlockTxs()) + args := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ CoreComponents: coreComponents, @@ -72,7 +77,7 @@ func createMetaBlockProcessor( FeeHandler: postprocess.NewFeeAccumulator(), RequestHandler: &testscommon.RequestHandlerStub{}, BlockChainHook: blockChainHook, - TxCoordinator: &mock.TransactionCoordinatorMock{}, + TxCoordinator: txCoordinator, EpochStartTrigger: epochStartHandler, HeaderValidator: headerValidator, GasHandler: &mock.GasHandlerMock{}, @@ -87,13 +92,13 @@ func createMetaBlockProcessor( VMContainersFactory: metaVMFactory, VmContainer: vmContainer, }, - SCToProtocol: &mock.SCToProtocolStub{}, + SCToProtocol: stakingToPeer, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, EpochStartDataCreator: epochStartDataCreator, EpochEconomics: &mock.EpochEconomicsStub{}, EpochRewardsCreator: &testscommon.RewardsCreatorStub{ GetLocalTxCacheCalled: func() epochStart.TransactionCacher { - return dataPool.NewCurrentBlockPool() + return dataComponents.Datapool().CurrentBlockTxs() }, }, EpochValidatorInfoCreator: valInfoCreator, @@ -200,3 +205,24 @@ func createHeaderValidator(coreComponents factory.CoreComponentsHolder) epochSta headerValidator, _ := blproc.NewHeaderValidator(argsHeaderValidator) return headerValidator } + +func createSCToProtocol( + coreComponents factory.CoreComponentsHolder, + stateComponents factory.StateComponentsHandler, + txCacher dataRetriever.TransactionCacher, +) process.SmartContractToProtocolHandler { + args := scToProtocol.ArgStakingToPeer{ + PubkeyConv: coreComponents.AddressPubKeyConverter(), + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + PeerState: stateComponents.PeerAccounts(), + BaseState: stateComponents.AccountsAdapter(), + ArgParser: smartContract.NewArgumentParser(), + CurrTxs: txCacher, + RatingsData: &mock.RatingsInfoMock{}, + EpochNotifier: coreComponents.EpochNotifier(), + StakingV4InitEpoch: stakingV4InitEpoch, + } + stakingToPeer, _ := scToProtocol.NewStakingToPeer(args) + return stakingToPeer +} diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 09415366322..16d418bc878 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/ElrondNetwork/elrond-go-core/core" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/config" "github.com/stretchr/testify/require" ) @@ -224,9 +225,9 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH } func TestStakingV4_CustomScenario(t *testing.T) { - pubKeys := generateAddresses(0, 20) + pubKeys := generateAddresses(0, 30) - //_ = logger.SetLogLevel("*:DEBUG") + _ = logger.SetLogLevel("*:DEBUG") owner1 := "owner1" owner1Stats := &OwnerStats{ @@ -239,9 +240,49 @@ func TestStakingV4_CustomScenario(t *testing.T) { } owner2 := "owner2" - owner2StakingQueueKeys := [][]byte{pubKeys[12], pubKeys[13], pubKeys[14]} owner2Stats := &OwnerStats{ - StakingQueueKeys: owner2StakingQueueKeys, + EligibleBlsKeys: map[uint32][][]byte{ + 1: pubKeys[9:10], + 2: pubKeys[10:11], + }, + WaitingBlsKeys: map[uint32][][]byte{ + 0: pubKeys[11:12], + 1: pubKeys[12:13], + 2: pubKeys[13:14], + }, + TotalStake: big.NewInt(5000), + } + + owner3 := "owner3" + owner3Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[14:15], + }, + WaitingBlsKeys: map[uint32][][]byte{ + 0: pubKeys[15:16], + }, + TotalStake: big.NewInt(5000), + } + + owner4 := "owner4" + owner4Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + 0: pubKeys[16:19], + 1: pubKeys[19:21], + 2: pubKeys[21:23], + }, + TotalStake: big.NewInt(5000), + } + + owner5 := "owner5" + owner5Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[23:25], + TotalStake: big.NewInt(5000), + } + + owner6 := "owner6" + owner6Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[25:26], TotalStake: big.NewInt(5000), } @@ -250,10 +291,14 @@ func TestStakingV4_CustomScenario(t *testing.T) { ShardConsensusGroupSize: 2, MinNumberOfEligibleShardNodes: 2, MinNumberOfEligibleMetaNodes: 2, - NumOfShards: 2, + NumOfShards: 4, Owners: map[string]*OwnerStats{ owner1: owner1Stats, owner2: owner2Stats, + owner3: owner3Stats, + owner4: owner4Stats, + owner5: owner5Stats, + owner6: owner6Stats, }, MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { @@ -267,6 +312,6 @@ func TestStakingV4_CustomScenario(t *testing.T) { node := NewTestMetaProcessorWithCustomNodes(cfg) node.EpochStartTrigger.SetRoundsPerEpoch(5) - node.Process(t, 16) + node.Process(t, 25) } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 0ef240a12f1..de94f0bd118 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -11,7 +11,6 @@ import ( "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" - vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/process/peer" @@ -23,6 +22,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" "github.com/ElrondNetwork/elrond-go/vm" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" ) func createSystemSCProcessor( @@ -32,9 +32,8 @@ func createSystemSCProcessor( shardCoordinator sharding.Coordinator, maxNodesConfig []config.MaxNodesChangeConfig, validatorStatisticsProcessor process.ValidatorStatisticsProcessor, - vmContainer process.VirtualMachinesContainer, + systemVM vmcommon.VMExecutionHandler, ) process.EpochStartSystemSCProcessor { - systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) argsStakingDataProvider := metachain.StakingDataProviderArgs{ EpochNotifier: coreComponents.EpochNotifier(), SystemVM: systemVM, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 357e212a7ac..56324fbbb44 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,6 +1,8 @@ package staking import ( + "bytes" + "encoding/hex" "fmt" "math/big" "strconv" @@ -11,15 +13,20 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/ElrondNetwork/elrond-go/vm" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" ) @@ -50,6 +57,10 @@ type TestMetaProcessor struct { NodesConfig nodesConfig AccountsAdapter state.AccountsAdapter Marshaller marshal.Marshalizer + TxCacher dataRetriever.TransactionCacher + TxCoordinator process.TransactionCoordinator + SystemVM vmcommon.VMExecutionHandler + StateComponents factory.StateComponentsHolder currentRound uint64 } @@ -164,7 +175,109 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), ) - newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, func() bool { return true }) + haveTime := func() bool { return true } + + if r == 17 && numOfRounds == 25 { + oneEncoded := hex.EncodeToString(big.NewInt(1).Bytes()) + pubKey := hex.EncodeToString([]byte("000address-3198")) + txData := hex.EncodeToString([]byte("stake")) + "@" + oneEncoded + "@" + pubKey + "@" + hex.EncodeToString([]byte("signature")) + + shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) + shardMiniBlockHeader := block.MiniBlockHeader{ + Hash: []byte("hashStake"), + ReceiverShardID: 0, + SenderShardID: core.MetachainShardId, + TxCount: 1, + } + shardMiniBlockHeaders = append(header.MiniBlockHeaders, shardMiniBlockHeader) + shardData := block.ShardData{ + Nonce: r, + ShardID: 0, + HeaderHash: []byte("hdr_hashStake"), + TxCount: 1, + ShardMiniBlockHeaders: shardMiniBlockHeaders, + DeveloperFees: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + } + header.ShardInfo = append(header.ShardInfo, shardData) + tmp.TxCacher.AddTx(shardMiniBlockHeader.Hash, &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(txData), + }) + + haveTime = func() bool { return false } + + blockBody := &block.Body{ + MiniBlocks: []*block.MiniBlock{ + { + TxHashes: [][]byte{shardMiniBlockHeader.Hash}, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + }, + } + + tmp.TxCoordinator.RequestBlockTransactions(blockBody) + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.EndOfEpochAddress, + CallValue: big.NewInt(0), + }, + RecipientAddr: vm.StakingSCAddress, + Function: "stakeNodesFromQueue", + } + arguments.Function = "stake" + arguments.CallerAddr = vm.ValidatorSCAddress + arguments.Arguments = [][]byte{[]byte("000address-3198"), []byte("000address-3198"), []byte("000address-3198")} + + vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) + + stakedData, _ := tmp.processSCOutputAccounts(vmOutput) + stakingSC := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + stakedDataBuffer, _ := stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) + + _ = stakingSC.DataTrieTracker().SaveKeyValue([]byte("000address-3198"), stakedData) + + tmp.AccountsAdapter.SaveAccount(stakingSC) + + var peerAcc state.PeerAccountHandler + + peerAcc, _ = state.NewPeerAccount([]byte("000address-3198")) + + tmp.StateComponents.PeerAccounts().SaveAccount(peerAcc) + tmp.AccountsAdapter.SaveAccount(peerAcc) + + tmp.AccountsAdapter.Commit() + tmp.StateComponents.PeerAccounts().Commit() + + loadedAcc, _ := tmp.StateComponents.PeerAccounts().LoadAccount([]byte("000address-3198")) + + loadedAccCasted, castOK := loadedAcc.(state.PeerAccountHandler) + if castOK { + + } + + stakingcommon.AddValidatorData( + tmp.AccountsAdapter, + []byte("000address-3198"), + [][]byte{[]byte("000address-3198")}, + big.NewInt(1000), + tmp.Marshaller, + ) + + tmp.AccountsAdapter.Commit() + tmp.StateComponents.PeerAccounts().Commit() + + stakedDataBuffer, _ = stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) + _ = stakedDataBuffer + _ = vmOutput + _ = stakedData + _ = loadedAcc + _ = loadedAccCasted + } + + newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) require.Nil(t, err) err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) @@ -284,3 +397,28 @@ func generateAddress(identifier uint32) []byte { uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) } + +func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutput) ([]byte, error) { + outputAccounts := process.SortVMOutputInsideData(vmOutput) + for _, outAcc := range outputAccounts { + if bytes.Equal(outAcc.Address, vm.StakingSCAddress) { + fmt.Println("DSADA") + } + + acc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, outAcc.Address) + + storageUpdates := process.GetSortedStorageUpdates(outAcc) + for _, storeUpdate := range storageUpdates { + if bytes.Equal(storeUpdate.Offset, []byte("000address-3198")) { + fmt.Println("DASDSA") + return storeUpdate.Data, nil + } + err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) + if err != nil { + return nil, err + } + } + } + + return nil, nil +} diff --git a/process/mock/transactionCoordinatorMock.go b/process/mock/transactionCoordinatorMock.go index f10b2bb7549..6680fa87e1e 100644 --- a/process/mock/transactionCoordinatorMock.go +++ b/process/mock/transactionCoordinatorMock.go @@ -32,6 +32,8 @@ type TransactionCoordinatorMock struct { GetAllIntermediateTxsCalled func() map[block.Type]map[string]data.TransactionHandler AddTxsFromMiniBlocksCalled func(miniBlocks block.MiniBlockSlice) AddTransactionsCalled func(txHandlers []data.TransactionHandler, blockType block.Type) + + miniBlocks []*block.MiniBlock } // GetAllCurrentLogs - @@ -44,7 +46,7 @@ func (tcm *TransactionCoordinatorMock) CreatePostProcessMiniBlocks() block.MiniB if tcm.CreatePostProcessMiniBlocksCalled != nil { return tcm.CreatePostProcessMiniBlocksCalled() } - return nil + return tcm.miniBlocks } // CreateReceiptsHash - @@ -73,6 +75,7 @@ func (tcm *TransactionCoordinatorMock) RequestMiniBlocks(header data.HeaderHandl // RequestBlockTransactions - func (tcm *TransactionCoordinatorMock) RequestBlockTransactions(body *block.Body) { if tcm.RequestBlockTransactionsCalled == nil { + tcm.miniBlocks = body.MiniBlocks return } From 60d6abef88a264fd730e6dc30a194f00507f7ce4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 9 May 2022 11:01:06 +0300 Subject: [PATCH 237/958] FIX: Set current header to save new staked node in UpdateProtocol --- integrationTests/vm/staking/baseTestMetaProcessor.go | 1 + integrationTests/vm/staking/testMetaProcessor.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index f040902e0b1..d54edc4a97c 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -102,6 +102,7 @@ func newTestMetaProcessor( TxCoordinator: txCoordinator, SystemVM: systemVM, StateComponents: stateComponents, + BlockChainHook: blockChainHook, } } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 56324fbbb44..0e1027168de 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -61,6 +61,7 @@ type TestMetaProcessor struct { TxCoordinator process.TransactionCoordinator SystemVM vmcommon.VMExecutionHandler StateComponents factory.StateComponentsHolder + BlockChainHook process.BlockChainHookHandler currentRound uint64 } @@ -219,6 +220,9 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { } tmp.TxCoordinator.RequestBlockTransactions(blockBody) + + tmp.BlockChainHook.SetCurrentHeader(header) + arguments := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ CallerAddr: vm.EndOfEpochAddress, From 697aea6b2a241226b7d5d451be4e295c7d01ffe9 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 9 May 2022 12:39:34 +0300 Subject: [PATCH 238/958] FEAT: Ugly version to UpdateProtocol with processSCOutputAccounts --- .../vm/staking/testMetaProcessor.go | 98 +++++++++++-------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 0e1027168de..2310c8a64d7 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -229,56 +229,61 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { CallValue: big.NewInt(0), }, RecipientAddr: vm.StakingSCAddress, - Function: "stakeNodesFromQueue", } arguments.Function = "stake" - arguments.CallerAddr = vm.ValidatorSCAddress - arguments.Arguments = [][]byte{[]byte("000address-3198"), []byte("000address-3198"), []byte("000address-3198")} + arguments.CallerAddr = []byte("000address-3198") + arguments.RecipientAddr = vm.ValidatorSCAddress + arguments.Arguments = [][]byte{big.NewInt(1).Bytes(), []byte("000address-3198"), []byte("signature")} + arguments.CallValue = big.NewInt(2000) + arguments.GasProvided = 10 vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) stakedData, _ := tmp.processSCOutputAccounts(vmOutput) - stakingSC := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) - stakedDataBuffer, _ := stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) - - _ = stakingSC.DataTrieTracker().SaveKeyValue([]byte("000address-3198"), stakedData) - - tmp.AccountsAdapter.SaveAccount(stakingSC) - - var peerAcc state.PeerAccountHandler - - peerAcc, _ = state.NewPeerAccount([]byte("000address-3198")) - - tmp.StateComponents.PeerAccounts().SaveAccount(peerAcc) - tmp.AccountsAdapter.SaveAccount(peerAcc) - - tmp.AccountsAdapter.Commit() - tmp.StateComponents.PeerAccounts().Commit() - - loadedAcc, _ := tmp.StateComponents.PeerAccounts().LoadAccount([]byte("000address-3198")) - - loadedAccCasted, castOK := loadedAcc.(state.PeerAccountHandler) - if castOK { - - } - - stakingcommon.AddValidatorData( - tmp.AccountsAdapter, - []byte("000address-3198"), - [][]byte{[]byte("000address-3198")}, - big.NewInt(1000), - tmp.Marshaller, - ) + //stakingSC := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) + //stakedDataBuffer, _ := stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) + // + //_ = stakingSC.DataTrieTracker().SaveKeyValue([]byte("000address-3198"), stakedData) + // + //tmp.AccountsAdapter.SaveAccount(stakingSC) + + //var peerAcc state.PeerAccountHandler + // + //peerAcc, _ = state.NewPeerAccount([]byte("000address-3198")) + // + //tmp.StateComponents.PeerAccounts().SaveAccount(peerAcc) + //tmp.AccountsAdapter.SaveAccount(peerAcc) + // + //tmp.AccountsAdapter.Commit() + //tmp.StateComponents.PeerAccounts().Commit() + // + //loadedAcc, _ := tmp.StateComponents.PeerAccounts().LoadAccount([]byte("000address-3198")) + // + //loadedAccCasted, castOK := loadedAcc.(state.PeerAccountHandler) + //if castOK { + // + //} + + /* + stakingcommon.AddValidatorData( + tmp.AccountsAdapter, + []byte("000address-3198"), + [][]byte{[]byte("000address-3198")}, + big.NewInt(1000), + tmp.Marshaller, + ) + + */ tmp.AccountsAdapter.Commit() tmp.StateComponents.PeerAccounts().Commit() - stakedDataBuffer, _ = stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) - _ = stakedDataBuffer + //stakedDataBuffer, _ = stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) + //_ = stakedDataBuffer _ = vmOutput _ = stakedData - _ = loadedAcc - _ = loadedAccCasted + //_ = loadedAcc + //_ = loadedAccCasted } newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) @@ -408,6 +413,9 @@ func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutpu if bytes.Equal(outAcc.Address, vm.StakingSCAddress) { fmt.Println("DSADA") } + if bytes.Equal(outAcc.Address, vm.ValidatorSCAddress) { + fmt.Println("VAAAAAAAAAAAAAAAAAAAAALLLLLLLLLLLLLl") + } acc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, outAcc.Address) @@ -415,12 +423,24 @@ func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutpu for _, storeUpdate := range storageUpdates { if bytes.Equal(storeUpdate.Offset, []byte("000address-3198")) { fmt.Println("DASDSA") - return storeUpdate.Data, nil + //return storeUpdate.Data, nil } err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) if err != nil { return nil, err } + + if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(big.NewInt(0)) != 0 { + err = acc.AddToBalance(outAcc.BalanceDelta) + if err != nil { + return nil, err + } + } + + err = tmp.AccountsAdapter.SaveAccount(acc) + if err != nil { + return nil, err + } } } From 9f172022d8d3fdb1642092f8f1a6b343fb747335 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 9 May 2022 16:19:29 +0300 Subject: [PATCH 239/958] FEAT: Add ProcessStake --- integrationTests/vm/staking/stakingV4_test.go | 14 +- .../vm/staking/testMetaProcessor.go | 178 ++++++------------ .../testMetaProcessorWithCustomNodesConfig.go | 108 +++++++++++ 3 files changed, 182 insertions(+), 118 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 16d418bc878..df5205f1e89 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -312,6 +312,18 @@ func TestStakingV4_CustomScenario(t *testing.T) { node := NewTestMetaProcessorWithCustomNodes(cfg) node.EpochStartTrigger.SetRoundsPerEpoch(5) - node.Process(t, 25) + //node.Process(t, 25) + node.Process(t, 18) + node.ProcessStake(t, map[string]*NodesRegisterData{ + "owner444": &NodesRegisterData{ + BLSKeys: [][]byte{generateAddress(444)}, + TotalStake: big.NewInt(2000), + }, + "owner555": &NodesRegisterData{ + BLSKeys: [][]byte{generateAddress(555), generateAddress(666)}, + TotalStake: big.NewInt(5000), + }, + }) + node.Process(t, 7) } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 2310c8a64d7..b8b864bd3d6 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,8 +1,6 @@ package staking import ( - "bytes" - "encoding/hex" "fmt" "math/big" "strconv" @@ -13,7 +11,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" @@ -25,7 +22,6 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" ) @@ -177,114 +173,70 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { ) haveTime := func() bool { return true } + /* + if r == 17 && numOfRounds == 25 { + numOfNodesToStake := big.NewInt(1).Bytes() + numOfNodesToStakeHex := hex.EncodeToString(numOfNodesToStake) + signature := []byte("signature") + pubKey := hex.EncodeToString([]byte("000address-3198")) + txData := hex.EncodeToString([]byte("stake")) + "@" + numOfNodesToStakeHex + "@" + pubKey + "@" + hex.EncodeToString(signature) + + shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) + shardMiniBlockHeader := block.MiniBlockHeader{ + Hash: []byte("hashStake"), + ReceiverShardID: 0, + SenderShardID: core.MetachainShardId, + TxCount: 1, + } + shardMiniBlockHeaders = append(header.MiniBlockHeaders, shardMiniBlockHeader) + shardData := block.ShardData{ + Nonce: r, + HeaderHash: []byte("hdr_hashStake"), + TxCount: 1, + ShardMiniBlockHeaders: shardMiniBlockHeaders, + } + header.ShardInfo = append(header.ShardInfo, shardData) + tmp.TxCacher.AddTx(shardMiniBlockHeader.Hash, &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(txData), + }) + + haveTime = func() bool { return false } + + blockBody := &block.Body{ + MiniBlocks: []*block.MiniBlock{ + { + TxHashes: [][]byte{shardMiniBlockHeader.Hash}, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + }, + } - if r == 17 && numOfRounds == 25 { - oneEncoded := hex.EncodeToString(big.NewInt(1).Bytes()) - pubKey := hex.EncodeToString([]byte("000address-3198")) - txData := hex.EncodeToString([]byte("stake")) + "@" + oneEncoded + "@" + pubKey + "@" + hex.EncodeToString([]byte("signature")) - - shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) - shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: []byte("hashStake"), - ReceiverShardID: 0, - SenderShardID: core.MetachainShardId, - TxCount: 1, - } - shardMiniBlockHeaders = append(header.MiniBlockHeaders, shardMiniBlockHeader) - shardData := block.ShardData{ - Nonce: r, - ShardID: 0, - HeaderHash: []byte("hdr_hashStake"), - TxCount: 1, - ShardMiniBlockHeaders: shardMiniBlockHeaders, - DeveloperFees: big.NewInt(0), - AccumulatedFees: big.NewInt(0), - } - header.ShardInfo = append(header.ShardInfo, shardData) - tmp.TxCacher.AddTx(shardMiniBlockHeader.Hash, &smartContractResult.SmartContractResult{ - RcvAddr: vm.StakingSCAddress, - Data: []byte(txData), - }) - - haveTime = func() bool { return false } - - blockBody := &block.Body{ - MiniBlocks: []*block.MiniBlock{ - { - TxHashes: [][]byte{shardMiniBlockHeader.Hash}, - SenderShardID: core.MetachainShardId, - ReceiverShardID: core.MetachainShardId, - Type: block.SmartContractResultBlock, + tmp.TxCoordinator.RequestBlockTransactions(blockBody) + + tmp.BlockChainHook.SetCurrentHeader(header) + + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: []byte("owner-3198"), + Arguments: [][]byte{numOfNodesToStake, []byte("000address-3198"), signature}, + CallValue: big.NewInt(2000), + GasProvided: 10, }, - }, - } + RecipientAddr: vm.ValidatorSCAddress, + Function: "stake", + } + vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) + + _, _ = tmp.processSCOutputAccounts(vmOutput) - tmp.TxCoordinator.RequestBlockTransactions(blockBody) - tmp.BlockChainHook.SetCurrentHeader(header) - arguments := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.EndOfEpochAddress, - CallValue: big.NewInt(0), - }, - RecipientAddr: vm.StakingSCAddress, } - arguments.Function = "stake" - arguments.CallerAddr = []byte("000address-3198") - arguments.RecipientAddr = vm.ValidatorSCAddress - arguments.Arguments = [][]byte{big.NewInt(1).Bytes(), []byte("000address-3198"), []byte("signature")} - arguments.CallValue = big.NewInt(2000) - arguments.GasProvided = 10 - - vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) - - stakedData, _ := tmp.processSCOutputAccounts(vmOutput) - //stakingSC := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) - //stakedDataBuffer, _ := stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) - // - //_ = stakingSC.DataTrieTracker().SaveKeyValue([]byte("000address-3198"), stakedData) - // - //tmp.AccountsAdapter.SaveAccount(stakingSC) - - //var peerAcc state.PeerAccountHandler - // - //peerAcc, _ = state.NewPeerAccount([]byte("000address-3198")) - // - //tmp.StateComponents.PeerAccounts().SaveAccount(peerAcc) - //tmp.AccountsAdapter.SaveAccount(peerAcc) - // - //tmp.AccountsAdapter.Commit() - //tmp.StateComponents.PeerAccounts().Commit() - // - //loadedAcc, _ := tmp.StateComponents.PeerAccounts().LoadAccount([]byte("000address-3198")) - // - //loadedAccCasted, castOK := loadedAcc.(state.PeerAccountHandler) - //if castOK { - // - //} - - /* - stakingcommon.AddValidatorData( - tmp.AccountsAdapter, - []byte("000address-3198"), - [][]byte{[]byte("000address-3198")}, - big.NewInt(1000), - tmp.Marshaller, - ) - - */ - - tmp.AccountsAdapter.Commit() - tmp.StateComponents.PeerAccounts().Commit() - - //stakedDataBuffer, _ = stakingSC.DataTrieTracker().RetrieveValue([]byte("000address-3198")) - //_ = stakedDataBuffer - _ = vmOutput - _ = stakedData - //_ = loadedAcc - //_ = loadedAccCasted - } + + */ newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) require.Nil(t, err) @@ -410,21 +362,10 @@ func generateAddress(identifier uint32) []byte { func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutput) ([]byte, error) { outputAccounts := process.SortVMOutputInsideData(vmOutput) for _, outAcc := range outputAccounts { - if bytes.Equal(outAcc.Address, vm.StakingSCAddress) { - fmt.Println("DSADA") - } - if bytes.Equal(outAcc.Address, vm.ValidatorSCAddress) { - fmt.Println("VAAAAAAAAAAAAAAAAAAAAALLLLLLLLLLLLLl") - } - acc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, outAcc.Address) storageUpdates := process.GetSortedStorageUpdates(outAcc) for _, storeUpdate := range storageUpdates { - if bytes.Equal(storeUpdate.Offset, []byte("000address-3198")) { - fmt.Println("DASDSA") - //return storeUpdate.Data, nil - } err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) if err != nil { return nil, err @@ -444,5 +385,8 @@ func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutpu } } + tmp.AccountsAdapter.Commit() + tmp.StateComponents.PeerAccounts().Commit() + return nil, nil } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 0b65503791f..6f51a795f85 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -1,13 +1,23 @@ package staking import ( + "encoding/hex" + "fmt" "math/big" + "testing" + "time" + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/ElrondNetwork/elrond-go/vm" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/stretchr/testify/require" ) type OwnerStats struct { @@ -72,6 +82,104 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr ) } +type NodesRegisterData struct { + BLSKeys [][]byte + TotalStake *big.Int +} + +func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*NodesRegisterData) { + _, err := tmp.MetaBlockProcessor.CreateNewHeader(tmp.currentRound, tmp.currentRound) + require.Nil(t, err) + + epoch := tmp.EpochStartTrigger.Epoch() + printNewHeaderRoundEpoch(tmp.currentRound, epoch) + + currentHeader, currentHash := tmp.getCurrentHeaderInfo() + header := createMetaBlockToCommit( + epoch, + tmp.currentRound, + currentHash, + currentHeader.GetRandSeed(), + tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), + ) + tmp.BlockChainHook.SetCurrentHeader(header) + + shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) + blockBody := &block.Body{MiniBlocks: make([]*block.MiniBlock, 0)} + + for owner, nodesData := range nodes { + numBLSKeys := int64(len(nodesData.BLSKeys)) + numOfNodesToStake := big.NewInt(numBLSKeys).Bytes() + numOfNodesToStakeHex := hex.EncodeToString(numOfNodesToStake) + _ = numOfNodesToStakeHex + for _, blsKey := range nodesData.BLSKeys { + signature := append([]byte("signature-"), blsKey...) + txData := hex.EncodeToString([]byte("stake")) + "@" + + hex.EncodeToString(big.NewInt(1).Bytes()) + "@" + + hex.EncodeToString(blsKey) + "@" + + hex.EncodeToString(signature) + + mbHeaderHash := []byte(fmt.Sprintf("mbHash-stake-blsKey=%s-owner=%s", blsKey, owner)) + shardMiniBlockHeader := block.MiniBlockHeader{ + Hash: mbHeaderHash, + ReceiverShardID: 0, + SenderShardID: core.MetachainShardId, + TxCount: 1, + } + shardMiniBlockHeaders = append(header.MiniBlockHeaders, shardMiniBlockHeader) + shardData := block.ShardData{ + Nonce: tmp.currentRound, + ShardID: 0, + HeaderHash: []byte("hdr_hashStake"), + TxCount: 1, + ShardMiniBlockHeaders: shardMiniBlockHeaders, + } + header.ShardInfo = append(header.ShardInfo, shardData) + tmp.TxCacher.AddTx(mbHeaderHash, &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(txData), + }) + + blockBody.MiniBlocks = append(blockBody.MiniBlocks, &block.MiniBlock{ + TxHashes: [][]byte{mbHeaderHash}, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + ) + + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: []byte(owner), + Arguments: [][]byte{big.NewInt(1).Bytes(), blsKey, signature}, + CallValue: big.NewInt(nodesData.TotalStake.Int64()).Div(nodesData.TotalStake, big.NewInt(numBLSKeys)), + GasProvided: 10, + }, + RecipientAddr: vm.ValidatorSCAddress, + Function: "stake", + } + vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) + + _, _ = tmp.processSCOutputAccounts(vmOutput) + } + + } + tmp.TxCoordinator.RequestBlockTransactions(blockBody) + + haveTime := func() bool { return false } + newHeader, newBlockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) + require.Nil(t, err) + + err = tmp.MetaBlockProcessor.CommitBlock(newHeader, newBlockBody) + require.Nil(t, err) + + time.Sleep(time.Millisecond * 50) + tmp.updateNodesConfig(epoch) + displayConfig(tmp.NodesConfig) + + tmp.currentRound += 1 +} + func createStakingQueueCustomNodes( owners map[string]*OwnerStats, marshaller marshal.Marshalizer, From 8086131795ab9a3db23668444b703896672d53c0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 9 May 2022 17:09:44 +0300 Subject: [PATCH 240/958] FEAT: Refactor ProcessStake 1 --- .../vm/staking/testMetaProcessor.go | 74 ++--------------- .../testMetaProcessorWithCustomNodesConfig.go | 81 ++++++++----------- 2 files changed, 39 insertions(+), 116 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index b8b864bd3d6..cdc01475ef0 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -173,70 +173,6 @@ func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { ) haveTime := func() bool { return true } - /* - if r == 17 && numOfRounds == 25 { - numOfNodesToStake := big.NewInt(1).Bytes() - numOfNodesToStakeHex := hex.EncodeToString(numOfNodesToStake) - signature := []byte("signature") - pubKey := hex.EncodeToString([]byte("000address-3198")) - txData := hex.EncodeToString([]byte("stake")) + "@" + numOfNodesToStakeHex + "@" + pubKey + "@" + hex.EncodeToString(signature) - - shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) - shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: []byte("hashStake"), - ReceiverShardID: 0, - SenderShardID: core.MetachainShardId, - TxCount: 1, - } - shardMiniBlockHeaders = append(header.MiniBlockHeaders, shardMiniBlockHeader) - shardData := block.ShardData{ - Nonce: r, - HeaderHash: []byte("hdr_hashStake"), - TxCount: 1, - ShardMiniBlockHeaders: shardMiniBlockHeaders, - } - header.ShardInfo = append(header.ShardInfo, shardData) - tmp.TxCacher.AddTx(shardMiniBlockHeader.Hash, &smartContractResult.SmartContractResult{ - RcvAddr: vm.StakingSCAddress, - Data: []byte(txData), - }) - - haveTime = func() bool { return false } - - blockBody := &block.Body{ - MiniBlocks: []*block.MiniBlock{ - { - TxHashes: [][]byte{shardMiniBlockHeader.Hash}, - SenderShardID: core.MetachainShardId, - ReceiverShardID: core.MetachainShardId, - Type: block.SmartContractResultBlock, - }, - }, - } - - tmp.TxCoordinator.RequestBlockTransactions(blockBody) - - tmp.BlockChainHook.SetCurrentHeader(header) - - arguments := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: []byte("owner-3198"), - Arguments: [][]byte{numOfNodesToStake, []byte("000address-3198"), signature}, - CallValue: big.NewInt(2000), - GasProvided: 10, - }, - RecipientAddr: vm.ValidatorSCAddress, - Function: "stake", - } - vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) - - _, _ = tmp.processSCOutputAccounts(vmOutput) - - - - } - - */ newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) require.Nil(t, err) @@ -359,7 +295,7 @@ func generateAddress(identifier uint32) []byte { return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) } -func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutput) ([]byte, error) { +func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutput) error { outputAccounts := process.SortVMOutputInsideData(vmOutput) for _, outAcc := range outputAccounts { acc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, outAcc.Address) @@ -368,19 +304,19 @@ func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutpu for _, storeUpdate := range storageUpdates { err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) if err != nil { - return nil, err + return err } if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(big.NewInt(0)) != 0 { err = acc.AddToBalance(outAcc.BalanceDelta) if err != nil { - return nil, err + return err } } err = tmp.AccountsAdapter.SaveAccount(acc) if err != nil { - return nil, err + return err } } } @@ -388,5 +324,5 @@ func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutpu tmp.AccountsAdapter.Commit() tmp.StateComponents.PeerAccounts().Commit() - return nil, nil + return nil } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 6f51a795f85..d47bc739aa3 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -2,7 +2,6 @@ package staking import ( "encoding/hex" - "fmt" "math/big" "testing" "time" @@ -104,66 +103,54 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes ) tmp.BlockChainHook.SetCurrentHeader(header) - shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) - blockBody := &block.Body{MiniBlocks: make([]*block.MiniBlock, 0)} + txHashes := make([][]byte, 0) for owner, nodesData := range nodes { numBLSKeys := int64(len(nodesData.BLSKeys)) numOfNodesToStake := big.NewInt(numBLSKeys).Bytes() - numOfNodesToStakeHex := hex.EncodeToString(numOfNodesToStake) - _ = numOfNodesToStakeHex + + txData := hex.EncodeToString([]byte("stake")) + "@" + hex.EncodeToString(numOfNodesToStake) + argsStake := [][]byte{numOfNodesToStake} + for _, blsKey := range nodesData.BLSKeys { signature := append([]byte("signature-"), blsKey...) - txData := hex.EncodeToString([]byte("stake")) + "@" + - hex.EncodeToString(big.NewInt(1).Bytes()) + "@" + - hex.EncodeToString(blsKey) + "@" + - hex.EncodeToString(signature) - - mbHeaderHash := []byte(fmt.Sprintf("mbHash-stake-blsKey=%s-owner=%s", blsKey, owner)) - shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: mbHeaderHash, - ReceiverShardID: 0, - SenderShardID: core.MetachainShardId, - TxCount: 1, - } - shardMiniBlockHeaders = append(header.MiniBlockHeaders, shardMiniBlockHeader) - shardData := block.ShardData{ - Nonce: tmp.currentRound, - ShardID: 0, - HeaderHash: []byte("hdr_hashStake"), - TxCount: 1, - ShardMiniBlockHeaders: shardMiniBlockHeaders, - } - header.ShardInfo = append(header.ShardInfo, shardData) - tmp.TxCacher.AddTx(mbHeaderHash, &smartContractResult.SmartContractResult{ + + argsStake = append(argsStake, blsKey, signature) + txData += "@" + hex.EncodeToString(blsKey) + "@" + hex.EncodeToString(signature) + + txHash := append([]byte("txHash-stake-"), blsKey...) + txHashes = append(txHashes, txHash) + tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ RcvAddr: vm.StakingSCAddress, Data: []byte(txData), }) + } - blockBody.MiniBlocks = append(blockBody.MiniBlocks, &block.MiniBlock{ - TxHashes: [][]byte{mbHeaderHash}, - SenderShardID: core.MetachainShardId, - ReceiverShardID: core.MetachainShardId, - Type: block.SmartContractResultBlock, + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: []byte(owner), + Arguments: argsStake, + CallValue: nodesData.TotalStake, + GasProvided: 10, }, - ) - - arguments := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: []byte(owner), - Arguments: [][]byte{big.NewInt(1).Bytes(), blsKey, signature}, - CallValue: big.NewInt(nodesData.TotalStake.Int64()).Div(nodesData.TotalStake, big.NewInt(numBLSKeys)), - GasProvided: 10, - }, - RecipientAddr: vm.ValidatorSCAddress, - Function: "stake", - } - vmOutput, _ := tmp.SystemVM.RunSmartContractCall(arguments) - - _, _ = tmp.processSCOutputAccounts(vmOutput) + RecipientAddr: vm.ValidatorSCAddress, + Function: "stake", } + vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) + require.Nil(t, err) + err = tmp.processSCOutputAccounts(vmOutput) + require.Nil(t, err) } + + blockBody := &block.Body{MiniBlocks: block.MiniBlockSlice{ + { + TxHashes: txHashes, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + }} tmp.TxCoordinator.RequestBlockTransactions(blockBody) haveTime := func() bool { return false } From d320f08bc46939130e6614d8b47f76ec98c449fa Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 9 May 2022 18:14:02 +0300 Subject: [PATCH 241/958] FEAT: Refactor ProcessStake 2 --- integrationTests/vm/staking/stakingV4_test.go | 28 ++++--- .../vm/staking/testMetaProcessor.go | 54 +++++++------ .../testMetaProcessorWithCustomNodesConfig.go | 78 +++++++------------ 3 files changed, 80 insertions(+), 80 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index df5205f1e89..77b7cc55223 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -312,18 +312,28 @@ func TestStakingV4_CustomScenario(t *testing.T) { node := NewTestMetaProcessorWithCustomNodes(cfg) node.EpochStartTrigger.SetRoundsPerEpoch(5) - //node.Process(t, 25) - node.Process(t, 18) - node.ProcessStake(t, map[string]*NodesRegisterData{ - "owner444": &NodesRegisterData{ + owner444 := "owner444" + owner555 := "owner555" + newNodes := map[string]*NodesRegisterData{ + owner444: { BLSKeys: [][]byte{generateAddress(444)}, - TotalStake: big.NewInt(2000), + TotalStake: big.NewInt(5000), }, - "owner555": &NodesRegisterData{ + owner555: { BLSKeys: [][]byte{generateAddress(555), generateAddress(666)}, - TotalStake: big.NewInt(5000), + TotalStake: big.NewInt(6000), }, - }) + } + node.Process(t, 15) + node.ProcessStake(t, newNodes) + + currNodesConfig := node.NodesConfig + requireSliceContains(t, currNodesConfig.auction, newNodes[owner444].BLSKeys) + requireSliceContains(t, currNodesConfig.auction, newNodes[owner555].BLSKeys) + + node.Process(t, 4) - node.Process(t, 7) + currNodesConfig = node.NodesConfig + requireMapContains(t, currNodesConfig.waiting, newNodes[owner444].BLSKeys) + requireMapContains(t, currNodesConfig.waiting, newNodes[owner555].BLSKeys) } diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index cdc01475ef0..771bb47c10d 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -34,6 +34,9 @@ const ( nodePrice = 1000 ) +func haveTime() bool { return true } +func noTime() bool { return false } + type nodesConfig struct { eligible map[uint32][][]byte waiting map[uint32][][]byte @@ -157,35 +160,42 @@ func createMaxNodesConfig( // Process - func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { for r := tmp.currentRound; r < tmp.currentRound+numOfRounds; r++ { - _, err := tmp.MetaBlockProcessor.CreateNewHeader(r, r) - require.Nil(t, err) + header := tmp.createNewHeader(t, r) + tmp.createAndCommitBlock(t, header, haveTime) + } - epoch := tmp.EpochStartTrigger.Epoch() - printNewHeaderRoundEpoch(r, epoch) + tmp.currentRound += numOfRounds +} - currentHeader, currentHash := tmp.getCurrentHeaderInfo() - header := createMetaBlockToCommit( - epoch, - r, - currentHash, - currentHeader.GetRandSeed(), - tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), - ) +func (tmp *TestMetaProcessor) createNewHeader(t *testing.T, round uint64) *block.MetaBlock { + _, err := tmp.MetaBlockProcessor.CreateNewHeader(round, round) + require.Nil(t, err) - haveTime := func() bool { return true } + epoch := tmp.EpochStartTrigger.Epoch() + printNewHeaderRoundEpoch(round, epoch) - newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) - require.Nil(t, err) + currentHeader, currentHash := tmp.getCurrentHeaderInfo() + header := createMetaBlockToCommit( + epoch, + round, + currentHash, + currentHeader.GetRandSeed(), + tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), + ) - err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) - require.Nil(t, err) + return header +} - time.Sleep(time.Millisecond * 50) - tmp.updateNodesConfig(epoch) - displayConfig(tmp.NodesConfig) - } +func (tmp *TestMetaProcessor) createAndCommitBlock(t *testing.T, header data.HeaderHandler, haveTime func() bool) { + newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) + require.Nil(t, err) - tmp.currentRound += numOfRounds + err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) + require.Nil(t, err) + + time.Sleep(time.Millisecond * 50) + tmp.updateNodesConfig(header.GetEpoch()) + displayConfig(tmp.NodesConfig) } func printNewHeaderRoundEpoch(round uint64, epoch uint32) { diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index d47bc739aa3..1beb05e0b4c 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "math/big" "testing" - "time" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data/block" @@ -87,60 +86,38 @@ type NodesRegisterData struct { } func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*NodesRegisterData) { - _, err := tmp.MetaBlockProcessor.CreateNewHeader(tmp.currentRound, tmp.currentRound) - require.Nil(t, err) - - epoch := tmp.EpochStartTrigger.Epoch() - printNewHeaderRoundEpoch(tmp.currentRound, epoch) - - currentHeader, currentHash := tmp.getCurrentHeaderInfo() - header := createMetaBlockToCommit( - epoch, - tmp.currentRound, - currentHash, - currentHeader.GetRandSeed(), - tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), - ) + header := tmp.createNewHeader(t, tmp.currentRound) tmp.BlockChainHook.SetCurrentHeader(header) txHashes := make([][]byte, 0) - for owner, nodesData := range nodes { numBLSKeys := int64(len(nodesData.BLSKeys)) - numOfNodesToStake := big.NewInt(numBLSKeys).Bytes() + numBLSKeysBytes := big.NewInt(numBLSKeys).Bytes() - txData := hex.EncodeToString([]byte("stake")) + "@" + hex.EncodeToString(numOfNodesToStake) - argsStake := [][]byte{numOfNodesToStake} + txData := hex.EncodeToString([]byte("stake")) + "@" + hex.EncodeToString(numBLSKeysBytes) + argsStake := [][]byte{numBLSKeysBytes} for _, blsKey := range nodesData.BLSKeys { signature := append([]byte("signature-"), blsKey...) argsStake = append(argsStake, blsKey, signature) txData += "@" + hex.EncodeToString(blsKey) + "@" + hex.EncodeToString(signature) - - txHash := append([]byte("txHash-stake-"), blsKey...) - txHashes = append(txHashes, txHash) - tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ - RcvAddr: vm.StakingSCAddress, - Data: []byte(txData), - }) } - arguments := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: []byte(owner), - Arguments: argsStake, - CallValue: nodesData.TotalStake, - GasProvided: 10, - }, - RecipientAddr: vm.ValidatorSCAddress, - Function: "stake", - } - vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) - require.Nil(t, err) + txHash := append([]byte("txHash-stake-"), []byte(owner)...) + txHashes = append(txHashes, txHash) + + tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(txData), + }) - err = tmp.processSCOutputAccounts(vmOutput) - require.Nil(t, err) + tmp.doStake(t, vmcommon.VMInput{ + CallerAddr: []byte(owner), + Arguments: argsStake, + CallValue: nodesData.TotalStake, + GasProvided: 10, + }) } blockBody := &block.Body{MiniBlocks: block.MiniBlockSlice{ @@ -152,19 +129,22 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes }, }} tmp.TxCoordinator.RequestBlockTransactions(blockBody) + tmp.createAndCommitBlock(t, header, noTime) - haveTime := func() bool { return false } - newHeader, newBlockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) - require.Nil(t, err) + tmp.currentRound += 1 +} - err = tmp.MetaBlockProcessor.CommitBlock(newHeader, newBlockBody) +func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmInput, + RecipientAddr: vm.ValidatorSCAddress, + Function: "stake", + } + vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) require.Nil(t, err) - time.Sleep(time.Millisecond * 50) - tmp.updateNodesConfig(epoch) - displayConfig(tmp.NodesConfig) - - tmp.currentRound += 1 + err = tmp.processSCOutputAccounts(vmOutput) + require.Nil(t, err) } func createStakingQueueCustomNodes( From 35cf84dc6acdd0870230741d0a272fa9f9bc87fe Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Tue, 10 May 2022 17:24:13 +0300 Subject: [PATCH 242/958] first version of the auction list api endpoint --- api/groups/validatorGroup.go | 37 +++++++- api/groups/validatorGroup_test.go | 78 ++++++++++++++++- api/mock/facadeStub.go | 6 ++ api/shared/interface.go | 1 + cmd/node/config/api.toml | 5 +- common/dtos.go | 7 ++ epochStart/metachain/systemSCs.go | 9 +- facade/initial/initialNodeFacade.go | 5 ++ facade/initial/initialNodeFacade_test.go | 4 + facade/interface.go | 3 + facade/mock/nodeStub.go | 6 ++ facade/nodeFacade.go | 5 ++ factory/blockProcessorCreator.go | 2 + factory/processComponents.go | 4 +- node/node.go | 4 + process/errors.go | 3 + process/interface.go | 1 + process/peer/validatorsProvider.go | 69 +++++++++++++-- process/peer/validatorsProvider_test.go | 52 ++++++++--- .../stakingcommon/stakingDataProviderStub.go | 87 +++++++++++++++++++ 20 files changed, 356 insertions(+), 32 deletions(-) create mode 100644 testscommon/stakingcommon/stakingDataProviderStub.go diff --git a/api/groups/validatorGroup.go b/api/groups/validatorGroup.go index 09ba8517583..50d392eb8ac 100644 --- a/api/groups/validatorGroup.go +++ b/api/groups/validatorGroup.go @@ -8,15 +8,20 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/api/errors" "github.com/ElrondNetwork/elrond-go/api/shared" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/state" "github.com/gin-gonic/gin" ) -const statisticsPath = "/statistics" +const ( + statisticsPath = "/statistics" + auctionPath = "/auction" +) // validatorFacadeHandler defines the methods to be implemented by a facade for validator requests type validatorFacadeHandler interface { ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) + AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) IsInterfaceNil() bool } @@ -43,6 +48,11 @@ func NewValidatorGroup(facade validatorFacadeHandler) (*validatorGroup, error) { Method: http.MethodGet, Handler: ng.statistics, }, + { + Path: auctionPath, + Method: http.MethodGet, + Handler: ng.auction, + }, } ng.endpoints = endpoints @@ -74,6 +84,31 @@ func (vg *validatorGroup) statistics(c *gin.Context) { ) } +// auction will return the list of the validators in the auction list +func (vg *validatorGroup) auction(c *gin.Context) { + valStats, err := vg.getFacade().AuctionListApi() + if err != nil { + c.JSON( + http.StatusBadRequest, + shared.GenericAPIResponse{ + Data: nil, + Error: err.Error(), + Code: shared.ReturnCodeRequestError, + }, + ) + return + } + + c.JSON( + http.StatusOK, + shared.GenericAPIResponse{ + Data: gin.H{"auctionList": valStats}, + Error: "", + Code: shared.ReturnCodeSuccess, + }, + ) +} + func (vg *validatorGroup) getFacade() validatorFacadeHandler { vg.mutFacade.RLock() defer vg.mutFacade.RUnlock() diff --git a/api/groups/validatorGroup_test.go b/api/groups/validatorGroup_test.go index 2fbb3844abd..f7a8666092e 100644 --- a/api/groups/validatorGroup_test.go +++ b/api/groups/validatorGroup_test.go @@ -11,6 +11,7 @@ import ( "github.com/ElrondNetwork/elrond-go/api/groups" "github.com/ElrondNetwork/elrond-go/api/mock" "github.com/ElrondNetwork/elrond-go/api/shared" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/state" "github.com/stretchr/testify/assert" @@ -33,11 +34,18 @@ func TestNewValidatorGroup(t *testing.T) { }) } -type ValidatorStatisticsResponse struct { +type validatorStatisticsResponse struct { Result map[string]*state.ValidatorApiResponse `json:"statistics"` Error string `json:"error"` } +type auctionListReponse struct { + Data struct { + Result []*common.AuctionListValidatorAPIResponse `json:"auctionList"` + } `json:"data"` + Error string +} + func TestValidatorStatistics_ErrorWhenFacadeFails(t *testing.T) { t.Parallel() @@ -59,7 +67,7 @@ func TestValidatorStatistics_ErrorWhenFacadeFails(t *testing.T) { resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) - response := ValidatorStatisticsResponse{} + response := validatorStatisticsResponse{} loadResponse(resp.Body, &response) assert.Equal(t, http.StatusBadRequest, resp.Code) @@ -96,7 +104,7 @@ func TestValidatorStatistics_ReturnsSuccessfully(t *testing.T) { response := shared.GenericAPIResponse{} loadResponse(resp.Body, &response) - validatorStatistics := ValidatorStatisticsResponse{} + validatorStatistics := validatorStatisticsResponse{} mapResponseData := response.Data.(map[string]interface{}) mapResponseDataBytes, _ := json.Marshal(mapResponseData) _ = json.Unmarshal(mapResponseDataBytes, &validatorStatistics) @@ -106,12 +114,76 @@ func TestValidatorStatistics_ReturnsSuccessfully(t *testing.T) { assert.Equal(t, validatorStatistics.Result, mapToReturn) } +func TestAuctionList_ErrorWhenFacadeFails(t *testing.T) { + t.Parallel() + + errStr := "error in facade" + + facade := mock.FacadeStub{ + AuctionListHandler: func() ([]*common.AuctionListValidatorAPIResponse, error) { + return nil, errors.New(errStr) + }, + } + + validatorGroup, err := groups.NewValidatorGroup(&facade) + require.NoError(t, err) + + ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) + + req, _ := http.NewRequest("GET", "/validator/auction", nil) + + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) + + response := auctionListReponse{} + loadResponse(resp.Body, &response) + + assert.Equal(t, http.StatusBadRequest, resp.Code) + assert.Contains(t, response.Error, errStr) +} + +func TestAuctionList_ReturnsSuccessfully(t *testing.T) { + t.Parallel() + + auctionListToReturn := []*common.AuctionListValidatorAPIResponse{ + { + Owner: "owner", + NodeKey: "nodeKey", + TopUp: "112233", + }, + } + + facade := mock.FacadeStub{ + AuctionListHandler: func() ([]*common.AuctionListValidatorAPIResponse, error) { + return auctionListToReturn, nil + }, + } + + validatorGroup, err := groups.NewValidatorGroup(&facade) + require.NoError(t, err) + + ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) + + req, _ := http.NewRequest("GET", "/validator/auction", nil) + + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) + + response := auctionListReponse{} + loadResponse(resp.Body, &response) + + assert.Equal(t, http.StatusOK, resp.Code) + + assert.Equal(t, response.Data.Result, auctionListToReturn) +} + func getValidatorRoutesConfig() config.ApiRoutesConfig { return config.ApiRoutesConfig{ APIPackages: map[string]config.APIPackageConfig{ "validator": { Routes: []config.RouteConfig{ {Name: "/statistics", Open: true}, + {Name: "/auction", Open: true}, }, }, }, diff --git a/api/mock/facadeStub.go b/api/mock/facadeStub.go index 18dd42ba1b7..cdf716d1ff8 100644 --- a/api/mock/facadeStub.go +++ b/api/mock/facadeStub.go @@ -35,6 +35,7 @@ type FacadeStub struct { ExecuteSCQueryHandler func(query *process.SCQuery) (*vm.VMOutputApi, error) StatusMetricsHandler func() external.StatusMetricsHandler ValidatorStatisticsHandler func() (map[string]*state.ValidatorApiResponse, error) + AuctionListHandler func() ([]*common.AuctionListValidatorAPIResponse, error) ComputeTransactionGasLimitHandler func(tx *transaction.Transaction) (*transaction.CostResponse, error) NodeConfigCalled func() map[string]interface{} GetQueryHandlerCalled func(name string) (debug.QueryHandler, error) @@ -287,6 +288,11 @@ func (f *FacadeStub) ValidatorStatisticsApi() (map[string]*state.ValidatorApiRes return f.ValidatorStatisticsHandler() } +// AuctionListApi is the mock implementation of a handler's AuctionListApi method +func (f *FacadeStub) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { + return f.AuctionListHandler() +} + // ExecuteSCQuery is a mock implementation. func (f *FacadeStub) ExecuteSCQuery(query *process.SCQuery) (*vm.VMOutputApi, error) { return f.ExecuteSCQueryHandler(query) diff --git a/api/shared/interface.go b/api/shared/interface.go index c3a740b5030..062c8f9c46a 100644 --- a/api/shared/interface.go +++ b/api/shared/interface.go @@ -107,6 +107,7 @@ type FacadeHandler interface { ComputeTransactionGasLimit(tx *transaction.Transaction) (*transaction.CostResponse, error) EncodeAddressPubkey(pk []byte) (string, error) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) + AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) ExecuteSCQuery(*process.SCQuery) (*vm.VMOutputApi, error) DecodeAddressPubkey(pk string) ([]byte, error) RestApiInterface() string diff --git a/cmd/node/config/api.toml b/cmd/node/config/api.toml index 5931e942ce1..30a59a24586 100644 --- a/cmd/node/config/api.toml +++ b/cmd/node/config/api.toml @@ -128,7 +128,10 @@ [APIPackages.validator] Routes = [ # /validator/statistics will return a list of validators statistics for all validators - { Name = "/statistics", Open = true } + { Name = "/statistics", Open = true }, + + # /validator/auction will return a list of nodes that are in the auction list + { Name = "/auction", Open = true }, ] [APIPackages.vm-values] diff --git a/common/dtos.go b/common/dtos.go index e58b2227c75..0744f7abf54 100644 --- a/common/dtos.go +++ b/common/dtos.go @@ -13,3 +13,10 @@ type TransactionsPoolAPIResponse struct { SmartContractResults []string `json:"smartContractResults"` Rewards []string `json:"rewards"` } + +// AuctionListValidatorAPIResponse holds the data needed for an auction node validator for responding to API calls +type AuctionListValidatorAPIResponse struct { + Owner string `json:"owner"` + NodeKey string `json:"nodeKey"` + TopUp string `json:"topUp"` +} diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index fb700dba120..d7cb53dcede 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -14,7 +14,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -343,9 +342,9 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - if log.GetLevel() > logger.LogDebug { - return - } + //if log.GetLevel() > logger.LogDebug { + // return + //} tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -375,7 +374,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Debug(message) + log.Info(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/facade/initial/initialNodeFacade.go b/facade/initial/initialNodeFacade.go index 157e335e6f7..a520179f79f 100644 --- a/facade/initial/initialNodeFacade.go +++ b/facade/initial/initialNodeFacade.go @@ -141,6 +141,11 @@ func (inf *initialNodeFacade) ValidatorStatisticsApi() (map[string]*state.Valida return nil, errNodeStarting } +// AuctionListApi returns nil and error +func (inf *initialNodeFacade) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { + return nil, errNodeStarting +} + // SendBulkTransactions returns 0 and error func (inf *initialNodeFacade) SendBulkTransactions(_ []*transaction.Transaction) (uint64, error) { return uint64(0), errNodeStarting diff --git a/facade/initial/initialNodeFacade_test.go b/facade/initial/initialNodeFacade_test.go index 324cde6e3da..7a68d2ff8ba 100644 --- a/facade/initial/initialNodeFacade_test.go +++ b/facade/initial/initialNodeFacade_test.go @@ -61,6 +61,10 @@ func TestDisabledNodeFacade_AllMethodsShouldNotPanic(t *testing.T) { assert.Nil(t, v1) assert.Equal(t, errNodeStarting, err) + v2, err := inf.AuctionListApi() + assert.Nil(t, v2) + assert.Equal(t, errNodeStarting, err) + u1, err := inf.SendBulkTransactions(nil) assert.Equal(t, uint64(0), u1) assert.Equal(t, errNodeStarting, err) diff --git a/facade/interface.go b/facade/interface.go index 820b0c950ab..19346839b91 100644 --- a/facade/interface.go +++ b/facade/interface.go @@ -79,6 +79,9 @@ type NodeHandler interface { // ValidatorStatisticsApi return the statistics for all the validators ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) + + AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) + DirectTrigger(epoch uint32, withEarlyEndOfEpoch bool) error IsSelfTrigger() bool diff --git a/facade/mock/nodeStub.go b/facade/mock/nodeStub.go index 80b35bf42bc..26c8a6c5b3a 100644 --- a/facade/mock/nodeStub.go +++ b/facade/mock/nodeStub.go @@ -33,6 +33,7 @@ type NodeStub struct { GenerateAndSendBulkTransactionsOneByOneHandler func(destination string, value *big.Int, nrTransactions uint64) error GetHeartbeatsHandler func() []data.PubKeyHeartbeat ValidatorStatisticsApiCalled func() (map[string]*state.ValidatorApiResponse, error) + AuctionListApiCalled func() ([]*common.AuctionListValidatorAPIResponse, error) DirectTriggerCalled func(epoch uint32, withEarlyEndOfEpoch bool) error IsSelfTriggerCalled func() bool GetQueryHandlerCalled func(name string) (debug.QueryHandler, error) @@ -166,6 +167,11 @@ func (ns *NodeStub) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResp return ns.ValidatorStatisticsApiCalled() } +// AuctionListApi - +func (ns *NodeStub) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { + return ns.AuctionListApiCalled() +} + // DirectTrigger - func (ns *NodeStub) DirectTrigger(epoch uint32, withEarlyEndOfEpoch bool) error { return ns.DirectTriggerCalled(epoch, withEarlyEndOfEpoch) diff --git a/facade/nodeFacade.go b/facade/nodeFacade.go index cd61c9ed7dd..4296260a2c9 100644 --- a/facade/nodeFacade.go +++ b/facade/nodeFacade.go @@ -279,6 +279,11 @@ func (nf *nodeFacade) ValidatorStatisticsApi() (map[string]*state.ValidatorApiRe return nf.node.ValidatorStatisticsApi() } +// AuctionListApi will return the data about the validators in the auction list +func (nf *nodeFacade) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { + return nf.node.AuctionListApi() +} + // SendBulkTransactions will send a bulk of transactions on the topic channel func (nf *nodeFacade) SendBulkTransactions(txs []*transaction.Transaction) (uint64, error) { return nf.node.SendBulkTransactions(txs) diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index a7bdec71826..455dd6b74d7 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -725,6 +725,8 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } + pcf.stakingDataProvider = stakingDataProvider + rewardsStorage := pcf.data.StorageService().GetStorer(dataRetriever.RewardTransactionUnit) miniBlockStorage := pcf.data.StorageService().GetStorer(dataRetriever.MiniBlockUnit) argsEpochRewards := metachainEpochStart.RewardsCreatorProxyArgs{ diff --git a/factory/processComponents.go b/factory/processComponents.go index 7089aad023d..c89bff22792 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -158,6 +158,7 @@ type processComponentsFactory struct { historyRepo dblookupext.HistoryRepository epochNotifier process.EpochNotifier importHandler update.ImportHandler + stakingDataProvider epochStart.StakingDataProvider data DataComponentsHolder coreData CoreComponentsHolder @@ -323,7 +324,8 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { CacheRefreshIntervalDurationInSec: cacheRefreshDuration, ValidatorStatistics: validatorStatisticsProcessor, MaxRating: pcf.maxRating, - PubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), } validatorsProvider, err := peer.NewValidatorsProvider(argVSP) diff --git a/node/node.go b/node/node.go index 7c7520a79c1..dd7b28585a6 100644 --- a/node/node.go +++ b/node/node.go @@ -864,6 +864,10 @@ func (n *Node) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, return n.processComponents.ValidatorsProvider().GetLatestValidators(), nil } +func (n *Node) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { + return n.processComponents.ValidatorsProvider().GetAuctionList(), nil +} + // DirectTrigger will start the hardfork trigger func (n *Node) DirectTrigger(epoch uint32, withEarlyEndOfEpoch bool) error { return n.hardforkTrigger.Trigger(epoch, withEarlyEndOfEpoch) diff --git a/process/errors.go b/process/errors.go index fd71c776246..b843c1aaa9d 100644 --- a/process/errors.go +++ b/process/errors.go @@ -191,6 +191,9 @@ var ErrNilShardCoordinator = errors.New("nil shard coordinator") // ErrNilNodesCoordinator signals that an operation has been attempted to or with a nil nodes coordinator var ErrNilNodesCoordinator = errors.New("nil nodes coordinator") +// ErrNilStakingDataProvider signals that a nil staking data provider was used +var ErrNilStakingDataProvider = errors.New("nil staking data provider") + // ErrNilKeyGen signals that an operation has been attempted to or with a nil single sign key generator var ErrNilKeyGen = errors.New("nil key generator") diff --git a/process/interface.go b/process/interface.go index 296fa194193..c6a8aa51c4a 100644 --- a/process/interface.go +++ b/process/interface.go @@ -289,6 +289,7 @@ type TransactionLogProcessorDatabase interface { // ValidatorsProvider is the main interface for validators' provider type ValidatorsProvider interface { GetLatestValidators() map[string]*state.ValidatorApiResponse + GetAuctionList() []*common.AuctionListValidatorAPIResponse IsInterfaceNil() bool Close() error } diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 63ee0a4b904..fe65033871e 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -10,6 +10,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" @@ -28,7 +29,9 @@ type validatorsProvider struct { lastCacheUpdate time.Time lock sync.RWMutex cancelFunc func() - pubkeyConverter core.PubkeyConverter + validatorPubKeyConverter core.PubkeyConverter + addressPubKeyConverter core.PubkeyConverter + stakingDataProvider epochStart.StakingDataProvider maxRating uint32 currentEpoch uint32 } @@ -39,7 +42,9 @@ type ArgValidatorsProvider struct { EpochStartEventNotifier process.EpochStartEventNotifier CacheRefreshIntervalDurationInSec time.Duration ValidatorStatistics process.ValidatorStatisticsProcessor - PubKeyConverter core.PubkeyConverter + ValidatorPubKeyConverter core.PubkeyConverter + AddressPubKeyConverter core.PubkeyConverter + StakingDataProvider epochStart.StakingDataProvider StartEpoch uint32 MaxRating uint32 } @@ -52,8 +57,11 @@ func NewValidatorsProvider( if check.IfNil(args.ValidatorStatistics) { return nil, process.ErrNilValidatorStatistics } - if check.IfNil(args.PubKeyConverter) { - return nil, process.ErrNilPubkeyConverter + if check.IfNil(args.ValidatorPubKeyConverter) { + return nil, fmt.Errorf("%w for validators", process.ErrNilPubkeyConverter) + } + if check.IfNil(args.AddressPubKeyConverter) { + return nil, fmt.Errorf("%w for addresses", process.ErrNilPubkeyConverter) } if check.IfNil(args.NodesCoordinator) { return nil, process.ErrNilNodesCoordinator @@ -61,6 +69,9 @@ func NewValidatorsProvider( if check.IfNil(args.EpochStartEventNotifier) { return nil, process.ErrNilEpochStartNotifier } + if check.IfNil(args.StakingDataProvider) { + return nil, process.ErrNilStakingDataProvider + } if args.MaxRating == 0 { return nil, process.ErrMaxRatingZero } @@ -73,13 +84,15 @@ func NewValidatorsProvider( valProvider := &validatorsProvider{ nodesCoordinator: args.NodesCoordinator, validatorStatistics: args.ValidatorStatistics, + stakingDataProvider: args.StakingDataProvider, cache: make(map[string]*state.ValidatorApiResponse), cacheRefreshIntervalDuration: args.CacheRefreshIntervalDurationInSec, refreshCache: make(chan uint32), lock: sync.RWMutex{}, cancelFunc: cancelfunc, maxRating: args.MaxRating, - pubkeyConverter: args.PubKeyConverter, + validatorPubKeyConverter: args.ValidatorPubKeyConverter, + addressPubKeyConverter: args.AddressPubKeyConverter, currentEpoch: args.StartEpoch, } @@ -91,6 +104,48 @@ func NewValidatorsProvider( // GetLatestValidators gets the latest configuration of validators from the peerAccountsTrie func (vp *validatorsProvider) GetLatestValidators() map[string]*state.ValidatorApiResponse { + return vp.getValidators() +} + +// GetAuctionList returns an array containing the validators that are currently in the auction list +func (vp *validatorsProvider) GetAuctionList() []*common.AuctionListValidatorAPIResponse { + validators := vp.getValidators() + + auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) + for pubKey, val := range validators { + if string(common.AuctionList) != val.ValidatorStatus { + continue + } + + pubKeyBytes, err := vp.validatorPubKeyConverter.Decode(pubKey) + if err != nil { + log.Error("validatorsProvider.GetAuctionList: cannot decode public key of a node", "error", err) + continue + } + + owner, err := vp.stakingDataProvider.GetBlsKeyOwner(pubKeyBytes) + if err != nil { + log.Error("validatorsProvider.GetAuctionList: cannot get bls key owner", "public key", pubKey, "error", err) + continue + } + + topUp, err := vp.stakingDataProvider.GetNodeStakedTopUp(pubKeyBytes) + if err != nil { + log.Error("validatorsProvider.GetAuctionList: cannot get node top up", "public key", pubKey, "error", err) + continue + } + + auctionListValidators = append(auctionListValidators, &common.AuctionListValidatorAPIResponse{ + Owner: vp.addressPubKeyConverter.Encode([]byte(owner)), + NodeKey: pubKey, + TopUp: topUp.String(), + }) + } + + return auctionListValidators +} + +func (vp *validatorsProvider) getValidators() map[string]*state.ValidatorApiResponse { vp.lock.RLock() shouldUpdate := time.Since(vp.lastCacheUpdate) > vp.cacheRefreshIntervalDuration vp.lock.RUnlock() @@ -222,7 +277,7 @@ func (vp *validatorsProvider) createValidatorApiResponseMapFromValidatorInfoMap( newCache := make(map[string]*state.ValidatorApiResponse) for _, validatorInfo := range allNodes.GetAllValidatorsInfo() { - strKey := vp.pubkeyConverter.Encode(validatorInfo.GetPublicKey()) + strKey := vp.validatorPubKeyConverter.Encode(validatorInfo.GetPublicKey()) newCache[strKey] = &state.ValidatorApiResponse{ NumLeaderSuccess: validatorInfo.GetLeaderSuccess(), NumLeaderFailure: validatorInfo.GetLeaderFailure(), @@ -253,7 +308,7 @@ func (vp *validatorsProvider) aggregateLists( ) { for shardID, shardValidators := range validatorsMap { for _, val := range shardValidators { - encodedKey := vp.pubkeyConverter.Encode(val) + encodedKey := vp.validatorPubKeyConverter.Encode(val) foundInTrieValidator, ok := newCache[encodedKey] peerType := string(currentList) diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 2424c3905e0..766b83768d2 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "math/big" + "strings" "sync" "sync/atomic" "testing" @@ -21,6 +22,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) @@ -43,10 +45,30 @@ func TestNewValidatorsProvider_WithMaxRatingZeroShouldErr(t *testing.T) { func TestNewValidatorsProvider_WithNilValidatorPubkeyConverterShouldErr(t *testing.T) { arg := createDefaultValidatorsProviderArg() - arg.PubKeyConverter = nil + arg.ValidatorPubKeyConverter = nil vp, err := NewValidatorsProvider(arg) - assert.Equal(t, process.ErrNilPubkeyConverter, err) + assert.True(t, errors.Is(err, process.ErrNilPubkeyConverter)) + assert.True(t, strings.Contains(err.Error(), "validator")) + assert.True(t, check.IfNil(vp)) +} + +func TestNewValidatorsProvider_WithNilAddressPubkeyConverterShouldErr(t *testing.T) { + arg := createDefaultValidatorsProviderArg() + arg.AddressPubKeyConverter = nil + vp, err := NewValidatorsProvider(arg) + + assert.True(t, errors.Is(err, process.ErrNilPubkeyConverter)) + assert.True(t, strings.Contains(err.Error(), "address")) + assert.True(t, check.IfNil(vp)) +} + +func TestNewValidatorsProvider_WithNilStakingDataProviderShouldErr(t *testing.T) { + arg := createDefaultValidatorsProviderArg() + arg.StakingDataProvider = nil + vp, err := NewValidatorsProvider(arg) + + assert.Equal(t, process.ErrNilStakingDataProvider, err) assert.True(t, check.IfNil(vp)) } @@ -211,7 +233,7 @@ func TestValidatorsProvider_UpdateCache_WithError(t *testing.T) { cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, refreshCache: nil, lock: sync.RWMutex{}, - pubkeyConverter: mock.NewPubkeyConverterMock(32), + validatorPubKeyConverter: mock.NewPubkeyConverterMock(32), } vsp.updateCache() @@ -285,7 +307,7 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { cache: nil, cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, refreshCache: nil, - pubkeyConverter: mock.NewPubkeyConverterMock(32), + validatorPubKeyConverter: mock.NewPubkeyConverterMock(32), lock: sync.RWMutex{}, } @@ -293,7 +315,7 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { assert.NotNil(t, vsp.cache) assert.Equal(t, len(validatorsMap.GetShardValidatorsInfoMap()[initialShardId]), len(vsp.cache)) - encodedKey := arg.PubKeyConverter.Encode(pk) + encodedKey := arg.ValidatorPubKeyConverter.Encode(pk) assert.NotNil(t, vsp.cache[encodedKey]) assert.Equal(t, initialList, vsp.cache[encodedKey].ValidatorStatus) assert.Equal(t, initialShardId, vsp.cache[encodedKey].ShardId) @@ -328,7 +350,7 @@ func TestValidatorsProvider_aggregatePType_equal(t *testing.T) { } vp := validatorsProvider{ - pubkeyConverter: pubKeyConverter, + validatorPubKeyConverter: pubKeyConverter, } vp.aggregateLists(cache, validatorsMap, common.EligibleList) @@ -398,7 +420,7 @@ func TestValidatorsProvider_createCache(t *testing.T) { validatorStatistics: arg.ValidatorStatistics, cache: nil, cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, - pubkeyConverter: pubKeyConverter, + validatorPubKeyConverter: pubKeyConverter, lock: sync.RWMutex{}, } @@ -468,7 +490,7 @@ func TestValidatorsProvider_createCache_combined(t *testing.T) { vsp := validatorsProvider{ nodesCoordinator: nodesCoordinator, validatorStatistics: arg.ValidatorStatistics, - pubkeyConverter: arg.PubKeyConverter, + validatorPubKeyConverter: arg.ValidatorPubKeyConverter, cache: nil, cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, lock: sync.RWMutex{}, @@ -476,12 +498,12 @@ func TestValidatorsProvider_createCache_combined(t *testing.T) { cache := vsp.createNewCache(0, validatorsMap) - encodedPkEligible := arg.PubKeyConverter.Encode(pkEligibleInTrie) + encodedPkEligible := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) assert.NotNil(t, cache[encodedPkEligible]) assert.Equal(t, eligibleList, cache[encodedPkEligible].ValidatorStatus) assert.Equal(t, nodesCoordinatorEligibleShardId, cache[encodedPkEligible].ShardId) - encodedPkLeavingInTrie := arg.PubKeyConverter.Encode(pkLeavingInTrie) + encodedPkLeavingInTrie := arg.ValidatorPubKeyConverter.Encode(pkLeavingInTrie) computedPeerType := fmt.Sprintf(common.CombinedPeerType, common.EligibleList, common.LeavingList) assert.NotNil(t, cache[encodedPkLeavingInTrie]) assert.Equal(t, computedPeerType, cache[encodedPkLeavingInTrie].ValidatorStatus) @@ -557,7 +579,7 @@ func TestValidatorsProvider_CallsUpdateCacheOnEpochChange(t *testing.T) { arg.ValidatorStatistics = validatorStatisticsProcessor vsp, _ := NewValidatorsProvider(arg) - encodedEligible := arg.PubKeyConverter.Encode(pkEligibleInTrie) + encodedEligible := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) assert.Equal(t, 0, len(vsp.GetCache())) // nothing in cache epochStartNotifier.NotifyAll(&block.Header{Nonce: 1, ShardID: 2, Round: 3}) time.Sleep(arg.CacheRefreshIntervalDurationInSec) @@ -595,7 +617,7 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin arg.ValidatorStatistics = validatorStatisticsProcessor vsp, _ := NewValidatorsProvider(arg) - encodedEligible := arg.PubKeyConverter.Encode(pkEligibleInTrie) + encodedEligible := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) assert.Equal(t, 0, len(vsp.GetCache())) // nothing in cache time.Sleep(arg.CacheRefreshIntervalDurationInSec) assert.Equal(t, 0, len(vsp.GetCache())) // nothing in cache @@ -635,13 +657,15 @@ func createDefaultValidatorsProviderArg() ArgValidatorsProvider { NodesCoordinator: &shardingMocks.NodesCoordinatorMock{}, StartEpoch: 1, EpochStartEventNotifier: &mock.EpochStartNotifierStub{}, + StakingDataProvider: &stakingcommon.StakingDataProviderStub{}, CacheRefreshIntervalDurationInSec: 1 * time.Millisecond, ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{ LastFinalizedRootHashCalled: func() []byte { return []byte("rootHash") }, }, - MaxRating: 100, - PubKeyConverter: mock.NewPubkeyConverterMock(32), + MaxRating: 100, + ValidatorPubKeyConverter: mock.NewPubkeyConverterMock(32), + AddressPubKeyConverter: mock.NewPubkeyConverterMock(32), } } diff --git a/testscommon/stakingcommon/stakingDataProviderStub.go b/testscommon/stakingcommon/stakingDataProviderStub.go new file mode 100644 index 00000000000..b1bebed2c7f --- /dev/null +++ b/testscommon/stakingcommon/stakingDataProviderStub.go @@ -0,0 +1,87 @@ +package stakingcommon + +import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go/state" +) + +// StakingDataProviderStub - +type StakingDataProviderStub struct { + CleanCalled func() + PrepareStakingDataCalled func(keys map[uint32][][]byte) error + GetTotalStakeEligibleNodesCalled func() *big.Int + GetTotalTopUpStakeEligibleNodesCalled func() *big.Int + GetNodeStakedTopUpCalled func(blsKey []byte) (*big.Int, error) + FillValidatorInfoCalled func(blsKey []byte) error + ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) +} + +// FillValidatorInfo - +func (sdps *StakingDataProviderStub) FillValidatorInfo(blsKey []byte) error { + if sdps.FillValidatorInfoCalled != nil { + return sdps.FillValidatorInfoCalled(blsKey) + } + return nil +} + +// ComputeUnQualifiedNodes - +func (sdps *StakingDataProviderStub) ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { + if sdps.ComputeUnQualifiedNodesCalled != nil { + return sdps.ComputeUnQualifiedNodesCalled(validatorInfos) + } + return nil, nil, nil +} + +// GetTotalStakeEligibleNodes - +func (sdps *StakingDataProviderStub) GetTotalStakeEligibleNodes() *big.Int { + if sdps.GetTotalStakeEligibleNodesCalled != nil { + return sdps.GetTotalStakeEligibleNodesCalled() + } + return big.NewInt(0) +} + +// GetTotalTopUpStakeEligibleNodes - +func (sdps *StakingDataProviderStub) GetTotalTopUpStakeEligibleNodes() *big.Int { + if sdps.GetTotalTopUpStakeEligibleNodesCalled != nil { + return sdps.GetTotalTopUpStakeEligibleNodesCalled() + } + return big.NewInt(0) +} + +// GetNodeStakedTopUp - +func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) { + if sdps.GetNodeStakedTopUpCalled != nil { + return sdps.GetNodeStakedTopUpCalled(blsKey) + } + return big.NewInt(0), nil +} + +// PrepareStakingData - +func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte) error { + if sdps.PrepareStakingDataCalled != nil { + return sdps.PrepareStakingDataCalled(keys) + } + return nil +} + +// Clean - +func (sdps *StakingDataProviderStub) Clean() { + if sdps.CleanCalled != nil { + sdps.CleanCalled() + } +} + +// GetBlsKeyOwner - +func (sdps *StakingDataProviderStub) GetBlsKeyOwner([]byte) (string, error) { + return "", nil +} + +// EpochConfirmed - +func (sdps *StakingDataProviderStub) EpochConfirmed(uint32, uint64) { +} + +// IsInterfaceNil - +func (sdps *StakingDataProviderStub) IsInterfaceNil() bool { + return sdps == nil +} From 08cc0b4d28f42b6604ce86571a5c57a2c06444ef Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 11 May 2022 10:37:32 +0300 Subject: [PATCH 243/958] fix validatorsProvider stub --- factory/consensusComponents_test.go | 3 ++- heartbeat/mock/validatorsProviderStub.go | 26 ------------------- .../mock/validatorsProviderStub.go | 26 ------------------- integrationTests/testP2PNode.go | 3 ++- integrationTests/testProcessorNode.go | 5 ++-- node/mock/validatorsProviderStub.go | 26 ------------------- node/node_test.go | 18 +++++++------ process/mock/validatorsProviderStub.go | 26 ------------------- .../stakingcommon}/validatorsProviderStub.go | 18 +++++++++++-- 9 files changed, 33 insertions(+), 118 deletions(-) delete mode 100644 heartbeat/mock/validatorsProviderStub.go delete mode 100644 integrationTests/mock/validatorsProviderStub.go delete mode 100644 node/mock/validatorsProviderStub.go delete mode 100644 process/mock/validatorsProviderStub.go rename {factory/mock => testscommon/stakingcommon}/validatorsProviderStub.go (57%) diff --git a/factory/consensusComponents_test.go b/factory/consensusComponents_test.go index 34b721fa4c1..df9de9af956 100644 --- a/factory/consensusComponents_test.go +++ b/factory/consensusComponents_test.go @@ -22,6 +22,7 @@ import ( dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" trieFactory "github.com/ElrondNetwork/elrond-go/trie/factory" "github.com/stretchr/testify/require" @@ -457,7 +458,7 @@ func getDefaultProcessComponents(shardCoordinator sharding.Coordinator) *mock.Pr HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, - ValidatorProvider: &mock.ValidatorsProviderStub{}, + ValidatorProvider: &stakingcommon.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, ReqHandler: &testscommon.RequestHandlerStub{}, diff --git a/heartbeat/mock/validatorsProviderStub.go b/heartbeat/mock/validatorsProviderStub.go deleted file mode 100644 index 5dfaaf22f4d..00000000000 --- a/heartbeat/mock/validatorsProviderStub.go +++ /dev/null @@ -1,26 +0,0 @@ -package mock - -import "github.com/ElrondNetwork/elrond-go/state" - -// ValidatorsProviderStub - -type ValidatorsProviderStub struct { - GetLatestValidatorsCalled func() map[string]*state.ValidatorApiResponse -} - -// GetLatestValidators - -func (vp *ValidatorsProviderStub) GetLatestValidators() map[string]*state.ValidatorApiResponse { - if vp.GetLatestValidatorsCalled != nil { - return vp.GetLatestValidatorsCalled() - } - return nil -} - -// Close - -func (vp *ValidatorsProviderStub) Close() error { - return nil -} - -// IsInterfaceNil - -func (vp *ValidatorsProviderStub) IsInterfaceNil() bool { - return vp == nil -} diff --git a/integrationTests/mock/validatorsProviderStub.go b/integrationTests/mock/validatorsProviderStub.go deleted file mode 100644 index 5dfaaf22f4d..00000000000 --- a/integrationTests/mock/validatorsProviderStub.go +++ /dev/null @@ -1,26 +0,0 @@ -package mock - -import "github.com/ElrondNetwork/elrond-go/state" - -// ValidatorsProviderStub - -type ValidatorsProviderStub struct { - GetLatestValidatorsCalled func() map[string]*state.ValidatorApiResponse -} - -// GetLatestValidators - -func (vp *ValidatorsProviderStub) GetLatestValidators() map[string]*state.ValidatorApiResponse { - if vp.GetLatestValidatorsCalled != nil { - return vp.GetLatestValidatorsCalled() - } - return nil -} - -// Close - -func (vp *ValidatorsProviderStub) Close() error { - return nil -} - -// IsInterfaceNil - -func (vp *ValidatorsProviderStub) IsInterfaceNil() bool { - return vp == nil -} diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go index 8c0ba72053f..b56bf79ccb0 100644 --- a/integrationTests/testP2PNode.go +++ b/integrationTests/testP2PNode.go @@ -31,6 +31,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/nodeTypeProviderMock" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/ElrondNetwork/elrond-go/update/trigger" ) @@ -169,7 +170,7 @@ func (tP2pNode *TestP2PNode) initNode() { processComponents := GetDefaultProcessComponents() processComponents.ShardCoord = tP2pNode.ShardCoordinator processComponents.NodesCoord = tP2pNode.NodesCoordinator - processComponents.ValidatorProvider = &mock.ValidatorsProviderStub{} + processComponents.ValidatorProvider = &stakingcommon.ValidatorsProviderStub{} processComponents.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ GetValidatorInfoForRootHashCalled: func(_ []byte) (state.ShardValidatorsInfoMapHandler, error) { ret := state.NewShardValidatorsInfoMap() diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 7514707a0c4..2ce686b4b3b 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -98,6 +98,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" trieFactory "github.com/ElrondNetwork/elrond-go/trie/factory" @@ -2948,7 +2949,7 @@ func (tpn *TestProcessorNode) createHeartbeatWithHardforkTrigger(heartbeatPk str return ret, nil }, } - processComponents.ValidatorProvider = &mock.ValidatorsProviderStub{} + processComponents.ValidatorProvider = &stakingcommon.ValidatorsProviderStub{} processComponents.EpochTrigger = tpn.EpochStartTrigger processComponents.EpochNotifier = tpn.EpochStartNotifier processComponents.WhiteListerVerifiedTxsInternal = tpn.WhiteListerVerifiedTxs @@ -3059,7 +3060,7 @@ func GetDefaultProcessComponents() *mock.ProcessComponentsStub { HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, - ValidatorProvider: &mock.ValidatorsProviderStub{}, + ValidatorProvider: &stakingcommon.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, ReqHandler: &testscommon.RequestHandlerStub{}, diff --git a/node/mock/validatorsProviderStub.go b/node/mock/validatorsProviderStub.go deleted file mode 100644 index 5dfaaf22f4d..00000000000 --- a/node/mock/validatorsProviderStub.go +++ /dev/null @@ -1,26 +0,0 @@ -package mock - -import "github.com/ElrondNetwork/elrond-go/state" - -// ValidatorsProviderStub - -type ValidatorsProviderStub struct { - GetLatestValidatorsCalled func() map[string]*state.ValidatorApiResponse -} - -// GetLatestValidators - -func (vp *ValidatorsProviderStub) GetLatestValidators() map[string]*state.ValidatorApiResponse { - if vp.GetLatestValidatorsCalled != nil { - return vp.GetLatestValidatorsCalled() - } - return nil -} - -// Close - -func (vp *ValidatorsProviderStub) Close() error { - return nil -} - -// IsInterfaceNil - -func (vp *ValidatorsProviderStub) IsInterfaceNil() bool { - return vp == nil -} diff --git a/node/node_test.go b/node/node_test.go index 723937fb408..63aea4ee227 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -47,6 +47,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" @@ -2593,15 +2594,16 @@ func TestNode_ValidatorStatisticsApi(t *testing.T) { }, } - validatorProvider := &mock.ValidatorsProviderStub{GetLatestValidatorsCalled: func() map[string]*state.ValidatorApiResponse { - apiResponses := make(map[string]*state.ValidatorApiResponse) + validatorProvider := &stakingcommon.ValidatorsProviderStub{ + GetLatestValidatorsCalled: func() map[string]*state.ValidatorApiResponse { + apiResponses := make(map[string]*state.ValidatorApiResponse) - for _, vi := range validatorsInfo.GetAllValidatorsInfo() { - apiResponses[hex.EncodeToString(vi.GetPublicKey())] = &state.ValidatorApiResponse{} - } + for _, vi := range validatorsInfo.GetAllValidatorsInfo() { + apiResponses[hex.EncodeToString(vi.GetPublicKey())] = &state.ValidatorApiResponse{} + } - return apiResponses - }, + return apiResponses + }, } processComponents := getDefaultProcessComponents() @@ -3677,7 +3679,7 @@ func getDefaultProcessComponents() *factoryMock.ProcessComponentsMock { HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, - ValidatorProvider: &mock.ValidatorsProviderStub{}, + ValidatorProvider: &stakingcommon.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, ReqHandler: &testscommon.RequestHandlerStub{}, diff --git a/process/mock/validatorsProviderStub.go b/process/mock/validatorsProviderStub.go deleted file mode 100644 index 5dfaaf22f4d..00000000000 --- a/process/mock/validatorsProviderStub.go +++ /dev/null @@ -1,26 +0,0 @@ -package mock - -import "github.com/ElrondNetwork/elrond-go/state" - -// ValidatorsProviderStub - -type ValidatorsProviderStub struct { - GetLatestValidatorsCalled func() map[string]*state.ValidatorApiResponse -} - -// GetLatestValidators - -func (vp *ValidatorsProviderStub) GetLatestValidators() map[string]*state.ValidatorApiResponse { - if vp.GetLatestValidatorsCalled != nil { - return vp.GetLatestValidatorsCalled() - } - return nil -} - -// Close - -func (vp *ValidatorsProviderStub) Close() error { - return nil -} - -// IsInterfaceNil - -func (vp *ValidatorsProviderStub) IsInterfaceNil() bool { - return vp == nil -} diff --git a/factory/mock/validatorsProviderStub.go b/testscommon/stakingcommon/validatorsProviderStub.go similarity index 57% rename from factory/mock/validatorsProviderStub.go rename to testscommon/stakingcommon/validatorsProviderStub.go index 5dfaaf22f4d..e22125dcacb 100644 --- a/factory/mock/validatorsProviderStub.go +++ b/testscommon/stakingcommon/validatorsProviderStub.go @@ -1,10 +1,14 @@ -package mock +package stakingcommon -import "github.com/ElrondNetwork/elrond-go/state" +import ( + "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/state" +) // ValidatorsProviderStub - type ValidatorsProviderStub struct { GetLatestValidatorsCalled func() map[string]*state.ValidatorApiResponse + GetAuctionListCalled func() []*common.AuctionListValidatorAPIResponse } // GetLatestValidators - @@ -12,6 +16,16 @@ func (vp *ValidatorsProviderStub) GetLatestValidators() map[string]*state.Valida if vp.GetLatestValidatorsCalled != nil { return vp.GetLatestValidatorsCalled() } + + return nil +} + +// GetAuctionList - +func (vp *ValidatorsProviderStub) GetAuctionList() []*common.AuctionListValidatorAPIResponse { + if vp.GetAuctionListCalled != nil { + return vp.GetAuctionListCalled() + } + return nil } From f174c9697418d8077118153e8cf17c63ae00b87f Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 11 May 2022 10:46:13 +0300 Subject: [PATCH 244/958] fix test facade interface --- integrationTests/interface.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationTests/interface.go b/integrationTests/interface.go index 02e968cd255..b13bd5cfa7c 100644 --- a/integrationTests/interface.go +++ b/integrationTests/interface.go @@ -88,6 +88,7 @@ type Facade interface { EncodeAddressPubkey(pk []byte) (string, error) GetThrottlerForEndpoint(endpoint string) (core.Throttler, bool) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) + AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) ExecuteSCQuery(*process.SCQuery) (*vm.VMOutputApi, error) DecodeAddressPubkey(pk string) ([]byte, error) GetProof(rootHash string, address string) (*common.GetProofResponse, error) From 3381b835eab250911fad7baeeed5a4d478875378 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 11 May 2022 11:34:04 +0300 Subject: [PATCH 245/958] bugfix: validators provider initialized too quickly and not for shards --- factory/blockProcessorCreator.go | 3 ++ factory/disabled/stakingDataProvider.go | 65 +++++++++++++++++++++++++ factory/processComponents.go | 36 +++++++------- 3 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 factory/disabled/stakingDataProvider.go diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 455dd6b74d7..cf7e6a5026f 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -12,6 +12,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/bootstrap/disabled" metachainEpochStart "github.com/ElrondNetwork/elrond-go/epochStart/metachain" + factoryDisabled "github.com/ElrondNetwork/elrond-go/factory/disabled" "github.com/ElrondNetwork/elrond-go/genesis" processDisabled "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" @@ -414,6 +415,8 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( vmFactoryForProcessing: vmFactory, } + pcf.stakingDataProvider = factoryDisabled.NewDisabledStakingDataProvider() + return blockProcessorComponents, nil } diff --git a/factory/disabled/stakingDataProvider.go b/factory/disabled/stakingDataProvider.go new file mode 100644 index 00000000000..fce43915ab6 --- /dev/null +++ b/factory/disabled/stakingDataProvider.go @@ -0,0 +1,65 @@ +package disabled + +import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go/state" +) + +var emptyBI = big.NewInt(0) + +type stakingDataProvider struct { +} + +// NewDisabledStakingDataProvider returns a new instance of stakingDataProvider +func NewDisabledStakingDataProvider() *stakingDataProvider { + return &stakingDataProvider{} +} + +// GetTotalStakeEligibleNodes returns an empty big integer +func (s *stakingDataProvider) GetTotalStakeEligibleNodes() *big.Int { + return emptyBI +} + +// GetTotalTopUpStakeEligibleNodes returns an empty big integer +func (s *stakingDataProvider) GetTotalTopUpStakeEligibleNodes() *big.Int { + return emptyBI +} + +// GetNodeStakedTopUp returns an empty big integer and a nil error +func (s *stakingDataProvider) GetNodeStakedTopUp(_ []byte) (*big.Int, error) { + return emptyBI, nil +} + +// PrepareStakingData returns a nil error +func (s *stakingDataProvider) PrepareStakingData(_ map[uint32][][]byte) error { + return nil +} + +// FillValidatorInfo returns a nil error +func (s *stakingDataProvider) FillValidatorInfo(_ []byte) error { + return nil +} + +// ComputeUnQualifiedNodes returns nil values +func (s *stakingDataProvider) ComputeUnQualifiedNodes(_ state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { + return nil, nil, nil +} + +// GetBlsKeyOwner returns an empty key and a nil error +func (s *stakingDataProvider) GetBlsKeyOwner(_ []byte) (string, error) { + return "", nil +} + +// Clean does nothing +func (s *stakingDataProvider) Clean() { +} + +// EpochConfirmed does nothing +func (s *stakingDataProvider) EpochConfirmed(_ uint32, _ uint64) { +} + +// IsInterfaceNil returns true if there is no value under the interface +func (s *stakingDataProvider) IsInterfaceNil() bool { + return s == nil +} diff --git a/factory/processComponents.go b/factory/processComponents.go index c89bff22792..15ef46c2530 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -316,23 +316,6 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { return nil, err } - cacheRefreshDuration := time.Duration(pcf.config.ValidatorStatistics.CacheRefreshIntervalInSec) * time.Second - argVSP := peer.ArgValidatorsProvider{ - NodesCoordinator: pcf.nodesCoordinator, - StartEpoch: startEpochNum, - EpochStartEventNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), - CacheRefreshIntervalDurationInSec: cacheRefreshDuration, - ValidatorStatistics: validatorStatisticsProcessor, - MaxRating: pcf.maxRating, - ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), - AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), - } - - validatorsProvider, err := peer.NewValidatorsProvider(argVSP) - if err != nil { - return nil, err - } - epochStartTrigger, err := pcf.newEpochStartTrigger(requestHandler) if err != nil { return nil, err @@ -505,6 +488,24 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { return nil, err } + cacheRefreshDuration := time.Duration(pcf.config.ValidatorStatistics.CacheRefreshIntervalInSec) * time.Second + argVSP := peer.ArgValidatorsProvider{ + NodesCoordinator: pcf.nodesCoordinator, + StartEpoch: startEpochNum, + EpochStartEventNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), + CacheRefreshIntervalDurationInSec: cacheRefreshDuration, + ValidatorStatistics: validatorStatisticsProcessor, + StakingDataProvider: pcf.stakingDataProvider, + MaxRating: pcf.maxRating, + ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), + } + + validatorsProvider, err := peer.NewValidatorsProvider(argVSP) + if err != nil { + return nil, err + } + conversionBase := 10 genesisNodePrice, ok := big.NewInt(0).SetString(pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, conversionBase) if !ok { @@ -614,7 +615,6 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { } func (pcf *processComponentsFactory) newValidatorStatisticsProcessor() (process.ValidatorStatisticsProcessor, error) { - storageService := pcf.data.StorageService() var peerDataPool peer.DataPool = pcf.data.Datapool() From 68a602a18f1db8ac84c935f578c7f8974096c78f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 11 May 2022 14:18:28 +0300 Subject: [PATCH 246/958] FEAT: Ugly test to unStake nodes with not enough funds --- .../vm/staking/baseTestMetaProcessor.go | 6 + .../vm/staking/configDisplayer.go | 63 ++-- integrationTests/vm/staking/stakingV4_test.go | 294 +++++++++++++++--- .../vm/staking/systemSCCreator.go | 27 +- .../vm/staking/testMetaProcessor.go | 4 +- .../testMetaProcessorWithCustomNodesConfig.go | 4 +- 6 files changed, 334 insertions(+), 64 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index d54edc4a97c..4913f8aaa8e 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -51,6 +51,10 @@ func newTestMetaProcessor( bootstrapComponents.ShardCoordinator(), stateComponents.PeerAccounts(), ) + stakingDataProvider := createStakingDataProvider( + coreComponents.EpochNotifier(), + systemVM, + ) scp := createSystemSCProcessor( nc, coreComponents, @@ -59,6 +63,7 @@ func newTestMetaProcessor( maxNodesConfig, validatorStatisticsProcessor, systemVM, + stakingDataProvider, ) txCoordinator := &mock.TransactionCoordinatorMock{} @@ -103,6 +108,7 @@ func newTestMetaProcessor( SystemVM: systemVM, StateComponents: stateComponents, BlockChainHook: blockChainHook, + StakingDataProvider: stakingDataProvider, } } diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index 2a6e55f4914..48b72525da6 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/ElrondNetwork/elrond-go-core/display" + "github.com/ElrondNetwork/elrond-go/state" ) const ( @@ -35,52 +36,78 @@ func getShortPubKeysList(pubKeys [][]byte) [][]byte { return pubKeysToDisplay } -func displayConfig(config nodesConfig) { +func getEligibleNodeKeys( + validatorsInfoMap state.ShardValidatorsInfoMapHandler, +) map[uint32][][]byte { + eligibleNodesKeys := make(map[uint32][][]byte) + for shardID, validatorsInfoSlice := range validatorsInfoMap.GetShardValidatorsInfoMap() { + eligibleNodesKeys[shardID] = make([][]byte, 0) + for _, validatorInfo := range validatorsInfoSlice { + eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.GetPublicKey()) + + } + } + return eligibleNodesKeys +} + +func (tmp *TestMetaProcessor) displayConfig(config nodesConfig) { lines := make([]*display.LineData, 0) + rootHash, _ := tmp.ValidatorStatistics.RootHash() + validatorsMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + + allNodes := getEligibleNodeKeys(validatorsMap) + tmp.StakingDataProvider.PrepareStakingData(allNodes) + for shard := range config.eligible { - lines = append(lines, getDisplayableValidatorsInShard("eligible", config.eligible[shard], shard)...) - lines = append(lines, getDisplayableValidatorsInShard("waiting", config.waiting[shard], shard)...) - lines = append(lines, getDisplayableValidatorsInShard("leaving", config.leaving[shard], shard)...) - lines = append(lines, getDisplayableValidatorsInShard("shuffled", config.shuffledOut[shard], shard)...) + lines = append(lines, tmp.getDisplayableValidatorsInShard("eligible", config.eligible[shard], shard)...) + lines = append(lines, tmp.getDisplayableValidatorsInShard("waiting", config.waiting[shard], shard)...) + lines = append(lines, tmp.getDisplayableValidatorsInShard("leaving", config.leaving[shard], shard)...) + lines = append(lines, tmp.getDisplayableValidatorsInShard("shuffled", config.shuffledOut[shard], shard)...) lines = append(lines, display.NewLineData(true, []string{})) } - lines = append(lines, display.NewLineData(true, []string{"eligible", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.eligible))), "All shards"})) - lines = append(lines, display.NewLineData(true, []string{"waiting", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.waiting))), "All shards"})) - lines = append(lines, display.NewLineData(true, []string{"leaving", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.leaving))), "All shards"})) - lines = append(lines, display.NewLineData(true, []string{"shuffled", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.shuffledOut))), "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"eligible", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.eligible))), "", "", "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"waiting", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.waiting))), "", "", "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"leaving", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.leaving))), "", "", "All shards"})) + lines = append(lines, display.NewLineData(true, []string{"shuffled", fmt.Sprintf("Total: %d", len(getAllPubKeys(config.shuffledOut))), "", "", "All shards"})) - tableHeader := []string{"List", "Pub key", "Shard ID"} + tableHeader := []string{"List", "BLS key", "Owner", "TopUp", "Shard ID"} table, _ := display.CreateTableString(tableHeader, lines) headline := display.Headline("Nodes config", "", delimiter) fmt.Printf("%s\n%s\n", headline, table) - displayValidators("Auction", config.auction) - displayValidators("Queue", config.queue) + tmp.displayValidators("Auction", config.auction) + tmp.displayValidators("Queue", config.queue) + + tmp.StakingDataProvider.Clean() } -func getDisplayableValidatorsInShard(list string, pubKeys [][]byte, shardID uint32) []*display.LineData { +func (tmp *TestMetaProcessor) getDisplayableValidatorsInShard(list string, pubKeys [][]byte, shardID uint32) []*display.LineData { pubKeysToDisplay := getShortPubKeysList(pubKeys) lines := make([]*display.LineData, 0) for idx, pk := range pubKeysToDisplay { horizontalLineAfter := idx == len(pubKeysToDisplay)-1 - line := display.NewLineData(horizontalLineAfter, []string{list, string(pk), strconv.Itoa(int(shardID))}) + owner, _ := tmp.StakingDataProvider.GetBlsKeyOwner(pk) + topUp, _ := tmp.StakingDataProvider.GetNodeStakedTopUp(pk) + line := display.NewLineData(horizontalLineAfter, []string{list, string(pk), owner, topUp.String(), strconv.Itoa(int(shardID))}) lines = append(lines, line) } - lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys)), strconv.Itoa(int(shardID))})) + lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys)), "", "", strconv.Itoa(int(shardID))})) return lines } -func displayValidators(list string, pubKeys [][]byte) { +func (tmp *TestMetaProcessor) displayValidators(list string, pubKeys [][]byte) { pubKeysToDisplay := getShortPubKeysList(pubKeys) lines := make([]*display.LineData, 0) - tableHeader := []string{"List", "Pub key"} + tableHeader := []string{"List", "BLS key", "Owner", "TopUp"} for idx, pk := range pubKeysToDisplay { horizontalLineAfter := idx == len(pubKeysToDisplay)-1 - lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk)})) + owner, _ := tmp.StakingDataProvider.GetBlsKeyOwner(pk) + topUp, _ := tmp.StakingDataProvider.GetNodeStakedTopUp(pk) + lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk), owner, topUp.String()})) } lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys))})) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 77b7cc55223..5fd661e2d80 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -6,8 +6,12 @@ import ( "testing" "github.com/ElrondNetwork/elrond-go-core/core" - logger "github.com/ElrondNetwork/elrond-go-logger" + "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/stretchr/testify/require" ) @@ -224,52 +228,214 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH } } -func TestStakingV4_CustomScenario(t *testing.T) { - pubKeys := generateAddresses(0, 30) - - _ = logger.SetLogLevel("*:DEBUG") +func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { + pubKeys := generateAddresses(0, 40) + // Owner1 has 8 nodes, but enough stake for just 7 nodes. At the end of the epoch(staking v4 init), + // the last node from staking queue should be unStaked owner1 := "owner1" owner1Stats := &OwnerStats{ EligibleBlsKeys: map[uint32][][]byte{ core.MetachainShardId: pubKeys[:3], - 0: pubKeys[3:6], }, - StakingQueueKeys: pubKeys[6:9], - TotalStake: big.NewInt(5000), + WaitingBlsKeys: map[uint32][][]byte{ + 0: pubKeys[3:6], // 1 waiting shard 0 + }, + StakingQueueKeys: pubKeys[6:8], // 2 queue + TotalStake: big.NewInt(7 * nodePrice), } + // Owner2 has 6 nodes, but enough stake for just 5 nodes. At the end of the epoch(staking v4 init), + // one node from waiting list should be unStaked owner2 := "owner2" owner2Stats := &OwnerStats{ EligibleBlsKeys: map[uint32][][]byte{ - 1: pubKeys[9:10], - 2: pubKeys[10:11], + 0: pubKeys[8:11], }, WaitingBlsKeys: map[uint32][][]byte{ - 0: pubKeys[11:12], - 1: pubKeys[12:13], - 2: pubKeys[13:14], + core.MetachainShardId: pubKeys[11:14], }, - TotalStake: big.NewInt(5000), + TotalStake: big.NewInt(5 * nodePrice), } + // Owner3 has 2 nodes in staking queue with with topUp = nodePrice owner3 := "owner3" owner3Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[14:16], + TotalStake: big.NewInt(3 * nodePrice), + } + + // Owner4 has 1 node in staking queue with topUp = nodePrice + owner4 := "owner4" + owner4Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[16:17], + TotalStake: big.NewInt(2 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 2, + ShardConsensusGroupSize: 2, + MinNumberOfEligibleShardNodes: 3, + MinNumberOfEligibleMetaNodes: 3, + NumOfShards: 1, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + owner2: owner2Stats, + owner3: owner3Stats, + owner4: owner4Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 12, + NodesToShufflePerShard: 1, + }, + { + EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, + MaxNumNodes: 10, + NodesToShufflePerShard: 1, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.eligible[0], 3) + require.Len(t, currNodesConfig.waiting[0], 3) + + requireSliceContainsNumOfElements(t, currNodesConfig.eligible[core.MetachainShardId], owner1Stats.EligibleBlsKeys[core.MetachainShardId], 3) + requireSliceContainsNumOfElements(t, currNodesConfig.waiting[core.MetachainShardId], owner2Stats.WaitingBlsKeys[core.MetachainShardId], 3) + + requireSliceContainsNumOfElements(t, currNodesConfig.eligible[0], owner2Stats.EligibleBlsKeys[0], 3) + requireSliceContainsNumOfElements(t, currNodesConfig.waiting[0], owner1Stats.WaitingBlsKeys[0], 3) + + owner1StakingQueue := owner1Stats.StakingQueueKeys + owner3StakingQueue := owner3Stats.StakingQueueKeys + owner4StakingQueue := owner4Stats.StakingQueueKeys + queue := make([][]byte, 0) + queue = append(queue, owner1StakingQueue...) + queue = append(queue, owner3StakingQueue...) + queue = append(queue, owner4StakingQueue...) + require.Len(t, currNodesConfig.queue, 5) + requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // 2. Check config after staking v4 initialization + node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 5) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 3) + require.Len(t, currNodesConfig.waiting[0], 3) + + // Owner1 will have the second node from queue removed, before adding all the nodes to auction list + queue = remove(queue, owner1StakingQueue[1]) + require.Empty(t, currNodesConfig.queue) + require.Len(t, currNodesConfig.auction, 4) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) + + // Owner2 will have one of the nodes in waiting list removed + require.Len(t, getAllPubKeys(currNodesConfig.leaving), 1) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.leaving), getAllPubKeys(owner2Stats.WaitingBlsKeys), 1) + + // Owner1 will unStake some EGLD => at the end of next epoch, he should the other node from auction list removed + unStake([]byte(owner1), node.AccountsAdapter, node.Marshaller, big.NewInt(0.1*nodePrice)) + + // 3. Check config in epoch = staking v4 + node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 3) + require.Len(t, getAllPubKeys(currNodesConfig.shuffledOut), 2) + + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) + require.Len(t, currNodesConfig.shuffledOut[core.MetachainShardId], 1) + require.Len(t, currNodesConfig.eligible[0], 3) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Len(t, currNodesConfig.shuffledOut[0], 1) + + // Owner1 will have the last node from auction list removed + queue = remove(queue, owner1StakingQueue[0]) + require.Len(t, currNodesConfig.auction, 3) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) + require.Len(t, getAllPubKeys(currNodesConfig.leaving), 1) + require.Equal(t, getAllPubKeys(currNodesConfig.leaving)[0], owner1StakingQueue[0]) + + // Owner3 will unStake EGLD => he will have negative top-up at the selection time => one of his nodes will be unStaked. + // His other node should not have been selected => remains in auction. + // Meanwhile, owner4 had never unStaked EGLD => his node from auction list node will be distributed to waiting + unStake([]byte(owner3), node.AccountsAdapter, node.Marshaller, big.NewInt(2*nodePrice)) + + // 4. Check config in epoch = staking v4 distribute auction to waiting + node.Process(t, 5) + currNodesConfig = node.NodesConfig + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.leaving), owner3StakingQueue, 1) + requireSliceContainsNumOfElements(t, currNodesConfig.auction, owner3StakingQueue, 1) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), owner4StakingQueue, 1) +} + +func remove(s [][]byte, elem []byte) [][]byte { + ret := s + for i, e := range s { + if bytes.Equal(elem, e) { + ret[i] = ret[len(s)-1] + return ret[:len(s)-1] + } + } + + return ret +} + +func unStake(owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { + validatorSC := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) + ownerStoredData, _ := validatorSC.DataTrieTracker().RetrieveValue(owner) + validatorData := &systemSmartContracts.ValidatorDataV2{} + _ = marshaller.Unmarshal(validatorData, ownerStoredData) + + validatorData.TotalStakeValue.Sub(validatorData.TotalStakeValue, stake) + + marshaledData, _ := marshaller.Marshal(validatorData) + _ = validatorSC.DataTrieTracker().SaveKeyValue(owner, marshaledData) + + _ = accountsDB.SaveAccount(validatorSC) + _, _ = accountsDB.Commit() +} + +func TestStakingV4_StakeNewNodes(t *testing.T) { + pubKeys := generateAddresses(0, 40) + + //_ = logger.SetLogLevel("*:DEBUG") + + owner1 := "owner1" + owner1Stats := &OwnerStats{ EligibleBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[14:15], + core.MetachainShardId: pubKeys[:3], }, WaitingBlsKeys: map[uint32][][]byte{ - 0: pubKeys[15:16], + 0: pubKeys[3:6], // 1 waiting shard 0 }, - TotalStake: big.NewInt(5000), + StakingQueueKeys: pubKeys[7:9], // 2 queue + TotalStake: big.NewInt(7000), } - owner4 := "owner4" - owner4Stats := &OwnerStats{ + owner2 := "owner2" + owner2Stats := &OwnerStats{ EligibleBlsKeys: map[uint32][][]byte{ - 0: pubKeys[16:19], - 1: pubKeys[19:21], - 2: pubKeys[21:23], + 0: pubKeys[17:20], //total 3 meta + }, + WaitingBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[13:16], }, TotalStake: big.NewInt(5000), } @@ -289,51 +455,109 @@ func TestStakingV4_CustomScenario(t *testing.T) { cfg := &InitialNodesConfig{ MetaConsensusGroupSize: 2, ShardConsensusGroupSize: 2, - MinNumberOfEligibleShardNodes: 2, - MinNumberOfEligibleMetaNodes: 2, - NumOfShards: 4, + MinNumberOfEligibleShardNodes: 3, + MinNumberOfEligibleMetaNodes: 3, + NumOfShards: 1, Owners: map[string]*OwnerStats{ owner1: owner1Stats, owner2: owner2Stats, - owner3: owner3Stats, - owner4: owner4Stats, owner5: owner5Stats, owner6: owner6Stats, }, MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { EpochEnable: 0, - MaxNumNodes: 4, - NodesToShufflePerShard: 2, + MaxNumNodes: 12, + NodesToShufflePerShard: 1, + }, + { + EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, + MaxNumNodes: 10, + NodesToShufflePerShard: 1, }, }, } //todo; check that in epoch = staking v4 nodes with not enough stake will be unstaked node := NewTestMetaProcessorWithCustomNodes(cfg) - node.EpochStartTrigger.SetRoundsPerEpoch(5) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) + + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.eligible[0], 3) + require.Len(t, currNodesConfig.waiting[0], 3) + + requireSliceContainsNumOfElements(t, currNodesConfig.eligible[core.MetachainShardId], owner1Stats.EligibleBlsKeys[core.MetachainShardId], 3) + requireSliceContainsNumOfElements(t, currNodesConfig.waiting[core.MetachainShardId], owner2Stats.WaitingBlsKeys[core.MetachainShardId], 3) + + requireSliceContainsNumOfElements(t, currNodesConfig.eligible[0], owner2Stats.EligibleBlsKeys[0], 3) + requireSliceContainsNumOfElements(t, currNodesConfig.waiting[0], owner1Stats.WaitingBlsKeys[0], 3) + + initialStakingQueue := owner1Stats.StakingQueueKeys + initialStakingQueue = append(initialStakingQueue, owner5Stats.StakingQueueKeys...) + initialStakingQueue = append(initialStakingQueue, owner6Stats.StakingQueueKeys...) + require.Len(t, currNodesConfig.queue, 5) + requireSliceContainsNumOfElements(t, currNodesConfig.queue, initialStakingQueue, 5) + + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // 2. Check config after staking v4 initialization + node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 5) + + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 3) + require.Len(t, currNodesConfig.waiting[0], 3) + + // Owner1 will have one of the nodes in staking queue removed + initialStakingQueue = initialStakingQueue[2:] + initialStakingQueue = append(initialStakingQueue, owner1Stats.StakingQueueKeys[0]) + require.Len(t, currNodesConfig.auction, 4) + requireSliceContainsNumOfElements(t, currNodesConfig.auction, initialStakingQueue, 4) + + // Owner2 will have one of the nodes in waiting list removed + require.Len(t, getAllPubKeys(currNodesConfig.leaving), 1) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.leaving), getAllPubKeys(owner2Stats.WaitingBlsKeys), 1) + + //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) + //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) + //require.Empty(t, nodesConfigStakingV4Init.queue) + //require.Empty(t, nodesConfigStakingV4Init.shuffledOut) + //requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) + + node.Process(t, 8) owner444 := "owner444" owner555 := "owner555" newNodes := map[string]*NodesRegisterData{ owner444: { BLSKeys: [][]byte{generateAddress(444)}, - TotalStake: big.NewInt(5000), + TotalStake: big.NewInt(50000), }, owner555: { BLSKeys: [][]byte{generateAddress(555), generateAddress(666)}, - TotalStake: big.NewInt(6000), + TotalStake: big.NewInt(60000), }, } - node.Process(t, 15) node.ProcessStake(t, newNodes) - currNodesConfig := node.NodesConfig + currNodesConfig = node.NodesConfig requireSliceContains(t, currNodesConfig.auction, newNodes[owner444].BLSKeys) requireSliceContains(t, currNodesConfig.auction, newNodes[owner555].BLSKeys) - node.Process(t, 4) + node.Process(t, 3) currNodesConfig = node.NodesConfig requireMapContains(t, currNodesConfig.waiting, newNodes[owner444].BLSKeys) requireMapContains(t, currNodesConfig.waiting, newNodes[owner555].BLSKeys) + + node.Process(t, 20) } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index de94f0bd118..fa42d71145e 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -6,6 +6,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" epochStartMock "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/factory" @@ -33,15 +34,8 @@ func createSystemSCProcessor( maxNodesConfig []config.MaxNodesChangeConfig, validatorStatisticsProcessor process.ValidatorStatisticsProcessor, systemVM vmcommon.VMExecutionHandler, + stakingDataProvider epochStart.StakingDataProvider, ) process.EpochStartSystemSCProcessor { - argsStakingDataProvider := metachain.StakingDataProviderArgs{ - EpochNotifier: coreComponents.EpochNotifier(), - SystemVM: systemVM, - MinNodePrice: strconv.Itoa(nodePrice), - StakingV4EnableEpoch: stakingV4EnableEpoch, - } - stakingSCProvider, _ := metachain.NewStakingDataProvider(argsStakingDataProvider) - args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, UserAccountsDB: stateComponents.AccountsAdapter(), @@ -54,7 +48,7 @@ func createSystemSCProcessor( ChanceComputer: &epochStartMock.ChanceComputerStub{}, EpochNotifier: coreComponents.EpochNotifier(), GenesisNodesConfig: &mock.NodesSetupStub{}, - StakingDataProvider: stakingSCProvider, + StakingDataProvider: stakingDataProvider, NodesConfigProvider: nc, ShardCoordinator: shardCoordinator, ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), @@ -72,6 +66,21 @@ func createSystemSCProcessor( return systemSCProcessor } +func createStakingDataProvider( + epochNotifier process.EpochNotifier, + systemVM vmcommon.VMExecutionHandler, +) epochStart.StakingDataProvider { + argsStakingDataProvider := metachain.StakingDataProviderArgs{ + EpochNotifier: epochNotifier, + SystemVM: systemVM, + MinNodePrice: strconv.Itoa(nodePrice), + StakingV4EnableEpoch: stakingV4EnableEpoch, + } + stakingSCProvider, _ := metachain.NewStakingDataProvider(argsStakingDataProvider) + + return stakingSCProvider +} + func createValidatorStatisticsProcessor( dataComponents factory.DataComponentsHolder, coreComponents factory.CoreComponentsHolder, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 771bb47c10d..510779d970e 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -16,6 +16,7 @@ import ( "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/process" @@ -61,6 +62,7 @@ type TestMetaProcessor struct { SystemVM vmcommon.VMExecutionHandler StateComponents factory.StateComponentsHolder BlockChainHook process.BlockChainHookHandler + StakingDataProvider epochStart.StakingDataProvider currentRound uint64 } @@ -195,7 +197,7 @@ func (tmp *TestMetaProcessor) createAndCommitBlock(t *testing.T, header data.Hea time.Sleep(time.Millisecond * 50) tmp.updateNodesConfig(header.GetEpoch()) - displayConfig(tmp.NodesConfig) + tmp.displayConfig(tmp.NodesConfig) } func printNewHeaderRoundEpoch(round uint64, epoch uint32) { diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 1beb05e0b4c..6029bdfbf47 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -134,6 +134,7 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes tmp.currentRound += 1 } +//TODO: Do the same for unStake func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, @@ -163,9 +164,10 @@ func createStakingQueueCustomNodes( []byte(owner), ) - stakingcommon.AddValidatorData( + stakingcommon.RegisterValidatorKeys( accountsAdapter, []byte(owner), + []byte(owner), ownerStats.StakingQueueKeys, ownerStats.TotalStake, marshaller, From d759fbc0dd55c766a439d2d82e7c7c72b69ddd02 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 11 May 2022 17:22:19 +0300 Subject: [PATCH 247/958] FIX: Refactor --- epochStart/metachain/systemSCs.go | 18 +- integrationTests/common.go | 38 +++ integrationTests/testProcessorNode.go | 39 +-- .../vm/staking/baseTestMetaProcessor.go | 205 +++++++++++++++ .../vm/staking/configDisplayer.go | 25 +- integrationTests/vm/staking/stakingQueue.go | 34 ++- integrationTests/vm/staking/stakingV4_test.go | 2 - .../vm/staking/testMetaProcessor.go | 242 ------------------ .../testMetaProcessorWithCustomNodesConfig.go | 43 +--- 9 files changed, 296 insertions(+), 350 deletions(-) create mode 100644 integrationTests/common.go diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 9408e07d980..b4bddc17fa3 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -375,28 +375,14 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Debug(message) + log.Info(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { - allNodes := s.getAllNodeKeys(validatorsInfoMap) + allNodes := GetAllNodeKeys(validatorsInfoMap) return s.prepareStakingData(allNodes) } -func (s *systemSCProcessor) getAllNodeKeys( - validatorsInfo state.ShardValidatorsInfoMapHandler, -) map[uint32][][]byte { - nodeKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfo.GetShardValidatorsInfoMap() { - nodeKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) - for _, validatorInfo := range validatorsInfoSlice { - nodeKeys[shardID] = append(nodeKeys[shardID], validatorInfo.GetPublicKey()) - } - } - - return nodeKeys -} - func (s *systemSCProcessor) updateToGovernanceV2() error { vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ diff --git a/integrationTests/common.go b/integrationTests/common.go new file mode 100644 index 00000000000..6f5602de789 --- /dev/null +++ b/integrationTests/common.go @@ -0,0 +1,38 @@ +package integrationTests + +import ( + "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" +) + +// ProcessSCOutputAccounts will save account changes in accounts db from vmOutput +func ProcessSCOutputAccounts(vmOutput *vmcommon.VMOutput, accountsDB state.AccountsAdapter) error { + outputAccounts := process.SortVMOutputInsideData(vmOutput) + for _, outAcc := range outputAccounts { + acc := stakingcommon.LoadUserAccount(accountsDB, outAcc.Address) + + storageUpdates := process.GetSortedStorageUpdates(outAcc) + for _, storeUpdate := range storageUpdates { + err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) + if err != nil { + return err + } + + if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(zero) != 0 { + err = acc.AddToBalance(outAcc.BalanceDelta) + if err != nil { + return err + } + } + + err = accountsDB.SaveAccount(acc) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 7514707a0c4..6ae4a0823b6 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1901,7 +1901,7 @@ func (tpn *TestProcessorNode) InitDelegationManager() { log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) } - err = tpn.processSCOutputAccounts(vmOutput) + err = ProcessSCOutputAccounts(vmOutput, tpn.AccntState) log.LogIfError(err) err = tpn.updateSystemSCContractsCode(vmInput.ContractCodeMetadata, vm.DelegationManagerSCAddress) @@ -1937,7 +1937,7 @@ func (tpn *TestProcessorNode) InitLiquidStaking() []byte { log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) } - err = tpn.processSCOutputAccounts(vmOutput) + err = ProcessSCOutputAccounts(vmOutput, tpn.AccntState) log.LogIfError(err) _, err = tpn.AccntState.Commit() @@ -1966,7 +1966,7 @@ func (tpn *TestProcessorNode) InitLiquidStaking() []byte { log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) } - err = tpn.processSCOutputAccounts(vmOutput) + err = ProcessSCOutputAccounts(vmOutput, tpn.AccntState) log.LogIfError(err) err = tpn.updateSystemSCContractsCode(vmInputCreate.ContractCodeMetadata, vm.LiquidStakingSCAddress) @@ -1991,39 +1991,6 @@ func (tpn *TestProcessorNode) updateSystemSCContractsCode(contractMetadata []byt return tpn.AccntState.SaveAccount(userAcc) } -// save account changes in state from vmOutput - protected by VM - every output can be treated as is. -func (tpn *TestProcessorNode) processSCOutputAccounts(vmOutput *vmcommon.VMOutput) error { - outputAccounts := process.SortVMOutputInsideData(vmOutput) - for _, outAcc := range outputAccounts { - acc, err := tpn.getUserAccount(outAcc.Address) - if err != nil { - return err - } - - storageUpdates := process.GetSortedStorageUpdates(outAcc) - for _, storeUpdate := range storageUpdates { - err = acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) - if err != nil { - return err - } - } - - if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(zero) != 0 { - err = acc.AddToBalance(outAcc.BalanceDelta) - if err != nil { - return err - } - } - - err = tpn.AccntState.SaveAccount(acc) - if err != nil { - return err - } - } - - return nil -} - func (tpn *TestProcessorNode) getUserAccount(address []byte) (state.UserAccountHandler, error) { acnt, err := tpn.AccntState.LoadAccount(address) if err != nil { diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 4913f8aaa8e..116bb3e11c1 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -1,19 +1,76 @@ package staking import ( + "fmt" + "math/big" + "strconv" + "strings" + "testing" + "time" + arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go-core/display" + "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/integrationTests" + "github.com/ElrondNetwork/elrond-go/process" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" + vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/stretchr/testify/require" +) + +const ( + stakingV4InitEpoch = 1 + stakingV4EnableEpoch = 2 + stakingV4DistributeAuctionToWaitingEpoch = 3 + addressLength = 15 + nodePrice = 1000 ) +func haveTime() bool { return true } +func noTime() bool { return false } + +type nodesConfig struct { + eligible map[uint32][][]byte + waiting map[uint32][][]byte + leaving map[uint32][][]byte + shuffledOut map[uint32][][]byte + queue [][]byte + auction [][]byte +} + +// TestMetaProcessor - +type TestMetaProcessor struct { + MetaBlockProcessor process.BlockProcessor + NodesCoordinator nodesCoordinator.NodesCoordinator + ValidatorStatistics process.ValidatorStatisticsProcessor + EpochStartTrigger integrationTests.TestEpochStartTrigger + BlockChainHandler data.ChainHandler + NodesConfig nodesConfig + AccountsAdapter state.AccountsAdapter + Marshaller marshal.Marshalizer + TxCacher dataRetriever.TransactionCacher + TxCoordinator process.TransactionCoordinator + SystemVM vmcommon.VMExecutionHandler + StateComponents factory.StateComponentsHolder + BlockChainHook process.BlockChainHookHandler + StakingDataProvider epochStart.StakingDataProvider + + currentRound uint64 +} + func newTestMetaProcessor( coreComponents factory.CoreComponentsHolder, dataComponents factory.DataComponentsHolder, @@ -141,3 +198,151 @@ func createEpochStartTrigger( return testTrigger } + +// Process - +func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { + for r := tmp.currentRound; r < tmp.currentRound+numOfRounds; r++ { + header := tmp.createNewHeader(t, r) + tmp.createAndCommitBlock(t, header, haveTime) + } + + tmp.currentRound += numOfRounds +} + +func (tmp *TestMetaProcessor) createNewHeader(t *testing.T, round uint64) *block.MetaBlock { + _, err := tmp.MetaBlockProcessor.CreateNewHeader(round, round) + require.Nil(t, err) + + epoch := tmp.EpochStartTrigger.Epoch() + printNewHeaderRoundEpoch(round, epoch) + + currentHeader, currentHash := tmp.getCurrentHeaderInfo() + header := createMetaBlockToCommit( + epoch, + round, + currentHash, + currentHeader.GetRandSeed(), + tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), + ) + + return header +} + +func (tmp *TestMetaProcessor) createAndCommitBlock(t *testing.T, header data.HeaderHandler, haveTime func() bool) { + newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) + require.Nil(t, err) + + err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) + require.Nil(t, err) + + time.Sleep(time.Millisecond * 50) + tmp.updateNodesConfig(header.GetEpoch()) + tmp.displayConfig(tmp.NodesConfig) +} + +func printNewHeaderRoundEpoch(round uint64, epoch uint32) { + headline := display.Headline( + fmt.Sprintf("Commiting header in epoch %v round %v", epoch, round), + "", + delimiter, + ) + fmt.Println(headline) +} + +func (tmp *TestMetaProcessor) getCurrentHeaderInfo() (data.HeaderHandler, []byte) { + currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() + currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() + if currentHeader == nil { + currentHeader = tmp.BlockChainHandler.GetGenesisHeader() + currentHash = tmp.BlockChainHandler.GetGenesisHeaderHash() + } + + return currentHeader, currentHash +} + +func createMetaBlockToCommit( + epoch uint32, + round uint64, + prevHash []byte, + prevRandSeed []byte, + consensusSize int, +) *block.MetaBlock { + roundStr := strconv.Itoa(int(round)) + hdr := block.MetaBlock{ + Epoch: epoch, + Nonce: round, + Round: round, + PrevHash: prevHash, + Signature: []byte("signature"), + PubKeysBitmap: []byte(strings.Repeat("f", consensusSize)), + RootHash: []byte("roothash" + roundStr), + ShardInfo: make([]block.ShardData, 0), + TxCount: 1, + PrevRandSeed: prevRandSeed, + RandSeed: []byte("randseed" + roundStr), + AccumulatedFeesInEpoch: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + DevFeesInEpoch: big.NewInt(0), + DeveloperFees: big.NewInt(0), + } + + shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) + shardMiniBlockHeader := block.MiniBlockHeader{ + Hash: []byte("mb_hash" + roundStr), + ReceiverShardID: 0, + SenderShardID: 0, + TxCount: 1, + } + shardMiniBlockHeaders = append(shardMiniBlockHeaders, shardMiniBlockHeader) + shardData := block.ShardData{ + Nonce: round, + ShardID: 0, + HeaderHash: []byte("hdr_hash" + roundStr), + TxCount: 1, + ShardMiniBlockHeaders: shardMiniBlockHeaders, + DeveloperFees: big.NewInt(0), + AccumulatedFees: big.NewInt(0), + } + hdr.ShardInfo = append(hdr.ShardInfo, shardData) + + return &hdr +} + +func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { + eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) + waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) + leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) + shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) + + rootHash, _ := tmp.ValidatorStatistics.RootHash() + validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + + auction := make([][]byte, 0) + for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { + if validator.GetList() == string(common.AuctionList) { + auction = append(auction, validator.GetPublicKey()) + } + } + + tmp.NodesConfig.eligible = eligible + tmp.NodesConfig.waiting = waiting + tmp.NodesConfig.shuffledOut = shuffledOut + tmp.NodesConfig.leaving = leaving + tmp.NodesConfig.auction = auction + tmp.NodesConfig.queue = tmp.getWaitingListKeys() +} + +func generateAddresses(startIdx, n uint32) [][]byte { + ret := make([][]byte, 0, n) + + for i := startIdx; i < n+startIdx; i++ { + ret = append(ret, generateAddress(i)) + } + + return ret +} + +func generateAddress(identifier uint32) []byte { + uniqueIdentifier := fmt.Sprintf("address-%d", identifier) + return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) +} diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index 48b72525da6..b2aeb784293 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -5,7 +5,7 @@ import ( "strconv" "github.com/ElrondNetwork/elrond-go-core/display" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/epochStart/metachain" ) const ( @@ -36,28 +36,17 @@ func getShortPubKeysList(pubKeys [][]byte) [][]byte { return pubKeysToDisplay } -func getEligibleNodeKeys( - validatorsInfoMap state.ShardValidatorsInfoMapHandler, -) map[uint32][][]byte { - eligibleNodesKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfoMap.GetShardValidatorsInfoMap() { - eligibleNodesKeys[shardID] = make([][]byte, 0) - for _, validatorInfo := range validatorsInfoSlice { - eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.GetPublicKey()) - - } - } - return eligibleNodesKeys +func (tmp *TestMetaProcessor) getAllNodeKeys() map[uint32][][]byte { + rootHash, _ := tmp.ValidatorStatistics.RootHash() + validatorsMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) + return metachain.GetAllNodeKeys(validatorsMap) } func (tmp *TestMetaProcessor) displayConfig(config nodesConfig) { lines := make([]*display.LineData, 0) - rootHash, _ := tmp.ValidatorStatistics.RootHash() - validatorsMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - - allNodes := getEligibleNodeKeys(validatorsMap) - tmp.StakingDataProvider.PrepareStakingData(allNodes) + allNodes := tmp.getAllNodeKeys() + _ = tmp.StakingDataProvider.PrepareStakingData(allNodes) for shard := range config.eligible { lines = append(lines, tmp.getDisplayableValidatorsInShard("eligible", config.eligible[shard], shard)...) diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index c4c313c2c1b..a26bafe6fa5 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -35,9 +35,10 @@ func createStakingQueue( owner, ) - stakingcommon.AddValidatorData( + stakingcommon.RegisterValidatorKeys( accountsAdapter, owner, + owner, ownerWaitingNodes, big.NewInt(int64(2*nodePrice*numOfNodesInStakingQueue)), marshaller, @@ -46,6 +47,37 @@ func createStakingQueue( return ownerWaitingNodes } +func createStakingQueueCustomNodes( + owners map[string]*OwnerStats, + marshaller marshal.Marshalizer, + accountsAdapter state.AccountsAdapter, +) [][]byte { + queue := make([][]byte, 0) + + for owner, ownerStats := range owners { + stakingcommon.AddKeysToWaitingList( + accountsAdapter, + ownerStats.StakingQueueKeys, + marshaller, + []byte(owner), + []byte(owner), + ) + + stakingcommon.RegisterValidatorKeys( + accountsAdapter, + []byte(owner), + []byte(owner), + ownerStats.StakingQueueKeys, + ownerStats.TotalStake, + marshaller, + ) + + queue = append(queue, ownerStats.StakingQueueKeys...) + } + + return queue +} + func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { stakingSCAcc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, vm.StakingSCAddress) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 5fd661e2d80..7eb26b61aa9 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -73,8 +73,6 @@ func requireMapDoesNotContain(t *testing.T, m map[uint32][][]byte, s [][]byte) { } } -// TODO: Staking v4: more tests to check exactly which nodes have been selected/unselected from previous nodes config auction - func TestStakingV4(t *testing.T) { numOfMetaNodes := uint32(400) numOfShards := uint32(3) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 510779d970e..5038a3738f6 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,72 +1,10 @@ package staking import ( - "fmt" - "math/big" - "strconv" - "strings" - "testing" - "time" - - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/display" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/factory" - "github.com/ElrondNetwork/elrond-go/integrationTests" - "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" - "github.com/stretchr/testify/require" -) - -const ( - stakingV4InitEpoch = 1 - stakingV4EnableEpoch = 2 - stakingV4DistributeAuctionToWaitingEpoch = 3 - addressLength = 15 - nodePrice = 1000 ) -func haveTime() bool { return true } -func noTime() bool { return false } - -type nodesConfig struct { - eligible map[uint32][][]byte - waiting map[uint32][][]byte - leaving map[uint32][][]byte - shuffledOut map[uint32][][]byte - queue [][]byte - auction [][]byte -} - -// TestMetaProcessor - -type TestMetaProcessor struct { - MetaBlockProcessor process.BlockProcessor - NodesCoordinator nodesCoordinator.NodesCoordinator - ValidatorStatistics process.ValidatorStatisticsProcessor - EpochStartTrigger integrationTests.TestEpochStartTrigger - BlockChainHandler data.ChainHandler - NodesConfig nodesConfig - AccountsAdapter state.AccountsAdapter - Marshaller marshal.Marshalizer - TxCacher dataRetriever.TransactionCacher - TxCoordinator process.TransactionCoordinator - SystemVM vmcommon.VMExecutionHandler - StateComponents factory.StateComponentsHolder - BlockChainHook process.BlockChainHookHandler - StakingDataProvider epochStart.StakingDataProvider - - currentRound uint64 -} - // NewTestMetaProcessor - func NewTestMetaProcessor( numOfMetaNodes uint32, @@ -158,183 +96,3 @@ func createMaxNodesConfig( return maxNodesConfig } - -// Process - -func (tmp *TestMetaProcessor) Process(t *testing.T, numOfRounds uint64) { - for r := tmp.currentRound; r < tmp.currentRound+numOfRounds; r++ { - header := tmp.createNewHeader(t, r) - tmp.createAndCommitBlock(t, header, haveTime) - } - - tmp.currentRound += numOfRounds -} - -func (tmp *TestMetaProcessor) createNewHeader(t *testing.T, round uint64) *block.MetaBlock { - _, err := tmp.MetaBlockProcessor.CreateNewHeader(round, round) - require.Nil(t, err) - - epoch := tmp.EpochStartTrigger.Epoch() - printNewHeaderRoundEpoch(round, epoch) - - currentHeader, currentHash := tmp.getCurrentHeaderInfo() - header := createMetaBlockToCommit( - epoch, - round, - currentHash, - currentHeader.GetRandSeed(), - tmp.NodesCoordinator.ConsensusGroupSize(core.MetachainShardId), - ) - - return header -} - -func (tmp *TestMetaProcessor) createAndCommitBlock(t *testing.T, header data.HeaderHandler, haveTime func() bool) { - newHeader, blockBody, err := tmp.MetaBlockProcessor.CreateBlock(header, haveTime) - require.Nil(t, err) - - err = tmp.MetaBlockProcessor.CommitBlock(newHeader, blockBody) - require.Nil(t, err) - - time.Sleep(time.Millisecond * 50) - tmp.updateNodesConfig(header.GetEpoch()) - tmp.displayConfig(tmp.NodesConfig) -} - -func printNewHeaderRoundEpoch(round uint64, epoch uint32) { - headline := display.Headline( - fmt.Sprintf("Commiting header in epoch %v round %v", epoch, round), - "", - delimiter, - ) - fmt.Println(headline) -} - -func (tmp *TestMetaProcessor) getCurrentHeaderInfo() (data.HeaderHandler, []byte) { - currentHeader := tmp.BlockChainHandler.GetCurrentBlockHeader() - currentHash := tmp.BlockChainHandler.GetCurrentBlockHeaderHash() - if currentHeader == nil { - currentHeader = tmp.BlockChainHandler.GetGenesisHeader() - currentHash = tmp.BlockChainHandler.GetGenesisHeaderHash() - } - - return currentHeader, currentHash -} - -func createMetaBlockToCommit( - epoch uint32, - round uint64, - prevHash []byte, - prevRandSeed []byte, - consensusSize int, -) *block.MetaBlock { - roundStr := strconv.Itoa(int(round)) - hdr := block.MetaBlock{ - Epoch: epoch, - Nonce: round, - Round: round, - PrevHash: prevHash, - Signature: []byte("signature"), - PubKeysBitmap: []byte(strings.Repeat("f", consensusSize)), - RootHash: []byte("roothash" + roundStr), - ShardInfo: make([]block.ShardData, 0), - TxCount: 1, - PrevRandSeed: prevRandSeed, - RandSeed: []byte("randseed" + roundStr), - AccumulatedFeesInEpoch: big.NewInt(0), - AccumulatedFees: big.NewInt(0), - DevFeesInEpoch: big.NewInt(0), - DeveloperFees: big.NewInt(0), - } - - shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0) - shardMiniBlockHeader := block.MiniBlockHeader{ - Hash: []byte("mb_hash" + roundStr), - ReceiverShardID: 0, - SenderShardID: 0, - TxCount: 1, - } - shardMiniBlockHeaders = append(shardMiniBlockHeaders, shardMiniBlockHeader) - shardData := block.ShardData{ - Nonce: round, - ShardID: 0, - HeaderHash: []byte("hdr_hash" + roundStr), - TxCount: 1, - ShardMiniBlockHeaders: shardMiniBlockHeaders, - DeveloperFees: big.NewInt(0), - AccumulatedFees: big.NewInt(0), - } - hdr.ShardInfo = append(hdr.ShardInfo, shardData) - - return &hdr -} - -func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { - eligible, _ := tmp.NodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) - waiting, _ := tmp.NodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) - leaving, _ := tmp.NodesCoordinator.GetAllLeavingValidatorsPublicKeys(epoch) - shuffledOut, _ := tmp.NodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) - - rootHash, _ := tmp.ValidatorStatistics.RootHash() - validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - - auction := make([][]byte, 0) - for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { - if validator.GetList() == string(common.AuctionList) { - auction = append(auction, validator.GetPublicKey()) - } - } - - tmp.NodesConfig.eligible = eligible - tmp.NodesConfig.waiting = waiting - tmp.NodesConfig.shuffledOut = shuffledOut - tmp.NodesConfig.leaving = leaving - tmp.NodesConfig.auction = auction - tmp.NodesConfig.queue = tmp.getWaitingListKeys() -} - -func generateAddresses(startIdx, n uint32) [][]byte { - ret := make([][]byte, 0, n) - - for i := startIdx; i < n+startIdx; i++ { - ret = append(ret, generateAddress(i)) - } - - return ret -} - -func generateAddress(identifier uint32) []byte { - uniqueIdentifier := fmt.Sprintf("address-%d", identifier) - return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) -} - -func (tmp *TestMetaProcessor) processSCOutputAccounts(vmOutput *vmcommon.VMOutput) error { - outputAccounts := process.SortVMOutputInsideData(vmOutput) - for _, outAcc := range outputAccounts { - acc := stakingcommon.LoadUserAccount(tmp.AccountsAdapter, outAcc.Address) - - storageUpdates := process.GetSortedStorageUpdates(outAcc) - for _, storeUpdate := range storageUpdates { - err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) - if err != nil { - return err - } - - if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(big.NewInt(0)) != 0 { - err = acc.AddToBalance(outAcc.BalanceDelta) - if err != nil { - return err - } - } - - err = tmp.AccountsAdapter.SaveAccount(acc) - if err != nil { - return err - } - } - } - - tmp.AccountsAdapter.Commit() - tmp.StateComponents.PeerAccounts().Commit() - - return nil -} diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 6029bdfbf47..6e964f7fc93 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -8,16 +8,15 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" ) +// OwnerStats - type OwnerStats struct { EligibleBlsKeys map[uint32][][]byte WaitingBlsKeys map[uint32][][]byte @@ -25,6 +24,7 @@ type OwnerStats struct { TotalStake *big.Int } +// InitialNodesConfig - type InitialNodesConfig struct { Owners map[string]*OwnerStats MaxNodesChangeConfig []config.MaxNodesChangeConfig @@ -35,6 +35,7 @@ type InitialNodesConfig struct { MetaConsensusGroupSize int } +// NewTestMetaProcessorWithCustomNodes - func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(config.NumOfShards) @@ -80,11 +81,14 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr ) } +// NodesRegisterData - type NodesRegisterData struct { BLSKeys [][]byte TotalStake *big.Int } +// ProcessStake will create a block containing mini blocks with staking txs using provided nodes. +// Block will be committed + call to validator system sc will be made to stake all nodes func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*NodesRegisterData) { header := tmp.createNewHeader(t, tmp.currentRound) tmp.BlockChainHook.SetCurrentHeader(header) @@ -144,37 +148,6 @@ func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) require.Nil(t, err) - err = tmp.processSCOutputAccounts(vmOutput) + err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) } - -func createStakingQueueCustomNodes( - owners map[string]*OwnerStats, - marshaller marshal.Marshalizer, - accountsAdapter state.AccountsAdapter, -) [][]byte { - queue := make([][]byte, 0) - - for owner, ownerStats := range owners { - stakingcommon.AddKeysToWaitingList( - accountsAdapter, - ownerStats.StakingQueueKeys, - marshaller, - []byte(owner), - []byte(owner), - ) - - stakingcommon.RegisterValidatorKeys( - accountsAdapter, - []byte(owner), - []byte(owner), - ownerStats.StakingQueueKeys, - ownerStats.TotalStake, - marshaller, - ) - - queue = append(queue, ownerStats.StakingQueueKeys...) - } - - return queue -} From 64dfc076976990c158904e47a0b39e3c4f393774 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 11 May 2022 17:22:53 +0300 Subject: [PATCH 248/958] FIX: Add common file --- epochStart/metachain/common.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 epochStart/metachain/common.go diff --git a/epochStart/metachain/common.go b/epochStart/metachain/common.go new file mode 100644 index 00000000000..6e826dc59de --- /dev/null +++ b/epochStart/metachain/common.go @@ -0,0 +1,16 @@ +package metachain + +import "github.com/ElrondNetwork/elrond-go/state" + +// GetAllNodeKeys returns all from the provided man +func GetAllNodeKeys(validatorsInfo state.ShardValidatorsInfoMapHandler) map[uint32][][]byte { + nodeKeys := make(map[uint32][][]byte) + for shardID, validatorsInfoSlice := range validatorsInfo.GetShardValidatorsInfoMap() { + nodeKeys[shardID] = make([][]byte, 0) + for _, validatorInfo := range validatorsInfoSlice { + nodeKeys[shardID] = append(nodeKeys[shardID], validatorInfo.GetPublicKey()) + } + } + + return nodeKeys +} From f745ff426f2eccdb4e444674d0b0906c51dd3684 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 11 May 2022 17:23:14 +0300 Subject: [PATCH 249/958] added unit tests for auction list validators fetching --- process/peer/validatorsProvider_test.go | 195 ++++++++++++++++++ .../stakingcommon/stakingDataProviderStub.go | 7 +- 2 files changed, 201 insertions(+), 1 deletion(-) diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 766b83768d2..bba3974c49b 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -25,6 +25,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNewValidatorsProvider_WithNilValidatorStatisticsShouldErr(t *testing.T) { @@ -629,6 +630,200 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin assert.Equal(t, 1, len(resp)) assert.NotNil(t, vsp.GetCache()[encodedEligible]) } + +func TestValidatorsProvider_GetAuctionList(t *testing.T) { + t.Parallel() + + t.Run("no entry, should return entry map", func(t *testing.T) { + t.Parallel() + + arg := createDefaultValidatorsProviderArg() + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) + + response := vp.GetAuctionList() + require.Empty(t, response) + }) + + t.Run("cannot get owner of key, should not fill it", func(t *testing.T) { + t.Parallel() + + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, + } + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil + } + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + return "", errors.New("cannot get owner") + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + return big.NewInt(10), nil + }, + } + + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) + + time.Sleep(arg.CacheRefreshIntervalDurationInSec) + + response := vp.GetAuctionList() + require.Empty(t, response) + }) + + t.Run("cannot get top up for node, should not fill it", func(t *testing.T) { + t.Parallel() + + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, + } + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil + } + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + return "", nil + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + return nil, errors.New("cannot get top up") + }, + } + + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) + + time.Sleep(arg.CacheRefreshIntervalDurationInSec) + + response := vp.GetAuctionList() + require.Empty(t, response) + }) + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, + } + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil + } + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-eligible"), + List: string(common.EligibleList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-waiting"), + List: string(common.WaitingList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-leaving"), + List: string(common.LeavingList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey1-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + if "pubkey0-auction" == string(key) { + return "owner0", nil + } + if "pubkey1-auction" == string(key) { + return "owner1", nil + } + return "", nil + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + if "pubkey0-auction" == string(key) { + return big.NewInt(100), nil + } + if "pubkey1-auction" == string(key) { + return big.NewInt(110), nil + } + return big.NewInt(0), nil + }, + } + + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) + + time.Sleep(arg.CacheRefreshIntervalDurationInSec) + + response := vp.GetAuctionList() + + // the result should contain only auction list validators with the correct owner and top up + expectedResponse := []*common.AuctionListValidatorAPIResponse{ + { + Owner: arg.AddressPubKeyConverter.Encode([]byte("owner0")), + NodeKey: hex.EncodeToString([]byte("pubkey0-auction")), + TopUp: "100", + }, + { + Owner: arg.AddressPubKeyConverter.Encode([]byte("owner1")), + NodeKey: hex.EncodeToString([]byte("pubkey1-auction")), + TopUp: "110", + }, + } + require.Equal(t, expectedResponse, response) + }) +} + func createMockValidatorInfo() *state.ValidatorInfo { initialInfo := &state.ValidatorInfo{ PublicKey: []byte("a1"), diff --git a/testscommon/stakingcommon/stakingDataProviderStub.go b/testscommon/stakingcommon/stakingDataProviderStub.go index b1bebed2c7f..42186468ca8 100644 --- a/testscommon/stakingcommon/stakingDataProviderStub.go +++ b/testscommon/stakingcommon/stakingDataProviderStub.go @@ -15,6 +15,7 @@ type StakingDataProviderStub struct { GetNodeStakedTopUpCalled func(blsKey []byte) (*big.Int, error) FillValidatorInfoCalled func(blsKey []byte) error ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) + GetBlsKeyOwnerCalled func([]byte) (string, error) } // FillValidatorInfo - @@ -73,7 +74,11 @@ func (sdps *StakingDataProviderStub) Clean() { } // GetBlsKeyOwner - -func (sdps *StakingDataProviderStub) GetBlsKeyOwner([]byte) (string, error) { +func (sdps *StakingDataProviderStub) GetBlsKeyOwner(key []byte) (string, error) { + if sdps.GetBlsKeyOwnerCalled != nil { + return sdps.GetBlsKeyOwnerCalled(key) + } + return "", nil } From ea654354052e320830dd2f3ebea23e1c4e64ef5d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 11 May 2022 19:09:44 +0300 Subject: [PATCH 250/958] FEAT: Add test for StakeNewNodes --- integrationTests/vm/staking/stakingV4_test.go | 224 ++++++++---------- .../testMetaProcessorWithCustomNodesConfig.go | 6 +- 2 files changed, 103 insertions(+), 127 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 7eb26b61aa9..cd88129ab3a 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -73,6 +73,33 @@ func requireMapDoesNotContain(t *testing.T, m map[uint32][][]byte, s [][]byte) { } } +func remove(s [][]byte, elem []byte) [][]byte { + ret := s + for i, e := range s { + if bytes.Equal(elem, e) { + ret[i] = ret[len(s)-1] + return ret[:len(s)-1] + } + } + + return ret +} + +func unStake(owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { + validatorSC := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) + ownerStoredData, _ := validatorSC.DataTrieTracker().RetrieveValue(owner) + validatorData := &systemSmartContracts.ValidatorDataV2{} + _ = marshaller.Unmarshal(validatorData, ownerStoredData) + + validatorData.TotalStakeValue.Sub(validatorData.TotalStakeValue, stake) + + marshaledData, _ := marshaller.Marshal(validatorData) + _ = validatorSC.DataTrieTracker().SaveKeyValue(owner, marshaledData) + + _ = accountsDB.SaveAccount(validatorSC) + _, _ = accountsDB.Commit() +} + func TestStakingV4(t *testing.T) { numOfMetaNodes := uint32(400) numOfShards := uint32(3) @@ -227,7 +254,7 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH } func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { - pubKeys := generateAddresses(0, 40) + pubKeys := generateAddresses(0, 20) // Owner1 has 8 nodes, but enough stake for just 7 nodes. At the end of the epoch(staking v4 init), // the last node from staking queue should be unStaked @@ -237,9 +264,9 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { core.MetachainShardId: pubKeys[:3], }, WaitingBlsKeys: map[uint32][][]byte{ - 0: pubKeys[3:6], // 1 waiting shard 0 + 0: pubKeys[3:6], }, - StakingQueueKeys: pubKeys[6:8], // 2 queue + StakingQueueKeys: pubKeys[6:8], TotalStake: big.NewInt(7 * nodePrice), } @@ -383,179 +410,124 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), owner4StakingQueue, 1) } -func remove(s [][]byte, elem []byte) [][]byte { - ret := s - for i, e := range s { - if bytes.Equal(elem, e) { - ret[i] = ret[len(s)-1] - return ret[:len(s)-1] - } - } - - return ret -} - -func unStake(owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { - validatorSC := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) - ownerStoredData, _ := validatorSC.DataTrieTracker().RetrieveValue(owner) - validatorData := &systemSmartContracts.ValidatorDataV2{} - _ = marshaller.Unmarshal(validatorData, ownerStoredData) - - validatorData.TotalStakeValue.Sub(validatorData.TotalStakeValue, stake) - - marshaledData, _ := marshaller.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(owner, marshaledData) - - _ = accountsDB.SaveAccount(validatorSC) - _, _ = accountsDB.Commit() -} - func TestStakingV4_StakeNewNodes(t *testing.T) { - pubKeys := generateAddresses(0, 40) - - //_ = logger.SetLogLevel("*:DEBUG") + pubKeys := generateAddresses(0, 20) + // Owner1 has 6 nodes, zero top up owner1 := "owner1" owner1Stats := &OwnerStats{ EligibleBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[:3], + core.MetachainShardId: pubKeys[:2], }, WaitingBlsKeys: map[uint32][][]byte{ - 0: pubKeys[3:6], // 1 waiting shard 0 + 0: pubKeys[2:4], }, - StakingQueueKeys: pubKeys[7:9], // 2 queue - TotalStake: big.NewInt(7000), + StakingQueueKeys: pubKeys[4:6], + TotalStake: big.NewInt(6 * nodePrice), } + // Owner2 has 4 nodes, zero top up owner2 := "owner2" owner2Stats := &OwnerStats{ EligibleBlsKeys: map[uint32][][]byte{ - 0: pubKeys[17:20], //total 3 meta + 0: pubKeys[6:8], }, WaitingBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[13:16], + core.MetachainShardId: pubKeys[8:10], }, - TotalStake: big.NewInt(5000), - } - - owner5 := "owner5" - owner5Stats := &OwnerStats{ - StakingQueueKeys: pubKeys[23:25], - TotalStake: big.NewInt(5000), + TotalStake: big.NewInt(4 * nodePrice), } - - owner6 := "owner6" - owner6Stats := &OwnerStats{ - StakingQueueKeys: pubKeys[25:26], - TotalStake: big.NewInt(5000), + // Owner3 has 1 node in staking queue with topUp = nodePrice + owner3 := "owner3" + owner3Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[10:11], + TotalStake: big.NewInt(2 * nodePrice), } cfg := &InitialNodesConfig{ - MetaConsensusGroupSize: 2, - ShardConsensusGroupSize: 2, - MinNumberOfEligibleShardNodes: 3, - MinNumberOfEligibleMetaNodes: 3, + MetaConsensusGroupSize: 1, + ShardConsensusGroupSize: 1, + MinNumberOfEligibleShardNodes: 1, + MinNumberOfEligibleMetaNodes: 1, NumOfShards: 1, Owners: map[string]*OwnerStats{ owner1: owner1Stats, owner2: owner2Stats, - owner5: owner5Stats, - owner6: owner6Stats, + owner3: owner3Stats, }, MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { EpochEnable: 0, - MaxNumNodes: 12, - NodesToShufflePerShard: 1, - }, - { - EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, - MaxNumNodes: 10, + MaxNumNodes: 8, NodesToShufflePerShard: 1, }, }, } - //todo; check that in epoch = staking v4 nodes with not enough stake will be unstaked node := NewTestMetaProcessorWithCustomNodes(cfg) node.EpochStartTrigger.SetRoundsPerEpoch(4) // 1. Check initial config is correct currNodesConfig := node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) - - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 3) - require.Len(t, currNodesConfig.eligible[0], 3) - require.Len(t, currNodesConfig.waiting[0], 3) - - requireSliceContainsNumOfElements(t, currNodesConfig.eligible[core.MetachainShardId], owner1Stats.EligibleBlsKeys[core.MetachainShardId], 3) - requireSliceContainsNumOfElements(t, currNodesConfig.waiting[core.MetachainShardId], owner2Stats.WaitingBlsKeys[core.MetachainShardId], 3) - - requireSliceContainsNumOfElements(t, currNodesConfig.eligible[0], owner2Stats.EligibleBlsKeys[0], 3) - requireSliceContainsNumOfElements(t, currNodesConfig.waiting[0], owner1Stats.WaitingBlsKeys[0], 3) + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 2) + require.Len(t, currNodesConfig.waiting[0], 2) - initialStakingQueue := owner1Stats.StakingQueueKeys - initialStakingQueue = append(initialStakingQueue, owner5Stats.StakingQueueKeys...) - initialStakingQueue = append(initialStakingQueue, owner6Stats.StakingQueueKeys...) - require.Len(t, currNodesConfig.queue, 5) - requireSliceContainsNumOfElements(t, currNodesConfig.queue, initialStakingQueue, 5) + owner1StakingQueue := owner1Stats.StakingQueueKeys + owner3StakingQueue := owner3Stats.StakingQueueKeys + queue := make([][]byte, 0) + queue = append(queue, owner1StakingQueue...) + queue = append(queue, owner3StakingQueue...) + require.Len(t, currNodesConfig.queue, 3) + requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - // 2. Check config after staking v4 initialization + // NewOwner1 stakes 1 node with top up = 2*node price; should be sent to auction list + newOwner1 := "newOwner1" + newNodes1 := map[string]*NodesRegisterData{ + newOwner1: { + BLSKeys: [][]byte{generateAddress(444)}, + TotalStake: big.NewInt(3 * nodePrice), + }, + } + // 2. Check config after staking v4 init when a new node is staked node.Process(t, 5) + node.ProcessStake(t, newNodes1) currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 6) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 5) - - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.eligible[0], 3) - require.Len(t, currNodesConfig.waiting[0], 3) - - // Owner1 will have one of the nodes in staking queue removed - initialStakingQueue = initialStakingQueue[2:] - initialStakingQueue = append(initialStakingQueue, owner1Stats.StakingQueueKeys[0]) + queue = append(queue, newNodes1[newOwner1].BLSKeys...) + require.Empty(t, currNodesConfig.queue) + require.Empty(t, currNodesConfig.leaving) require.Len(t, currNodesConfig.auction, 4) - requireSliceContainsNumOfElements(t, currNodesConfig.auction, initialStakingQueue, 4) - - // Owner2 will have one of the nodes in waiting list removed - require.Len(t, getAllPubKeys(currNodesConfig.leaving), 1) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.leaving), getAllPubKeys(owner2Stats.WaitingBlsKeys), 1) - - //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) - //require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) - //require.Empty(t, nodesConfigStakingV4Init.queue) - //require.Empty(t, nodesConfigStakingV4Init.shuffledOut) - //requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) - - node.Process(t, 8) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) - owner444 := "owner444" - owner555 := "owner555" - newNodes := map[string]*NodesRegisterData{ - owner444: { - BLSKeys: [][]byte{generateAddress(444)}, - TotalStake: big.NewInt(50000), - }, - owner555: { + // NewOwner2 stakes 2 node with top up = 2*node price; should be sent to auction list + newOwner2 := "newOwner2" + newNodes2 := map[string]*NodesRegisterData{ + newOwner2: { BLSKeys: [][]byte{generateAddress(555), generateAddress(666)}, - TotalStake: big.NewInt(60000), + TotalStake: big.NewInt(4 * nodePrice), }, } - node.ProcessStake(t, newNodes) - + // 2. Check in epoch = staking v4 when 2 new nodes are staked + node.Process(t, 4) + node.ProcessStake(t, newNodes2) currNodesConfig = node.NodesConfig - requireSliceContains(t, currNodesConfig.auction, newNodes[owner444].BLSKeys) - requireSliceContains(t, currNodesConfig.auction, newNodes[owner555].BLSKeys) - - node.Process(t, 3) + queue = append(queue, newNodes2[newOwner2].BLSKeys...) + require.Empty(t, currNodesConfig.queue) + requireSliceContainsNumOfElements(t, currNodesConfig.auction, queue, 6) + // 3. Epoch = staking v4 distribute auction to waiting + // Only the new 2 owners + owner3 had enough top up to be distributed to waiting. + // Meanwhile; owner1 which had 0 top up, still has his bls keys in auction + node.Process(t, 5) currNodesConfig = node.NodesConfig - requireMapContains(t, currNodesConfig.waiting, newNodes[owner444].BLSKeys) - requireMapContains(t, currNodesConfig.waiting, newNodes[owner555].BLSKeys) - - node.Process(t, 20) + require.Empty(t, currNodesConfig.queue) + requireMapContains(t, currNodesConfig.waiting, newNodes1[newOwner1].BLSKeys) + requireMapContains(t, currNodesConfig.waiting, newNodes2[newOwner2].BLSKeys) + requireMapContains(t, currNodesConfig.waiting, owner3StakingQueue) + requireSliceContains(t, currNodesConfig.auction, owner1StakingQueue) } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 6e964f7fc93..f9f6570672e 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -123,6 +123,8 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes GasProvided: 10, }) } + _, err := tmp.AccountsAdapter.Commit() + require.Nil(t, err) blockBody := &block.Body{MiniBlocks: block.MiniBlockSlice{ { @@ -138,7 +140,9 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes tmp.currentRound += 1 } -//TODO: Do the same for unStake +//TODO: +// 1. Do the same for unStake/unJail +// 2. Use this func to stake initial nodes instead of hard coding them func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, From bc87eac63d9891b07cde0f380502250da455c9fb Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 12 May 2022 12:52:17 +0300 Subject: [PATCH 251/958] FIX: General fixes --- epochStart/metachain/common.go | 2 +- epochStart/metachain/systemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 18 ++++++------- .../vm/staking/baseTestMetaProcessor.go | 2 -- .../vm/staking/configDisplayer.go | 14 +++++++--- integrationTests/vm/staking/stakingV4_test.go | 26 +++++++++++-------- .../testMetaProcessorWithCustomNodesConfig.go | 10 +++---- process/mock/transactionCoordinatorMock.go | 2 +- 8 files changed, 41 insertions(+), 35 deletions(-) diff --git a/epochStart/metachain/common.go b/epochStart/metachain/common.go index 6e826dc59de..e030ac1e979 100644 --- a/epochStart/metachain/common.go +++ b/epochStart/metachain/common.go @@ -2,7 +2,7 @@ package metachain import "github.com/ElrondNetwork/elrond-go/state" -// GetAllNodeKeys returns all from the provided man +// GetAllNodeKeys returns all from the provided map func GetAllNodeKeys(validatorsInfo state.ShardValidatorsInfoMapHandler) map[uint32][][]byte { nodeKeys := make(map[uint32][][]byte) for shardID, validatorsInfoSlice := range validatorsInfo.GetShardValidatorsInfoMap() { diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index b4bddc17fa3..e101dd43be4 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -375,7 +375,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Info(message) + log.Debug(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 93448be71e9..79eacbacae3 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1277,23 +1277,23 @@ func TestSystemSCProcessor_ProcessSystemSmartContractUnStakeFromDelegationContra contract, _ := scContainer.Get(vm.FirstDelegationSCAddress) _ = scContainer.Add(delegationAddr, contract) - prepareStakingContractWithData( + stakingcommon.AddStakingData( args.UserAccountsDB, - []byte("stakedPubKey0"), - []byte("waitingPubKey"), - args.Marshalizer, delegationAddr, delegationAddr, + [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, + args.Marshalizer, ) - - stakingcommon.AddStakingData(args.UserAccountsDB, + allKeys := [][]byte{[]byte("stakedPubKey0"), []byte("waitingPubKey"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")} + stakingcommon.RegisterValidatorKeys( + args.UserAccountsDB, delegationAddr, delegationAddr, - [][]byte{[]byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")}, + allKeys, + big.NewInt(3000), args.Marshalizer, ) - allKeys := [][]byte{[]byte("stakedPubKey0"), []byte("waitingPubKey"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")} - stakingcommon.AddValidatorData(args.UserAccountsDB, delegationAddr, allKeys[2:], big.NewInt(3000), args.Marshalizer) + addDelegationData(args.UserAccountsDB, delegationAddr, allKeys, args.Marshalizer) _, _ = args.UserAccountsDB.Commit() diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 116bb3e11c1..d805c880c28 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -64,7 +64,6 @@ type TestMetaProcessor struct { TxCacher dataRetriever.TransactionCacher TxCoordinator process.TransactionCoordinator SystemVM vmcommon.VMExecutionHandler - StateComponents factory.StateComponentsHolder BlockChainHook process.BlockChainHookHandler StakingDataProvider epochStart.StakingDataProvider @@ -163,7 +162,6 @@ func newTestMetaProcessor( TxCacher: dataComponents.Datapool().CurrentBlockTxs(), TxCoordinator: txCoordinator, SystemVM: systemVM, - StateComponents: stateComponents, BlockChainHook: blockChainHook, StakingDataProvider: stakingDataProvider, } diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index b2aeb784293..816ee2e90f3 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -1,6 +1,7 @@ package staking import ( + "bytes" "fmt" "strconv" @@ -79,8 +80,11 @@ func (tmp *TestMetaProcessor) getDisplayableValidatorsInShard(list string, pubKe horizontalLineAfter := idx == len(pubKeysToDisplay)-1 owner, _ := tmp.StakingDataProvider.GetBlsKeyOwner(pk) topUp, _ := tmp.StakingDataProvider.GetNodeStakedTopUp(pk) - line := display.NewLineData(horizontalLineAfter, []string{list, string(pk), owner, topUp.String(), strconv.Itoa(int(shardID))}) - lines = append(lines, line) + if bytes.Equal(pk, []byte("...")) { + lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk), "...", "...", strconv.Itoa(int(shardID))})) + } else { + lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk), owner, topUp.String(), strconv.Itoa(int(shardID))})) + } } lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys)), "", "", strconv.Itoa(int(shardID))})) @@ -96,7 +100,11 @@ func (tmp *TestMetaProcessor) displayValidators(list string, pubKeys [][]byte) { horizontalLineAfter := idx == len(pubKeysToDisplay)-1 owner, _ := tmp.StakingDataProvider.GetBlsKeyOwner(pk) topUp, _ := tmp.StakingDataProvider.GetNodeStakedTopUp(pk) - lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk), owner, topUp.String()})) + if bytes.Equal(pk, []byte("...")) { + lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk), "...", "..."})) + } else { + lines = append(lines, display.NewLineData(horizontalLineAfter, []string{list, string(pk), owner, topUp.String()})) + } } lines = append(lines, display.NewLineData(true, []string{list, fmt.Sprintf("Total: %d", len(pubKeys))})) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index cd88129ab3a..4e56c115d6c 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -85,19 +85,24 @@ func remove(s [][]byte, elem []byte) [][]byte { return ret } -func unStake(owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { +func unStake(t *testing.T, owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { validatorSC := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) - ownerStoredData, _ := validatorSC.DataTrieTracker().RetrieveValue(owner) + ownerStoredData, err := validatorSC.DataTrieTracker().RetrieveValue(owner) + require.Nil(t, err) + validatorData := &systemSmartContracts.ValidatorDataV2{} - _ = marshaller.Unmarshal(validatorData, ownerStoredData) + err = marshaller.Unmarshal(validatorData, ownerStoredData) + require.Nil(t, err) validatorData.TotalStakeValue.Sub(validatorData.TotalStakeValue, stake) - marshaledData, _ := marshaller.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(owner, marshaledData) + err = validatorSC.DataTrieTracker().SaveKeyValue(owner, marshaledData) + require.Nil(t, err) - _ = accountsDB.SaveAccount(validatorSC) - _, _ = accountsDB.Commit() + err = accountsDB.SaveAccount(validatorSC) + require.Nil(t, err) + _, err = accountsDB.Commit() + require.Nil(t, err) } func TestStakingV4(t *testing.T) { @@ -336,7 +341,6 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { requireSliceContainsNumOfElements(t, currNodesConfig.eligible[core.MetachainShardId], owner1Stats.EligibleBlsKeys[core.MetachainShardId], 3) requireSliceContainsNumOfElements(t, currNodesConfig.waiting[core.MetachainShardId], owner2Stats.WaitingBlsKeys[core.MetachainShardId], 3) - requireSliceContainsNumOfElements(t, currNodesConfig.eligible[0], owner2Stats.EligibleBlsKeys[0], 3) requireSliceContainsNumOfElements(t, currNodesConfig.waiting[0], owner1Stats.WaitingBlsKeys[0], 3) @@ -373,8 +377,8 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { require.Len(t, getAllPubKeys(currNodesConfig.leaving), 1) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.leaving), getAllPubKeys(owner2Stats.WaitingBlsKeys), 1) - // Owner1 will unStake some EGLD => at the end of next epoch, he should the other node from auction list removed - unStake([]byte(owner1), node.AccountsAdapter, node.Marshaller, big.NewInt(0.1*nodePrice)) + // Owner1 will unStake some EGLD => at the end of next epoch, he should have the other node from queue(now auction list) removed + unStake(t, []byte(owner1), node.AccountsAdapter, node.Marshaller, big.NewInt(0.1*nodePrice)) // 3. Check config in epoch = staking v4 node.Process(t, 5) @@ -400,7 +404,7 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { // Owner3 will unStake EGLD => he will have negative top-up at the selection time => one of his nodes will be unStaked. // His other node should not have been selected => remains in auction. // Meanwhile, owner4 had never unStaked EGLD => his node from auction list node will be distributed to waiting - unStake([]byte(owner3), node.AccountsAdapter, node.Marshaller, big.NewInt(2*nodePrice)) + unStake(t, []byte(owner3), node.AccountsAdapter, node.Marshaller, big.NewInt(2*nodePrice)) // 4. Check config in epoch = staking v4 distribute auction to waiting node.Process(t, 5) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index f9f6570672e..210e8b17a06 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -39,10 +39,6 @@ type InitialNodesConfig struct { func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaProcessor { coreComponents, dataComponents, bootstrapComponents, statusComponents, stateComponents := createComponentHolders(config.NumOfShards) - _ = dataComponents - _ = bootstrapComponents - _ = statusComponents - queue := createStakingQueueCustomNodes( config.Owners, coreComponents.InternalMarshalizer(), @@ -126,15 +122,15 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes _, err := tmp.AccountsAdapter.Commit() require.Nil(t, err) - blockBody := &block.Body{MiniBlocks: block.MiniBlockSlice{ + miniBlocks := block.MiniBlockSlice{ { TxHashes: txHashes, SenderShardID: core.MetachainShardId, ReceiverShardID: core.MetachainShardId, Type: block.SmartContractResultBlock, }, - }} - tmp.TxCoordinator.RequestBlockTransactions(blockBody) + } + tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) tmp.createAndCommitBlock(t, header, noTime) tmp.currentRound += 1 diff --git a/process/mock/transactionCoordinatorMock.go b/process/mock/transactionCoordinatorMock.go index 6680fa87e1e..befbcefb053 100644 --- a/process/mock/transactionCoordinatorMock.go +++ b/process/mock/transactionCoordinatorMock.go @@ -75,7 +75,6 @@ func (tcm *TransactionCoordinatorMock) RequestMiniBlocks(header data.HeaderHandl // RequestBlockTransactions - func (tcm *TransactionCoordinatorMock) RequestBlockTransactions(body *block.Body) { if tcm.RequestBlockTransactionsCalled == nil { - tcm.miniBlocks = body.MiniBlocks return } @@ -235,6 +234,7 @@ func (tcm *TransactionCoordinatorMock) GetAllIntermediateTxs() map[block.Type]ma // AddTxsFromMiniBlocks - func (tcm *TransactionCoordinatorMock) AddTxsFromMiniBlocks(miniBlocks block.MiniBlockSlice) { if tcm.AddTxsFromMiniBlocksCalled == nil { + tcm.miniBlocks = miniBlocks return } From d410a16ab813c5b34c09a417093ccbc9cef47244 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Thu, 12 May 2022 14:50:04 +0300 Subject: [PATCH 252/958] fixes after review --- api/groups/validatorGroup_test.go | 8 -- api/mock/facadeStub.go | 132 +++++++++++++++--- .../metachain/rewardsCreatorProxy_test.go | 3 +- epochStart/metachain/rewardsV2_test.go | 25 ++-- epochStart/metachain/systemSCs.go | 9 +- epochStart/metachain/systemSCs_test.go | 4 +- epochStart/mock/stakingDataProviderStub.go | 87 ------------ facade/mock/nodeStub.go | 60 ++++++-- factory/disabled/stakingDataProvider.go | 8 +- 9 files changed, 186 insertions(+), 150 deletions(-) delete mode 100644 epochStart/mock/stakingDataProviderStub.go diff --git a/api/groups/validatorGroup_test.go b/api/groups/validatorGroup_test.go index f7a8666092e..750d56573fd 100644 --- a/api/groups/validatorGroup_test.go +++ b/api/groups/validatorGroup_test.go @@ -95,9 +95,7 @@ func TestValidatorStatistics_ReturnsSuccessfully(t *testing.T) { require.NoError(t, err) ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) - req, _ := http.NewRequest("GET", "/validator/statistics", nil) - resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) @@ -118,7 +116,6 @@ func TestAuctionList_ErrorWhenFacadeFails(t *testing.T) { t.Parallel() errStr := "error in facade" - facade := mock.FacadeStub{ AuctionListHandler: func() ([]*common.AuctionListValidatorAPIResponse, error) { return nil, errors.New(errStr) @@ -129,9 +126,7 @@ func TestAuctionList_ErrorWhenFacadeFails(t *testing.T) { require.NoError(t, err) ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) - req, _ := http.NewRequest("GET", "/validator/auction", nil) - resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) @@ -152,7 +147,6 @@ func TestAuctionList_ReturnsSuccessfully(t *testing.T) { TopUp: "112233", }, } - facade := mock.FacadeStub{ AuctionListHandler: func() ([]*common.AuctionListValidatorAPIResponse, error) { return auctionListToReturn, nil @@ -163,9 +157,7 @@ func TestAuctionList_ReturnsSuccessfully(t *testing.T) { require.NoError(t, err) ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) - req, _ := http.NewRequest("GET", "/validator/auction", nil) - resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) diff --git a/api/mock/facadeStub.go b/api/mock/facadeStub.go index cdf716d1ff8..2b805c3a4cf 100644 --- a/api/mock/facadeStub.go +++ b/api/mock/facadeStub.go @@ -154,12 +154,20 @@ func (f *FacadeStub) PprofEnabled() bool { // GetHeartbeats returns the slice of heartbeat info func (f *FacadeStub) GetHeartbeats() ([]data.PubKeyHeartbeat, error) { - return f.GetHeartbeatsHandler() + if f.GetHeartbeatsHandler != nil { + return f.GetHeartbeatsHandler() + } + + return nil, nil } // GetBalance is the mock implementation of a handler's GetBalance method func (f *FacadeStub) GetBalance(address string) (*big.Int, error) { - return f.BalanceHandler(address) + if f.BalanceHandler != nil { + return f.BalanceHandler(address) + } + + return nil, nil } // GetValueForKey is the mock implementation of a handler's GetValueForKey method @@ -236,7 +244,11 @@ func (f *FacadeStub) GetAllIssuedESDTs(tokenType string) ([]string, error) { // GetAccount - func (f *FacadeStub) GetAccount(address string) (api.AccountResponse, error) { - return f.GetAccountHandler(address) + if f.GetAccountHandler != nil { + return f.GetAccountHandler(address) + } + + return api.AccountResponse{}, nil } // CreateTransaction is mock implementation of a handler's CreateTransaction method @@ -255,77 +267,137 @@ func (f *FacadeStub) CreateTransaction( version uint32, options uint32, ) (*transaction.Transaction, []byte, error) { - return f.CreateTransactionHandler(nonce, value, receiver, receiverUsername, sender, senderUsername, gasPrice, gasLimit, data, signatureHex, chainID, version, options) + if f.CreateTransactionHandler != nil { + return f.CreateTransactionHandler(nonce, value, receiver, receiverUsername, sender, senderUsername, gasPrice, gasLimit, data, signatureHex, chainID, version, options) + } + + return nil, nil, nil } // GetTransaction is the mock implementation of a handler's GetTransaction method func (f *FacadeStub) GetTransaction(hash string, withResults bool) (*transaction.ApiTransactionResult, error) { - return f.GetTransactionHandler(hash, withResults) + if f.GetTransactionHandler != nil { + return f.GetTransactionHandler(hash, withResults) + } + + return nil, nil } // SimulateTransactionExecution is the mock implementation of a handler's SimulateTransactionExecution method func (f *FacadeStub) SimulateTransactionExecution(tx *transaction.Transaction) (*txSimData.SimulationResults, error) { - return f.SimulateTransactionExecutionHandler(tx) + if f.SimulateTransactionExecutionHandler != nil { + return f.SimulateTransactionExecutionHandler(tx) + } + + return nil, nil } // SendBulkTransactions is the mock implementation of a handler's SendBulkTransactions method func (f *FacadeStub) SendBulkTransactions(txs []*transaction.Transaction) (uint64, error) { - return f.SendBulkTransactionsHandler(txs) + if f.SendBulkTransactionsHandler != nil { + return f.SendBulkTransactionsHandler(txs) + } + + return 0, nil } // ValidateTransaction - func (f *FacadeStub) ValidateTransaction(tx *transaction.Transaction) error { - return f.ValidateTransactionHandler(tx) + if f.ValidateTransactionHandler != nil { + return f.ValidateTransactionHandler(tx) + } + + return nil } // ValidateTransactionForSimulation - func (f *FacadeStub) ValidateTransactionForSimulation(tx *transaction.Transaction, bypassSignature bool) error { - return f.ValidateTransactionForSimulationHandler(tx, bypassSignature) + if f.ValidateTransactionForSimulationHandler != nil { + return f.ValidateTransactionForSimulationHandler(tx, bypassSignature) + } + + return nil } // ValidatorStatisticsApi is the mock implementation of a handler's ValidatorStatisticsApi method func (f *FacadeStub) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) { - return f.ValidatorStatisticsHandler() + if f.ValidatorStatisticsHandler != nil { + return f.ValidatorStatisticsHandler() + } + + return nil, nil } // AuctionListApi is the mock implementation of a handler's AuctionListApi method func (f *FacadeStub) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { - return f.AuctionListHandler() + if f.AuctionListHandler != nil { + return f.AuctionListHandler() + } + + return nil, nil } // ExecuteSCQuery is a mock implementation. func (f *FacadeStub) ExecuteSCQuery(query *process.SCQuery) (*vm.VMOutputApi, error) { - return f.ExecuteSCQueryHandler(query) + if f.ExecuteSCQueryHandler != nil { + return f.ExecuteSCQueryHandler(query) + } + + return nil, nil } // StatusMetrics is the mock implementation for the StatusMetrics func (f *FacadeStub) StatusMetrics() external.StatusMetricsHandler { - return f.StatusMetricsHandler() + if f.StatusMetricsHandler != nil { + return f.StatusMetricsHandler() + } + + return nil } // GetTotalStakedValue - func (f *FacadeStub) GetTotalStakedValue() (*api.StakeValues, error) { - return f.GetTotalStakedValueHandler() + if f.GetTotalStakedValueHandler != nil { + return f.GetTotalStakedValueHandler() + } + + return nil, nil } // GetDirectStakedList - func (f *FacadeStub) GetDirectStakedList() ([]*api.DirectStakedValue, error) { - return f.GetDirectStakedListHandler() + if f.GetDirectStakedListHandler != nil { + return f.GetDirectStakedListHandler() + } + + return nil, nil } // GetDelegatorsList - func (f *FacadeStub) GetDelegatorsList() ([]*api.Delegator, error) { - return f.GetDelegatorsListHandler() + if f.GetDelegatorsListHandler != nil { + return f.GetDelegatorsListHandler() + } + + return nil, nil } // ComputeTransactionGasLimit - func (f *FacadeStub) ComputeTransactionGasLimit(tx *transaction.Transaction) (*transaction.CostResponse, error) { - return f.ComputeTransactionGasLimitHandler(tx) + if f.ComputeTransactionGasLimitHandler != nil { + return f.ComputeTransactionGasLimitHandler(tx) + } + + return nil, nil } // NodeConfig - func (f *FacadeStub) NodeConfig() map[string]interface{} { - return f.NodeConfigCalled() + if f.NodeConfigCalled != nil { + return f.NodeConfigCalled() + } + + return nil } // EncodeAddressPubkey - @@ -340,22 +412,38 @@ func (f *FacadeStub) DecodeAddressPubkey(pk string) ([]byte, error) { // GetQueryHandler - func (f *FacadeStub) GetQueryHandler(name string) (debug.QueryHandler, error) { - return f.GetQueryHandlerCalled(name) + if f.GetQueryHandlerCalled != nil { + return f.GetQueryHandlerCalled(name) + } + + return nil, nil } // GetPeerInfo - func (f *FacadeStub) GetPeerInfo(pid string) ([]core.QueryP2PPeerInfo, error) { - return f.GetPeerInfoCalled(pid) + if f.GetPeerInfoCalled != nil { + return f.GetPeerInfoCalled(pid) + } + + return nil, nil } // GetBlockByNonce - func (f *FacadeStub) GetBlockByNonce(nonce uint64, withTxs bool) (*api.Block, error) { - return f.GetBlockByNonceCalled(nonce, withTxs) + if f.GetBlockByNonceCalled != nil { + return f.GetBlockByNonceCalled(nonce, withTxs) + } + + return nil, nil } // GetBlockByHash - func (f *FacadeStub) GetBlockByHash(hash string, withTxs bool) (*api.Block, error) { - return f.GetBlockByHashCalled(hash, withTxs) + if f.GetBlockByHashCalled != nil { + return f.GetBlockByHashCalled(hash, withTxs) + } + + return nil, nil } // GetBlockByRound - diff --git a/epochStart/metachain/rewardsCreatorProxy_test.go b/epochStart/metachain/rewardsCreatorProxy_test.go index 3059128e2ee..9f41d0662f7 100644 --- a/epochStart/metachain/rewardsCreatorProxy_test.go +++ b/epochStart/metachain/rewardsCreatorProxy_test.go @@ -17,6 +17,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) @@ -367,7 +368,7 @@ func createDefaultRewardsCreatorProxyArgs() RewardsCreatorProxyArgs { return RewardsCreatorProxyArgs{ BaseRewardsCreatorArgs: getBaseRewardsArguments(), - StakingDataProvider: &mock.StakingDataProviderStub{}, + StakingDataProvider: &stakingcommon.StakingDataProviderStub{}, EconomicsDataProvider: NewEpochEconomicsStatistics(), RewardsHandler: rewardsHandler, } diff --git a/epochStart/metachain/rewardsV2_test.go b/epochStart/metachain/rewardsV2_test.go index 41f88f54f8b..1bdc1724a6a 100644 --- a/epochStart/metachain/rewardsV2_test.go +++ b/epochStart/metachain/rewardsV2_test.go @@ -19,6 +19,7 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/economicsmocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) @@ -126,7 +127,7 @@ func TestNewRewardsCreatorV2_getTopUpForAllEligibleNodes(t *testing.T) { args := getRewardsCreatorV2Arguments() topUpVal, _ := big.NewInt(0).SetString("100000000000000000000", 10) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { topUp := big.NewInt(0).Set(topUpVal) return topUp, nil @@ -155,7 +156,7 @@ func TestNewRewardsCreatorV2_getTopUpForAllEligibleSomeBLSKeysNotFoundZeroed(t * args := getRewardsCreatorV2Arguments() topUpVal, _ := big.NewInt(0).SetString("100000000000000000000", 10) notFoundKey := []byte("notFound") - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { if bytes.Equal(blsKey, notFoundKey) { return nil, fmt.Errorf("not found") @@ -607,7 +608,7 @@ func TestNewRewardsCreatorV2_computeTopUpRewardsPerNode(t *testing.T) { nodesRewardInfo := dummyRwd.initNodesRewardsInfo(vInfo) _, _ = setDummyValuesInNodesRewardInfo(nodesRewardInfo, nbEligiblePerShard, tuStake, 0) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { for shardID, vList := range vInfo.GetShardValidatorsInfoMap() { for i, v := range vList { @@ -653,7 +654,7 @@ func TestNewRewardsCreatorV2_computeTopUpRewardsPerNodeNotFoundBLSKeys(t *testin args := getRewardsCreatorV2Arguments() nbEligiblePerShard := uint32(400) vInfo := createDefaultValidatorInfo(nbEligiblePerShard, args.ShardCoordinator, args.NodesConfigProvider, 100, defaultBlocksPerShard) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { return nil, fmt.Errorf("not found") }, @@ -737,7 +738,7 @@ func TestNewRewardsCreatorV2_computeRewardsPerNode(t *testing.T) { nodesRewardInfo := dummyRwd.initNodesRewardsInfo(vInfo) _, totalTopUpStake := setDummyValuesInNodesRewardInfo(nodesRewardInfo, nbEligiblePerShard, tuStake, 0) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetTotalTopUpStakeEligibleNodesCalled: func() *big.Int { topUpStake := big.NewInt(0).Set(totalTopUpStake) return topUpStake @@ -1042,7 +1043,7 @@ func TestNewRewardsCreatorV35_computeRewardsPer3200NodesWithDifferentTopups(t *t nodesRewardInfo, _ := setupNodeRewardInfo(setupResult, vInfo, topupStakePerNode, tt.validatorTopupStake) setupResult.EconomicsDataProvider.SetRewardsToBeDistributedForBlocks(setupResult.rewardsForBlocks) - setupResult.RewardsCreatorArgsV2.StakingDataProvider = &mock.StakingDataProviderStub{ + setupResult.RewardsCreatorArgsV2.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetTotalTopUpStakeEligibleNodesCalled: func() *big.Int { return topupEligibleStake }, @@ -1149,7 +1150,7 @@ func TestNewRewardsCreatorV2_computeRewardsPer3200NodesWithDifferentTopups(t *te nodesRewardInfo, _ := setupNodeRewardInfo(setupResult, vInfo, topupStakePerNode, tt.validatorTopupStake) setupResult.EconomicsDataProvider.SetRewardsToBeDistributedForBlocks(setupResult.rewardsForBlocks) - setupResult.RewardsCreatorArgsV2.StakingDataProvider = &mock.StakingDataProviderStub{ + setupResult.RewardsCreatorArgsV2.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetTotalTopUpStakeEligibleNodesCalled: func() *big.Int { return topupEligibleStake }, @@ -1267,7 +1268,7 @@ func computeRewardsAndDust(nbEligiblePerShard uint32, args SetupRewardsResult, t totalEligibleStake, _ := big.NewInt(0).SetString("4000000"+"000000000000000000", 10) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetTotalTopUpStakeEligibleNodesCalled: func() *big.Int { return totalTopUpStake }, @@ -1583,7 +1584,7 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks(t *testing.T) { nodesRewardInfo := dummyRwd.initNodesRewardsInfo(vInfo) _, _ = setDummyValuesInNodesRewardInfo(nodesRewardInfo, nbEligiblePerShard, tuStake, 0) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetTotalTopUpStakeEligibleNodesCalled: func() *big.Int { totalTopUpStake, _ := big.NewInt(0).SetString("3000000000000000000000000", 10) return totalTopUpStake @@ -1679,7 +1680,7 @@ func TestNewRewardsCreatorV2_CreateRewardsMiniBlocks2169Nodes(t *testing.T) { topupValue.Mul(topupValue, multiplier) _, totalTopupStake := setValuesInNodesRewardInfo(nodesRewardInfo, topupValue, tuStake) - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetTotalTopUpStakeEligibleNodesCalled: func() *big.Int { return totalTopupStake }, @@ -1775,7 +1776,7 @@ func getRewardsCreatorV2Arguments() RewardsCreatorArgsV2 { } return RewardsCreatorArgsV2{ BaseRewardsCreatorArgs: getBaseRewardsArguments(), - StakingDataProvider: &mock.StakingDataProviderStub{}, + StakingDataProvider: &stakingcommon.StakingDataProviderStub{}, EconomicsDataProvider: NewEpochEconomicsStatistics(), RewardsHandler: rewardsHandler, } @@ -1795,7 +1796,7 @@ func getRewardsCreatorV35Arguments() RewardsCreatorArgsV2 { } return RewardsCreatorArgsV2{ BaseRewardsCreatorArgs: getBaseRewardsArguments(), - StakingDataProvider: &mock.StakingDataProviderStub{}, + StakingDataProvider: &stakingcommon.StakingDataProviderStub{}, EconomicsDataProvider: NewEpochEconomicsStatistics(), RewardsHandler: rewardsHandler, } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index d7cb53dcede..fb700dba120 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -14,6 +14,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -342,9 +343,9 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - //if log.GetLevel() > logger.LogDebug { - // return - //} + if log.GetLevel() > logger.LogDebug { + return + } tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -374,7 +375,7 @@ func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfo } message := fmt.Sprintf("Auction list\n%s", table) - log.Info(message) + log.Debug(message) } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f4a22520eca..c4de6347a6d 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1780,7 +1780,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) errProcessStakingData := errors.New("error processing staking data") - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ PrepareStakingDataCalled: func(keys map[uint32][][]byte) error { return errProcessStakingData }, @@ -1808,7 +1808,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 1}} errGetNodeTopUp := errors.New("error getting top up per node") - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { switch string(blsKey) { case "pubKey0", "pubKey1": diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go deleted file mode 100644 index 52519110336..00000000000 --- a/epochStart/mock/stakingDataProviderStub.go +++ /dev/null @@ -1,87 +0,0 @@ -package mock - -import ( - "math/big" - - "github.com/ElrondNetwork/elrond-go/state" -) - -// StakingDataProviderStub - -type StakingDataProviderStub struct { - CleanCalled func() - PrepareStakingDataCalled func(keys map[uint32][][]byte) error - GetTotalStakeEligibleNodesCalled func() *big.Int - GetTotalTopUpStakeEligibleNodesCalled func() *big.Int - GetNodeStakedTopUpCalled func(blsKey []byte) (*big.Int, error) - FillValidatorInfoCalled func(blsKey []byte) error - ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) -} - -// FillValidatorInfo - -func (sdps *StakingDataProviderStub) FillValidatorInfo(blsKey []byte) error { - if sdps.FillValidatorInfoCalled != nil { - return sdps.FillValidatorInfoCalled(blsKey) - } - return nil -} - -// ComputeUnQualifiedNodes - -func (sdps *StakingDataProviderStub) ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { - if sdps.ComputeUnQualifiedNodesCalled != nil { - return sdps.ComputeUnQualifiedNodesCalled(validatorInfos) - } - return nil, nil, nil -} - -// GetTotalStakeEligibleNodes - -func (sdps *StakingDataProviderStub) GetTotalStakeEligibleNodes() *big.Int { - if sdps.GetTotalStakeEligibleNodesCalled != nil { - return sdps.GetTotalStakeEligibleNodesCalled() - } - return big.NewInt(0) -} - -// GetTotalTopUpStakeEligibleNodes - -func (sdps *StakingDataProviderStub) GetTotalTopUpStakeEligibleNodes() *big.Int { - if sdps.GetTotalTopUpStakeEligibleNodesCalled != nil { - return sdps.GetTotalTopUpStakeEligibleNodesCalled() - } - return big.NewInt(0) -} - -// GetNodeStakedTopUp - -func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) { - if sdps.GetNodeStakedTopUpCalled != nil { - return sdps.GetNodeStakedTopUpCalled(blsKey) - } - return big.NewInt(0), nil -} - -// PrepareStakingData - -func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte) error { - if sdps.PrepareStakingDataCalled != nil { - return sdps.PrepareStakingDataCalled(keys) - } - return nil -} - -// Clean - -func (sdps *StakingDataProviderStub) Clean() { - if sdps.CleanCalled != nil { - sdps.CleanCalled() - } -} - -// GetBlsKeyOwner - -func (sdps *StakingDataProviderStub) GetBlsKeyOwner([]byte) (string, error) { - return "", nil -} - -// EpochConfirmed - -func (sdps *StakingDataProviderStub) EpochConfirmed(uint32, uint64) { -} - -// IsInterfaceNil - -func (sdps *StakingDataProviderStub) IsInterfaceNil() bool { - return sdps == nil -} diff --git a/facade/mock/nodeStub.go b/facade/mock/nodeStub.go index 26c8a6c5b3a..2d0ffe6bad6 100644 --- a/facade/mock/nodeStub.go +++ b/facade/mock/nodeStub.go @@ -118,7 +118,11 @@ func (ns *NodeStub) DecodeAddressPubkey(pk string) ([]byte, error) { // GetBalance - func (ns *NodeStub) GetBalance(address string) (*big.Int, error) { - return ns.GetBalanceHandler(address) + if ns.GetBalanceHandler != nil { + return ns.GetBalanceHandler(address) + } + + return nil, nil } // CreateTransaction - @@ -130,22 +134,38 @@ func (ns *NodeStub) CreateTransaction(nonce uint64, value string, receiver strin //ValidateTransaction - func (ns *NodeStub) ValidateTransaction(tx *transaction.Transaction) error { - return ns.ValidateTransactionHandler(tx) + if ns.ValidateTransactionHandler != nil { + return ns.ValidateTransactionHandler(tx) + } + + return nil } // ValidateTransactionForSimulation - func (ns *NodeStub) ValidateTransactionForSimulation(tx *transaction.Transaction, bypassSignature bool) error { - return ns.ValidateTransactionForSimulationCalled(tx, bypassSignature) + if ns.ValidateTransactionForSimulationCalled != nil { + return ns.ValidateTransactionForSimulationCalled(tx, bypassSignature) + } + + return nil } // SendBulkTransactions - func (ns *NodeStub) SendBulkTransactions(txs []*transaction.Transaction) (uint64, error) { - return ns.SendBulkTransactionsHandler(txs) + if ns.SendBulkTransactionsHandler != nil { + return ns.SendBulkTransactionsHandler(txs) + } + + return 0, nil } // GetAccount - func (ns *NodeStub) GetAccount(address string) (api.AccountResponse, error) { - return ns.GetAccountHandler(address) + if ns.GetAccountHandler != nil { + return ns.GetAccountHandler(address) + } + + return api.AccountResponse{}, nil } // GetCode - @@ -159,27 +179,47 @@ func (ns *NodeStub) GetCode(codeHash []byte) []byte { // GetHeartbeats - func (ns *NodeStub) GetHeartbeats() []data.PubKeyHeartbeat { - return ns.GetHeartbeatsHandler() + if ns.GetHeartbeatsHandler != nil { + return ns.GetHeartbeatsHandler() + } + + return nil } // ValidatorStatisticsApi - func (ns *NodeStub) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, error) { - return ns.ValidatorStatisticsApiCalled() + if ns.ValidatorStatisticsApiCalled != nil { + return ns.ValidatorStatisticsApiCalled() + } + + return nil, nil } // AuctionListApi - func (ns *NodeStub) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { - return ns.AuctionListApiCalled() + if ns.AuctionListApiCalled != nil { + return ns.AuctionListApiCalled() + } + + return nil, nil } // DirectTrigger - func (ns *NodeStub) DirectTrigger(epoch uint32, withEarlyEndOfEpoch bool) error { - return ns.DirectTriggerCalled(epoch, withEarlyEndOfEpoch) + if ns.DirectTriggerCalled != nil { + return ns.DirectTriggerCalled(epoch, withEarlyEndOfEpoch) + } + + return nil } // IsSelfTrigger - func (ns *NodeStub) IsSelfTrigger() bool { - return ns.IsSelfTriggerCalled() + if ns.IsSelfTriggerCalled != nil { + return ns.IsSelfTriggerCalled() + } + + return false } // GetQueryHandler - diff --git a/factory/disabled/stakingDataProvider.go b/factory/disabled/stakingDataProvider.go index fce43915ab6..953b84d7a66 100644 --- a/factory/disabled/stakingDataProvider.go +++ b/factory/disabled/stakingDataProvider.go @@ -6,7 +6,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" ) -var emptyBI = big.NewInt(0) +var zeroBI = big.NewInt(0) type stakingDataProvider struct { } @@ -18,17 +18,17 @@ func NewDisabledStakingDataProvider() *stakingDataProvider { // GetTotalStakeEligibleNodes returns an empty big integer func (s *stakingDataProvider) GetTotalStakeEligibleNodes() *big.Int { - return emptyBI + return zeroBI } // GetTotalTopUpStakeEligibleNodes returns an empty big integer func (s *stakingDataProvider) GetTotalTopUpStakeEligibleNodes() *big.Int { - return emptyBI + return zeroBI } // GetNodeStakedTopUp returns an empty big integer and a nil error func (s *stakingDataProvider) GetNodeStakedTopUp(_ []byte) (*big.Int, error) { - return emptyBI, nil + return zeroBI, nil } // PrepareStakingData returns a nil error From b51f9a4376a08ae89eb322071a57f6e904b75faf Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 12 May 2022 15:58:47 +0300 Subject: [PATCH 253/958] FEAT: First ugly version --- epochStart/metachain/auctionListSelector.go | 245 ++++++++++++++++++++ epochStart/metachain/systemSCs.go | 205 +--------------- 2 files changed, 255 insertions(+), 195 deletions(-) create mode 100644 epochStart/metachain/auctionListSelector.go diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go new file mode 100644 index 00000000000..d3f799b7926 --- /dev/null +++ b/epochStart/metachain/auctionListSelector.go @@ -0,0 +1,245 @@ +package metachain + +import ( + "bytes" + "encoding/hex" + "fmt" + "math/big" + "sort" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/display" + logger "github.com/ElrondNetwork/elrond-go-logger" + "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/state" +) + +type auctionListSelector struct { + currentNodesEnableConfig config.MaxNodesChangeConfig + shardCoordinator sharding.Coordinator + stakingDataProvider epochStart.StakingDataProvider + maxNodesEnableConfig []config.MaxNodesChangeConfig +} + +type AuctionListSelectorArgs struct { + ShardCoordinator sharding.Coordinator + StakingDataProvider epochStart.StakingDataProvider + EpochNotifier process.EpochNotifier + MaxNodesEnableConfig []config.MaxNodesChangeConfig +} + +func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, error) { + asl := &auctionListSelector{ + shardCoordinator: args.ShardCoordinator, + stakingDataProvider: args.StakingDataProvider, + } + + asl.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) + copy(asl.maxNodesEnableConfig, args.MaxNodesEnableConfig) + args.EpochNotifier.RegisterNotifyHandler(asl) + + return asl, nil +} + +func (als *auctionListSelector) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { + auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) + numOfShuffledNodes := als.currentNodesEnableConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) + + numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) + if err != nil { + log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", + err, + currNumOfValidators, + numOfShuffledNodes, + )) + numOfValidatorsAfterShuffling = 0 + } + + availableSlots, err := safeSub(als.currentNodesEnableConfig.MaxNumNodes, numOfValidatorsAfterShuffling) + if availableSlots == 0 || err != nil { + log.Info(fmt.Sprintf("%v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", + err, + als.currentNodesEnableConfig.MaxNumNodes, + numOfValidatorsAfterShuffling, + )) + return nil + } + + auctionListSize := uint32(len(auctionList)) + log.Info("systemSCProcessor.selectNodesFromAuctionList", + "max nodes", als.currentNodesEnableConfig.MaxNumNodes, + "current number of validators", currNumOfValidators, + "num of nodes which will be shuffled out", numOfShuffledNodes, + "num of validators after shuffling", numOfValidatorsAfterShuffling, + "auction list size", auctionListSize, + fmt.Sprintf("available slots (%v -%v)", als.currentNodesEnableConfig.MaxNumNodes, numOfValidatorsAfterShuffling), availableSlots, + ) + + err = als.sortAuctionList(auctionList, randomness) + if err != nil { + return err + } + + numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) + als.displayAuctionList(auctionList, numOfAvailableNodeSlots) + + for i := uint32(0); i < numOfAvailableNodeSlots; i++ { + newNode := auctionList[i] + newNode.SetList(string(common.SelectedFromAuctionList)) + err = validatorsInfoMap.Replace(auctionList[i], newNode) + if err != nil { + return err + } + } + + return nil +} + +// TODO: Move this in elrond-go-core +func safeSub(a, b uint32) (uint32, error) { + if a < b { + return 0, core.ErrSubtractionOverflow + } + return a - b, nil +} + +func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, uint32) { + auctionList := make([]state.ValidatorInfoHandler, 0) + numOfValidators := uint32(0) + + for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { + if validator.GetList() == string(common.AuctionList) { + auctionList = append(auctionList, validator) + continue + } + if isValidator(validator) { + numOfValidators++ + } + } + + return auctionList, numOfValidators +} + +func (als *auctionListSelector) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { + if len(auctionList) == 0 { + return nil + } + + validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) + if err != nil { + return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) + } + + pubKeyLen := len(auctionList[0].GetPublicKey()) + normRandomness := calcNormRand(randomness, pubKeyLen) + sort.SliceStable(auctionList, func(i, j int) bool { + pubKey1 := auctionList[i].GetPublicKey() + pubKey2 := auctionList[j].GetPublicKey() + + nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] + nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] + + if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { + return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) + } + + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 + }) + + return nil +} + +func (als *auctionListSelector) getValidatorTopUpMap(validators []state.ValidatorInfoHandler) (map[string]*big.Int, error) { + ret := make(map[string]*big.Int, len(validators)) + + for _, validator := range validators { + pubKey := validator.GetPublicKey() + topUp, err := als.stakingDataProvider.GetNodeStakedTopUp(pubKey) + if err != nil { + return nil, fmt.Errorf("%w when trying to get top up per node for %s", err, hex.EncodeToString(pubKey)) + } + + ret[string(pubKey)] = topUp + } + + return ret, nil +} + +func calcNormRand(randomness []byte, expectedLen int) []byte { + rand := randomness + randLen := len(rand) + + if expectedLen > randLen { + repeatedCt := expectedLen/randLen + 1 // todo: fix possible div by 0 + rand = bytes.Repeat(randomness, repeatedCt) + } + + rand = rand[:expectedLen] + return rand +} + +func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { + xorLen := len(randomness) + + key1Xor := make([]byte, xorLen) + key2Xor := make([]byte, xorLen) + + for idx := 0; idx < xorLen; idx++ { + key1Xor[idx] = pubKey1[idx] ^ randomness[idx] + key2Xor[idx] = pubKey2[idx] ^ randomness[idx] + } + + return bytes.Compare(key1Xor, key2Xor) == 1 +} + +func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { + if log.GetLevel() > logger.LogDebug { + return + } + + tableHeader := []string{"Owner", "Registered key", "TopUp per node"} + lines := make([]*display.LineData, 0, len(auctionList)) + horizontalLine := false + for idx, validator := range auctionList { + pubKey := validator.GetPublicKey() + + owner, err := als.stakingDataProvider.GetBlsKeyOwner(pubKey) + log.LogIfError(err) + + topUp, err := als.stakingDataProvider.GetNodeStakedTopUp(pubKey) + log.LogIfError(err) + + horizontalLine = uint32(idx) == numOfSelectedNodes-1 + line := display.NewLineData(horizontalLine, []string{ + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(pubKey), + topUp.String(), + }) + lines = append(lines, line) + } + + table, err := display.CreateTableString(tableHeader, lines) + if err != nil { + log.Error("could not create table", "error", err) + return + } + + message := fmt.Sprintf("Auction list\n%s", table) + log.Debug(message) +} + +func (als *auctionListSelector) EpochConfirmed(epoch uint32, _ uint64) { + for _, maxNodesConfig := range als.maxNodesEnableConfig { + if epoch >= maxNodesConfig.EpochEnable { + als.currentNodesEnableConfig = maxNodesConfig + } + } +} + +func (als *auctionListSelector) IsInterfaceNil() bool { + return als == nil +} diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index e101dd43be4..6f58912ba6b 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -1,20 +1,14 @@ package metachain import ( - "bytes" - "encoding/hex" "fmt" "math" "math/big" - "sort" - "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go-core/marshal" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" @@ -51,6 +45,7 @@ type ArgsNewEpochStartSystemSCProcessing struct { type systemSCProcessor struct { *legacySystemSCProcessor + auctionListSelector *auctionListSelector governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 @@ -73,11 +68,19 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr return nil, err } + als, _ := NewAuctionListSelector(AuctionListSelectorArgs{ + ShardCoordinator: args.ShardCoordinator, + StakingDataProvider: args.StakingDataProvider, + EpochNotifier: args.EpochNotifier, + MaxNodesEnableConfig: args.MaxNodesEnableConfig, + }) + s := &systemSCProcessor{ legacySystemSCProcessor: legacy, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + auctionListSelector: als, } log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) @@ -146,7 +149,7 @@ func (s *systemSCProcessor) processWithNewFlags( return err } - err = s.selectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) + err = s.auctionListSelector.selectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) if err != nil { return err } @@ -190,194 +193,6 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( return s.updateDelegationContracts(mapOwnersKeys) } -// TODO: Staking v4: perhaps create a subcomponent which handles selection, which would be also very useful in tests -func (s *systemSCProcessor) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { - auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) - numOfShuffledNodes := s.currentNodesEnableConfig.NodesToShufflePerShard * (s.shardCoordinator.NumberOfShards() + 1) - - numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) - if err != nil { - log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", - err, - currNumOfValidators, - numOfShuffledNodes, - )) - numOfValidatorsAfterShuffling = 0 - } - - availableSlots, err := safeSub(s.maxNodes, numOfValidatorsAfterShuffling) - if availableSlots == 0 || err != nil { - log.Info(fmt.Sprintf("%v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", - err, - s.maxNodes, - numOfValidatorsAfterShuffling, - )) - return nil - } - - auctionListSize := uint32(len(auctionList)) - log.Info("systemSCProcessor.selectNodesFromAuctionList", - "max nodes", s.maxNodes, - "current number of validators", currNumOfValidators, - "num of nodes which will be shuffled out", numOfShuffledNodes, - "num of validators after shuffling", numOfValidatorsAfterShuffling, - "auction list size", auctionListSize, - fmt.Sprintf("available slots (%v -%v)", s.maxNodes, numOfValidatorsAfterShuffling), availableSlots, - ) - - err = s.sortAuctionList(auctionList, randomness) - if err != nil { - return err - } - - numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) - s.displayAuctionList(auctionList, numOfAvailableNodeSlots) - - for i := uint32(0); i < numOfAvailableNodeSlots; i++ { - newNode := auctionList[i] - newNode.SetList(string(common.SelectedFromAuctionList)) - err = validatorsInfoMap.Replace(auctionList[i], newNode) - if err != nil { - return err - } - } - - return nil -} - -// TODO: Move this in elrond-go-core -func safeSub(a, b uint32) (uint32, error) { - if a < b { - return 0, core.ErrSubtractionOverflow - } - return a - b, nil -} - -func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, uint32) { - auctionList := make([]state.ValidatorInfoHandler, 0) - numOfValidators := uint32(0) - - for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { - if validator.GetList() == string(common.AuctionList) { - auctionList = append(auctionList, validator) - continue - } - if isValidator(validator) { - numOfValidators++ - } - } - - return auctionList, numOfValidators -} - -func (s *systemSCProcessor) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { - if len(auctionList) == 0 { - return nil - } - - validatorTopUpMap, err := s.getValidatorTopUpMap(auctionList) - if err != nil { - return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) - } - - pubKeyLen := len(auctionList[0].GetPublicKey()) - normRandomness := calcNormRand(randomness, pubKeyLen) - sort.SliceStable(auctionList, func(i, j int) bool { - pubKey1 := auctionList[i].GetPublicKey() - pubKey2 := auctionList[j].GetPublicKey() - - nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] - nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] - - if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { - return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) - } - - return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 - }) - - return nil -} - -func (s *systemSCProcessor) getValidatorTopUpMap(validators []state.ValidatorInfoHandler) (map[string]*big.Int, error) { - ret := make(map[string]*big.Int, len(validators)) - - for _, validator := range validators { - pubKey := validator.GetPublicKey() - topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) - if err != nil { - return nil, fmt.Errorf("%w when trying to get top up per node for %s", err, hex.EncodeToString(pubKey)) - } - - ret[string(pubKey)] = topUp - } - - return ret, nil -} - -func calcNormRand(randomness []byte, expectedLen int) []byte { - rand := randomness - randLen := len(rand) - - if expectedLen > randLen { - repeatedCt := expectedLen/randLen + 1 // todo: fix possible div by 0 - rand = bytes.Repeat(randomness, repeatedCt) - } - - rand = rand[:expectedLen] - return rand -} - -func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { - xorLen := len(randomness) - - key1Xor := make([]byte, xorLen) - key2Xor := make([]byte, xorLen) - - for idx := 0; idx < xorLen; idx++ { - key1Xor[idx] = pubKey1[idx] ^ randomness[idx] - key2Xor[idx] = pubKey2[idx] ^ randomness[idx] - } - - return bytes.Compare(key1Xor, key2Xor) == 1 -} - -func (s *systemSCProcessor) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - if log.GetLevel() > logger.LogDebug { - return - } - - tableHeader := []string{"Owner", "Registered key", "TopUp per node"} - lines := make([]*display.LineData, 0, len(auctionList)) - horizontalLine := false - for idx, validator := range auctionList { - pubKey := validator.GetPublicKey() - - owner, err := s.stakingDataProvider.GetBlsKeyOwner(pubKey) - log.LogIfError(err) - - topUp, err := s.stakingDataProvider.GetNodeStakedTopUp(pubKey) - log.LogIfError(err) - - horizontalLine = uint32(idx) == numOfSelectedNodes-1 - line := display.NewLineData(horizontalLine, []string{ - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(pubKey), - topUp.String(), - }) - lines = append(lines, line) - } - - table, err := display.CreateTableString(tableHeader, lines) - if err != nil { - log.Error("could not create table", "error", err) - return - } - - message := fmt.Sprintf("Auction list\n%s", table) - log.Debug(message) -} - func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { allNodes := GetAllNodeKeys(validatorsInfoMap) return s.prepareStakingData(allNodes) From 7494d6b8535add10cbd566fb25ebd5ca0f896cb0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 12 May 2022 16:09:36 +0300 Subject: [PATCH 254/958] FIX: Add maxNumNodes var --- epochStart/metachain/auctionListSelector.go | 13 +++++++------ epochStart/metachain/systemSCs.go | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index d3f799b7926..771e560ca92 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -45,9 +45,10 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, return asl, nil } -func (als *auctionListSelector) selectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { +func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) numOfShuffledNodes := als.currentNodesEnableConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) + maxNumNodes := als.currentNodesEnableConfig.MaxNumNodes numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { @@ -59,24 +60,24 @@ func (als *auctionListSelector) selectNodesFromAuctionList(validatorsInfoMap sta numOfValidatorsAfterShuffling = 0 } - availableSlots, err := safeSub(als.currentNodesEnableConfig.MaxNumNodes, numOfValidatorsAfterShuffling) + availableSlots, err := safeSub(maxNumNodes, numOfValidatorsAfterShuffling) if availableSlots == 0 || err != nil { log.Info(fmt.Sprintf("%v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", err, - als.currentNodesEnableConfig.MaxNumNodes, + maxNumNodes, numOfValidatorsAfterShuffling, )) return nil } auctionListSize := uint32(len(auctionList)) - log.Info("systemSCProcessor.selectNodesFromAuctionList", - "max nodes", als.currentNodesEnableConfig.MaxNumNodes, + log.Info("systemSCProcessor.SelectNodesFromAuctionList", + "max nodes", maxNumNodes, "current number of validators", currNumOfValidators, "num of nodes which will be shuffled out", numOfShuffledNodes, "num of validators after shuffling", numOfValidatorsAfterShuffling, "auction list size", auctionListSize, - fmt.Sprintf("available slots (%v -%v)", als.currentNodesEnableConfig.MaxNumNodes, numOfValidatorsAfterShuffling), availableSlots, + fmt.Sprintf("available slots (%v -%v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) err = als.sortAuctionList(auctionList, randomness) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6f58912ba6b..60525ff5ec0 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -149,7 +149,7 @@ func (s *systemSCProcessor) processWithNewFlags( return err } - err = s.auctionListSelector.selectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) + err = s.auctionListSelector.SelectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) if err != nil { return err } From 9c196c083682c278db6e30419a6d56836fe5a37b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 12 May 2022 16:16:23 +0300 Subject: [PATCH 255/958] FIX: After review --- .../vm/staking/baseTestMetaProcessor.go | 3 ++- integrationTests/vm/staking/stakingV4_test.go | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index d805c880c28..7c56eabaedc 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -82,7 +82,8 @@ func newTestMetaProcessor( ) *TestMetaProcessor { gasScheduleNotifier := createGasScheduleNotifier() blockChainHook := createBlockChainHook( - dataComponents, coreComponents, + dataComponents, + coreComponents, stateComponents.AccountsAdapter(), bootstrapComponents.ShardCoordinator(), gasScheduleNotifier, diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 4e56c115d6c..4203eed4b76 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -73,12 +73,13 @@ func requireMapDoesNotContain(t *testing.T, m map[uint32][][]byte, s [][]byte) { } } -func remove(s [][]byte, elem []byte) [][]byte { - ret := s - for i, e := range s { +// remove will remove the item from slice without keeping the order of the original slice +func remove(slice [][]byte, elem []byte) [][]byte { + ret := slice + for i, e := range slice { if bytes.Equal(elem, e) { - ret[i] = ret[len(s)-1] - return ret[:len(s)-1] + ret[i] = ret[len(slice)-1] + return ret[:len(slice)-1] } } @@ -403,7 +404,7 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { // Owner3 will unStake EGLD => he will have negative top-up at the selection time => one of his nodes will be unStaked. // His other node should not have been selected => remains in auction. - // Meanwhile, owner4 had never unStaked EGLD => his node from auction list node will be distributed to waiting + // Meanwhile, owner4 had never unStaked EGLD => his node from auction list will be distributed to waiting unStake(t, []byte(owner3), node.AccountsAdapter, node.Marshaller, big.NewInt(2*nodePrice)) // 4. Check config in epoch = staking v4 distribute auction to waiting From 72443f34438cf4d17b817e5e767e4fd67ffa6c73 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Thu, 12 May 2022 16:56:09 +0300 Subject: [PATCH 256/958] remove empty lines --- api/groups/validatorGroup_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/groups/validatorGroup_test.go b/api/groups/validatorGroup_test.go index 750d56573fd..67cf8c5613a 100644 --- a/api/groups/validatorGroup_test.go +++ b/api/groups/validatorGroup_test.go @@ -108,7 +108,6 @@ func TestValidatorStatistics_ReturnsSuccessfully(t *testing.T) { _ = json.Unmarshal(mapResponseDataBytes, &validatorStatistics) assert.Equal(t, http.StatusOK, resp.Code) - assert.Equal(t, validatorStatistics.Result, mapToReturn) } @@ -165,7 +164,6 @@ func TestAuctionList_ReturnsSuccessfully(t *testing.T) { loadResponse(resp.Body, &response) assert.Equal(t, http.StatusOK, resp.Code) - assert.Equal(t, response.Data.Result, auctionListToReturn) } From 9c47f152fafc9e0939e71b2ee26cb210d9532939 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 13 May 2022 14:08:32 +0300 Subject: [PATCH 257/958] FEAT: Add AuctionListSelector interface and inject it --- epochStart/errors.go | 3 ++ epochStart/interface.go | 6 +++ epochStart/metachain/auctionListSelector.go | 17 +++++-- epochStart/metachain/systemSCs.go | 15 +++--- epochStart/metachain/systemSCs_test.go | 51 ++++++++++++++----- factory/blockProcessorCreator.go | 13 +++++ integrationTests/testProcessorNode.go | 9 ++++ .../vm/staking/systemSCCreator.go | 9 ++++ 8 files changed, 99 insertions(+), 24 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 2edb86f6e82..24cb6799890 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -328,3 +328,6 @@ var ErrSortAuctionList = errors.New("error while trying to sort auction list") // ErrReceivedNewListNodeInStakingV4 signals that a new node has been assigned in common.NewList instead of common.AuctionList after staking v4 var ErrReceivedNewListNodeInStakingV4 = errors.New("new node has been assigned in common.NewList instead of common.AuctionList after staking v4") + +// ErrNilAuctionListSelector signals that a nil auction list selector has been provided +var ErrNilAuctionListSelector = errors.New("nil auction list selector has been provided") diff --git a/epochStart/interface.go b/epochStart/interface.go index 900e759712c..8fed49f2bb7 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -199,3 +199,9 @@ type EpochNotifier interface { CheckEpoch(epoch uint32) IsInterfaceNil() bool } + +type AuctionListSelector interface { + SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error + EpochConfirmed(epoch uint32, timestamp uint64) + IsInterfaceNil() bool +} diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 771e560ca92..f1f67671bb4 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -8,6 +8,7 @@ import ( "sort" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/display" logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" @@ -33,12 +34,22 @@ type AuctionListSelectorArgs struct { } func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, error) { + if check.IfNil(args.ShardCoordinator) { + return nil, epochStart.ErrNilShardCoordinator + } + if check.IfNil(args.StakingDataProvider) { + return nil, epochStart.ErrNilStakingDataProvider + } + if check.IfNil(args.EpochNotifier) { + return nil, epochStart.ErrNilEpochNotifier + } + asl := &auctionListSelector{ - shardCoordinator: args.ShardCoordinator, - stakingDataProvider: args.StakingDataProvider, + maxNodesEnableConfig: make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)), + shardCoordinator: args.ShardCoordinator, + stakingDataProvider: args.StakingDataProvider, } - asl.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) copy(asl.maxNodesEnableConfig, args.MaxNodesEnableConfig) args.EpochNotifier.RegisterNotifyHandler(asl) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 60525ff5ec0..4eab681200c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -41,11 +41,12 @@ type ArgsNewEpochStartSystemSCProcessing struct { EpochNotifier process.EpochNotifier NodesConfigProvider epochStart.NodesConfigProvider StakingDataProvider epochStart.StakingDataProvider + AuctionListSelector epochStart.AuctionListSelector } type systemSCProcessor struct { *legacySystemSCProcessor - auctionListSelector *auctionListSelector + auctionListSelector epochStart.AuctionListSelector governanceEnableEpoch uint32 builtInOnMetaEnableEpoch uint32 @@ -62,25 +63,21 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr if check.IfNil(args.EpochNotifier) { return nil, epochStart.ErrNilEpochStartNotifier } + if check.IfNil(args.AuctionListSelector) { + return nil, epochStart.ErrNilAuctionListSelector + } legacy, err := newLegacySystemSCProcessor(args) if err != nil { return nil, err } - als, _ := NewAuctionListSelector(AuctionListSelectorArgs{ - ShardCoordinator: args.ShardCoordinator, - StakingDataProvider: args.StakingDataProvider, - EpochNotifier: args.EpochNotifier, - MaxNodesEnableConfig: args.MaxNodesEnableConfig, - }) - s := &systemSCProcessor{ legacySystemSCProcessor: legacy, governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, - auctionListSelector: als, + auctionListSelector: args.AuctionListSelector, } log.Debug("systemSC: enable epoch for governanceV2 init", "epoch", s.governanceEnableEpoch) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 79eacbacae3..9cefb83fe44 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -850,6 +850,12 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS argsStakingDataProvider.MinNodePrice = "1000" stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + argsAuctionListSelector := AuctionListSelectorArgs{ + ShardCoordinator: shardCoordinator, + StakingDataProvider: stakingSCProvider, + EpochNotifier: en, + } + als, _ := NewAuctionListSelector(argsAuctionListSelector) args := ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, @@ -864,6 +870,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS EpochNotifier: en, GenesisNodesConfig: nodesSetup, StakingDataProvider: stakingSCProvider, + AuctionListSelector: als, NodesConfigProvider: &shardingMocks.NodesCoordinatorStub{ ConsensusGroupSizeCalled: func(shardID uint32) int { if shardID == core.MetachainShardId { @@ -1787,20 +1794,26 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 1}} errGetNodeTopUp := errors.New("error getting top up per node") - args.StakingDataProvider = &mock.StakingDataProviderStub{ - GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - switch string(blsKey) { - case "pubKey0", "pubKey1": - return nil, errGetNodeTopUp - default: - require.Fail(t, "should not call this func with other params") - return nil, nil - } + argsAuctionListSelector := AuctionListSelectorArgs{ + ShardCoordinator: args.ShardCoordinator, + StakingDataProvider: &mock.StakingDataProviderStub{ + GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { + switch string(blsKey) { + case "pubKey0", "pubKey1": + return nil, errGetNodeTopUp + default: + require.Fail(t, "should not call this func with other params") + return nil, nil + } + }, }, + EpochNotifier: args.EpochNotifier, + MaxNodesEnableConfig: []config.MaxNodesChangeConfig{{MaxNumNodes: 1}}, } + als, _ := NewAuctionListSelector(argsAuctionListSelector) + args.AuctionListSelector = als owner := []byte("owner") ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} @@ -1823,7 +1836,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 1}} + argsAuctionListSelector := AuctionListSelectorArgs{ + ShardCoordinator: args.ShardCoordinator, + StakingDataProvider: args.StakingDataProvider, + EpochNotifier: args.EpochNotifier, + MaxNodesEnableConfig: []config.MaxNodesChangeConfig{{MaxNumNodes: 1}}, + } + als, _ := NewAuctionListSelector(argsAuctionListSelector) + args.AuctionListSelector = als owner1 := []byte("owner1") owner2 := []byte("owner2") @@ -1857,7 +1877,14 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{MaxNumNodes: 6}} + argsAuctionListSelector := AuctionListSelectorArgs{ + ShardCoordinator: args.ShardCoordinator, + StakingDataProvider: args.StakingDataProvider, + EpochNotifier: args.EpochNotifier, + MaxNodesEnableConfig: []config.MaxNodesChangeConfig{{MaxNumNodes: 6}}, + } + als, _ := NewAuctionListSelector(argsAuctionListSelector) + args.AuctionListSelector = als owner1 := []byte("owner1") owner2 := []byte("owner2") diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index a7bdec71826..030899d4bbf 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -803,6 +803,17 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( "in processComponentsFactory.newMetaBlockProcessor", err) } + argsAuctionListSelector := metachainEpochStart.AuctionListSelectorArgs{ + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + StakingDataProvider: stakingDataProvider, + EpochNotifier: pcf.coreData.EpochNotifier(), + MaxNodesEnableConfig: enableEpochs.MaxNodesChangeEnableEpoch, + } + auctionListSelector, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelector) + if err != nil { + return nil, err + } + argsEpochSystemSC := metachainEpochStart.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, UserAccountsDB: pcf.state.AccountsAdapter(), @@ -821,7 +832,9 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), ESDTOwnerAddressBytes: esdtOwnerAddress, EpochConfig: pcf.epochConfig, + AuctionListSelector: auctionListSelector, } + epochStartSystemSCProcessor, err := metachainEpochStart.NewSystemSCProcessor(argsEpochSystemSC) if err != nil { return nil, err diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 6ae4a0823b6..60b1382c2d4 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2188,6 +2188,14 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { } epochStartValidatorInfo, _ := metachain.NewValidatorInfoCreator(argsEpochValidatorInfo) + + argsAuctionListSelector := metachain.AuctionListSelectorArgs{ + ShardCoordinator: tpn.ShardCoordinator, + StakingDataProvider: stakingDataProvider, + EpochNotifier: tpn.EpochNotifier, + } + auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) + argsEpochSystemSC := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, UserAccountsDB: tpn.AccntState, @@ -2204,6 +2212,7 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { NodesConfigProvider: tpn.NodesCoordinator, ShardCoordinator: tpn.ShardCoordinator, ESDTOwnerAddressBytes: vm.EndOfEpochAddress, + AuctionListSelector: auctionListSelector, EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: StakingV2Epoch, diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index fa42d71145e..74763a3da34 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -36,6 +36,14 @@ func createSystemSCProcessor( systemVM vmcommon.VMExecutionHandler, stakingDataProvider epochStart.StakingDataProvider, ) process.EpochStartSystemSCProcessor { + argsAuctionListSelector := metachain.AuctionListSelectorArgs{ + ShardCoordinator: shardCoordinator, + StakingDataProvider: stakingDataProvider, + EpochNotifier: coreComponents.EpochNotifier(), + MaxNodesEnableConfig: maxNodesConfig, + } + auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) + args := metachain.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, UserAccountsDB: stateComponents.AccountsAdapter(), @@ -60,6 +68,7 @@ func createSystemSCProcessor( }, }, MaxNodesEnableConfig: maxNodesConfig, + AuctionListSelector: auctionListSelector, } systemSCProcessor, _ := metachain.NewSystemSCProcessor(args) From df31428293bcae1dc658fdbff8e1d18ed75f9227 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 13 May 2022 14:47:06 +0300 Subject: [PATCH 258/958] FEAT: Possible div by zero --- epochStart/interface.go | 1 + epochStart/metachain/auctionListSelector.go | 14 +++++++++++++- epochStart/metachain/systemSCs_test.go | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index 8fed49f2bb7..8c92b3ad300 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -200,6 +200,7 @@ type EpochNotifier interface { IsInterfaceNil() bool } +// AuctionListSelector handles selection of nodes from auction list to be sent to waiting list, based on their top up type AuctionListSelector interface { SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error EpochConfirmed(epoch uint32, timestamp uint64) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index f1f67671bb4..089dc28e77b 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -26,6 +26,7 @@ type auctionListSelector struct { maxNodesEnableConfig []config.MaxNodesChangeConfig } +// AuctionListSelectorArgs is a struct placeholder for all arguments required to create a NewAuctionListSelector type AuctionListSelectorArgs struct { ShardCoordinator sharding.Coordinator StakingDataProvider epochStart.StakingDataProvider @@ -33,6 +34,8 @@ type AuctionListSelectorArgs struct { MaxNodesEnableConfig []config.MaxNodesChangeConfig } +// NewAuctionListSelector will create a new auctionListSelector, which handles selection of nodes from auction list based +// on their top up func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, error) { if check.IfNil(args.ShardCoordinator) { return nil, epochStart.ErrNilShardCoordinator @@ -56,7 +59,14 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, return asl, nil } +// SelectNodesFromAuctionList will select nodes from validatorsInfoMap based on their top up. If two or more validators +// have the same top-up, then sorting will be done based on blsKey XOR randomness. Selected nodes will have their list set +// to common.SelectNodesFromAuctionList func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { + if len(randomness) == 0 { + return process.ErrNilRandSeed + } + auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) numOfShuffledNodes := als.currentNodesEnableConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) maxNumNodes := als.currentNodesEnableConfig.MaxNumNodes @@ -186,7 +196,7 @@ func calcNormRand(randomness []byte, expectedLen int) []byte { randLen := len(rand) if expectedLen > randLen { - repeatedCt := expectedLen/randLen + 1 // todo: fix possible div by 0 + repeatedCt := expectedLen/randLen + 1 rand = bytes.Repeat(randomness, repeatedCt) } @@ -244,6 +254,7 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator log.Debug(message) } +// EpochConfirmed is called whenever a new epoch is confirmed func (als *auctionListSelector) EpochConfirmed(epoch uint32, _ uint64) { for _, maxNodesConfig := range als.maxNodesEnableConfig { if epoch >= maxNodesConfig.EpochEnable { @@ -252,6 +263,7 @@ func (als *auctionListSelector) EpochConfirmed(epoch uint32, _ uint64) { } } +// IsInterfaceNil checks if the underlying pointer is nil func (als *auctionListSelector) IsInterfaceNil() bool { return als == nil } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 9cefb83fe44..fcf4a026799 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1826,7 +1826,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("rnd")}) require.Error(t, err) require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) @@ -1861,7 +1861,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("rnd")}) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ From 56ce46a274968c32c1bcbb3153a801a69737e790 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 13 May 2022 17:55:41 +0300 Subject: [PATCH 259/958] FEAT: Add MaxNodesChangeConfigProvider --- epochStart/errors.go | 3 + epochStart/interface.go | 11 +- epochStart/metachain/auctionListSelector.go | 44 ++---- .../metachain/auctionListSelector_test.go | 132 ++++++++++++++++++ epochStart/metachain/legacySystemSCs.go | 2 - epochStart/metachain/systemSCs_test.go | 41 +++--- epochStart/notifier/nodesConfigProvider.go | 77 ++++++++++ factory/blockProcessorCreator.go | 16 ++- integrationTests/testProcessorNode.go | 10 +- .../vm/staking/systemSCCreator.go | 12 +- 10 files changed, 282 insertions(+), 66 deletions(-) create mode 100644 epochStart/metachain/auctionListSelector_test.go create mode 100644 epochStart/notifier/nodesConfigProvider.go diff --git a/epochStart/errors.go b/epochStart/errors.go index 24cb6799890..0023fd5625b 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -329,5 +329,8 @@ var ErrSortAuctionList = errors.New("error while trying to sort auction list") // ErrReceivedNewListNodeInStakingV4 signals that a new node has been assigned in common.NewList instead of common.AuctionList after staking v4 var ErrReceivedNewListNodeInStakingV4 = errors.New("new node has been assigned in common.NewList instead of common.AuctionList after staking v4") +// ErrNilMaxNodesChangeConfigProvider signals that a nil nodes config provider has been provided +var ErrNilMaxNodesChangeConfigProvider = errors.New("nil nodes config provider has been provided") + // ErrNilAuctionListSelector signals that a nil auction list selector has been provided var ErrNilAuctionListSelector = errors.New("nil auction list selector has been provided") diff --git a/epochStart/interface.go b/epochStart/interface.go index 8c92b3ad300..887b51986ef 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -7,6 +7,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/state" vmcommon "github.com/ElrondNetwork/elrond-vm-common" ) @@ -200,9 +201,17 @@ type EpochNotifier interface { IsInterfaceNil() bool } +// MaxNodesChangeConfigProvider provides all config.MaxNodesChangeConfig, as well as +// the current config.MaxNodesChangeConfig based on the current epoch +type MaxNodesChangeConfigProvider interface { + GetAllNodesConfig() []config.MaxNodesChangeConfig + GetCurrentNodesConfig() config.MaxNodesChangeConfig + EpochConfirmed(epoch uint32, round uint64) + IsInterfaceNil() bool +} + // AuctionListSelector handles selection of nodes from auction list to be sent to waiting list, based on their top up type AuctionListSelector interface { SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error - EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 089dc28e77b..5077c231e3b 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -12,7 +12,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/display" logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" @@ -20,18 +19,16 @@ import ( ) type auctionListSelector struct { - currentNodesEnableConfig config.MaxNodesChangeConfig - shardCoordinator sharding.Coordinator - stakingDataProvider epochStart.StakingDataProvider - maxNodesEnableConfig []config.MaxNodesChangeConfig + shardCoordinator sharding.Coordinator + stakingDataProvider epochStart.StakingDataProvider + nodesConfigProvider epochStart.MaxNodesChangeConfigProvider } // AuctionListSelectorArgs is a struct placeholder for all arguments required to create a NewAuctionListSelector type AuctionListSelectorArgs struct { - ShardCoordinator sharding.Coordinator - StakingDataProvider epochStart.StakingDataProvider - EpochNotifier process.EpochNotifier - MaxNodesEnableConfig []config.MaxNodesChangeConfig + ShardCoordinator sharding.Coordinator + StakingDataProvider epochStart.StakingDataProvider + MaxNodesChangeConfigProvider epochStart.MaxNodesChangeConfigProvider } // NewAuctionListSelector will create a new auctionListSelector, which handles selection of nodes from auction list based @@ -43,19 +40,16 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, if check.IfNil(args.StakingDataProvider) { return nil, epochStart.ErrNilStakingDataProvider } - if check.IfNil(args.EpochNotifier) { - return nil, epochStart.ErrNilEpochNotifier + if check.IfNil(args.MaxNodesChangeConfigProvider) { + return nil, epochStart.ErrNilMaxNodesChangeConfigProvider } asl := &auctionListSelector{ - maxNodesEnableConfig: make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)), - shardCoordinator: args.ShardCoordinator, - stakingDataProvider: args.StakingDataProvider, + shardCoordinator: args.ShardCoordinator, + stakingDataProvider: args.StakingDataProvider, + nodesConfigProvider: args.MaxNodesChangeConfigProvider, } - copy(asl.maxNodesEnableConfig, args.MaxNodesEnableConfig) - args.EpochNotifier.RegisterNotifyHandler(asl) - return asl, nil } @@ -67,10 +61,10 @@ func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap sta return process.ErrNilRandSeed } - auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) - numOfShuffledNodes := als.currentNodesEnableConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) - maxNumNodes := als.currentNodesEnableConfig.MaxNumNodes + currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() + numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) + auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", @@ -81,6 +75,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap sta numOfValidatorsAfterShuffling = 0 } + maxNumNodes := currNodesConfig.MaxNumNodes availableSlots, err := safeSub(maxNumNodes, numOfValidatorsAfterShuffling) if availableSlots == 0 || err != nil { log.Info(fmt.Sprintf("%v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", @@ -254,15 +249,6 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator log.Debug(message) } -// EpochConfirmed is called whenever a new epoch is confirmed -func (als *auctionListSelector) EpochConfirmed(epoch uint32, _ uint64) { - for _, maxNodesConfig := range als.maxNodesEnableConfig { - if epoch >= maxNodesConfig.EpochEnable { - als.currentNodesEnableConfig = maxNodesConfig - } - } -} - // IsInterfaceNil checks if the underlying pointer is nil func (als *auctionListSelector) IsInterfaceNil() bool { return als == nil diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go new file mode 100644 index 00000000000..a09f789ecf6 --- /dev/null +++ b/epochStart/metachain/auctionListSelector_test.go @@ -0,0 +1,132 @@ +package metachain + +import ( + "testing" + + "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/epochStart/notifier" + "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/stretchr/testify/require" +) + +func createAuctionListSelectorArgs() AuctionListSelectorArgs { + epochNotifier := forking.NewGenericEpochNotifier() + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, nil) + + argsStakingDataProvider := createStakingDataProviderArgs() + stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) + + shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + return AuctionListSelectorArgs{ + ShardCoordinator: shardCoordinator, + StakingDataProvider: stakingSCProvider, + MaxNodesChangeConfigProvider: nodesConfigProvider, + } +} + +func TestNewAuctionListSelector(t *testing.T) { + t.Parallel() + + t.Run("nil shard coordinator", func(t *testing.T) { + t.Parallel() + args := createAuctionListSelectorArgs() + args.ShardCoordinator = nil + als, err := NewAuctionListSelector(args) + require.Nil(t, als) + require.Equal(t, epochStart.ErrNilShardCoordinator, err) + }) + + t.Run("nil staking data provider", func(t *testing.T) { + t.Parallel() + args := createAuctionListSelectorArgs() + args.StakingDataProvider = nil + als, err := NewAuctionListSelector(args) + require.Nil(t, als) + require.Equal(t, epochStart.ErrNilStakingDataProvider, err) + }) + + t.Run("nil max nodes change config provider", func(t *testing.T) { + t.Parallel() + args := createAuctionListSelectorArgs() + args.MaxNodesChangeConfigProvider = nil + als, err := NewAuctionListSelector(args) + require.Nil(t, als) + require.Equal(t, epochStart.ErrNilMaxNodesChangeConfigProvider, err) + }) + + t.Run("should work", func(t *testing.T) { + t.Parallel() + args := createAuctionListSelectorArgs() + als, err := NewAuctionListSelector(args) + require.NotNil(t, als) + require.Nil(t, err) + }) +} + +/* +func TestAuctionListSelector_EpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { + t.Parallel() + + args := createAuctionListSelectorArgs() + nodesConfigEpoch0 := config.MaxNodesChangeConfig{ + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + } + nodesConfigEpoch1 := config.MaxNodesChangeConfig{ + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + } + nodesConfigEpoch6 := config.MaxNodesChangeConfig{ + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 1, + } + + args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{ + nodesConfigEpoch0, + nodesConfigEpoch1, + nodesConfigEpoch6, + } + + als, _ := NewAuctionListSelector(args) + + als.EpochConfirmed(0, 0) + require.Equal(t, nodesConfigEpoch0, als.currentNodesEnableConfig) + + als.EpochConfirmed(1, 1) + require.Equal(t, nodesConfigEpoch1, als.currentNodesEnableConfig) + + for epoch := uint32(2); epoch <= 5; epoch++ { + als.EpochConfirmed(epoch, uint64(epoch)) + require.Equal(t, nodesConfigEpoch1, als.currentNodesEnableConfig) + } + + // simulate restart + als.EpochConfirmed(0, 0) + als.EpochConfirmed(5, 5) + require.Equal(t, nodesConfigEpoch1, als.currentNodesEnableConfig) + + als.EpochConfirmed(6, 6) + require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) + + // simulate restart + als.EpochConfirmed(0, 0) + als.EpochConfirmed(6, 6) + require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) + + for epoch := uint32(7); epoch <= 20; epoch++ { + als.EpochConfirmed(epoch, uint64(epoch)) + require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) + } + + // simulate restart + als.EpochConfirmed(1, 1) + als.EpochConfirmed(21, 21) + require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) +} + +*/ diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 91d64a5363b..777aa6957dd 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -46,7 +46,6 @@ type legacySystemSCProcessor struct { mapNumSwitchedPerShard map[uint32]uint32 mapNumSwitchablePerShard map[uint32]uint32 maxNodesEnableConfig []config.MaxNodesChangeConfig - currentNodesEnableConfig config.MaxNodesChangeConfig maxNodes uint32 switchEnableEpoch uint32 @@ -1363,7 +1362,6 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { } if epoch >= maxNodesConfig.EpochEnable { s.maxNodes = maxNodesConfig.MaxNumNodes - s.currentNodesEnableConfig = maxNodesConfig } } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index fcf4a026799..2994c9d4f83 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -27,6 +27,7 @@ import ( "github.com/ElrondNetwork/elrond-go/dataRetriever/dataPool" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/mock" + "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" @@ -850,10 +851,12 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS argsStakingDataProvider.MinNodePrice = "1000" stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(en, nil) argsAuctionListSelector := AuctionListSelectorArgs{ - ShardCoordinator: shardCoordinator, - StakingDataProvider: stakingSCProvider, - EpochNotifier: en, + ShardCoordinator: shardCoordinator, + StakingDataProvider: stakingSCProvider, + MaxNodesChangeConfigProvider: nodesConfigProvider, } als, _ := NewAuctionListSelector(argsAuctionListSelector) @@ -1796,6 +1799,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) errGetNodeTopUp := errors.New("error getting top up per node") + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: args.ShardCoordinator, StakingDataProvider: &mock.StakingDataProviderStub{ @@ -1809,8 +1813,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA } }, }, - EpochNotifier: args.EpochNotifier, - MaxNodesEnableConfig: []config.MaxNodesChangeConfig{{MaxNumNodes: 1}}, + MaxNodesChangeConfigProvider: nodesConfigProvider, } als, _ := NewAuctionListSelector(argsAuctionListSelector) args.AuctionListSelector = als @@ -1824,7 +1827,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) s, _ := NewSystemSCProcessor(args) - s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("rnd")}) require.Error(t, err) @@ -1836,11 +1839,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForA t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, nil) argsAuctionListSelector := AuctionListSelectorArgs{ - ShardCoordinator: args.ShardCoordinator, - StakingDataProvider: args.StakingDataProvider, - EpochNotifier: args.EpochNotifier, - MaxNodesEnableConfig: []config.MaxNodesChangeConfig{{MaxNumNodes: 1}}, + ShardCoordinator: args.ShardCoordinator, + StakingDataProvider: args.StakingDataProvider, + MaxNodesChangeConfigProvider: nodesConfigProvider, } als, _ := NewAuctionListSelector(argsAuctionListSelector) args.AuctionListSelector = als @@ -1877,11 +1880,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 6}}) argsAuctionListSelector := AuctionListSelectorArgs{ - ShardCoordinator: args.ShardCoordinator, - StakingDataProvider: args.StakingDataProvider, - EpochNotifier: args.EpochNotifier, - MaxNodesEnableConfig: []config.MaxNodesChangeConfig{{MaxNumNodes: 6}}, + ShardCoordinator: args.ShardCoordinator, + StakingDataProvider: args.StakingDataProvider, + MaxNodesChangeConfigProvider: nodesConfigProvider, } als, _ := NewAuctionListSelector(argsAuctionListSelector) args.AuctionListSelector = als @@ -1917,7 +1920,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1)) s, _ := NewSystemSCProcessor(args) - s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("pubKey7")}) require.Nil(t, err) @@ -2006,14 +2009,12 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err := s.processLegacy(validatorsInfoMap, 0, 0) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch0, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch0.MaxNumNodes, s.maxNodes) s.EpochConfirmed(1, 1) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 1, 1) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch1, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) for epoch := uint32(2); epoch <= 5; epoch++ { @@ -2021,7 +2022,6 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, uint64(epoch), epoch) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch1, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) } @@ -2031,14 +2031,12 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 5, 5) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch1, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) s.EpochConfirmed(6, 6) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 6, 6) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) // simulate restart @@ -2047,7 +2045,6 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 6, 6) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) for epoch := uint32(7); epoch <= 20; epoch++ { @@ -2055,7 +2052,6 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, uint64(epoch), epoch) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) } @@ -2065,7 +2061,6 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 21, 21) require.Nil(t, err) - require.Equal(t, nodesConfigEpoch6, s.currentNodesEnableConfig) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) } diff --git a/epochStart/notifier/nodesConfigProvider.go b/epochStart/notifier/nodesConfigProvider.go new file mode 100644 index 00000000000..0766400ce95 --- /dev/null +++ b/epochStart/notifier/nodesConfigProvider.go @@ -0,0 +1,77 @@ +package notifier + +import ( + "sort" + "sync" + + "github.com/ElrondNetwork/elrond-go-core/core/check" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/process" +) + +type nodesConfigProvider struct { + mutex sync.Mutex + currentNodesConfig config.MaxNodesChangeConfig + allNodesConfigs []config.MaxNodesChangeConfig +} + +// NewNodesConfigProvider returns a new instance of nodesConfigProvider, which provides the current +// config.MaxNodesChangeConfig based on the current epoch +func NewNodesConfigProvider( + epochNotifier process.EpochNotifier, + maxNodesEnableConfig []config.MaxNodesChangeConfig, +) (*nodesConfigProvider, error) { + if check.IfNil(epochNotifier) { + return nil, epochStart.ErrNilEpochNotifier + } + + ncp := &nodesConfigProvider{ + allNodesConfigs: make([]config.MaxNodesChangeConfig, len(maxNodesEnableConfig)), + } + copy(ncp.allNodesConfigs, maxNodesEnableConfig) + ncp.sortConfigs() + epochNotifier.RegisterNotifyHandler(ncp) + + return ncp, nil +} + +func (ncp *nodesConfigProvider) sortConfigs() { + ncp.mutex.Lock() + defer ncp.mutex.Unlock() + + sort.Slice(ncp.allNodesConfigs, func(i, j int) bool { + return ncp.allNodesConfigs[i].EpochEnable < ncp.allNodesConfigs[j].EpochEnable + }) +} + +func (ncp *nodesConfigProvider) GetAllNodesConfig() []config.MaxNodesChangeConfig { + ncp.mutex.Lock() + defer ncp.mutex.Unlock() + + return ncp.allNodesConfigs +} + +func (ncp *nodesConfigProvider) GetCurrentNodesConfig() config.MaxNodesChangeConfig { + ncp.mutex.Lock() + defer ncp.mutex.Unlock() + + return ncp.currentNodesConfig +} + +// EpochConfirmed is called whenever a new epoch is confirmed +func (ncp *nodesConfigProvider) EpochConfirmed(epoch uint32, _ uint64) { + ncp.mutex.Lock() + defer ncp.mutex.Unlock() + + for _, maxNodesConfig := range ncp.allNodesConfigs { + if epoch >= maxNodesConfig.EpochEnable { + ncp.currentNodesConfig = maxNodesConfig + } + } +} + +// IsInterfaceNil checks if the underlying pointer is nil +func (ncp *nodesConfigProvider) IsInterfaceNil() bool { + return ncp == nil +} diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 030899d4bbf..6758c39ef8c 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -12,6 +12,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/bootstrap/disabled" metachainEpochStart "github.com/ElrondNetwork/elrond-go/epochStart/metachain" + "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/genesis" processDisabled "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" @@ -803,11 +804,18 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( "in processComponentsFactory.newMetaBlockProcessor", err) } + maxNodesChangeConfigProvider, err := notifier.NewNodesConfigProvider( + pcf.epochNotifier, + enableEpochs.MaxNodesChangeEnableEpoch, + ) + if err != nil { + return nil, err + } + argsAuctionListSelector := metachainEpochStart.AuctionListSelectorArgs{ - ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), - StakingDataProvider: stakingDataProvider, - EpochNotifier: pcf.coreData.EpochNotifier(), - MaxNodesEnableConfig: enableEpochs.MaxNodesChangeEnableEpoch, + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + StakingDataProvider: stakingDataProvider, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, } auctionListSelector, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelector) if err != nil { diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 60b1382c2d4..310773b0d6c 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2189,10 +2189,14 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { epochStartValidatorInfo, _ := metachain.NewValidatorInfoCreator(argsEpochValidatorInfo) + maxNodesChangeConfigProvider, _ := notifier.NewNodesConfigProvider( + tpn.EpochNotifier, + nil, + ) argsAuctionListSelector := metachain.AuctionListSelectorArgs{ - ShardCoordinator: tpn.ShardCoordinator, - StakingDataProvider: stakingDataProvider, - EpochNotifier: tpn.EpochNotifier, + ShardCoordinator: tpn.ShardCoordinator, + StakingDataProvider: stakingDataProvider, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 74763a3da34..66b0592dc4b 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -9,6 +9,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" epochStartMock "github.com/ElrondNetwork/elrond-go/epochStart/mock" + "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/factory" "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" @@ -36,11 +37,14 @@ func createSystemSCProcessor( systemVM vmcommon.VMExecutionHandler, stakingDataProvider epochStart.StakingDataProvider, ) process.EpochStartSystemSCProcessor { + maxNodesChangeConfigProvider, _ := notifier.NewNodesConfigProvider( + coreComponents.EpochNotifier(), + maxNodesConfig, + ) argsAuctionListSelector := metachain.AuctionListSelectorArgs{ - ShardCoordinator: shardCoordinator, - StakingDataProvider: stakingDataProvider, - EpochNotifier: coreComponents.EpochNotifier(), - MaxNodesEnableConfig: maxNodesConfig, + ShardCoordinator: shardCoordinator, + StakingDataProvider: stakingDataProvider, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) From cd99bed95bc61bef0d96729e938c230d41b4d7c4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 16 May 2022 12:16:12 +0300 Subject: [PATCH 260/958] FEAT: Add MaxNodesChangeConfigProvider in systemSCs.go --- epochStart/metachain/legacySystemSCs.go | 101 +++++++++--------- epochStart/metachain/systemSCs.go | 12 +-- epochStart/metachain/systemSCs_test.go | 43 ++++---- factory/blockProcessorCreator.go | 36 +++---- integrationTests/testProcessorNode.go | 33 +++--- .../vm/staking/systemSCCreator.go | 4 +- 6 files changed, 115 insertions(+), 114 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 777aa6957dd..4cad49d9d4a 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -17,7 +17,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/common" vInfo "github.com/ElrondNetwork/elrond-go/common/validatorInfo" - "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" @@ -29,24 +28,24 @@ import ( ) type legacySystemSCProcessor struct { - systemVM vmcommon.VMExecutionHandler - userAccountsDB state.AccountsAdapter - marshalizer marshal.Marshalizer - peerAccountsDB state.AccountsAdapter - chanceComputer nodesCoordinator.ChanceComputer - shardCoordinator sharding.Coordinator - startRating uint32 - validatorInfoCreator epochStart.ValidatorInfoCreator - genesisNodesConfig sharding.GenesisNodesSetupHandler - nodesConfigProvider epochStart.NodesConfigProvider - stakingDataProvider epochStart.StakingDataProvider - endOfEpochCallerAddress []byte - stakingSCAddress []byte - esdtOwnerAddressBytes []byte - mapNumSwitchedPerShard map[uint32]uint32 - mapNumSwitchablePerShard map[uint32]uint32 - maxNodesEnableConfig []config.MaxNodesChangeConfig - maxNodes uint32 + systemVM vmcommon.VMExecutionHandler + userAccountsDB state.AccountsAdapter + marshalizer marshal.Marshalizer + peerAccountsDB state.AccountsAdapter + chanceComputer nodesCoordinator.ChanceComputer + shardCoordinator sharding.Coordinator + startRating uint32 + validatorInfoCreator epochStart.ValidatorInfoCreator + genesisNodesConfig sharding.GenesisNodesSetupHandler + nodesConfigProvider epochStart.NodesConfigProvider + stakingDataProvider epochStart.StakingDataProvider + maxNodesChangeConfigProvider epochStart.MaxNodesChangeConfigProvider + endOfEpochCallerAddress []byte + stakingSCAddress []byte + esdtOwnerAddressBytes []byte + mapNumSwitchedPerShard map[uint32]uint32 + mapNumSwitchablePerShard map[uint32]uint32 + maxNodes uint32 switchEnableEpoch uint32 hystNodesEnableEpoch uint32 @@ -77,30 +76,31 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega } legacy := &legacySystemSCProcessor{ - systemVM: args.SystemVM, - userAccountsDB: args.UserAccountsDB, - peerAccountsDB: args.PeerAccountsDB, - marshalizer: args.Marshalizer, - startRating: args.StartRating, - validatorInfoCreator: args.ValidatorInfoCreator, - genesisNodesConfig: args.GenesisNodesConfig, - endOfEpochCallerAddress: args.EndOfEpochCallerAddress, - stakingSCAddress: args.StakingSCAddress, - chanceComputer: args.ChanceComputer, - mapNumSwitchedPerShard: make(map[uint32]uint32), - mapNumSwitchablePerShard: make(map[uint32]uint32), - switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, - hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, - delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, - stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, - esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, - stakingDataProvider: args.StakingDataProvider, - nodesConfigProvider: args.NodesConfigProvider, - shardCoordinator: args.ShardCoordinator, - correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, - esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, - saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, - stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, + systemVM: args.SystemVM, + userAccountsDB: args.UserAccountsDB, + peerAccountsDB: args.PeerAccountsDB, + marshalizer: args.Marshalizer, + startRating: args.StartRating, + validatorInfoCreator: args.ValidatorInfoCreator, + genesisNodesConfig: args.GenesisNodesConfig, + endOfEpochCallerAddress: args.EndOfEpochCallerAddress, + stakingSCAddress: args.StakingSCAddress, + chanceComputer: args.ChanceComputer, + mapNumSwitchedPerShard: make(map[uint32]uint32), + mapNumSwitchablePerShard: make(map[uint32]uint32), + switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, + hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, + delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, + stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, + esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, + stakingDataProvider: args.StakingDataProvider, + nodesConfigProvider: args.NodesConfigProvider, + shardCoordinator: args.ShardCoordinator, + correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, + esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, + saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, + stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, + maxNodesChangeConfigProvider: args.MaxNodesChangeConfigProvider, } log.Debug("legacySystemSC: enable epoch for switch jail waiting", "epoch", legacy.switchEnableEpoch) @@ -112,12 +112,6 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega log.Debug("legacySystemSC: enable epoch for save jailed always", "epoch", legacy.saveJailedAlwaysEnableEpoch) log.Debug("legacySystemSC: enable epoch for initializing staking v4", "epoch", legacy.stakingV4InitEnableEpoch) - legacy.maxNodesEnableConfig = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) - copy(legacy.maxNodesEnableConfig, args.MaxNodesEnableConfig) - sort.Slice(legacy.maxNodesEnableConfig, func(i, j int) bool { - return legacy.maxNodesEnableConfig[i].EpochEnable < legacy.maxNodesEnableConfig[j].EpochEnable - }) - return legacy, nil } @@ -158,6 +152,9 @@ func checkLegacyArgs(args ArgsNewEpochStartSystemSCProcessing) error { if check.IfNil(args.ShardCoordinator) { return epochStart.ErrNilShardCoordinator } + if check.IfNil(args.MaxNodesChangeConfigProvider) { + return epochStart.ErrNilMaxNodesChangeConfigProvider + } if len(args.ESDTOwnerAddressBytes) == 0 { return epochStart.ErrEmptyESDTOwnerAddress } @@ -1356,14 +1353,12 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) s.flagChangeMaxNodesEnabled.SetValue(false) - for _, maxNodesConfig := range s.maxNodesEnableConfig { + for _, maxNodesConfig := range s.maxNodesChangeConfigProvider.GetAllNodesConfig() { if epoch == maxNodesConfig.EpochEnable { s.flagChangeMaxNodesEnabled.SetValue(true) } - if epoch >= maxNodesConfig.EpochEnable { - s.maxNodes = maxNodesConfig.MaxNumNodes - } } + s.maxNodes = s.maxNodesChangeConfigProvider.GetCurrentNodesConfig().MaxNumNodes log.Debug("legacySystemSC: consider also (minimum) hysteresis nodes for minimum number of nodes", "enabled", epoch >= s.hystNodesEnableEpoch) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 4eab681200c..0f88ebbe16c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -34,14 +34,14 @@ type ArgsNewEpochStartSystemSCProcessing struct { EndOfEpochCallerAddress []byte StakingSCAddress []byte - MaxNodesEnableConfig []config.MaxNodesChangeConfig ESDTOwnerAddressBytes []byte - GenesisNodesConfig sharding.GenesisNodesSetupHandler - EpochNotifier process.EpochNotifier - NodesConfigProvider epochStart.NodesConfigProvider - StakingDataProvider epochStart.StakingDataProvider - AuctionListSelector epochStart.AuctionListSelector + GenesisNodesConfig sharding.GenesisNodesSetupHandler + EpochNotifier process.EpochNotifier + NodesConfigProvider epochStart.NodesConfigProvider + StakingDataProvider epochStart.StakingDataProvider + AuctionListSelector epochStart.AuctionListSelector + MaxNodesChangeConfigProvider epochStart.MaxNodesChangeConfigProvider } type systemSCProcessor struct { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 2994c9d4f83..630aa10e840 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -892,6 +892,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS StakingV4EnableEpoch: 445, }, }, + MaxNodesChangeConfigProvider: nodesConfigProvider, } return args, metaVmFactory.SystemSmartContractContainer() } @@ -1034,7 +1035,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueue(t * t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: 0, MaxNumNodes: 10}} + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{EpochEnable: 0, MaxNumNodes: 10}}) + args.MaxNodesChangeConfigProvider = nodesConfigProvider s, _ := NewSystemSCProcessor(args) prepareStakingContractWithData( @@ -1082,8 +1084,9 @@ func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwne t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(10, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: 10, MaxNumNodes: 10}} + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{EpochEnable: 10, MaxNumNodes: 10}}) args.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 10 + args.MaxNodesChangeConfigProvider = nodesConfigProvider s, _ := NewSystemSCProcessor(args) prepareStakingContractWithData( @@ -1995,30 +1998,32 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar MaxNumNodes: 48, NodesToShufflePerShard: 1, } - - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{ - nodesConfigEpoch0, - nodesConfigEpoch1, - nodesConfigEpoch6, - } + nodesConfigProvider, _ := notifier.NewNodesConfigProvider( + args.EpochNotifier, + []config.MaxNodesChangeConfig{ + nodesConfigEpoch0, + nodesConfigEpoch1, + nodesConfigEpoch6, + }) + args.MaxNodesChangeConfigProvider = nodesConfigProvider validatorsInfoMap := state.NewShardValidatorsInfoMap() s, _ := NewSystemSCProcessor(args) - s.EpochConfirmed(0, 0) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 0, Nonce: 0}) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err := s.processLegacy(validatorsInfoMap, 0, 0) require.Nil(t, err) require.Equal(t, nodesConfigEpoch0.MaxNumNodes, s.maxNodes) - s.EpochConfirmed(1, 1) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 1, Nonce: 1}) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 1, 1) require.Nil(t, err) require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) for epoch := uint32(2); epoch <= 5; epoch++ { - s.EpochConfirmed(epoch, uint64(epoch)) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: epoch, Nonce: uint64(epoch)}) require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, uint64(epoch), epoch) require.Nil(t, err) @@ -2026,29 +2031,29 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar } // simulate restart - s.EpochConfirmed(0, 0) - s.EpochConfirmed(5, 5) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 0, Nonce: 0}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 5, Nonce: 5}) require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 5, 5) require.Nil(t, err) require.Equal(t, nodesConfigEpoch1.MaxNumNodes, s.maxNodes) - s.EpochConfirmed(6, 6) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 6, Nonce: 6}) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 6, 6) require.Nil(t, err) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) // simulate restart - s.EpochConfirmed(0, 0) - s.EpochConfirmed(6, 6) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 0, Nonce: 0}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 6, Nonce: 6}) require.True(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 6, 6) require.Nil(t, err) require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) for epoch := uint32(7); epoch <= 20; epoch++ { - s.EpochConfirmed(epoch, uint64(epoch)) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: epoch, Nonce: uint64(epoch)}) require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, uint64(epoch), epoch) require.Nil(t, err) @@ -2056,8 +2061,8 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar } // simulate restart - s.EpochConfirmed(1, 1) - s.EpochConfirmed(21, 21) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 1, Nonce: 1}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: 21, Nonce: 21}) require.False(t, s.flagChangeMaxNodesEnabled.IsSet()) err = s.processLegacy(validatorsInfoMap, 21, 21) require.Nil(t, err) diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 6758c39ef8c..b14e3c95ebf 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -823,24 +823,24 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( } argsEpochSystemSC := metachainEpochStart.ArgsNewEpochStartSystemSCProcessing{ - SystemVM: systemVM, - UserAccountsDB: pcf.state.AccountsAdapter(), - PeerAccountsDB: pcf.state.PeerAccounts(), - Marshalizer: pcf.coreData.InternalMarshalizer(), - StartRating: pcf.coreData.RatingsData().StartRating(), - ValidatorInfoCreator: validatorStatisticsProcessor, - EndOfEpochCallerAddress: vm.EndOfEpochAddress, - StakingSCAddress: vm.StakingSCAddress, - ChanceComputer: pcf.coreData.Rater(), - EpochNotifier: pcf.coreData.EpochNotifier(), - GenesisNodesConfig: pcf.coreData.GenesisNodesSetup(), - MaxNodesEnableConfig: enableEpochs.MaxNodesChangeEnableEpoch, - StakingDataProvider: stakingDataProvider, - NodesConfigProvider: pcf.nodesCoordinator, - ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), - ESDTOwnerAddressBytes: esdtOwnerAddress, - EpochConfig: pcf.epochConfig, - AuctionListSelector: auctionListSelector, + SystemVM: systemVM, + UserAccountsDB: pcf.state.AccountsAdapter(), + PeerAccountsDB: pcf.state.PeerAccounts(), + Marshalizer: pcf.coreData.InternalMarshalizer(), + StartRating: pcf.coreData.RatingsData().StartRating(), + ValidatorInfoCreator: validatorStatisticsProcessor, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ChanceComputer: pcf.coreData.Rater(), + EpochNotifier: pcf.coreData.EpochNotifier(), + GenesisNodesConfig: pcf.coreData.GenesisNodesSetup(), + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + StakingDataProvider: stakingDataProvider, + NodesConfigProvider: pcf.nodesCoordinator, + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + ESDTOwnerAddressBytes: esdtOwnerAddress, + EpochConfig: pcf.epochConfig, + AuctionListSelector: auctionListSelector, } epochStartSystemSCProcessor, err := metachainEpochStart.NewSystemSCProcessor(argsEpochSystemSC) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 310773b0d6c..08db3b3e030 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2201,22 +2201,23 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) argsEpochSystemSC := metachain.ArgsNewEpochStartSystemSCProcessing{ - SystemVM: systemVM, - UserAccountsDB: tpn.AccntState, - PeerAccountsDB: tpn.PeerState, - Marshalizer: TestMarshalizer, - StartRating: tpn.RatingsData.StartRating(), - ValidatorInfoCreator: tpn.ValidatorStatisticsProcessor, - EndOfEpochCallerAddress: vm.EndOfEpochAddress, - StakingSCAddress: vm.StakingSCAddress, - ChanceComputer: tpn.NodesCoordinator, - EpochNotifier: tpn.EpochNotifier, - GenesisNodesConfig: tpn.NodesSetup, - StakingDataProvider: stakingDataProvider, - NodesConfigProvider: tpn.NodesCoordinator, - ShardCoordinator: tpn.ShardCoordinator, - ESDTOwnerAddressBytes: vm.EndOfEpochAddress, - AuctionListSelector: auctionListSelector, + SystemVM: systemVM, + UserAccountsDB: tpn.AccntState, + PeerAccountsDB: tpn.PeerState, + Marshalizer: TestMarshalizer, + StartRating: tpn.RatingsData.StartRating(), + ValidatorInfoCreator: tpn.ValidatorStatisticsProcessor, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ChanceComputer: tpn.NodesCoordinator, + EpochNotifier: tpn.EpochNotifier, + GenesisNodesConfig: tpn.NodesSetup, + StakingDataProvider: stakingDataProvider, + NodesConfigProvider: tpn.NodesCoordinator, + ShardCoordinator: tpn.ShardCoordinator, + ESDTOwnerAddressBytes: vm.EndOfEpochAddress, + AuctionListSelector: auctionListSelector, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ StakingV2EnableEpoch: StakingV2Epoch, diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 66b0592dc4b..c71bd2f747e 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -71,8 +71,8 @@ func createSystemSCProcessor( MaxNodesChangeEnableEpoch: maxNodesConfig, }, }, - MaxNodesEnableConfig: maxNodesConfig, - AuctionListSelector: auctionListSelector, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + AuctionListSelector: auctionListSelector, } systemSCProcessor, _ := metachain.NewSystemSCProcessor(args) From cd758f64ba839974db5bb4e666107cd62c5d665f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 16 May 2022 18:47:48 +0300 Subject: [PATCH 261/958] FEAT: Add tests in nodesConfigProvider_test.go --- .../metachain/auctionListSelector_test.go | 66 ---------- epochStart/metachain/legacySystemSCs.go | 1 + .../notifier/nodesConfigProvider_test.go | 121 ++++++++++++++++++ 3 files changed, 122 insertions(+), 66 deletions(-) create mode 100644 epochStart/notifier/nodesConfigProvider_test.go diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index a09f789ecf6..ce948ae527a 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -64,69 +64,3 @@ func TestNewAuctionListSelector(t *testing.T) { require.Nil(t, err) }) } - -/* -func TestAuctionListSelector_EpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { - t.Parallel() - - args := createAuctionListSelectorArgs() - nodesConfigEpoch0 := config.MaxNodesChangeConfig{ - EpochEnable: 0, - MaxNumNodes: 36, - NodesToShufflePerShard: 4, - } - nodesConfigEpoch1 := config.MaxNodesChangeConfig{ - EpochEnable: 1, - MaxNumNodes: 56, - NodesToShufflePerShard: 2, - } - nodesConfigEpoch6 := config.MaxNodesChangeConfig{ - EpochEnable: 6, - MaxNumNodes: 48, - NodesToShufflePerShard: 1, - } - - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{ - nodesConfigEpoch0, - nodesConfigEpoch1, - nodesConfigEpoch6, - } - - als, _ := NewAuctionListSelector(args) - - als.EpochConfirmed(0, 0) - require.Equal(t, nodesConfigEpoch0, als.currentNodesEnableConfig) - - als.EpochConfirmed(1, 1) - require.Equal(t, nodesConfigEpoch1, als.currentNodesEnableConfig) - - for epoch := uint32(2); epoch <= 5; epoch++ { - als.EpochConfirmed(epoch, uint64(epoch)) - require.Equal(t, nodesConfigEpoch1, als.currentNodesEnableConfig) - } - - // simulate restart - als.EpochConfirmed(0, 0) - als.EpochConfirmed(5, 5) - require.Equal(t, nodesConfigEpoch1, als.currentNodesEnableConfig) - - als.EpochConfirmed(6, 6) - require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) - - // simulate restart - als.EpochConfirmed(0, 0) - als.EpochConfirmed(6, 6) - require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) - - for epoch := uint32(7); epoch <= 20; epoch++ { - als.EpochConfirmed(epoch, uint64(epoch)) - require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) - } - - // simulate restart - als.EpochConfirmed(1, 1) - als.EpochConfirmed(21, 21) - require.Equal(t, nodesConfigEpoch6, als.currentNodesEnableConfig) -} - -*/ diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 4cad49d9d4a..34daa27a50c 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -1356,6 +1356,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { for _, maxNodesConfig := range s.maxNodesChangeConfigProvider.GetAllNodesConfig() { if epoch == maxNodesConfig.EpochEnable { s.flagChangeMaxNodesEnabled.SetValue(true) + break } } s.maxNodes = s.maxNodesChangeConfigProvider.GetCurrentNodesConfig().MaxNumNodes diff --git a/epochStart/notifier/nodesConfigProvider_test.go b/epochStart/notifier/nodesConfigProvider_test.go new file mode 100644 index 00000000000..2c3f7ac4dec --- /dev/null +++ b/epochStart/notifier/nodesConfigProvider_test.go @@ -0,0 +1,121 @@ +package notifier + +import ( + "testing" + + "github.com/ElrondNetwork/elrond-go-core/data/block" + "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/config" + "github.com/ElrondNetwork/elrond-go/process" + "github.com/stretchr/testify/require" +) + +func TestNewNodesConfigProvider(t *testing.T) { + t.Parallel() + + ncp, err := NewNodesConfigProvider(nil, nil) + require.Equal(t, process.ErrNilEpochNotifier, err) + require.True(t, ncp.IsInterfaceNil()) + + epochNotifier := forking.NewGenericEpochNotifier() + ncp, err = NewNodesConfigProvider(epochNotifier, nil) + require.Nil(t, err) + require.False(t, ncp.IsInterfaceNil()) +} + +func TestNodesConfigProvider_GetAllNodesConfigSorted(t *testing.T) { + t.Parallel() + + nodesConfigEpoch0 := config.MaxNodesChangeConfig{ + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + } + nodesConfigEpoch1 := config.MaxNodesChangeConfig{ + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + } + nodesConfigEpoch6 := config.MaxNodesChangeConfig{ + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 1, + } + + unsortedNodesConfig := []config.MaxNodesChangeConfig{ + nodesConfigEpoch6, + nodesConfigEpoch0, + nodesConfigEpoch1, + } + sortedNodesConfig := []config.MaxNodesChangeConfig{ + nodesConfigEpoch0, + nodesConfigEpoch1, + nodesConfigEpoch6, + } + + epochNotifier := forking.NewGenericEpochNotifier() + ncp, _ := NewNodesConfigProvider(epochNotifier, unsortedNodesConfig) + require.Equal(t, sortedNodesConfig, ncp.GetAllNodesConfig()) +} + +func TestNodesConfigProvider_EpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { + t.Parallel() + + nodesConfigEpoch0 := config.MaxNodesChangeConfig{ + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + } + nodesConfigEpoch1 := config.MaxNodesChangeConfig{ + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + } + nodesConfigEpoch6 := config.MaxNodesChangeConfig{ + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 1, + } + + allNodesConfig := []config.MaxNodesChangeConfig{ + nodesConfigEpoch0, + nodesConfigEpoch1, + nodesConfigEpoch6, + } + epochNotifier := forking.NewGenericEpochNotifier() + ncp, _ := NewNodesConfigProvider(epochNotifier, allNodesConfig) + + epochNotifier.CheckEpoch(&block.Header{Epoch: 0}) + require.Equal(t, nodesConfigEpoch0, ncp.GetCurrentNodesConfig()) + + epochNotifier.CheckEpoch(&block.Header{Epoch: 1}) + require.Equal(t, nodesConfigEpoch1, ncp.GetCurrentNodesConfig()) + + for epoch := uint32(2); epoch <= 5; epoch++ { + epochNotifier.CheckEpoch(&block.Header{Epoch: epoch}) + require.Equal(t, nodesConfigEpoch1, ncp.GetCurrentNodesConfig()) + } + + // simulate restart + epochNotifier.CheckEpoch(&block.Header{Epoch: 0}) + epochNotifier.CheckEpoch(&block.Header{Epoch: 5}) + require.Equal(t, nodesConfigEpoch1, ncp.GetCurrentNodesConfig()) + + epochNotifier.CheckEpoch(&block.Header{Epoch: 6}) + require.Equal(t, nodesConfigEpoch6, ncp.GetCurrentNodesConfig()) + + // simulate restart + epochNotifier.CheckEpoch(&block.Header{Epoch: 0}) + epochNotifier.CheckEpoch(&block.Header{Epoch: 6}) + require.Equal(t, nodesConfigEpoch6, ncp.GetCurrentNodesConfig()) + + for epoch := uint32(7); epoch <= 20; epoch++ { + epochNotifier.CheckEpoch(&block.Header{Epoch: epoch}) + require.Equal(t, nodesConfigEpoch6, ncp.GetCurrentNodesConfig()) + } + + // simulate restart + epochNotifier.CheckEpoch(&block.Header{Epoch: 1}) + epochNotifier.CheckEpoch(&block.Header{Epoch: 21}) + require.Equal(t, nodesConfigEpoch6, ncp.GetCurrentNodesConfig()) +} From 39e886d6e5aec78efb1fabb6089f4ff7b7f57106 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 17 May 2022 11:16:31 +0300 Subject: [PATCH 262/958] FEAT: Move auction selector related tests --- .../metachain/auctionListSelector_test.go | 79 +++++++++++++++-- epochStart/metachain/systemSCs_test.go | 84 ------------------- 2 files changed, 73 insertions(+), 90 deletions(-) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index ce948ae527a..5a0dd95687e 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -1,19 +1,26 @@ package metachain import ( + "errors" + "math/big" + "strings" "testing" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/common/forking" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/state" "github.com/stretchr/testify/require" ) -func createAuctionListSelectorArgs() AuctionListSelectorArgs { +func createAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) AuctionListSelectorArgs { epochNotifier := forking.NewGenericEpochNotifier() - nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, nil) + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, config) argsStakingDataProvider := createStakingDataProviderArgs() stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) @@ -31,7 +38,7 @@ func TestNewAuctionListSelector(t *testing.T) { t.Run("nil shard coordinator", func(t *testing.T) { t.Parallel() - args := createAuctionListSelectorArgs() + args := createAuctionListSelectorArgs(nil) args.ShardCoordinator = nil als, err := NewAuctionListSelector(args) require.Nil(t, als) @@ -40,7 +47,7 @@ func TestNewAuctionListSelector(t *testing.T) { t.Run("nil staking data provider", func(t *testing.T) { t.Parallel() - args := createAuctionListSelectorArgs() + args := createAuctionListSelectorArgs(nil) args.StakingDataProvider = nil als, err := NewAuctionListSelector(args) require.Nil(t, als) @@ -49,7 +56,7 @@ func TestNewAuctionListSelector(t *testing.T) { t.Run("nil max nodes change config provider", func(t *testing.T) { t.Parallel() - args := createAuctionListSelectorArgs() + args := createAuctionListSelectorArgs(nil) args.MaxNodesChangeConfigProvider = nil als, err := NewAuctionListSelector(args) require.Nil(t, als) @@ -58,9 +65,69 @@ func TestNewAuctionListSelector(t *testing.T) { t.Run("should work", func(t *testing.T) { t.Parallel() - args := createAuctionListSelectorArgs() + args := createAuctionListSelectorArgs(nil) als, err := NewAuctionListSelector(args) require.NotNil(t, als) require.Nil(t, err) }) } + +func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionNodes(t *testing.T) { + t.Parallel() + + args := createAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) + als, _ := NewAuctionListSelector(args) + + owner1 := []byte("owner1") + owner2 := []byte("owner2") + + owner1StakedKeys := [][]byte{[]byte("pubKey0")} + owner2StakedKeys := [][]byte{[]byte("pubKey1")} + + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) + require.Nil(t, err) + + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) +} + +func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingAuctionList(t *testing.T) { + t.Parallel() + + args := createAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 10}}) + + errGetNodeTopUp := errors.New("error getting top up per node") + args.StakingDataProvider = &mock.StakingDataProviderStub{ + GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { + switch string(blsKey) { + case "pubKey0", "pubKey1": + return nil, errGetNodeTopUp + default: + require.Fail(t, "should not call this func with other params") + return nil, nil + } + }, + } + als, _ := NewAuctionListSelector(args) + + owner := []byte("owner") + ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} + + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) + + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) + require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) +} diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 630aa10e840..43252378f9a 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -8,7 +8,6 @@ import ( "math" "math/big" "os" - "strings" "testing" arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" @@ -1796,89 +1795,6 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa require.Equal(t, errProcessStakingData, err) } -func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingAuctionList(t *testing.T) { - t.Parallel() - - args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - - errGetNodeTopUp := errors.New("error getting top up per node") - nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) - argsAuctionListSelector := AuctionListSelectorArgs{ - ShardCoordinator: args.ShardCoordinator, - StakingDataProvider: &mock.StakingDataProviderStub{ - GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - switch string(blsKey) { - case "pubKey0", "pubKey1": - return nil, errGetNodeTopUp - default: - require.Fail(t, "should not call this func with other params") - return nil, nil - } - }, - }, - MaxNodesChangeConfigProvider: nodesConfigProvider, - } - als, _ := NewAuctionListSelector(argsAuctionListSelector) - args.AuctionListSelector = als - - owner := []byte("owner") - ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) - - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) - _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) - - s, _ := NewSystemSCProcessor(args) - args.EpochNotifier.CheckEpoch(&block.Header{Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch}) - - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("rnd")}) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) - require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) -} - -func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4NotEnoughSlotsForAuctionNodes(t *testing.T) { - t.Parallel() - - args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, nil) - argsAuctionListSelector := AuctionListSelectorArgs{ - ShardCoordinator: args.ShardCoordinator, - StakingDataProvider: args.StakingDataProvider, - MaxNodesChangeConfigProvider: nodesConfigProvider, - } - als, _ := NewAuctionListSelector(argsAuctionListSelector) - args.AuctionListSelector = als - - owner1 := []byte("owner1") - owner2 := []byte("owner2") - - owner1StakedKeys := [][]byte{[]byte("pubKey0")} - owner2StakedKeys := [][]byte{[]byte("pubKey1")} - - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(2000), args.Marshalizer) - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(2000), args.Marshalizer) - - validatorsInfo := state.NewShardValidatorsInfoMap() - - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) - - s, _ := NewSystemSCProcessor(args) - s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("rnd")}) - require.Nil(t, err) - - expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ - 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), - createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0), - }, - } - require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) -} - func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() From 238733eab157e166ba50a79a793c66a8335b71ea Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 17 May 2022 11:20:10 +0300 Subject: [PATCH 263/958] FIX: Add comm --- epochStart/notifier/nodesConfigProvider.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/epochStart/notifier/nodesConfigProvider.go b/epochStart/notifier/nodesConfigProvider.go index 0766400ce95..d9019f56b68 100644 --- a/epochStart/notifier/nodesConfigProvider.go +++ b/epochStart/notifier/nodesConfigProvider.go @@ -45,6 +45,7 @@ func (ncp *nodesConfigProvider) sortConfigs() { }) } +// GetAllNodesConfig returns all config.MaxNodesChangeConfig func (ncp *nodesConfigProvider) GetAllNodesConfig() []config.MaxNodesChangeConfig { ncp.mutex.Lock() defer ncp.mutex.Unlock() @@ -52,6 +53,7 @@ func (ncp *nodesConfigProvider) GetAllNodesConfig() []config.MaxNodesChangeConfi return ncp.allNodesConfigs } +// GetCurrentNodesConfig returns the current config.MaxNodesChangeConfig, based on epoch func (ncp *nodesConfigProvider) GetCurrentNodesConfig() config.MaxNodesChangeConfig { ncp.mutex.Lock() defer ncp.mutex.Unlock() From 8b4d1b8c6664b3528711ff1c2c75e6591624a33b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 17 May 2022 13:45:12 +0300 Subject: [PATCH 264/958] FEAT: First ugly version --- epochStart/interface.go | 1 + epochStart/metachain/auctionListSelector.go | 58 +++++++++++++++++++++ epochStart/metachain/stakingDataProvider.go | 15 ++++++ epochStart/mock/stakingDataProviderStub.go | 4 ++ 4 files changed, 78 insertions(+) diff --git a/epochStart/interface.go b/epochStart/interface.go index 887b51986ef..689bb58df9d 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -151,6 +151,7 @@ type StakingDataProvider interface { GetTotalStakeEligibleNodes() *big.Int GetTotalTopUpStakeEligibleNodes() *big.Int GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) + GetNumStakedNodes(blsKey []byte) (int64, error) PrepareStakingData(keys map[uint32][][]byte) error FillValidatorInfo(blsKey []byte) error ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 5077c231e3b..339ddb0cd48 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -3,6 +3,7 @@ package metachain import ( "bytes" "encoding/hex" + "errors" "fmt" "math/big" "sort" @@ -141,6 +142,63 @@ func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInf return auctionList, numOfValidators } +func (als *auctionListSelector) getMinRequiredTopUp(auctionList []state.ValidatorInfoHandler) (*big.Int, error) { + validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) + if err != nil { + return nil, fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) + } + + maxTopUp := big.NewInt(1000000) // todo: extract to const + step := big.NewInt(10) // egld + + for topUp := big.NewInt(0.1); topUp.Cmp(maxTopUp) >= 0; topUp = topUp.Add(topUp, step) { + numNodesQualifyingForTopUp := int64(0) + for _, validator := range auctionList { + tmp := big.NewInt(0).Set(topUp) + validatorStakedNodes, err := als.stakingDataProvider.GetNumStakedNodes(validator.GetPublicKey()) + if err != nil { + return nil, err + } + + tmp = tmp.Mul(tmp, big.NewInt(validatorStakedNodes)) + validatorTotalTopUp := validatorTopUpMap[string(validator.GetPublicKey())] + validatorTopUpForAuction := validatorTotalTopUp.Sub(validatorTotalTopUp, tmp) + + if validatorTopUpForAuction.Cmp(topUp) == -1 { + continue + } + + qualifiedNodes := big.NewInt(0) + qualifiedNodes = qualifiedNodes.Div(validatorTopUpForAuction, topUp) + + if qualifiedNodes.Int64() > validatorStakedNodes { + numNodesQualifyingForTopUp += als.getNumNodesInAuction(validator.GetPublicKey()) + } else { + numNodesQualifyingForTopUp += qualifiedNodes.Int64() + } + + } + + if numNodesQualifyingForTopUp < int64(als.nodesConfigProvider.GetCurrentNodesConfig().MaxNumNodes) { + return topUp.Sub(topUp, step), nil + } + } + + return nil, errors.New("COULD NOT FIND TOPUP") +} + +func (als *auctionListSelector) sortAuctionListV2(auctionList []state.ValidatorInfoHandler, randomness []byte) error { + if len(auctionList) == 0 { + return nil + } + + return nil +} + +func (als *auctionListSelector) getNumNodesInAuction(blsKey []byte) int64 { + return 1 +} + func (als *auctionListSelector) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { if len(auctionList) == 0 { return nil diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 952381aecdd..5361ab1bd85 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -120,6 +120,21 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return ownerInfo.topUpPerNode, nil } +func (sdp *stakingDataProvider) GetNumStakedNodes(blsKey []byte) (int64, error) { + owner, err := sdp.GetBlsKeyOwner(blsKey) + if err != nil { + log.Debug("GetOwnerStakingStats", "key", hex.EncodeToString(blsKey), "error", err) + return 0, err + } + + ownerInfo, ok := sdp.cache[owner] + if !ok { + return 0, epochStart.ErrOwnerDoesntHaveEligibleNodesInEpoch + } + + return ownerInfo.numStakedNodes, nil +} + // PrepareStakingData prepares the staking data for the given map of node keys per shard func (sdp *stakingDataProvider) PrepareStakingData(keys map[uint32][][]byte) error { sdp.Clean() diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 52519110336..a0ebc3e6b7a 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -57,6 +57,10 @@ func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int return big.NewInt(0), nil } +func (sdps *StakingDataProviderStub) GetNumStakedNodes([]byte) (int64, error) { + return 0, nil +} + // PrepareStakingData - func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte) error { if sdps.PrepareStakingDataCalled != nil { From 2f9c1c890ee94687dc9e34b0fc276a676d4fbb17 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 17 May 2022 15:22:37 +0300 Subject: [PATCH 265/958] FEAT: First ugly working version --- epochStart/metachain/auctionListSelector.go | 123 +++++++++++++++----- 1 file changed, 94 insertions(+), 29 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 339ddb0cd48..77c9d118f2f 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -11,7 +11,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/display" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" @@ -97,18 +96,18 @@ func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap sta fmt.Sprintf("available slots (%v -%v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - err = als.sortAuctionList(auctionList, randomness) + numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) + selectedNodesFromAuction, err := als.sortAuctionListV2(auctionList, numOfAvailableNodeSlots, randomness) if err != nil { return err } - numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) - als.displayAuctionList(auctionList, numOfAvailableNodeSlots) + als.displayAuctionList(selectedNodesFromAuction, numOfAvailableNodeSlots) for i := uint32(0); i < numOfAvailableNodeSlots; i++ { - newNode := auctionList[i] + newNode := selectedNodesFromAuction[i] newNode.SetList(string(common.SelectedFromAuctionList)) - err = validatorsInfoMap.Replace(auctionList[i], newNode) + err = validatorsInfoMap.Replace(selectedNodesFromAuction[i], newNode) if err != nil { return err } @@ -142,29 +141,35 @@ func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInf return auctionList, numOfValidators } -func (als *auctionListSelector) getMinRequiredTopUp(auctionList []state.ValidatorInfoHandler) (*big.Int, error) { +func (als *auctionListSelector) getMinRequiredTopUp(auctionList []state.ValidatorInfoHandler, auctionListSize uint32) (*big.Int, error) { validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) if err != nil { return nil, fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) } + validatorAuctionNodesMap, err := als.getValidatorNumAuctionNodesMap(auctionList) + if err != nil { + return nil, fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) + } + minTopUp := big.NewInt(1) maxTopUp := big.NewInt(1000000) // todo: extract to const - step := big.NewInt(10) // egld + step := big.NewInt(10) + + for topUp := minTopUp; topUp.Cmp(maxTopUp) < 0; topUp = topUp.Add(topUp, step) { - for topUp := big.NewInt(0.1); topUp.Cmp(maxTopUp) >= 0; topUp = topUp.Add(topUp, step) { numNodesQualifyingForTopUp := int64(0) - for _, validator := range auctionList { - tmp := big.NewInt(0).Set(topUp) + for _, validator := range auctionList { // possible improvement: if we find a validator with not enough topUp, ignore any oncoming nodes from that owner validatorStakedNodes, err := als.stakingDataProvider.GetNumStakedNodes(validator.GetPublicKey()) if err != nil { return nil, err } - tmp = tmp.Mul(tmp, big.NewInt(validatorStakedNodes)) - validatorTotalTopUp := validatorTopUpMap[string(validator.GetPublicKey())] - validatorTopUpForAuction := validatorTotalTopUp.Sub(validatorTotalTopUp, tmp) + minQualifiedTopUpForAuction := big.NewInt(0) + minQualifiedTopUpForAuction = minQualifiedTopUpForAuction.Mul(topUp, big.NewInt(validatorStakedNodes)) + validatorTotalTopUp := big.NewInt(0).SetBytes(validatorTopUpMap[string(validator.GetPublicKey())].Bytes()) - if validatorTopUpForAuction.Cmp(topUp) == -1 { + validatorTopUpForAuction := validatorTotalTopUp.Sub(validatorTotalTopUp, minQualifiedTopUpForAuction) + if validatorTopUpForAuction.Cmp(topUp) < 0 { continue } @@ -172,31 +177,91 @@ func (als *auctionListSelector) getMinRequiredTopUp(auctionList []state.Validato qualifiedNodes = qualifiedNodes.Div(validatorTopUpForAuction, topUp) if qualifiedNodes.Int64() > validatorStakedNodes { - numNodesQualifyingForTopUp += als.getNumNodesInAuction(validator.GetPublicKey()) + numNodesQualifyingForTopUp += validatorAuctionNodesMap[string(validator.GetPublicKey())] } else { numNodesQualifyingForTopUp += qualifiedNodes.Int64() } - } - if numNodesQualifyingForTopUp < int64(als.nodesConfigProvider.GetCurrentNodesConfig().MaxNumNodes) { - return topUp.Sub(topUp, step), nil + if numNodesQualifyingForTopUp < int64(auctionListSize) { + if topUp.Cmp(minTopUp) == 0 { + return big.NewInt(0), nil + } else { + return topUp.Sub(topUp, step), nil + } } } return nil, errors.New("COULD NOT FIND TOPUP") } -func (als *auctionListSelector) sortAuctionListV2(auctionList []state.ValidatorInfoHandler, randomness []byte) error { +func (als *auctionListSelector) sortAuctionListV2(auctionList []state.ValidatorInfoHandler, auctionListSize uint32, randomness []byte) ([]state.ValidatorInfoHandler, error) { if len(auctionList) == 0 { - return nil + return nil, nil } - return nil + minTopUp, err := als.getMinRequiredTopUp(auctionList, auctionListSize) + if err != nil { + return nil, err + } + + validatorTopUpMap, _ := als.getValidatorTopUpMap(auctionList) + qualifiedValidators := make([]state.ValidatorInfoHandler, 0) + + for _, validator := range auctionList { + if validatorTopUpMap[string(validator.GetPublicKey())].Cmp(minTopUp) >= 0 { + qualifiedValidators = append(qualifiedValidators, validator) + } + } + + als.sortValidators(qualifiedValidators, validatorTopUpMap, randomness) + return qualifiedValidators, nil } -func (als *auctionListSelector) getNumNodesInAuction(blsKey []byte) int64 { - return 1 +func (als *auctionListSelector) getValidatorNumAuctionNodesMap(auctionList []state.ValidatorInfoHandler) (map[string]int64, error) { + ret := make(map[string]int64) + ownerAuctionNodesMap := make(map[string][][]byte) + + for _, validator := range auctionList { + owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) + if err != nil { + return nil, err + } + + ownerAuctionNodesMap[owner] = append(ownerAuctionNodesMap[owner], validator.GetPublicKey()) + } + + for _, auctionNodes := range ownerAuctionNodesMap { + for _, auctionNode := range auctionNodes { + ret[string(auctionNode)] = int64(len(auctionNodes)) + } + + } + + return ret, nil +} + +func (als *auctionListSelector) sortValidators( + auctionList []state.ValidatorInfoHandler, + validatorTopUpMap map[string]*big.Int, + randomness []byte, +) { + pubKeyLen := len(auctionList[0].GetPublicKey()) + normRandomness := calcNormRand(randomness, pubKeyLen) + sort.SliceStable(auctionList, func(i, j int) bool { + pubKey1 := auctionList[i].GetPublicKey() + pubKey2 := auctionList[j].GetPublicKey() + + nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] + nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] + + if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { + return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) + } + + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 + }) + } func (als *auctionListSelector) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { @@ -238,7 +303,7 @@ func (als *auctionListSelector) getValidatorTopUpMap(validators []state.Validato return nil, fmt.Errorf("%w when trying to get top up per node for %s", err, hex.EncodeToString(pubKey)) } - ret[string(pubKey)] = topUp + ret[string(pubKey)] = big.NewInt(0).SetBytes(topUp.Bytes()) } return ret, nil @@ -272,9 +337,9 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { } func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - if log.GetLevel() > logger.LogDebug { - return - } + //if log.GetLevel() > logger.LogDebug { + // return + //} tableHeader := []string{"Owner", "Registered key", "TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) @@ -304,7 +369,7 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator } message := fmt.Sprintf("Auction list\n%s", table) - log.Debug(message) + log.Info(message) } // IsInterfaceNil checks if the underlying pointer is nil From e7f6b9c546c8771a52de69d34e0fb1edc5054955 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 19 May 2022 10:54:51 +0300 Subject: [PATCH 266/958] FEAT: Intermediary code --- epochStart/interface.go | 4 +- epochStart/metachain/auctionListSelector.go | 210 ++++++++++++-------- epochStart/metachain/stakingDataProvider.go | 58 +++++- epochStart/metachain/systemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 18 +- epochStart/mock/stakingDataProviderStub.go | 8 + 6 files changed, 203 insertions(+), 97 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index 689bb58df9d..e98b6cf0e0d 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -151,8 +151,10 @@ type StakingDataProvider interface { GetTotalStakeEligibleNodes() *big.Int GetTotalTopUpStakeEligibleNodes() *big.Int GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) - GetNumStakedNodes(blsKey []byte) (int64, error) + GetNumStakedNodes(owner []byte) (int64, error) + GetTotalTopUp(owner []byte) (*big.Int, error) PrepareStakingData(keys map[uint32][][]byte) error + PrepareStakingDataForStakingV4(validatorsMap state.ShardValidatorsInfoMapHandler) error FillValidatorInfo(blsKey []byte) error ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 77c9d118f2f..3d85b54ea53 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -97,22 +97,12 @@ func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap sta ) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) - selectedNodesFromAuction, err := als.sortAuctionListV2(auctionList, numOfAvailableNodeSlots, randomness) + err = als.sortAuctionList(auctionList, numOfAvailableNodeSlots, validatorsInfoMap, randomness) if err != nil { return err } - als.displayAuctionList(selectedNodesFromAuction, numOfAvailableNodeSlots) - - for i := uint32(0); i < numOfAvailableNodeSlots; i++ { - newNode := selectedNodesFromAuction[i] - newNode.SetList(string(common.SelectedFromAuctionList)) - err = validatorsInfoMap.Replace(selectedNodesFromAuction[i], newNode) - if err != nil { - return err - } - } - + als.displayAuctionList(auctionList, numOfAvailableNodeSlots) return nil } @@ -141,81 +131,166 @@ func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInf return auctionList, numOfValidators } -func (als *auctionListSelector) getMinRequiredTopUp(auctionList []state.ValidatorInfoHandler, auctionListSize uint32) (*big.Int, error) { - validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) - if err != nil { - return nil, fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) +type ownerData struct { + activeNodes int64 + auctionNodes int64 + stakedNodes int64 + totalTopUp *big.Int + topUpPerNode *big.Int +} + +func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoHandler) (map[string]*ownerData, error) { + ownersData := make(map[string]*ownerData) + + for _, node := range auctionList { + owner, err := als.stakingDataProvider.GetBlsKeyOwner(node.GetPublicKey()) + if err != nil { + return nil, err + } + + stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes([]byte(owner)) + if err != nil { + return nil, err + } + + totalTopUp, err := als.stakingDataProvider.GetTotalTopUp([]byte(owner)) + if err != nil { + return nil, err + } + + //topUpPerNode, err := als.stakingDataProvider.GetNodeStakedTopUp(node.GetPublicKey()) + //if err != nil { + // return nil, err + //} + + data, exists := ownersData[owner] + if exists { + data.auctionNodes++ + data.activeNodes-- + } else { + ownersData[owner] = &ownerData{ + auctionNodes: 1, + activeNodes: stakedNodes - 1, + stakedNodes: stakedNodes, + totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), + topUpPerNode: big.NewInt(0).Div(totalTopUp, big.NewInt(stakedNodes)), + } + } + } + + return ownersData, nil +} + +func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { + ret := make(map[string]*ownerData) + for owner, data := range ownersData { + ret[owner] = &ownerData{ + activeNodes: data.activeNodes, + auctionNodes: data.auctionNodes, + stakedNodes: data.stakedNodes, + totalTopUp: data.totalTopUp, + topUpPerNode: data.topUpPerNode, + } } - validatorAuctionNodesMap, err := als.getValidatorNumAuctionNodesMap(auctionList) + + return ret +} + +func (als *auctionListSelector) getMinRequiredTopUp( + auctionList []state.ValidatorInfoHandler, + validatorTopUpMap map[string]*big.Int, + numAvailableSlots uint32, +) (*big.Int, error) { + ownersData, err := als.getOwnersData(auctionList) if err != nil { - return nil, fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) + return nil, err } - minTopUp := big.NewInt(1) - maxTopUp := big.NewInt(1000000) // todo: extract to const - step := big.NewInt(10) + minTopUp := big.NewInt(1) // pornim de la topup cel mai slab din lista initiala + maxTopUp := big.NewInt(1000000) // todo: extract to const // max top up from auction list + step := big.NewInt(100) - for topUp := minTopUp; topUp.Cmp(maxTopUp) < 0; topUp = topUp.Add(topUp, step) { + previousConfig := copyOwnersData(ownersData) - numNodesQualifyingForTopUp := int64(0) - for _, validator := range auctionList { // possible improvement: if we find a validator with not enough topUp, ignore any oncoming nodes from that owner - validatorStakedNodes, err := als.stakingDataProvider.GetNumStakedNodes(validator.GetPublicKey()) - if err != nil { - return nil, err - } + fmt.Println("current config: ", previousConfig) + for topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()); topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { - minQualifiedTopUpForAuction := big.NewInt(0) - minQualifiedTopUpForAuction = minQualifiedTopUpForAuction.Mul(topUp, big.NewInt(validatorStakedNodes)) - validatorTotalTopUp := big.NewInt(0).SetBytes(validatorTopUpMap[string(validator.GetPublicKey())].Bytes()) + numNodesQualifyingForTopUp := int64(0) + previousConfig = copyOwnersData(ownersData) + for ownerPubKey, owner := range ownersData { + validatorActiveNodes := owner.activeNodes - validatorTopUpForAuction := validatorTotalTopUp.Sub(validatorTotalTopUp, minQualifiedTopUpForAuction) + minQualifiedTopUpForAuction := big.NewInt(0).Mul(topUp, big.NewInt(validatorActiveNodes)) + validatorTopUpForAuction := big.NewInt(0).Sub(owner.totalTopUp, minQualifiedTopUpForAuction) if validatorTopUpForAuction.Cmp(topUp) < 0 { + delete(ownersData, ownerPubKey) continue } - qualifiedNodes := big.NewInt(0) - qualifiedNodes = qualifiedNodes.Div(validatorTopUpForAuction, topUp) - - if qualifiedNodes.Int64() > validatorStakedNodes { - numNodesQualifyingForTopUp += validatorAuctionNodesMap[string(validator.GetPublicKey())] + qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp) + if qualifiedNodes.Int64() > owner.auctionNodes { + numNodesQualifyingForTopUp += owner.auctionNodes } else { + numNodesQualifyingForTopUp += qualifiedNodes.Int64() + //removedNodesFromAuction := owner.auctionNodes - qualifiedNodes.Int64() + owner.auctionNodes = qualifiedNodes.Int64() + + //gainedTopUpFromRemovedNodes := big.NewInt(0).Mul(owner.topUpPerNode, big.NewInt(removedNodesFromAuction)) + //owner.totalTopUp = big.NewInt(0).Add(owner.totalTopUp, gainedTopUpFromRemovedNodes) + owner.topUpPerNode = big.NewInt(0).Div(owner.totalTopUp, big.NewInt(owner.activeNodes+owner.auctionNodes)) + } } - if numNodesQualifyingForTopUp < int64(auctionListSize) { + if numNodesQualifyingForTopUp < int64(numAvailableSlots) { + fmt.Println("last config", previousConfig) if topUp.Cmp(minTopUp) == 0 { return big.NewInt(0), nil } else { return topUp.Sub(topUp, step), nil } } - } + } + _ = previousConfig return nil, errors.New("COULD NOT FIND TOPUP") } -func (als *auctionListSelector) sortAuctionListV2(auctionList []state.ValidatorInfoHandler, auctionListSize uint32, randomness []byte) ([]state.ValidatorInfoHandler, error) { +func (als *auctionListSelector) sortAuctionList( + auctionList []state.ValidatorInfoHandler, + numOfAvailableNodeSlots uint32, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + randomness []byte, +) error { if len(auctionList) == 0 { - return nil, nil + return nil } - minTopUp, err := als.getMinRequiredTopUp(auctionList, auctionListSize) + validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) if err != nil { - return nil, err + return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) } - validatorTopUpMap, _ := als.getValidatorTopUpMap(auctionList) - qualifiedValidators := make([]state.ValidatorInfoHandler, 0) + minTopUp, err := als.getMinRequiredTopUp(auctionList, validatorTopUpMap, numOfAvailableNodeSlots) + if err != nil { + return err + } - for _, validator := range auctionList { - if validatorTopUpMap[string(validator.GetPublicKey())].Cmp(minTopUp) >= 0 { - qualifiedValidators = append(qualifiedValidators, validator) + als.sortValidators(auctionList, validatorTopUpMap, randomness) + + for i, validator := range auctionList { + if validatorTopUpMap[string(validator.GetPublicKey())].Cmp(minTopUp) >= 0 && i < int(numOfAvailableNodeSlots) { + newNode := validator + newNode.SetList(string(common.SelectedFromAuctionList)) + err = validatorsInfoMap.Replace(validator, newNode) + if err != nil { + return err + } } - } - als.sortValidators(qualifiedValidators, validatorTopUpMap, randomness) - return qualifiedValidators, nil + } + return nil } func (als *auctionListSelector) getValidatorNumAuctionNodesMap(auctionList []state.ValidatorInfoHandler) (map[string]int64, error) { @@ -264,35 +339,6 @@ func (als *auctionListSelector) sortValidators( } -func (als *auctionListSelector) sortAuctionList(auctionList []state.ValidatorInfoHandler, randomness []byte) error { - if len(auctionList) == 0 { - return nil - } - - validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) - if err != nil { - return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) - } - - pubKeyLen := len(auctionList[0].GetPublicKey()) - normRandomness := calcNormRand(randomness, pubKeyLen) - sort.SliceStable(auctionList, func(i, j int) bool { - pubKey1 := auctionList[i].GetPublicKey() - pubKey2 := auctionList[j].GetPublicKey() - - nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] - nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] - - if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { - return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) - } - - return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 - }) - - return nil -} - func (als *auctionListSelector) getValidatorTopUpMap(validators []state.ValidatorInfoHandler) (map[string]*big.Int, error) { ret := make(map[string]*big.Int, len(validators)) @@ -355,8 +401,8 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator horizontalLine = uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(pubKey), + (owner), + string(pubKey), topUp.String(), }) lines = append(lines, line) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 5361ab1bd85..4e220f618ea 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -10,6 +10,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/common/validatorInfo" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/state" @@ -20,6 +21,7 @@ import ( type ownerStats struct { numEligible int numStakedNodes int64 + numAuctionNodes int64 topUpValue *big.Int totalStaked *big.Int eligibleBaseStake *big.Int @@ -120,14 +122,8 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return ownerInfo.topUpPerNode, nil } -func (sdp *stakingDataProvider) GetNumStakedNodes(blsKey []byte) (int64, error) { - owner, err := sdp.GetBlsKeyOwner(blsKey) - if err != nil { - log.Debug("GetOwnerStakingStats", "key", hex.EncodeToString(blsKey), "error", err) - return 0, err - } - - ownerInfo, ok := sdp.cache[owner] +func (sdp *stakingDataProvider) GetNumStakedNodes(owner []byte) (int64, error) { + ownerInfo, ok := sdp.cache[string(owner)] if !ok { return 0, epochStart.ErrOwnerDoesntHaveEligibleNodesInEpoch } @@ -135,6 +131,15 @@ func (sdp *stakingDataProvider) GetNumStakedNodes(blsKey []byte) (int64, error) return ownerInfo.numStakedNodes, nil } +func (sdp *stakingDataProvider) GetTotalTopUp(owner []byte) (*big.Int, error) { + ownerInfo, ok := sdp.cache[string(owner)] + if !ok { + return nil, epochStart.ErrOwnerDoesntHaveEligibleNodesInEpoch + } + + return ownerInfo.topUpValue, nil +} + // PrepareStakingData prepares the staking data for the given map of node keys per shard func (sdp *stakingDataProvider) PrepareStakingData(keys map[uint32][][]byte) error { sdp.Clean() @@ -153,6 +158,21 @@ func (sdp *stakingDataProvider) PrepareStakingData(keys map[uint32][][]byte) err return nil } +func (sdp *stakingDataProvider) PrepareStakingDataForStakingV4(validatorsMap state.ShardValidatorsInfoMapHandler) error { + sdp.Clean() + + for _, validator := range validatorsMap.GetAllValidatorsInfo() { + err := sdp.loadDataForValidatorWithStakingV4(validator) + if err != nil { + return err + } + } + + sdp.processStakingData() + + return nil +} + func (sdp *stakingDataProvider) processStakingData() { totalEligibleStake := big.NewInt(0) totalEligibleTopUpStake := big.NewInt(0) @@ -208,6 +228,28 @@ func (sdp *stakingDataProvider) getAndFillOwnerStatsFromSC(blsKey []byte) (*owne return ownerData, nil } +// loadDataForBlsKey will be called for each BLS key that took part in the consensus (no matter the shard ID) so the +// staking data can be recovered from the staking system smart contracts. +// The function will error if something went wrong. It does change the inner state of the called instance. +func (sdp *stakingDataProvider) loadDataForValidatorWithStakingV4(validator state.ValidatorInfoHandler) error { + sdp.mutStakingData.Lock() + defer sdp.mutStakingData.Unlock() + + ownerData, err := sdp.getAndFillOwnerStatsFromSC(validator.GetPublicKey()) + if err != nil { + log.Debug("error computing rewards for bls key", "step", "get owner data", "key", hex.EncodeToString(validator.GetPublicKey()), "error", err) + return err + } + + if validatorInfo.WasEligibleInCurrentEpoch(validator) { + ownerData.numEligible++ + } else if validator.GetList() == string(common.AuctionList) { + ownerData.numAuctionNodes++ + } + + return nil +} + // loadDataForBlsKey will be called for each BLS key that took part in the consensus (no matter the shard ID) so the // staking data can be recovered from the staking system smart contracts. // The function will error if something went wrong. It does change the inner state of the called instance. diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 0f88ebbe16c..d51db47a961 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -131,7 +131,7 @@ func (s *systemSCProcessor) processWithNewFlags( } if s.flagStakingV4Enabled.IsSet() { - err := s.prepareStakingDataForAllNodes(validatorsInfoMap) + err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) // s.stakingDataProvider.PrepareStakingDataForStakingV4(validatorsInfoMap) if err != nil { return err } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 43252378f9a..80fade0730f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1812,16 +1812,19 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner2 := []byte("owner2") owner3 := []byte("owner3") owner4 := []byte("owner4") + owner5 := []byte("owner5") owner1StakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")} owner2StakedKeys := [][]byte{[]byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5")} owner3StakedKeys := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} - owner4StakedKeys := [][]byte{[]byte("pubKey8"), []byte("pubKey9")} + owner4StakedKeys := [][]byte{[]byte("pubKey8"), []byte("pubKey9"), []byte("pubKe10"), []byte("pubKe11")} + owner5StakedKeys := [][]byte{[]byte("pubKe12"), []byte("pubKe13")} - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6000), args.Marshalizer) - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(3000), args.Marshalizer) - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(2000), args.Marshalizer) - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(3000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6666), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(5555), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(4444), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(6666), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner5, owner5, owner5StakedKeys, big.NewInt(1000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) @@ -1837,6 +1840,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[2], common.AuctionList, owner4, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[3], common.AuctionList, owner4, 1)) + + _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[0], common.EligibleList, owner5, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[1], common.AuctionList, owner5, 1)) s, _ := NewSystemSCProcessor(args) args.EpochNotifier.CheckEpoch(&block.Header{Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch}) diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index a0ebc3e6b7a..601e5fbc71f 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -61,6 +61,10 @@ func (sdps *StakingDataProviderStub) GetNumStakedNodes([]byte) (int64, error) { return 0, nil } +func (sdps *StakingDataProviderStub) GetTotalTopUp([]byte) (*big.Int, error) { + return big.NewInt(0), nil +} + // PrepareStakingData - func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte) error { if sdps.PrepareStakingDataCalled != nil { @@ -69,6 +73,10 @@ func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte return nil } +func (sdps *StakingDataProviderStub) PrepareStakingDataForStakingV4(state.ShardValidatorsInfoMapHandler) error { + return nil +} + // Clean - func (sdps *StakingDataProviderStub) Clean() { if sdps.CleanCalled != nil { From 0ab80fcbb5a4ccd77c6f86e06203f68c181b5370 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 19 May 2022 14:04:43 +0300 Subject: [PATCH 267/958] FEAT: Stable code --- epochStart/metachain/auctionListSelector.go | 91 ++++++++++++++++----- epochStart/metachain/systemSCs_test.go | 35 +++++--- 2 files changed, 95 insertions(+), 31 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 3d85b54ea53..74de0aae73b 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -137,6 +137,7 @@ type ownerData struct { stakedNodes int64 totalTopUp *big.Int topUpPerNode *big.Int + auctionList []state.ValidatorInfoHandler } func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoHandler) (map[string]*ownerData, error) { @@ -167,6 +168,7 @@ func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoH if exists { data.auctionNodes++ data.activeNodes-- + data.auctionList = append(data.auctionList, node) } else { ownersData[owner] = &ownerData{ auctionNodes: 1, @@ -174,6 +176,7 @@ func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoH stakedNodes: stakedNodes, totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), topUpPerNode: big.NewInt(0).Div(totalTopUp, big.NewInt(stakedNodes)), + auctionList: []state.ValidatorInfoHandler{node}, } } } @@ -190,7 +193,9 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { stakedNodes: data.stakedNodes, totalTopUp: data.totalTopUp, topUpPerNode: data.topUpPerNode, + auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), } + copy(ret[owner].auctionList, data.auctionList) } return ret @@ -200,10 +205,11 @@ func (als *auctionListSelector) getMinRequiredTopUp( auctionList []state.ValidatorInfoHandler, validatorTopUpMap map[string]*big.Int, numAvailableSlots uint32, -) (*big.Int, error) { + randomness []byte, +) ([]state.ValidatorInfoHandler, *big.Int, error) { ownersData, err := als.getOwnersData(auctionList) if err != nil { - return nil, err + return nil, nil, err } minTopUp := big.NewInt(1) // pornim de la topup cel mai slab din lista initiala @@ -233,28 +239,60 @@ func (als *auctionListSelector) getMinRequiredTopUp( } else { numNodesQualifyingForTopUp += qualifiedNodes.Int64() - //removedNodesFromAuction := owner.auctionNodes - qualifiedNodes.Int64() - owner.auctionNodes = qualifiedNodes.Int64() - //gainedTopUpFromRemovedNodes := big.NewInt(0).Mul(owner.topUpPerNode, big.NewInt(removedNodesFromAuction)) - //owner.totalTopUp = big.NewInt(0).Add(owner.totalTopUp, gainedTopUpFromRemovedNodes) + owner.auctionNodes = qualifiedNodes.Int64() owner.topUpPerNode = big.NewInt(0).Div(owner.totalTopUp, big.NewInt(owner.activeNodes+owner.auctionNodes)) } } if numNodesQualifyingForTopUp < int64(numAvailableSlots) { - fmt.Println("last config", previousConfig) + + selectedNodes := als.selectNodes(previousConfig, numAvailableSlots, randomness) + if topUp.Cmp(minTopUp) == 0 { - return big.NewInt(0), nil + return selectedNodes, big.NewInt(0), nil } else { - return topUp.Sub(topUp, step), nil + return selectedNodes, topUp.Sub(topUp, step), nil } } } _ = previousConfig - return nil, errors.New("COULD NOT FIND TOPUP") + return nil, nil, errors.New("COULD NOT FIND TOPUP") +} + +func (als *auctionListSelector) selectNodes(ownersData map[string]*ownerData, numAvailableSlots uint32, randomness []byte) []state.ValidatorInfoHandler { + selectedFromAuction := make([]state.ValidatorInfoHandler, 0) + validatorTopUpMap := make(map[string]*big.Int) + + for _, owner := range ownersData { + sortListByXORWithRand(owner.auctionList, randomness) + for i := int64(0); i < owner.auctionNodes; i++ { + currNode := owner.auctionList[i] + validatorTopUpMap[string(currNode.GetPublicKey())] = big.NewInt(0).SetBytes(owner.topUpPerNode.Bytes()) + } + + selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.auctionNodes]...) + } + + als.sortValidators(selectedFromAuction, validatorTopUpMap, randomness) + + selectedFromAuction = selectedFromAuction[:numAvailableSlots] + + return selectedFromAuction +} + +func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) { + pubKeyLen := len(list[0].GetPublicKey()) + normRandomness := calcNormRand(randomness, pubKeyLen) + + sort.SliceStable(list, func(i, j int) bool { + pubKey1 := list[i].GetPublicKey() + pubKey2 := list[j].GetPublicKey() + + return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) + }) } func (als *auctionListSelector) sortAuctionList( @@ -272,24 +310,35 @@ func (als *auctionListSelector) sortAuctionList( return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) } - minTopUp, err := als.getMinRequiredTopUp(auctionList, validatorTopUpMap, numOfAvailableNodeSlots) + selectedNodes, minTopUp, err := als.getMinRequiredTopUp(auctionList, validatorTopUpMap, numOfAvailableNodeSlots, randomness) if err != nil { return err } - als.sortValidators(auctionList, validatorTopUpMap, randomness) - - for i, validator := range auctionList { - if validatorTopUpMap[string(validator.GetPublicKey())].Cmp(minTopUp) >= 0 && i < int(numOfAvailableNodeSlots) { - newNode := validator - newNode.SetList(string(common.SelectedFromAuctionList)) - err = validatorsInfoMap.Replace(validator, newNode) - if err != nil { - return err + //als.sortValidators(auctionList, validatorTopUpMap, randomness) + /* + for i, validator := range auctionList { + if validatorTopUpMap[string(validator.GetPublicKey())].Cmp(minTopUp) >= 0 && i < int(numOfAvailableNodeSlots) { + newNode := validator + newNode.SetList(string(common.SelectedFromAuctionList)) + err = validatorsInfoMap.Replace(validator, newNode) + if err != nil { + return err + } } - } + }*/ + + for _, node := range selectedNodes { + newNode := node + newNode.SetList(string(common.SelectedFromAuctionList)) + err = validatorsInfoMap.Replace(node, newNode) + if err != nil { + return err + } } + + _ = minTopUp return nil } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 80fade0730f..4a97474e4d1 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1877,11 +1877,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing - XOR2 = []byte("pubKey5") XOR []byte("pubKey7") = [0 0 0 0 0 0 2] - XOR3 = []byte("pubKey7") XOR []byte("pubKey7") = [0 0 0 0 0 0 0] */ - requireTopUpPerNodes(t, s.stakingDataProvider, owner1StakedKeys, big.NewInt(1000)) - requireTopUpPerNodes(t, s.stakingDataProvider, owner2StakedKeys, big.NewInt(0)) - requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(0)) - requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(500)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner1StakedKeys, big.NewInt(1222)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner2StakedKeys, big.NewInt(851)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(1222)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(666)) + // selected = 10, 4, 2 expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), @@ -1897,7 +1898,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1), createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1), - createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4, 1), + createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1), + createValidatorInfo(owner4StakedKeys[2], common.SelectedFromAuctionList, owner4, 1), + createValidatorInfo(owner4StakedKeys[3], common.AuctionList, owner4, 1), + + createValidatorInfo(owner5StakedKeys[0], common.LeavingList, owner5, 1), + createValidatorInfo(owner5StakedKeys[1], common.AuctionList, owner5, 1), }, } require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) @@ -1994,11 +2000,20 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar } func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { - for _, pubKey := range stakedPubKeys { - topUpPerNode, err := s.GetNodeStakedTopUp(pubKey) - require.Nil(t, err) - require.Equal(t, topUpPerNode, topUp) - } + owner, err := s.GetBlsKeyOwner(stakedPubKeys[0]) + require.Nil(t, err) + + totalTopUp, err := s.GetTotalTopUp([]byte(owner)) + require.Nil(t, err) + + topUpPerNode := big.NewInt(0).Div(totalTopUp, big.NewInt(int64(len(stakedPubKeys)))) + require.Equal(t, topUp, topUpPerNode) + + //for _, pubKey := range stakedPubKeys { + // topUpPerNode, err := s.GetNodeStakedTopUp(pubKey) + // require.Nil(t, err) + // require.Equal(t, topUpPerNode, topUp) + //} } // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing From e9ca4d3ed844394dba9d551caa600d54fd1c57b7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 19 May 2022 17:35:55 +0300 Subject: [PATCH 268/958] FEAT: Do not add unqualified nodes in auction --- epochStart/interface.go | 6 +- epochStart/metachain/auctionListSelector.go | 119 ++++++++---------- .../metachain/auctionListSelector_test.go | 11 +- epochStart/metachain/stakingDataProvider.go | 6 +- epochStart/metachain/systemSCs.go | 30 +++-- epochStart/metachain/systemSCs_test.go | 41 ++++-- 6 files changed, 115 insertions(+), 98 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index e98b6cf0e0d..04ab154d4ee 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -215,6 +215,10 @@ type MaxNodesChangeConfigProvider interface { // AuctionListSelector handles selection of nodes from auction list to be sent to waiting list, based on their top up type AuctionListSelector interface { - SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error + SelectNodesFromAuctionList( + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + unqualifiedOwners map[string]struct{}, + randomness []byte, + ) error IsInterfaceNil() bool } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 74de0aae73b..31a8e9780d3 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -56,7 +56,11 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, // SelectNodesFromAuctionList will select nodes from validatorsInfoMap based on their top up. If two or more validators // have the same top-up, then sorting will be done based on blsKey XOR randomness. Selected nodes will have their list set // to common.SelectNodesFromAuctionList -func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { +func (als *auctionListSelector) SelectNodesFromAuctionList( + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + unqualifiedOwners map[string]struct{}, + randomness []byte, +) error { if len(randomness) == 0 { return process.ErrNilRandSeed } @@ -64,7 +68,11 @@ func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap sta currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) - auctionList, currNumOfValidators := getAuctionListAndNumOfValidators(validatorsInfoMap) + auctionList, currNumOfValidators, err := als.getAuctionListAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) + if err != nil { + return err + } + numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", @@ -114,11 +122,28 @@ func safeSub(a, b uint32) (uint32, error) { return a - b, nil } -func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, uint32) { +func (als *auctionListSelector) getAuctionListAndNumOfValidators( + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + unqualifiedOwners map[string]struct{}, +) ([]state.ValidatorInfoHandler, uint32, error) { auctionList := make([]state.ValidatorInfoHandler, 0) numOfValidators := uint32(0) for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { + owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) + if err != nil { + return nil, 0, err + } + + _, isUnqualified := unqualifiedOwners[owner] + if isUnqualified { + log.Debug("auctionListSelector: found unqualified owner, do not add validator in auction selection", + "owner", hex.EncodeToString([]byte(owner)), + "bls key", hex.EncodeToString(validator.GetPublicKey()), + ) + continue + } + if validator.GetList() == string(common.AuctionList) { auctionList = append(auctionList, validator) continue @@ -128,7 +153,7 @@ func getAuctionListAndNumOfValidators(validatorsInfoMap state.ShardValidatorsInf } } - return auctionList, numOfValidators + return auctionList, numOfValidators, nil } type ownerData struct { @@ -154,16 +179,15 @@ func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoH return nil, err } + if stakedNodes == 0 { + return nil, process.ErrNodeIsNotSynced + } + totalTopUp, err := als.stakingDataProvider.GetTotalTopUp([]byte(owner)) if err != nil { return nil, err } - //topUpPerNode, err := als.stakingDataProvider.GetNodeStakedTopUp(node.GetPublicKey()) - //if err != nil { - // return nil, err - //} - data, exists := ownersData[owner] if exists { data.auctionNodes++ @@ -203,7 +227,6 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { func (als *auctionListSelector) getMinRequiredTopUp( auctionList []state.ValidatorInfoHandler, - validatorTopUpMap map[string]*big.Int, numAvailableSlots uint32, randomness []byte, ) ([]state.ValidatorInfoHandler, *big.Int, error) { @@ -216,49 +239,47 @@ func (als *auctionListSelector) getMinRequiredTopUp( maxTopUp := big.NewInt(1000000) // todo: extract to const // max top up from auction list step := big.NewInt(100) - previousConfig := copyOwnersData(ownersData) - - fmt.Println("current config: ", previousConfig) for topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()); topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { - numNodesQualifyingForTopUp := int64(0) - previousConfig = copyOwnersData(ownersData) - for ownerPubKey, owner := range ownersData { - validatorActiveNodes := owner.activeNodes + previousConfig := copyOwnersData(ownersData) - minQualifiedTopUpForAuction := big.NewInt(0).Mul(topUp, big.NewInt(validatorActiveNodes)) - validatorTopUpForAuction := big.NewInt(0).Sub(owner.totalTopUp, minQualifiedTopUpForAuction) + for ownerPubKey, owner := range ownersData { + activeNodes := big.NewInt(owner.activeNodes) + topUpActiveNodes := big.NewInt(0).Mul(topUp, activeNodes) + validatorTopUpForAuction := big.NewInt(0).Sub(owner.totalTopUp, topUpActiveNodes) if validatorTopUpForAuction.Cmp(topUp) < 0 { delete(ownersData, ownerPubKey) continue } qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp) - if qualifiedNodes.Int64() > owner.auctionNodes { + qualifiedNodesInt := qualifiedNodes.Int64() + if qualifiedNodesInt > owner.auctionNodes { numNodesQualifyingForTopUp += owner.auctionNodes } else { + numNodesQualifyingForTopUp += qualifiedNodesInt - numNodesQualifyingForTopUp += qualifiedNodes.Int64() - - owner.auctionNodes = qualifiedNodes.Int64() - owner.topUpPerNode = big.NewInt(0).Div(owner.totalTopUp, big.NewInt(owner.activeNodes+owner.auctionNodes)) + owner.auctionNodes = qualifiedNodesInt + ownerRemainingNodes := big.NewInt(owner.activeNodes + owner.auctionNodes) + owner.topUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) } } if numNodesQualifyingForTopUp < int64(numAvailableSlots) { - selectedNodes := als.selectNodes(previousConfig, numAvailableSlots, randomness) - if topUp.Cmp(minTopUp) == 0 { + selectedNodes := als.selectNodes(previousConfig, uint32(len(auctionList)), randomness) + return selectedNodes, big.NewInt(0), nil } else { + selectedNodes := als.selectNodes(previousConfig, numAvailableSlots, randomness) return selectedNodes, topUp.Sub(topUp, step), nil } } } - _ = previousConfig + return nil, nil, errors.New("COULD NOT FIND TOPUP") } @@ -305,30 +326,11 @@ func (als *auctionListSelector) sortAuctionList( return nil } - validatorTopUpMap, err := als.getValidatorTopUpMap(auctionList) - if err != nil { - return fmt.Errorf("%w: %v", epochStart.ErrSortAuctionList, err) - } - - selectedNodes, minTopUp, err := als.getMinRequiredTopUp(auctionList, validatorTopUpMap, numOfAvailableNodeSlots, randomness) + selectedNodes, minTopUp, err := als.getMinRequiredTopUp(auctionList, numOfAvailableNodeSlots, randomness) if err != nil { return err } - //als.sortValidators(auctionList, validatorTopUpMap, randomness) - /* - for i, validator := range auctionList { - if validatorTopUpMap[string(validator.GetPublicKey())].Cmp(minTopUp) >= 0 && i < int(numOfAvailableNodeSlots) { - newNode := validator - newNode.SetList(string(common.SelectedFromAuctionList)) - err = validatorsInfoMap.Replace(validator, newNode) - if err != nil { - return err - } - } - - }*/ - for _, node := range selectedNodes { newNode := node newNode.SetList(string(common.SelectedFromAuctionList)) @@ -342,29 +344,6 @@ func (als *auctionListSelector) sortAuctionList( return nil } -func (als *auctionListSelector) getValidatorNumAuctionNodesMap(auctionList []state.ValidatorInfoHandler) (map[string]int64, error) { - ret := make(map[string]int64) - ownerAuctionNodesMap := make(map[string][][]byte) - - for _, validator := range auctionList { - owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) - if err != nil { - return nil, err - } - - ownerAuctionNodesMap[owner] = append(ownerAuctionNodesMap[owner], validator.GetPublicKey()) - } - - for _, auctionNodes := range ownerAuctionNodesMap { - for _, auctionNode := range auctionNodes { - ret[string(auctionNode)] = int64(len(auctionNodes)) - } - - } - - return ret, nil -} - func (als *auctionListSelector) sortValidators( auctionList []state.ValidatorInfoHandler, validatorTopUpMap map[string]*big.Int, diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 5a0dd95687e..2a4f74b9727 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -1,9 +1,6 @@ package metachain import ( - "errors" - "math/big" - "strings" "testing" "github.com/ElrondNetwork/elrond-go-core/core" @@ -11,7 +8,6 @@ import ( "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" @@ -88,7 +84,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) - err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ @@ -100,6 +96,8 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } +//TODO: probably remove this test +/* func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingAuctionList(t *testing.T) { t.Parallel() @@ -126,8 +124,9 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) - err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) require.Error(t, err) require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) } +*/ diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 4e220f618ea..d900db503c4 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -397,9 +397,9 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.ShardValidatorsInfoMapHandler) (map[string]string, error) { mapBLSKeyStatus := make(map[string]string) - for _, validatorInfo := range validatorsInfo.GetAllValidatorsInfo() { - list := validatorInfo.GetList() - pubKey := validatorInfo.GetPublicKey() + for _, validator := range validatorsInfo.GetAllValidatorsInfo() { + list := validator.GetList() + pubKey := validator.GetPublicKey() if sdp.flagStakingV4Enable.IsSet() && list == string(common.NewList) { return nil, fmt.Errorf("%w, bls key = %s", diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index d51db47a961..01c6be56e79 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -141,12 +141,12 @@ func (s *systemSCProcessor) processWithNewFlags( return err } - err = s.unStakeNodesWithNotEnoughFundsWithStakingV4(validatorsInfoMap, header.GetEpoch()) + unqualifiedOwners, err := s.unStakeNodesWithNotEnoughFundsWithStakingV4(validatorsInfoMap, header.GetEpoch()) if err != nil { return err } - err = s.auctionListSelector.SelectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) + err = s.auctionListSelector.SelectNodesFromAuctionList(validatorsInfoMap, unqualifiedOwners, header.GetPrevRandSeed()) if err != nil { return err } @@ -158,10 +158,10 @@ func (s *systemSCProcessor) processWithNewFlags( func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( validatorsInfoMap state.ShardValidatorsInfoMapHandler, epoch uint32, -) error { +) (map[string]struct{}, error) { nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) if err != nil { - return err + return nil, err } log.Debug("unStake nodes with not enough funds", "num", len(nodesToUnStake)) @@ -169,12 +169,12 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( log.Debug("unStake at end of epoch for node", "blsKey", blsKey) err = s.unStakeOneNode(blsKey, epoch) if err != nil { - return err + return nil, err } validatorInfo := validatorsInfoMap.GetValidator(blsKey) if validatorInfo == nil { - return fmt.Errorf( + return nil, fmt.Errorf( "%w in systemSCProcessor.unStakeNodesWithNotEnoughFundsWithStakingV4 because validator might be in additional queue after staking v4", epochStart.ErrNilValidatorInfo) } @@ -183,11 +183,25 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( validatorLeaving.SetList(string(common.LeavingList)) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { - return err + return nil, err } } + err = s.updateDelegationContracts(mapOwnersKeys) + if err != nil { + + } + + return copyOwnerKeysInMap(mapOwnersKeys), nil +} + +func copyOwnerKeysInMap(mapOwnersKeys map[string][][]byte) map[string]struct{} { + ret := make(map[string]struct{}) + + for owner, _ := range mapOwnersKeys { + ret[owner] = struct{}{} + } - return s.updateDelegationContracts(mapOwnersKeys) + return ret } func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 4a97474e4d1..e0f14833ecb 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -845,9 +845,12 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS vmContainer, _ := metaVmFactory.Create() systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) - argsStakingDataProvider := createStakingDataProviderArgs() - argsStakingDataProvider.SystemVM = systemVM - argsStakingDataProvider.MinNodePrice = "1000" + argsStakingDataProvider := StakingDataProviderArgs{ + EpochNotifier: en, + SystemVM: systemVM, + MinNodePrice: "1000", + StakingV4EnableEpoch: stakingV4EnableEpoch, + } stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) @@ -1813,18 +1816,24 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing owner3 := []byte("owner3") owner4 := []byte("owner4") owner5 := []byte("owner5") + owner6 := []byte("owner6") + owner7 := []byte("owner7") owner1StakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1"), []byte("pubKey2")} owner2StakedKeys := [][]byte{[]byte("pubKey3"), []byte("pubKey4"), []byte("pubKey5")} owner3StakedKeys := [][]byte{[]byte("pubKey6"), []byte("pubKey7")} owner4StakedKeys := [][]byte{[]byte("pubKey8"), []byte("pubKey9"), []byte("pubKe10"), []byte("pubKe11")} owner5StakedKeys := [][]byte{[]byte("pubKe12"), []byte("pubKe13")} + owner6StakedKeys := [][]byte{[]byte("pubKe14"), []byte("pubKe15")} + owner7StakedKeys := [][]byte{[]byte("pubKe16"), []byte("pubKe17")} stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(6666), args.Marshalizer) stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(5555), args.Marshalizer) stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3StakedKeys, big.NewInt(4444), args.Marshalizer) stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner4, owner4, owner4StakedKeys, big.NewInt(6666), args.Marshalizer) - stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner5, owner5, owner5StakedKeys, big.NewInt(1000), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner5, owner5, owner5StakedKeys, big.NewInt(1500), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner6, owner6, owner6StakedKeys, big.NewInt(1500), args.Marshalizer) + stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner7, owner7, owner7StakedKeys, big.NewInt(1500), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) @@ -1846,6 +1855,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[0], common.EligibleList, owner5, 1)) _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[1], common.AuctionList, owner5, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner6StakedKeys[0], common.AuctionList, owner6, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner6StakedKeys[1], common.AuctionList, owner6, 1)) + + _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[0], common.EligibleList, owner7, 2)) + _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[1], common.EligibleList, owner7, 2)) + s, _ := NewSystemSCProcessor(args) args.EpochNotifier.CheckEpoch(&block.Header{Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("pubKey7")}) @@ -1881,6 +1896,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing requireTopUpPerNodes(t, s.stakingDataProvider, owner2StakedKeys, big.NewInt(851)) requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(1222)) requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(666)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner5StakedKeys, big.NewInt(0)) // selected = 10, 4, 2 expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ @@ -1902,10 +1918,18 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing createValidatorInfo(owner4StakedKeys[2], common.SelectedFromAuctionList, owner4, 1), createValidatorInfo(owner4StakedKeys[3], common.AuctionList, owner4, 1), - createValidatorInfo(owner5StakedKeys[0], common.LeavingList, owner5, 1), - createValidatorInfo(owner5StakedKeys[1], common.AuctionList, owner5, 1), + createValidatorInfo(owner5StakedKeys[0], common.EligibleList, owner5, 1), + createValidatorInfo(owner5StakedKeys[1], common.LeavingList, owner5, 1), + + createValidatorInfo(owner6StakedKeys[0], common.LeavingList, owner6, 1), + createValidatorInfo(owner6StakedKeys[1], common.AuctionList, owner6, 1), + }, + 2: { + createValidatorInfo(owner7StakedKeys[0], common.LeavingList, owner7, 2), + createValidatorInfo(owner7StakedKeys[1], common.EligibleList, owner7, 2), }, } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } @@ -2018,10 +2042,7 @@ func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, staked // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte, shardID uint32) *state.ValidatorInfo { - rating := uint32(0) - if list == common.NewList || list == common.AuctionList || list == common.SelectedFromAuctionList { - rating = uint32(5) - } + rating := uint32(5) return &state.ValidatorInfo{ PublicKey: pubKey, From 2c41f17ddc56dee7d5aa662fcd0c253e6b35fb21 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 19 May 2022 17:50:32 +0300 Subject: [PATCH 269/958] CLN: Quick fix broken test --- .../metachain/auctionListSelector_test.go | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 2a4f74b9727..6048a9caede 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -1,6 +1,7 @@ package metachain import ( + "math/big" "testing" "github.com/ElrondNetwork/elrond-go-core/core" @@ -11,6 +12,7 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) @@ -29,6 +31,19 @@ func createAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) Auction } } +func createFullAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) (AuctionListSelectorArgs, ArgsNewEpochStartSystemSCProcessing) { + epochNotifier := forking.NewGenericEpochNotifier() + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, config) + + argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + return AuctionListSelectorArgs{ + ShardCoordinator: shardCoordinator, + StakingDataProvider: argsSystemSC.StakingDataProvider, + MaxNodesChangeConfigProvider: nodesConfigProvider, + }, argsSystemSC +} + func TestNewAuctionListSelector(t *testing.T) { t.Parallel() @@ -71,9 +86,7 @@ func TestNewAuctionListSelector(t *testing.T) { func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionNodes(t *testing.T) { t.Parallel() - args := createAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) - als, _ := NewAuctionListSelector(args) - + args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) owner1 := []byte("owner1") owner2 := []byte("owner2") @@ -83,7 +96,10 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + als, _ := NewAuctionListSelector(args) err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) require.Nil(t, err) From dcf9f5bc21dbb51ebdc280ee971aaaa5a785f942 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 20 May 2022 12:20:16 +0300 Subject: [PATCH 270/958] FIX: not selecting unqualified nodes for auction --- epochStart/errors.go | 3 ++ epochStart/metachain/auctionListSelector.go | 31 +++++++++++++-------- epochStart/metachain/systemSCs_test.go | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 0023fd5625b..53652eb7a11 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -334,3 +334,6 @@ var ErrNilMaxNodesChangeConfigProvider = errors.New("nil nodes config provider h // ErrNilAuctionListSelector signals that a nil auction list selector has been provided var ErrNilAuctionListSelector = errors.New("nil auction list selector has been provided") + +// ErrOwnerHasNoStakedNode signals that an owner has no staked node +var ErrOwnerHasNoStakedNode = errors.New("owner has no staked node") diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 31a8e9780d3..ddf4f0a5515 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -135,16 +135,16 @@ func (als *auctionListSelector) getAuctionListAndNumOfValidators( return nil, 0, err } - _, isUnqualified := unqualifiedOwners[owner] - if isUnqualified { - log.Debug("auctionListSelector: found unqualified owner, do not add validator in auction selection", - "owner", hex.EncodeToString([]byte(owner)), - "bls key", hex.EncodeToString(validator.GetPublicKey()), - ) - continue - } + if isInAuction(validator) { + _, isUnqualified := unqualifiedOwners[owner] + if isUnqualified { + log.Debug("auctionListSelector: found node in auction with unqualified owner, do not add it to selection", + "owner", owner, + "bls key", string(validator.GetPublicKey()), + ) + continue + } - if validator.GetList() == string(common.AuctionList) { auctionList = append(auctionList, validator) continue } @@ -156,6 +156,10 @@ func (als *auctionListSelector) getAuctionListAndNumOfValidators( return auctionList, numOfValidators, nil } +func isInAuction(validator state.ValidatorInfoHandler) bool { + return validator.GetList() == string(common.AuctionList) +} + type ownerData struct { activeNodes int64 auctionNodes int64 @@ -180,7 +184,11 @@ func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoH } if stakedNodes == 0 { - return nil, process.ErrNodeIsNotSynced + return nil, fmt.Errorf("auctionListSelector.getOwnersDat: error: %w, owner: %s, node: %s", + epochStart.ErrOwnerHasNoStakedNode, + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(node.GetPublicKey()), + ) } totalTopUp, err := als.stakingDataProvider.GetTotalTopUp([]byte(owner)) @@ -194,12 +202,13 @@ func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoH data.activeNodes-- data.auctionList = append(data.auctionList, node) } else { + stakedNodesBigInt := big.NewInt(stakedNodes) ownersData[owner] = &ownerData{ auctionNodes: 1, activeNodes: stakedNodes - 1, stakedNodes: stakedNodes, totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), - topUpPerNode: big.NewInt(0).Div(totalTopUp, big.NewInt(stakedNodes)), + topUpPerNode: big.NewInt(0).Div(totalTopUp, stakedNodesBigInt), auctionList: []state.ValidatorInfoHandler{node}, } } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e0f14833ecb..26a192daff4 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1802,7 +1802,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing t.Parallel() args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 6}}) + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 8}}) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: args.ShardCoordinator, StakingDataProvider: args.StakingDataProvider, From f06c188517daddd574ba8fab6a4e01576f1e4875 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 20 May 2022 15:22:06 +0300 Subject: [PATCH 271/958] CLN: Start refactor --- epochStart/metachain/auctionListSelector.go | 206 +++++++++++++------- 1 file changed, 132 insertions(+), 74 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index ddf4f0a5515..c4be2d21d27 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -3,8 +3,8 @@ package metachain import ( "bytes" "encoding/hex" - "errors" "fmt" + "math" "math/big" "sort" @@ -68,7 +68,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) - auctionList, currNumOfValidators, err := als.getAuctionListAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) + auctionList, ownersData, currNumOfValidators, err := als.getAuctionListAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) if err != nil { return err } @@ -104,8 +104,13 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v -%v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) + if len(auctionList) == 0 { + log.Debug("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") + return nil + } + numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) - err = als.sortAuctionList(auctionList, numOfAvailableNodeSlots, validatorsInfoMap, randomness) + err = als.sortAuctionList(auctionList, ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) if err != nil { return err } @@ -125,14 +130,15 @@ func safeSub(a, b uint32) (uint32, error) { func (als *auctionListSelector) getAuctionListAndNumOfValidators( validatorsInfoMap state.ShardValidatorsInfoMapHandler, unqualifiedOwners map[string]struct{}, -) ([]state.ValidatorInfoHandler, uint32, error) { +) ([]state.ValidatorInfoHandler, map[string]*ownerData, uint32, error) { + ownersData := make(map[string]*ownerData) auctionList := make([]state.ValidatorInfoHandler, 0) numOfValidators := uint32(0) for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) if err != nil { - return nil, 0, err + return nil, nil, 0, err } if isInAuction(validator) { @@ -145,6 +151,11 @@ func (als *auctionListSelector) getAuctionListAndNumOfValidators( continue } + err = als.addOwnerData(validator, ownersData) + if err != nil { + return nil, nil, 0, err + } + auctionList = append(auctionList, validator) continue } @@ -153,7 +164,7 @@ func (als *auctionListSelector) getAuctionListAndNumOfValidators( } } - return auctionList, numOfValidators, nil + return auctionList, ownersData, numOfValidators, nil } func isInAuction(validator state.ValidatorInfoHandler) bool { @@ -169,49 +180,61 @@ type ownerData struct { auctionList []state.ValidatorInfoHandler } -func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoHandler) (map[string]*ownerData, error) { - ownersData := make(map[string]*ownerData) +func (als *auctionListSelector) addOwnerData( + validator state.ValidatorInfoHandler, + ownersData map[string]*ownerData, +) error { + owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) + if err != nil { + return err + } - for _, node := range auctionList { - owner, err := als.stakingDataProvider.GetBlsKeyOwner(node.GetPublicKey()) - if err != nil { - return nil, err - } + stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes([]byte(owner)) + if err != nil { + return err + } - stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes([]byte(owner)) - if err != nil { - return nil, err - } + if stakedNodes == 0 { + return fmt.Errorf("auctionListSelector.getOwnersDat: error: %w, owner: %s, node: %s", + epochStart.ErrOwnerHasNoStakedNode, + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(validator.GetPublicKey()), + ) + } + + totalTopUp, err := als.stakingDataProvider.GetTotalTopUp([]byte(owner)) + if err != nil { + return err + } - if stakedNodes == 0 { - return nil, fmt.Errorf("auctionListSelector.getOwnersDat: error: %w, owner: %s, node: %s", - epochStart.ErrOwnerHasNoStakedNode, - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(node.GetPublicKey()), - ) + data, exists := ownersData[owner] + if exists { + data.auctionNodes++ + data.activeNodes-- + data.auctionList = append(data.auctionList, validator) + } else { + stakedNodesBigInt := big.NewInt(stakedNodes) + ownersData[owner] = &ownerData{ + auctionNodes: 1, + activeNodes: stakedNodes - 1, + stakedNodes: stakedNodes, + totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), + topUpPerNode: big.NewInt(0).Div(totalTopUp, stakedNodesBigInt), + auctionList: []state.ValidatorInfoHandler{validator}, } + } + + return nil +} - totalTopUp, err := als.stakingDataProvider.GetTotalTopUp([]byte(owner)) +func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoHandler) (map[string]*ownerData, error) { + ownersData := make(map[string]*ownerData) + + for _, node := range auctionList { + err := als.addOwnerData(node, ownersData) if err != nil { return nil, err } - - data, exists := ownersData[owner] - if exists { - data.auctionNodes++ - data.activeNodes-- - data.auctionList = append(data.auctionList, node) - } else { - stakedNodesBigInt := big.NewInt(stakedNodes) - ownersData[owner] = &ownerData{ - auctionNodes: 1, - activeNodes: stakedNodes - 1, - stakedNodes: stakedNodes, - totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), - topUpPerNode: big.NewInt(0).Div(totalTopUp, stakedNodesBigInt), - auctionList: []state.ValidatorInfoHandler{node}, - } - } } return ownersData, nil @@ -234,23 +257,47 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { return ret } +func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { + min := big.NewInt(math.MaxInt64) + max := big.NewInt(0) + + for _, owner := range ownersData { + if owner.topUpPerNode.Cmp(min) < 0 { + min = big.NewInt(0).SetBytes(owner.topUpPerNode.Bytes()) + } + + ownerNumNodesWithOnlyOneAuctionNode := big.NewInt(owner.activeNodes + 1) + maxPossibleTopUpForOwner := big.NewInt(0).Div(owner.totalTopUp, ownerNumNodesWithOnlyOneAuctionNode) + if maxPossibleTopUpForOwner.Cmp(max) > 0 { + max = big.NewInt(0).SetBytes(maxPossibleTopUpForOwner.Bytes()) + } + } + if min.Cmp(big.NewInt(1)) < 0 { + min = big.NewInt(1) + } + + return min, max +} + func (als *auctionListSelector) getMinRequiredTopUp( auctionList []state.ValidatorInfoHandler, + ownersData map[string]*ownerData, numAvailableSlots uint32, randomness []byte, ) ([]state.ValidatorInfoHandler, *big.Int, error) { - ownersData, err := als.getOwnersData(auctionList) - if err != nil { - return nil, nil, err - } + //minTopUp := big.NewInt(1) // pornim de la topup cel mai slab din lista initiala + //maxTopUp := big.NewInt(1000000) // todo: extract to const // max top up from auction list - minTopUp := big.NewInt(1) // pornim de la topup cel mai slab din lista initiala - maxTopUp := big.NewInt(1000000) // todo: extract to const // max top up from auction list - step := big.NewInt(100) + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? + step := big.NewInt(10) // todo: granulate step if max- min < step???? + fmt.Println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^MIN TOP UP: ", minTopUp.Int64(), "MAX TOP UP", maxTopUp.Int64()) + previousConfig := copyOwnersData(ownersData) + minRequiredTopUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) + var selectedNodes []state.ValidatorInfoHandler for topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()); topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { numNodesQualifyingForTopUp := int64(0) - previousConfig := copyOwnersData(ownersData) + previousConfig = copyOwnersData(ownersData) for ownerPubKey, owner := range ownersData { activeNodes := big.NewInt(owner.activeNodes) @@ -261,14 +308,12 @@ func (als *auctionListSelector) getMinRequiredTopUp( continue } - qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp) - qualifiedNodesInt := qualifiedNodes.Int64() - if qualifiedNodesInt > owner.auctionNodes { + qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp).Int64() + if qualifiedNodes > owner.auctionNodes { numNodesQualifyingForTopUp += owner.auctionNodes } else { - numNodesQualifyingForTopUp += qualifiedNodesInt - - owner.auctionNodes = qualifiedNodesInt + numNodesQualifyingForTopUp += qualifiedNodes + owner.auctionNodes = qualifiedNodes ownerRemainingNodes := big.NewInt(owner.activeNodes + owner.auctionNodes) owner.topUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) @@ -276,27 +321,29 @@ func (als *auctionListSelector) getMinRequiredTopUp( } if numNodesQualifyingForTopUp < int64(numAvailableSlots) { - if topUp.Cmp(minTopUp) == 0 { - selectedNodes := als.selectNodes(previousConfig, uint32(len(auctionList)), randomness) - return selectedNodes, big.NewInt(0), nil } else { - selectedNodes := als.selectNodes(previousConfig, numAvailableSlots, randomness) - return selectedNodes, topUp.Sub(topUp, step), nil + minRequiredTopUp = big.NewInt(0).Sub(topUp, step) } + break } } - - return nil, nil, errors.New("COULD NOT FIND TOPUP") + selectedNodes = als.selectNodes(previousConfig, numAvailableSlots, randomness) + return selectedNodes, minRequiredTopUp, nil } -func (als *auctionListSelector) selectNodes(ownersData map[string]*ownerData, numAvailableSlots uint32, randomness []byte) []state.ValidatorInfoHandler { +func (als *auctionListSelector) selectNodes( + ownersData map[string]*ownerData, + numAvailableSlots uint32, + randomness []byte, +) []state.ValidatorInfoHandler { selectedFromAuction := make([]state.ValidatorInfoHandler, 0) validatorTopUpMap := make(map[string]*big.Int) for _, owner := range ownersData { + sortListByXORWithRand(owner.auctionList, randomness) for i := int64(0); i < owner.auctionNodes; i++ { currNode := owner.auctionList[i] @@ -325,28 +372,39 @@ func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) }) } +func markAuctionNodesAsSelected( + selectedNodes []state.ValidatorInfoHandler, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, +) error { + for _, node := range selectedNodes { + newNode := node + newNode.SetList(string(common.SelectedFromAuctionList)) + + err := validatorsInfoMap.Replace(node, newNode) + if err != nil { + return err + } + } + + return nil +} + func (als *auctionListSelector) sortAuctionList( auctionList []state.ValidatorInfoHandler, + ownersData map[string]*ownerData, numOfAvailableNodeSlots uint32, validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - if len(auctionList) == 0 { - return nil - } - selectedNodes, minTopUp, err := als.getMinRequiredTopUp(auctionList, numOfAvailableNodeSlots, randomness) + selectedNodes, minTopUp, err := als.getMinRequiredTopUp(auctionList, ownersData, numOfAvailableNodeSlots, randomness) if err != nil { return err } - for _, node := range selectedNodes { - newNode := node - newNode.SetList(string(common.SelectedFromAuctionList)) - err = validatorsInfoMap.Replace(node, newNode) - if err != nil { - return err - } + err = markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) + if err != nil { + return err } _ = minTopUp From a5659dc3d8f87bf3b07f0facf39c5ff2513076c3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 20 May 2022 16:47:11 +0300 Subject: [PATCH 272/958] CLN: Refactor 2 --- epochStart/metachain/auctionListSelector.go | 79 ++++++++++--------- .../metachain/auctionListSelector_test.go | 8 +- 2 files changed, 50 insertions(+), 37 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index c4be2d21d27..411fb236603 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -56,6 +56,7 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, // SelectNodesFromAuctionList will select nodes from validatorsInfoMap based on their top up. If two or more validators // have the same top-up, then sorting will be done based on blsKey XOR randomness. Selected nodes will have their list set // to common.SelectNodesFromAuctionList +// Depends that dat is filled in staking data provider func (als *auctionListSelector) SelectNodesFromAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, unqualifiedOwners map[string]struct{}, @@ -110,7 +111,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( } numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) - err = als.sortAuctionList(auctionList, ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) + err = als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) if err != nil { return err } @@ -172,12 +173,14 @@ func isInAuction(validator state.ValidatorInfoHandler) bool { } type ownerData struct { - activeNodes int64 - auctionNodes int64 - stakedNodes int64 - totalTopUp *big.Int - topUpPerNode *big.Int - auctionList []state.ValidatorInfoHandler + activeNodes int64 + auctionNodes int64 + qualifiedAuctionNodes int64 + stakedNodes int64 + totalTopUp *big.Int + topUpPerNode *big.Int + qualifiedTopUpPerNode *big.Int + auctionList []state.ValidatorInfoHandler } func (als *auctionListSelector) addOwnerData( @@ -210,17 +213,21 @@ func (als *auctionListSelector) addOwnerData( data, exists := ownersData[owner] if exists { data.auctionNodes++ + data.qualifiedAuctionNodes++ data.activeNodes-- data.auctionList = append(data.auctionList, validator) } else { stakedNodesBigInt := big.NewInt(stakedNodes) + topUpPerNode := big.NewInt(0).Div(totalTopUp, stakedNodesBigInt) ownersData[owner] = &ownerData{ - auctionNodes: 1, - activeNodes: stakedNodes - 1, - stakedNodes: stakedNodes, - totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), - topUpPerNode: big.NewInt(0).Div(totalTopUp, stakedNodesBigInt), - auctionList: []state.ValidatorInfoHandler{validator}, + auctionNodes: 1, + qualifiedAuctionNodes: 1, + activeNodes: stakedNodes - 1, + stakedNodes: stakedNodes, + totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), + topUpPerNode: topUpPerNode, + qualifiedTopUpPerNode: topUpPerNode, + auctionList: []state.ValidatorInfoHandler{validator}, } } @@ -244,12 +251,14 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { ret := make(map[string]*ownerData) for owner, data := range ownersData { ret[owner] = &ownerData{ - activeNodes: data.activeNodes, - auctionNodes: data.auctionNodes, - stakedNodes: data.stakedNodes, - totalTopUp: data.totalTopUp, - topUpPerNode: data.topUpPerNode, - auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), + activeNodes: data.activeNodes, + auctionNodes: data.auctionNodes, + qualifiedAuctionNodes: data.qualifiedAuctionNodes, + stakedNodes: data.stakedNodes, + totalTopUp: data.totalTopUp, + topUpPerNode: data.topUpPerNode, + qualifiedTopUpPerNode: data.qualifiedTopUpPerNode, + auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), } copy(ret[owner].auctionList, data.auctionList) } @@ -279,17 +288,18 @@ func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.In return min, max } -func (als *auctionListSelector) getMinRequiredTopUp( - auctionList []state.ValidatorInfoHandler, +func (als *auctionListSelector) selectNodesAndMinTopUp( ownersData map[string]*ownerData, numAvailableSlots uint32, randomness []byte, ) ([]state.ValidatorInfoHandler, *big.Int, error) { - //minTopUp := big.NewInt(1) // pornim de la topup cel mai slab din lista initiala - //maxTopUp := big.NewInt(1000000) // todo: extract to const // max top up from auction list - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? - step := big.NewInt(10) // todo: granulate step if max- min < step???? + log.Debug("auctionListSelector: calc min and max possible top up", + "min top up", minTopUp.String(), + "max top up", maxTopUp.String(), + ) + + step := big.NewInt(10) // todo: granulate step if max- min < step???? fmt.Println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^MIN TOP UP: ", minTopUp.Int64(), "MAX TOP UP", maxTopUp.Int64()) previousConfig := copyOwnersData(ownersData) @@ -313,17 +323,15 @@ func (als *auctionListSelector) getMinRequiredTopUp( numNodesQualifyingForTopUp += owner.auctionNodes } else { numNodesQualifyingForTopUp += qualifiedNodes - owner.auctionNodes = qualifiedNodes + owner.qualifiedAuctionNodes = qualifiedNodes - ownerRemainingNodes := big.NewInt(owner.activeNodes + owner.auctionNodes) - owner.topUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) + ownerRemainingNodes := big.NewInt(owner.activeNodes + owner.qualifiedAuctionNodes) + owner.qualifiedTopUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) } } if numNodesQualifyingForTopUp < int64(numAvailableSlots) { - if topUp.Cmp(minTopUp) == 0 { - - } else { + if !(topUp.Cmp(minTopUp) == 0) { minRequiredTopUp = big.NewInt(0).Sub(topUp, step) } break @@ -345,12 +353,12 @@ func (als *auctionListSelector) selectNodes( for _, owner := range ownersData { sortListByXORWithRand(owner.auctionList, randomness) - for i := int64(0); i < owner.auctionNodes; i++ { + for i := int64(0); i < owner.qualifiedAuctionNodes; i++ { currNode := owner.auctionList[i] - validatorTopUpMap[string(currNode.GetPublicKey())] = big.NewInt(0).SetBytes(owner.topUpPerNode.Bytes()) + validatorTopUpMap[string(currNode.GetPublicKey())] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) } - selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.auctionNodes]...) + selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.qualifiedAuctionNodes]...) } als.sortValidators(selectedFromAuction, validatorTopUpMap, randomness) @@ -390,14 +398,13 @@ func markAuctionNodesAsSelected( } func (als *auctionListSelector) sortAuctionList( - auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfAvailableNodeSlots uint32, validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - selectedNodes, minTopUp, err := als.getMinRequiredTopUp(auctionList, ownersData, numOfAvailableNodeSlots, randomness) + selectedNodes, minTopUp, err := als.selectNodesAndMinTopUp(ownersData, numOfAvailableNodeSlots, randomness) if err != nil { return err } diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 6048a9caede..10d0be4164a 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -96,11 +96,17 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN validatorsInfo := state.NewShardValidatorsInfoMap() _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + err := args.StakingDataProvider.FillValidatorInfo(owner1StakedKeys[0]) + require.Nil(t, err) + err = args.StakingDataProvider.FillValidatorInfo(owner2StakedKeys[0]) + require.Nil(t, err) + als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + err = als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ From 7e22f59477189c80f0c50a90007263bf18a195d7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 20 May 2022 18:35:29 +0300 Subject: [PATCH 273/958] CLN: Refactor 3 --- epochStart/metachain/auctionListDisplayer.go | 111 ++++++++++++ epochStart/metachain/auctionListSelector.go | 168 ++++++------------- 2 files changed, 161 insertions(+), 118 deletions(-) create mode 100644 epochStart/metachain/auctionListDisplayer.go diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go new file mode 100644 index 00000000000..2a0e8b7ffec --- /dev/null +++ b/epochStart/metachain/auctionListDisplayer.go @@ -0,0 +1,111 @@ +package metachain + +import ( + "fmt" + "strconv" + + "github.com/ElrondNetwork/elrond-go-core/display" + "github.com/ElrondNetwork/elrond-go/state" +) + +const maxPubKeyDisplayableLen = 20 + +func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { + pubKeys := "" + + for idx, validator := range list { + pubKey := validator.GetPublicKey() + displayablePubKey := pubKey + + pubKeyLen := len(pubKey) + if pubKeyLen > maxPubKeyDisplayableLen { + displayablePubKey = make([]byte, 0) + displayablePubKey = append(displayablePubKey, pubKey[:maxPubKeyDisplayableLen/2]...) + displayablePubKey = append(displayablePubKey, []byte("...")...) + displayablePubKey = append(displayablePubKey, pubKey[pubKeyLen-maxPubKeyDisplayableLen/2:]...) + } + + pubKeys += string(displayablePubKey) // todo: hex here + addDelimiter := idx != len(list)-1 + if addDelimiter { + pubKeys += ", " + } + } + + return pubKeys +} + +func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*ownerData) { + //if log.GetLevel() > logger.LogDebug { + // return + //} + + tableHeader := []string{ + "Owner", + "Num active nodes", + "Num auction nodes", + "Num staked nodes", + "Total top up", + "Top up per node", + "Auction list nodes", + } + lines := make([]*display.LineData, 0, len(ownersData)) + for ownerPubKey, owner := range ownersData { + + line := []string{ + (ownerPubKey), + strconv.Itoa(int(owner.numActiveNodes)), + strconv.Itoa(int(owner.numAuctionNodes)), + strconv.Itoa(int(owner.numStakedNodes)), + owner.totalTopUp.String(), + owner.topUpPerNode.String(), + getShortDisplayableBlsKeys(owner.auctionList), + } + lines = append(lines, display.NewLineData(false, line)) + } + + table, err := display.CreateTableString(tableHeader, lines) + if err != nil { + log.Error("could not create table", "error", err) + return + } + + message := fmt.Sprintf("Nodes config in auction list\n%s", table) + log.Info(message) +} + +func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { + //if log.GetLevel() > logger.LogDebug { + // return + //} + + tableHeader := []string{"Owner", "Registered key", "TopUp per node"} + lines := make([]*display.LineData, 0, len(auctionList)) + horizontalLine := false + for idx, validator := range auctionList { + pubKey := validator.GetPublicKey() + + owner, err := als.stakingDataProvider.GetBlsKeyOwner(pubKey) + log.LogIfError(err) + + topUp, err := als.stakingDataProvider.GetNodeStakedTopUp(pubKey) + log.LogIfError(err) + + horizontalLine = uint32(idx) == numOfSelectedNodes-1 + line := display.NewLineData(horizontalLine, []string{ + (owner), + string(pubKey), + topUp.String(), + }) + lines = append(lines, line) + } + + table, err := display.CreateTableString(tableHeader, lines) + if err != nil { + log.Error("could not create table", "error", err) + return + } + + message := fmt.Sprintf("Auction list\n%s", table) + log.Info(message) +} diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 411fb236603..de93db90f43 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -10,7 +10,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" @@ -110,6 +109,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return nil } + als.displayOwnersConfig(ownersData) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) err = als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) if err != nil { @@ -173,14 +173,14 @@ func isInAuction(validator state.ValidatorInfoHandler) bool { } type ownerData struct { - activeNodes int64 - auctionNodes int64 - qualifiedAuctionNodes int64 - stakedNodes int64 - totalTopUp *big.Int - topUpPerNode *big.Int - qualifiedTopUpPerNode *big.Int - auctionList []state.ValidatorInfoHandler + numActiveNodes int64 + numAuctionNodes int64 + numQualifiedAuctionNodes int64 + numStakedNodes int64 + totalTopUp *big.Int + topUpPerNode *big.Int + qualifiedTopUpPerNode *big.Int + auctionList []state.ValidatorInfoHandler } func (als *auctionListSelector) addOwnerData( @@ -212,53 +212,40 @@ func (als *auctionListSelector) addOwnerData( data, exists := ownersData[owner] if exists { - data.auctionNodes++ - data.qualifiedAuctionNodes++ - data.activeNodes-- + data.numAuctionNodes++ + data.numQualifiedAuctionNodes++ + data.numActiveNodes-- data.auctionList = append(data.auctionList, validator) } else { stakedNodesBigInt := big.NewInt(stakedNodes) topUpPerNode := big.NewInt(0).Div(totalTopUp, stakedNodesBigInt) ownersData[owner] = &ownerData{ - auctionNodes: 1, - qualifiedAuctionNodes: 1, - activeNodes: stakedNodes - 1, - stakedNodes: stakedNodes, - totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), - topUpPerNode: topUpPerNode, - qualifiedTopUpPerNode: topUpPerNode, - auctionList: []state.ValidatorInfoHandler{validator}, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numActiveNodes: stakedNodes - 1, + numStakedNodes: stakedNodes, + totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), + topUpPerNode: topUpPerNode, + qualifiedTopUpPerNode: topUpPerNode, + auctionList: []state.ValidatorInfoHandler{validator}, } } return nil } -func (als *auctionListSelector) getOwnersData(auctionList []state.ValidatorInfoHandler) (map[string]*ownerData, error) { - ownersData := make(map[string]*ownerData) - - for _, node := range auctionList { - err := als.addOwnerData(node, ownersData) - if err != nil { - return nil, err - } - } - - return ownersData, nil -} - func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { ret := make(map[string]*ownerData) for owner, data := range ownersData { ret[owner] = &ownerData{ - activeNodes: data.activeNodes, - auctionNodes: data.auctionNodes, - qualifiedAuctionNodes: data.qualifiedAuctionNodes, - stakedNodes: data.stakedNodes, - totalTopUp: data.totalTopUp, - topUpPerNode: data.topUpPerNode, - qualifiedTopUpPerNode: data.qualifiedTopUpPerNode, - auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), + numActiveNodes: data.numActiveNodes, + numAuctionNodes: data.numAuctionNodes, + numQualifiedAuctionNodes: data.numQualifiedAuctionNodes, + numStakedNodes: data.numStakedNodes, + totalTopUp: data.totalTopUp, + topUpPerNode: data.topUpPerNode, + qualifiedTopUpPerNode: data.qualifiedTopUpPerNode, + auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), } copy(ret[owner].auctionList, data.auctionList) } @@ -275,7 +262,7 @@ func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.In min = big.NewInt(0).SetBytes(owner.topUpPerNode.Bytes()) } - ownerNumNodesWithOnlyOneAuctionNode := big.NewInt(owner.activeNodes + 1) + ownerNumNodesWithOnlyOneAuctionNode := big.NewInt(owner.numActiveNodes + 1) maxPossibleTopUpForOwner := big.NewInt(0).Div(owner.totalTopUp, ownerNumNodesWithOnlyOneAuctionNode) if maxPossibleTopUpForOwner.Cmp(max) > 0 { max = big.NewInt(0).SetBytes(maxPossibleTopUpForOwner.Bytes()) @@ -288,11 +275,10 @@ func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.In return min, max } -func (als *auctionListSelector) selectNodesAndMinTopUp( +func (als *auctionListSelector) calcSoftAuctionNodesConfig( ownersData map[string]*ownerData, numAvailableSlots uint32, - randomness []byte, -) ([]state.ValidatorInfoHandler, *big.Int, error) { +) (map[string]*ownerData, *big.Int, error) { minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? log.Debug("auctionListSelector: calc min and max possible top up", "min top up", minTopUp.String(), @@ -304,13 +290,13 @@ func (als *auctionListSelector) selectNodesAndMinTopUp( previousConfig := copyOwnersData(ownersData) minRequiredTopUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) - var selectedNodes []state.ValidatorInfoHandler + for topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()); topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { numNodesQualifyingForTopUp := int64(0) previousConfig = copyOwnersData(ownersData) for ownerPubKey, owner := range ownersData { - activeNodes := big.NewInt(owner.activeNodes) + activeNodes := big.NewInt(owner.numActiveNodes) topUpActiveNodes := big.NewInt(0).Mul(topUp, activeNodes) validatorTopUpForAuction := big.NewInt(0).Sub(owner.totalTopUp, topUpActiveNodes) if validatorTopUpForAuction.Cmp(topUp) < 0 { @@ -319,13 +305,13 @@ func (als *auctionListSelector) selectNodesAndMinTopUp( } qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp).Int64() - if qualifiedNodes > owner.auctionNodes { - numNodesQualifyingForTopUp += owner.auctionNodes + if qualifiedNodes > owner.numAuctionNodes { + numNodesQualifyingForTopUp += owner.numAuctionNodes } else { numNodesQualifyingForTopUp += qualifiedNodes - owner.qualifiedAuctionNodes = qualifiedNodes + owner.numQualifiedAuctionNodes = qualifiedNodes - ownerRemainingNodes := big.NewInt(owner.activeNodes + owner.qualifiedAuctionNodes) + ownerRemainingNodes := big.NewInt(owner.numActiveNodes + owner.numQualifiedAuctionNodes) owner.qualifiedTopUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) } } @@ -338,8 +324,8 @@ func (als *auctionListSelector) selectNodesAndMinTopUp( } } - selectedNodes = als.selectNodes(previousConfig, numAvailableSlots, randomness) - return selectedNodes, minRequiredTopUp, nil + + return previousConfig, minRequiredTopUp, nil } func (als *auctionListSelector) selectNodes( @@ -351,21 +337,20 @@ func (als *auctionListSelector) selectNodes( validatorTopUpMap := make(map[string]*big.Int) for _, owner := range ownersData { - sortListByXORWithRand(owner.auctionList, randomness) - for i := int64(0); i < owner.qualifiedAuctionNodes; i++ { - currNode := owner.auctionList[i] - validatorTopUpMap[string(currNode.GetPublicKey())] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) - } - - selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.qualifiedAuctionNodes]...) + addQualifiedValidatorsTopUpInMap(owner, validatorTopUpMap) + selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } als.sortValidators(selectedFromAuction, validatorTopUpMap, randomness) + return selectedFromAuction[:numAvailableSlots] +} - selectedFromAuction = selectedFromAuction[:numAvailableSlots] - - return selectedFromAuction +func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { + for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { + validatorPubKey := owner.auctionList[i].GetPublicKey() + validatorTopUpMap[string(validatorPubKey)] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) + } } func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) { @@ -403,12 +388,12 @@ func (als *auctionListSelector) sortAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - - selectedNodes, minTopUp, err := als.selectNodesAndMinTopUp(ownersData, numOfAvailableNodeSlots, randomness) + softAuctionNodesConfig, minTopUp, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) if err != nil { return err } + selectedNodes := als.selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) err = markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) if err != nil { return err @@ -438,23 +423,6 @@ func (als *auctionListSelector) sortValidators( return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 }) - -} - -func (als *auctionListSelector) getValidatorTopUpMap(validators []state.ValidatorInfoHandler) (map[string]*big.Int, error) { - ret := make(map[string]*big.Int, len(validators)) - - for _, validator := range validators { - pubKey := validator.GetPublicKey() - topUp, err := als.stakingDataProvider.GetNodeStakedTopUp(pubKey) - if err != nil { - return nil, fmt.Errorf("%w when trying to get top up per node for %s", err, hex.EncodeToString(pubKey)) - } - - ret[string(pubKey)] = big.NewInt(0).SetBytes(topUp.Bytes()) - } - - return ret, nil } func calcNormRand(randomness []byte, expectedLen int) []byte { @@ -484,42 +452,6 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { return bytes.Compare(key1Xor, key2Xor) == 1 } -func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { - //if log.GetLevel() > logger.LogDebug { - // return - //} - - tableHeader := []string{"Owner", "Registered key", "TopUp per node"} - lines := make([]*display.LineData, 0, len(auctionList)) - horizontalLine := false - for idx, validator := range auctionList { - pubKey := validator.GetPublicKey() - - owner, err := als.stakingDataProvider.GetBlsKeyOwner(pubKey) - log.LogIfError(err) - - topUp, err := als.stakingDataProvider.GetNodeStakedTopUp(pubKey) - log.LogIfError(err) - - horizontalLine = uint32(idx) == numOfSelectedNodes-1 - line := display.NewLineData(horizontalLine, []string{ - (owner), - string(pubKey), - topUp.String(), - }) - lines = append(lines, line) - } - - table, err := display.CreateTableString(tableHeader, lines) - if err != nil { - log.Error("could not create table", "error", err) - return - } - - message := fmt.Sprintf("Auction list\n%s", table) - log.Info(message) -} - // IsInterfaceNil checks if the underlying pointer is nil func (als *auctionListSelector) IsInterfaceNil() bool { return als == nil From 900ed740ab7009f9772d4ae8a20344f1ae742439 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 12:20:38 +0300 Subject: [PATCH 274/958] CLN: Refactor 4 --- epochStart/metachain/auctionListDisplayer.go | 78 ++++++++++++++++++-- epochStart/metachain/auctionListSelector.go | 42 ++++++----- 2 files changed, 93 insertions(+), 27 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 2a0e8b7ffec..a5d4e749172 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -2,6 +2,7 @@ package metachain import ( "fmt" + "math/big" "strconv" "github.com/ElrondNetwork/elrond-go-core/display" @@ -10,6 +11,25 @@ import ( const maxPubKeyDisplayableLen = 20 +func displayRequiredTopUp(topUp *big.Int, max *big.Int, min *big.Int, step *big.Int) { + //if log.GetLevel() > logger.LogDebug { + // return + //} + + minPossible := big.NewInt(minEGLD) + if !(topUp.Cmp(minPossible) == 0) { + topUp = big.NewInt(0).Sub(topUp, step) + } + + valToIterate := big.NewInt(0).Sub(topUp, min) + iterations := big.NewInt(0).Div(valToIterate, step) + + log.Info("auctionListSelector: found min required", + "topUp", topUp.String(), + "after num of iterations", iterations.String(), + ) +} + func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { pubKeys := "" @@ -42,9 +62,9 @@ func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*owner tableHeader := []string{ "Owner", + "Num staked nodes", "Num active nodes", "Num auction nodes", - "Num staked nodes", "Total top up", "Top up per node", "Auction list nodes", @@ -54,9 +74,9 @@ func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*owner line := []string{ (ownerPubKey), + strconv.Itoa(int(owner.numStakedNodes)), strconv.Itoa(int(owner.numActiveNodes)), strconv.Itoa(int(owner.numAuctionNodes)), - strconv.Itoa(int(owner.numStakedNodes)), owner.totalTopUp.String(), owner.topUpPerNode.String(), getShortDisplayableBlsKeys(owner.auctionList), @@ -70,16 +90,60 @@ func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*owner return } - message := fmt.Sprintf("Nodes config in auction list\n%s", table) + message := fmt.Sprintf("Initial nodes config in auction list\n%s", table) + log.Info(message) +} + +func (als *auctionListSelector) displayOwnersSelectedConfig(ownersData2 map[string]*ownerData, randomness []byte) { + //if log.GetLevel() > logger.LogDebug { + // return + //} + ownersData := copyOwnersData(ownersData2) + tableHeader := []string{ + "Owner", + "Num staked nodes", + "TopUp per node", + "Total top up", + "Num auction nodes", + "Num qualified auction nodes", + "Num active nodes", + "Qualified top up per node", + "Selected auction list nodes", + } + lines := make([]*display.LineData, 0, len(ownersData)) + for ownerPubKey, owner := range ownersData { + selectedFromAuction := owner.auctionList[:owner.numQualifiedAuctionNodes] + + line := []string{ + (ownerPubKey), + strconv.Itoa(int(owner.numStakedNodes)), + owner.topUpPerNode.String(), + owner.totalTopUp.String(), + strconv.Itoa(int(owner.numAuctionNodes)), + strconv.Itoa(int(owner.numQualifiedAuctionNodes)), + strconv.Itoa(int(owner.numActiveNodes)), + owner.qualifiedTopUpPerNode.String(), + getShortDisplayableBlsKeys(selectedFromAuction), + } + lines = append(lines, display.NewLineData(false, line)) + } + + table, err := display.CreateTableString(tableHeader, lines) + if err != nil { + log.Error("could not create table", "error", err) + return + } + + message := fmt.Sprintf("Selected nodes config in auction list\n%s", table) log.Info(message) } -func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, numOfSelectedNodes uint32) { +func (als *auctionListSelector) displayAuctionListV2(auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfSelectedNodes uint32) { //if log.GetLevel() > logger.LogDebug { // return //} - tableHeader := []string{"Owner", "Registered key", "TopUp per node"} + tableHeader := []string{"Owner", "Registered key", "Qualified TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) horizontalLine := false for idx, validator := range auctionList { @@ -88,7 +152,7 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator owner, err := als.stakingDataProvider.GetBlsKeyOwner(pubKey) log.LogIfError(err) - topUp, err := als.stakingDataProvider.GetNodeStakedTopUp(pubKey) + topUp := ownersData[owner].qualifiedTopUpPerNode log.LogIfError(err) horizontalLine = uint32(idx) == numOfSelectedNodes-1 @@ -106,6 +170,6 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator return } - message := fmt.Sprintf("Auction list\n%s", table) + message := fmt.Sprintf("Final selected nodes from auction list\n%s", table) log.Info(message) } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index de93db90f43..29fe53a9b66 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/hex" "fmt" - "math" "math/big" "sort" @@ -17,6 +16,10 @@ import ( "github.com/ElrondNetwork/elrond-go/state" ) +const oneEGLD = 1000000000000000000 // with 18 decimals = 1 EGLD +const minEGLD = 1 // with 18 decimals = 0.00...01 egld +const maxEGLD = 21000000 // without 18 decimals + type auctionListSelector struct { shardCoordinator sharding.Coordinator stakingDataProvider epochStart.StakingDataProvider @@ -104,7 +107,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v -%v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - if len(auctionList) == 0 { + if auctionListSize == 0 { log.Debug("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") return nil } @@ -116,7 +119,6 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return err } - als.displayAuctionList(auctionList, numOfAvailableNodeSlots) return nil } @@ -254,7 +256,7 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { } func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { - min := big.NewInt(math.MaxInt64) + min := big.NewInt(0).Mul(big.NewInt(oneEGLD), big.NewInt(maxEGLD)) max := big.NewInt(0) for _, owner := range ownersData { @@ -268,8 +270,10 @@ func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.In max = big.NewInt(0).SetBytes(maxPossibleTopUpForOwner.Bytes()) } } - if min.Cmp(big.NewInt(1)) < 0 { - min = big.NewInt(1) + + minPossible := big.NewInt(minEGLD) + if min.Cmp(minPossible) < 0 { + min = minPossible } return min, max @@ -278,20 +282,18 @@ func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.In func (als *auctionListSelector) calcSoftAuctionNodesConfig( ownersData map[string]*ownerData, numAvailableSlots uint32, -) (map[string]*ownerData, *big.Int, error) { +) (map[string]*ownerData, error) { minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? - log.Debug("auctionListSelector: calc min and max possible top up", + log.Info("auctionListSelector: calc min and max possible top up", "min top up", minTopUp.String(), "max top up", maxTopUp.String(), ) - step := big.NewInt(10) // todo: granulate step if max- min < step???? - fmt.Println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^MIN TOP UP: ", minTopUp.Int64(), "MAX TOP UP", maxTopUp.Int64()) - + step := big.NewInt(10) // todo: granulate step if max- min < step???? + 10 egld for real previousConfig := copyOwnersData(ownersData) - minRequiredTopUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) + topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) - for topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()); topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { + for ; topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { numNodesQualifyingForTopUp := int64(0) previousConfig = copyOwnersData(ownersData) @@ -317,15 +319,12 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } if numNodesQualifyingForTopUp < int64(numAvailableSlots) { - if !(topUp.Cmp(minTopUp) == 0) { - minRequiredTopUp = big.NewInt(0).Sub(topUp, step) - } break } } - - return previousConfig, minRequiredTopUp, nil + displayRequiredTopUp(topUp, maxTopUp, minTopUp, step) + return previousConfig, nil } func (als *auctionListSelector) selectNodes( @@ -342,7 +341,10 @@ func (als *auctionListSelector) selectNodes( selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } + als.displayOwnersSelectedConfig(ownersData, randomness) als.sortValidators(selectedFromAuction, validatorTopUpMap, randomness) + als.displayAuctionListV2(selectedFromAuction, ownersData, numAvailableSlots) + return selectedFromAuction[:numAvailableSlots] } @@ -388,7 +390,8 @@ func (als *auctionListSelector) sortAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - softAuctionNodesConfig, minTopUp, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) + // TODO: Here add a stopwatch to measure execution time + softAuctionNodesConfig, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) if err != nil { return err } @@ -399,7 +402,6 @@ func (als *auctionListSelector) sortAuctionList( return err } - _ = minTopUp return nil } From c9f2fb067c51291b894a0d2015d726c450cbcaf1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 13:08:05 +0300 Subject: [PATCH 275/958] CLN: Refactor 5 --- epochStart/metachain/auctionListDisplayer.go | 4 +- epochStart/metachain/auctionListSelector.go | 76 +++++++++++--------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index a5d4e749172..c6358c00e17 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -94,7 +94,7 @@ func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*owner log.Info(message) } -func (als *auctionListSelector) displayOwnersSelectedConfig(ownersData2 map[string]*ownerData, randomness []byte) { +func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData2 map[string]*ownerData) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -138,7 +138,7 @@ func (als *auctionListSelector) displayOwnersSelectedConfig(ownersData2 map[stri log.Info(message) } -func (als *auctionListSelector) displayAuctionListV2(auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfSelectedNodes uint32) { +func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfSelectedNodes uint32) { //if log.GetLevel() > logger.LogDebug { // return //} diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 29fe53a9b66..96c4082299b 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -18,7 +18,7 @@ import ( const oneEGLD = 1000000000000000000 // with 18 decimals = 1 EGLD const minEGLD = 1 // with 18 decimals = 0.00...01 egld -const maxEGLD = 21000000 // without 18 decimals +const allEGLD = 21000000 // without 18 decimals type auctionListSelector struct { shardCoordinator sharding.Coordinator @@ -71,10 +71,14 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) - auctionList, ownersData, currNumOfValidators, err := als.getAuctionListAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) + ownersData, auctionListSize, currNumOfValidators, err := als.getAuctionDataAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) if err != nil { return err } + if auctionListSize == 0 { + log.Debug("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") + return nil + } numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { @@ -97,7 +101,6 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return nil } - auctionListSize := uint32(len(auctionList)) log.Info("systemSCProcessor.SelectNodesFromAuctionList", "max nodes", maxNumNodes, "current number of validators", currNumOfValidators, @@ -107,19 +110,17 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v -%v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - if auctionListSize == 0 { - log.Debug("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") - return nil - } - als.displayOwnersConfig(ownersData) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) - err = als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) - if err != nil { - return err - } - return nil + sw := core.NewStopWatch() + sw.Start("auctionListSelector.sortAuctionList") + defer func() { + sw.Stop("auctionListSelector.sortAuctionList") + log.Info("time measurements", sw.GetMeasurements()...) + }() + + return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } // TODO: Move this in elrond-go-core @@ -130,18 +131,18 @@ func safeSub(a, b uint32) (uint32, error) { return a - b, nil } -func (als *auctionListSelector) getAuctionListAndNumOfValidators( +func (als *auctionListSelector) getAuctionDataAndNumOfValidators( validatorsInfoMap state.ShardValidatorsInfoMapHandler, unqualifiedOwners map[string]struct{}, -) ([]state.ValidatorInfoHandler, map[string]*ownerData, uint32, error) { +) (map[string]*ownerData, uint32, uint32, error) { ownersData := make(map[string]*ownerData) - auctionList := make([]state.ValidatorInfoHandler, 0) numOfValidators := uint32(0) + numOfNodesInAuction := uint32(0) for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) if err != nil { - return nil, nil, 0, err + return nil, 0, 0, err } if isInAuction(validator) { @@ -156,10 +157,10 @@ func (als *auctionListSelector) getAuctionListAndNumOfValidators( err = als.addOwnerData(validator, ownersData) if err != nil { - return nil, nil, 0, err + return nil, 0, 0, err } - auctionList = append(auctionList, validator) + numOfNodesInAuction++ continue } if isValidator(validator) { @@ -167,7 +168,7 @@ func (als *auctionListSelector) getAuctionListAndNumOfValidators( } } - return auctionList, ownersData, numOfValidators, nil + return ownersData, numOfNodesInAuction, numOfValidators, nil } func isInAuction(validator state.ValidatorInfoHandler) bool { @@ -256,7 +257,7 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { } func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { - min := big.NewInt(0).Mul(big.NewInt(oneEGLD), big.NewInt(maxEGLD)) + min := big.NewInt(0).Mul(big.NewInt(oneEGLD), big.NewInt(allEGLD)) max := big.NewInt(0) for _, owner := range ownersData { @@ -290,9 +291,9 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( ) step := big.NewInt(10) // todo: granulate step if max- min < step???? + 10 egld for real - previousConfig := copyOwnersData(ownersData) topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) + previousConfig := copyOwnersData(ownersData) for ; topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { numNodesQualifyingForTopUp := int64(0) previousConfig = copyOwnersData(ownersData) @@ -323,6 +324,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } } + displayRequiredTopUp(topUp, maxTopUp, minTopUp, step) return previousConfig, nil } @@ -335,19 +337,30 @@ func (als *auctionListSelector) selectNodes( selectedFromAuction := make([]state.ValidatorInfoHandler, 0) validatorTopUpMap := make(map[string]*big.Int) + pubKeyLen := getPubKeyLen(ownersData) + normRand := calcNormRand(randomness, pubKeyLen) + for _, owner := range ownersData { - sortListByXORWithRand(owner.auctionList, randomness) + sortListByXORWithRand(owner.auctionList, normRand) addQualifiedValidatorsTopUpInMap(owner, validatorTopUpMap) selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } - als.displayOwnersSelectedConfig(ownersData, randomness) - als.sortValidators(selectedFromAuction, validatorTopUpMap, randomness) - als.displayAuctionListV2(selectedFromAuction, ownersData, numAvailableSlots) + als.displayOwnersSelectedNodes(ownersData) + als.sortValidators(selectedFromAuction, validatorTopUpMap, normRand) + als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) return selectedFromAuction[:numAvailableSlots] } +func getPubKeyLen(ownersData map[string]*ownerData) int { + for _, owner := range ownersData { + return len(owner.auctionList[0].GetPublicKey()) + } + + return 0 +} + func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { validatorPubKey := owner.auctionList[i].GetPublicKey() @@ -356,14 +369,11 @@ func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[st } func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) { - pubKeyLen := len(list[0].GetPublicKey()) - normRandomness := calcNormRand(randomness, pubKeyLen) - sort.SliceStable(list, func(i, j int) bool { pubKey1 := list[i].GetPublicKey() pubKey2 := list[j].GetPublicKey() - return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) + return compareByXORWithRandomness(pubKey1, pubKey2, randomness) }) } @@ -390,13 +400,13 @@ func (als *auctionListSelector) sortAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - // TODO: Here add a stopwatch to measure execution time softAuctionNodesConfig, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) if err != nil { return err } selectedNodes := als.selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) + err = markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) if err != nil { return err @@ -410,8 +420,6 @@ func (als *auctionListSelector) sortValidators( validatorTopUpMap map[string]*big.Int, randomness []byte, ) { - pubKeyLen := len(auctionList[0].GetPublicKey()) - normRandomness := calcNormRand(randomness, pubKeyLen) sort.SliceStable(auctionList, func(i, j int) bool { pubKey1 := auctionList[i].GetPublicKey() pubKey2 := auctionList[j].GetPublicKey() @@ -420,7 +428,7 @@ func (als *auctionListSelector) sortValidators( nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { - return compareByXORWithRandomness(pubKey1, pubKey2, normRandomness) + return compareByXORWithRandomness(pubKey1, pubKey2, randomness) } return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 From 31118ab24ec231e7a2be1304719ab5ba6e2a046d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 13:42:45 +0300 Subject: [PATCH 276/958] FIX: After review --- epochStart/errors.go | 3 ++ epochStart/metachain/auctionListSelector.go | 6 ++-- .../metachain/auctionListSelector_test.go | 32 +++++++++++++++++++ epochStart/notifier/nodesConfigProvider.go | 10 +++--- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 0023fd5625b..6295220614a 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -334,3 +334,6 @@ var ErrNilMaxNodesChangeConfigProvider = errors.New("nil nodes config provider h // ErrNilAuctionListSelector signals that a nil auction list selector has been provided var ErrNilAuctionListSelector = errors.New("nil auction list selector has been provided") + +// ErrUint32SubtractionOverflow signals uint32 subtraction overflowed +var ErrUint32SubtractionOverflow = errors.New("uint32 subtraction overflowed") diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 5077c231e3b..6da73c9f954 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -119,7 +119,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList(validatorsInfoMap sta // TODO: Move this in elrond-go-core func safeSub(a, b uint32) (uint32, error) { if a < b { - return 0, core.ErrSubtractionOverflow + return 0, epochStart.ErrUint32SubtractionOverflow } return a - b, nil } @@ -152,7 +152,7 @@ func (als *auctionListSelector) sortAuctionList(auctionList []state.ValidatorInf } pubKeyLen := len(auctionList[0].GetPublicKey()) - normRandomness := calcNormRand(randomness, pubKeyLen) + normRandomness := calcNormalizedRandomness(randomness, pubKeyLen) sort.SliceStable(auctionList, func(i, j int) bool { pubKey1 := auctionList[i].GetPublicKey() pubKey2 := auctionList[j].GetPublicKey() @@ -186,7 +186,7 @@ func (als *auctionListSelector) getValidatorTopUpMap(validators []state.Validato return ret, nil } -func calcNormRand(randomness []byte, expectedLen int) []byte { +func calcNormalizedRandomness(randomness []byte, expectedLen int) []byte { rand := randomness randLen := len(rand) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 5a0dd95687e..8713eb9815b 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -131,3 +131,35 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) } + +func TestCalcNormRand(t *testing.T) { + t.Parallel() + + t.Run("randomness longer than expected len", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 2) + require.Equal(t, []byte("ra"), result) + }) + + t.Run("randomness length equal to expected len", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 4) + require.Equal(t, []byte("rand"), result) + }) + + t.Run("randomness length less than expected len", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 6) + require.Equal(t, []byte("randra"), result) + }) + + t.Run("expected len is zero", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 0) + require.Empty(t, result) + }) +} diff --git a/epochStart/notifier/nodesConfigProvider.go b/epochStart/notifier/nodesConfigProvider.go index d9019f56b68..0ebcc5c49d6 100644 --- a/epochStart/notifier/nodesConfigProvider.go +++ b/epochStart/notifier/nodesConfigProvider.go @@ -11,7 +11,7 @@ import ( ) type nodesConfigProvider struct { - mutex sync.Mutex + mutex sync.RWMutex currentNodesConfig config.MaxNodesChangeConfig allNodesConfigs []config.MaxNodesChangeConfig } @@ -47,16 +47,16 @@ func (ncp *nodesConfigProvider) sortConfigs() { // GetAllNodesConfig returns all config.MaxNodesChangeConfig func (ncp *nodesConfigProvider) GetAllNodesConfig() []config.MaxNodesChangeConfig { - ncp.mutex.Lock() - defer ncp.mutex.Unlock() + ncp.mutex.RLock() + defer ncp.mutex.RUnlock() return ncp.allNodesConfigs } // GetCurrentNodesConfig returns the current config.MaxNodesChangeConfig, based on epoch func (ncp *nodesConfigProvider) GetCurrentNodesConfig() config.MaxNodesChangeConfig { - ncp.mutex.Lock() - defer ncp.mutex.Unlock() + ncp.mutex.RLock() + defer ncp.mutex.RUnlock() return ncp.currentNodesConfig } From 5a363a0a0e7a3770a5b65e4e98c7aee919eaf5fa Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 13:46:42 +0300 Subject: [PATCH 277/958] FIX: After merges --- epochStart/errors.go | 3 ++ epochStart/metachain/auctionListSelector.go | 6 +-- .../metachain/auctionListSelector_test.go | 37 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 53652eb7a11..4be6c61eb5b 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -337,3 +337,6 @@ var ErrNilAuctionListSelector = errors.New("nil auction list selector has been p // ErrOwnerHasNoStakedNode signals that an owner has no staked node var ErrOwnerHasNoStakedNode = errors.New("owner has no staked node") + +// ErrUint32SubtractionOverflow signals uint32 subtraction overflowed +var ErrUint32SubtractionOverflow = errors.New("uint32 subtraction overflowed") diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 96c4082299b..0b6c011fdd7 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -126,7 +126,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( // TODO: Move this in elrond-go-core func safeSub(a, b uint32) (uint32, error) { if a < b { - return 0, core.ErrSubtractionOverflow + return 0, epochStart.ErrUint32SubtractionOverflow } return a - b, nil } @@ -338,7 +338,7 @@ func (als *auctionListSelector) selectNodes( validatorTopUpMap := make(map[string]*big.Int) pubKeyLen := getPubKeyLen(ownersData) - normRand := calcNormRand(randomness, pubKeyLen) + normRand := calcNormalizedRandomness(randomness, pubKeyLen) for _, owner := range ownersData { sortListByXORWithRand(owner.auctionList, normRand) @@ -435,7 +435,7 @@ func (als *auctionListSelector) sortValidators( }) } -func calcNormRand(randomness []byte, expectedLen int) []byte { +func calcNormalizedRandomness(randomness []byte, expectedLen int) []byte { rand := randomness randLen := len(rand) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 10d0be4164a..09df1e9794c 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -152,3 +152,40 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) } */ + +func TestCalcNormalizedRandomness(t *testing.T) { + t.Parallel() + + t.Run("randomness longer than expected len", func(t *testing.T) { + t.Parallel() + + randomness := []byte("rand") + expectedLen := 2 + + result := calcNormalizedRandomness(randomness, expectedLen) + + require.Equal(t, []byte("ra"), result) + }) + + t.Run("randomness length equal to expected len", func(t *testing.T) { + t.Parallel() + + randomness := []byte("rand") + expectedLen := 4 + + result := calcNormalizedRandomness(randomness, expectedLen) + + require.Equal(t, []byte("rand"), result) + }) + + t.Run("randomness length less than expected len", func(t *testing.T) { + t.Parallel() + + randomness := []byte("rand") + expectedLen := 6 + + result := calcNormalizedRandomness(randomness, expectedLen) + + require.Equal(t, []byte("randra"), result) + }) +} From c3217c1e745977bd86c608b0638133d7cf86a6a7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 13:48:29 +0300 Subject: [PATCH 278/958] FIX: After merges 2 --- .../metachain/auctionListSelector_test.go | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 09df1e9794c..11a9a6a3a58 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -159,33 +159,28 @@ func TestCalcNormalizedRandomness(t *testing.T) { t.Run("randomness longer than expected len", func(t *testing.T) { t.Parallel() - randomness := []byte("rand") - expectedLen := 2 - - result := calcNormalizedRandomness(randomness, expectedLen) - + result := calcNormalizedRandomness([]byte("rand"), 2) require.Equal(t, []byte("ra"), result) }) t.Run("randomness length equal to expected len", func(t *testing.T) { t.Parallel() - randomness := []byte("rand") - expectedLen := 4 - - result := calcNormalizedRandomness(randomness, expectedLen) - + result := calcNormalizedRandomness([]byte("rand"), 4) require.Equal(t, []byte("rand"), result) }) t.Run("randomness length less than expected len", func(t *testing.T) { t.Parallel() - randomness := []byte("rand") - expectedLen := 6 + result := calcNormalizedRandomness([]byte("rand"), 6) + require.Equal(t, []byte("randra"), result) + }) - result := calcNormalizedRandomness(randomness, expectedLen) + t.Run("expected len is zero", func(t *testing.T) { + t.Parallel() - require.Equal(t, []byte("randra"), result) + result := calcNormalizedRandomness([]byte("rand"), 0) + require.Empty(t, result) }) } From b932f5903f45aa893ab302e020f794c214051033 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 14:25:52 +0300 Subject: [PATCH 279/958] CLN: Refactor 5 --- epochStart/errors.go | 3 --- epochStart/metachain/auctionListSelector.go | 9 ++++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 4be6c61eb5b..92ff5cb8b18 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -323,9 +323,6 @@ var ErrNilScheduledDataSyncerFactory = errors.New("nil scheduled data syncer fac // ErrCouldNotInitLiquidStakingSystemSC signals that liquid staking system sc init failed var ErrCouldNotInitLiquidStakingSystemSC = errors.New("could not init liquid staking system sc") -// ErrSortAuctionList signals that an error occurred while trying to sort auction list -var ErrSortAuctionList = errors.New("error while trying to sort auction list") - // ErrReceivedNewListNodeInStakingV4 signals that a new node has been assigned in common.NewList instead of common.AuctionList after staking v4 var ErrReceivedNewListNodeInStakingV4 = errors.New("new node has been assigned in common.NewList instead of common.AuctionList after staking v4") diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 0b6c011fdd7..1d3b72a76e0 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -26,7 +26,7 @@ type auctionListSelector struct { nodesConfigProvider epochStart.MaxNodesChangeConfigProvider } -// AuctionListSelectorArgs is a struct placeholder for all arguments required to create a NewAuctionListSelector +// AuctionListSelectorArgs is a struct placeholder for all arguments required to create a auctionListSelector type AuctionListSelectorArgs struct { ShardCoordinator sharding.Coordinator StakingDataProvider epochStart.StakingDataProvider @@ -68,9 +68,6 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return process.ErrNilRandSeed } - currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() - numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) - ownersData, auctionListSize, currNumOfValidators, err := als.getAuctionDataAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) if err != nil { return err @@ -80,6 +77,8 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return nil } + currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() + numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", @@ -107,7 +106,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( "num of nodes which will be shuffled out", numOfShuffledNodes, "num of validators after shuffling", numOfValidatorsAfterShuffling, "auction list size", auctionListSize, - fmt.Sprintf("available slots (%v -%v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, + fmt.Sprintf("available slots (%v - %v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) als.displayOwnersConfig(ownersData) From b3b91296f78c0ca45517082cf8c27383005cf68f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 14:46:03 +0300 Subject: [PATCH 280/958] CLN: Refactor 6 --- epochStart/metachain/auctionListDisplayer.go | 2 +- epochStart/metachain/auctionListSelector.go | 234 ++++++------------- epochStart/metachain/auctionListSorting.go | 104 +++++++++ 3 files changed, 171 insertions(+), 169 deletions(-) create mode 100644 epochStart/metachain/auctionListSorting.go diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index c6358c00e17..7c73b25056c 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -11,7 +11,7 @@ import ( const maxPubKeyDisplayableLen = 20 -func displayRequiredTopUp(topUp *big.Int, max *big.Int, min *big.Int, step *big.Int) { +func displayRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { //if log.GetLevel() > logger.LogDebug { // return //} diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 1d3b72a76e0..8d1e18a9862 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -1,11 +1,9 @@ package metachain import ( - "bytes" "encoding/hex" "fmt" "math/big" - "sort" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/core/check" @@ -20,6 +18,17 @@ const oneEGLD = 1000000000000000000 // with 18 decimals = 1 EGLD const minEGLD = 1 // with 18 decimals = 0.00...01 egld const allEGLD = 21000000 // without 18 decimals +type ownerData struct { + numActiveNodes int64 + numAuctionNodes int64 + numQualifiedAuctionNodes int64 + numStakedNodes int64 + totalTopUp *big.Int + topUpPerNode *big.Int + qualifiedTopUpPerNode *big.Int + auctionList []state.ValidatorInfoHandler +} + type auctionListSelector struct { shardCoordinator sharding.Coordinator stakingDataProvider epochStart.StakingDataProvider @@ -122,14 +131,6 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } -// TODO: Move this in elrond-go-core -func safeSub(a, b uint32) (uint32, error) { - if a < b { - return 0, epochStart.ErrUint32SubtractionOverflow - } - return a - b, nil -} - func (als *auctionListSelector) getAuctionDataAndNumOfValidators( validatorsInfoMap state.ShardValidatorsInfoMapHandler, unqualifiedOwners map[string]struct{}, @@ -174,40 +175,30 @@ func isInAuction(validator state.ValidatorInfoHandler) bool { return validator.GetList() == string(common.AuctionList) } -type ownerData struct { - numActiveNodes int64 - numAuctionNodes int64 - numQualifiedAuctionNodes int64 - numStakedNodes int64 - totalTopUp *big.Int - topUpPerNode *big.Int - qualifiedTopUpPerNode *big.Int - auctionList []state.ValidatorInfoHandler -} - func (als *auctionListSelector) addOwnerData( validator state.ValidatorInfoHandler, ownersData map[string]*ownerData, ) error { - owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) + validatorPubKey := validator.GetPublicKey() + owner, err := als.stakingDataProvider.GetBlsKeyOwner(validatorPubKey) if err != nil { return err } - stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes([]byte(owner)) + ownerPubKey := []byte(owner) + stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes(ownerPubKey) if err != nil { return err } - if stakedNodes == 0 { return fmt.Errorf("auctionListSelector.getOwnersDat: error: %w, owner: %s, node: %s", epochStart.ErrOwnerHasNoStakedNode, - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(validator.GetPublicKey()), + hex.EncodeToString(ownerPubKey), + hex.EncodeToString(validatorPubKey), ) } - totalTopUp, err := als.stakingDataProvider.GetTotalTopUp([]byte(owner)) + totalTopUp, err := als.stakingDataProvider.GetTotalTopUp(ownerPubKey) if err != nil { return err } @@ -236,47 +227,27 @@ func (als *auctionListSelector) addOwnerData( return nil } -func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { - ret := make(map[string]*ownerData) - for owner, data := range ownersData { - ret[owner] = &ownerData{ - numActiveNodes: data.numActiveNodes, - numAuctionNodes: data.numAuctionNodes, - numQualifiedAuctionNodes: data.numQualifiedAuctionNodes, - numStakedNodes: data.numStakedNodes, - totalTopUp: data.totalTopUp, - topUpPerNode: data.topUpPerNode, - qualifiedTopUpPerNode: data.qualifiedTopUpPerNode, - auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), - } - copy(ret[owner].auctionList, data.auctionList) +// TODO: Move this in elrond-go-core +func safeSub(a, b uint32) (uint32, error) { + if a < b { + return 0, epochStart.ErrUint32SubtractionOverflow } - - return ret + return a - b, nil } -func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { - min := big.NewInt(0).Mul(big.NewInt(oneEGLD), big.NewInt(allEGLD)) - max := big.NewInt(0) - - for _, owner := range ownersData { - if owner.topUpPerNode.Cmp(min) < 0 { - min = big.NewInt(0).SetBytes(owner.topUpPerNode.Bytes()) - } - - ownerNumNodesWithOnlyOneAuctionNode := big.NewInt(owner.numActiveNodes + 1) - maxPossibleTopUpForOwner := big.NewInt(0).Div(owner.totalTopUp, ownerNumNodesWithOnlyOneAuctionNode) - if maxPossibleTopUpForOwner.Cmp(max) > 0 { - max = big.NewInt(0).SetBytes(maxPossibleTopUpForOwner.Bytes()) - } - } - - minPossible := big.NewInt(minEGLD) - if min.Cmp(minPossible) < 0 { - min = minPossible +func (als *auctionListSelector) sortAuctionList( + ownersData map[string]*ownerData, + numOfAvailableNodeSlots uint32, + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + randomness []byte, +) error { + softAuctionNodesConfig, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) + if err != nil { + return err } - return min, max + selectedNodes := als.selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) + return markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) } func (als *auctionListSelector) calcSoftAuctionNodesConfig( @@ -324,56 +295,51 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } - displayRequiredTopUp(topUp, maxTopUp, minTopUp, step) + displayRequiredTopUp(topUp, minTopUp, step) return previousConfig, nil } -func (als *auctionListSelector) selectNodes( - ownersData map[string]*ownerData, - numAvailableSlots uint32, - randomness []byte, -) []state.ValidatorInfoHandler { - selectedFromAuction := make([]state.ValidatorInfoHandler, 0) - validatorTopUpMap := make(map[string]*big.Int) - - pubKeyLen := getPubKeyLen(ownersData) - normRand := calcNormalizedRandomness(randomness, pubKeyLen) +func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { + min := big.NewInt(0).Mul(big.NewInt(oneEGLD), big.NewInt(allEGLD)) + max := big.NewInt(0) for _, owner := range ownersData { - sortListByXORWithRand(owner.auctionList, normRand) - addQualifiedValidatorsTopUpInMap(owner, validatorTopUpMap) - selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) - } - - als.displayOwnersSelectedNodes(ownersData) - als.sortValidators(selectedFromAuction, validatorTopUpMap, normRand) - als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) + if owner.topUpPerNode.Cmp(min) < 0 { + min = big.NewInt(0).SetBytes(owner.topUpPerNode.Bytes()) + } - return selectedFromAuction[:numAvailableSlots] -} + ownerNumNodesWithOnlyOneAuctionNode := big.NewInt(owner.numActiveNodes + 1) + maxPossibleTopUpForOwner := big.NewInt(0).Div(owner.totalTopUp, ownerNumNodesWithOnlyOneAuctionNode) + if maxPossibleTopUpForOwner.Cmp(max) > 0 { + max = big.NewInt(0).SetBytes(maxPossibleTopUpForOwner.Bytes()) + } + } -func getPubKeyLen(ownersData map[string]*ownerData) int { - for _, owner := range ownersData { - return len(owner.auctionList[0].GetPublicKey()) + minPossible := big.NewInt(minEGLD) + if min.Cmp(minPossible) < 0 { + min = minPossible } - return 0 + return min, max } -func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { - for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { - validatorPubKey := owner.auctionList[i].GetPublicKey() - validatorTopUpMap[string(validatorPubKey)] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) +func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { + ret := make(map[string]*ownerData) + for owner, data := range ownersData { + ret[owner] = &ownerData{ + numActiveNodes: data.numActiveNodes, + numAuctionNodes: data.numAuctionNodes, + numQualifiedAuctionNodes: data.numQualifiedAuctionNodes, + numStakedNodes: data.numStakedNodes, + totalTopUp: data.totalTopUp, + topUpPerNode: data.topUpPerNode, + qualifiedTopUpPerNode: data.qualifiedTopUpPerNode, + auctionList: make([]state.ValidatorInfoHandler, len(data.auctionList)), + } + copy(ret[owner].auctionList, data.auctionList) } -} -func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) { - sort.SliceStable(list, func(i, j int) bool { - pubKey1 := list[i].GetPublicKey() - pubKey2 := list[j].GetPublicKey() - - return compareByXORWithRandomness(pubKey1, pubKey2, randomness) - }) + return ret } func markAuctionNodesAsSelected( @@ -393,74 +359,6 @@ func markAuctionNodesAsSelected( return nil } -func (als *auctionListSelector) sortAuctionList( - ownersData map[string]*ownerData, - numOfAvailableNodeSlots uint32, - validatorsInfoMap state.ShardValidatorsInfoMapHandler, - randomness []byte, -) error { - softAuctionNodesConfig, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) - if err != nil { - return err - } - - selectedNodes := als.selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) - - err = markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) - if err != nil { - return err - } - - return nil -} - -func (als *auctionListSelector) sortValidators( - auctionList []state.ValidatorInfoHandler, - validatorTopUpMap map[string]*big.Int, - randomness []byte, -) { - sort.SliceStable(auctionList, func(i, j int) bool { - pubKey1 := auctionList[i].GetPublicKey() - pubKey2 := auctionList[j].GetPublicKey() - - nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] - nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] - - if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { - return compareByXORWithRandomness(pubKey1, pubKey2, randomness) - } - - return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 - }) -} - -func calcNormalizedRandomness(randomness []byte, expectedLen int) []byte { - rand := randomness - randLen := len(rand) - - if expectedLen > randLen { - repeatedCt := expectedLen/randLen + 1 - rand = bytes.Repeat(randomness, repeatedCt) - } - - rand = rand[:expectedLen] - return rand -} - -func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { - xorLen := len(randomness) - - key1Xor := make([]byte, xorLen) - key2Xor := make([]byte, xorLen) - - for idx := 0; idx < xorLen; idx++ { - key1Xor[idx] = pubKey1[idx] ^ randomness[idx] - key2Xor[idx] = pubKey2[idx] ^ randomness[idx] - } - - return bytes.Compare(key1Xor, key2Xor) == 1 -} - // IsInterfaceNil checks if the underlying pointer is nil func (als *auctionListSelector) IsInterfaceNil() bool { return als == nil diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go new file mode 100644 index 00000000000..f875dafd773 --- /dev/null +++ b/epochStart/metachain/auctionListSorting.go @@ -0,0 +1,104 @@ +package metachain + +import ( + "bytes" + "math/big" + "sort" + + "github.com/ElrondNetwork/elrond-go/state" +) + +func (als *auctionListSelector) selectNodes( + ownersData map[string]*ownerData, + numAvailableSlots uint32, + randomness []byte, +) []state.ValidatorInfoHandler { + selectedFromAuction := make([]state.ValidatorInfoHandler, 0) + validatorTopUpMap := make(map[string]*big.Int) + + pubKeyLen := getPubKeyLen(ownersData) + normRand := calcNormalizedRandomness(randomness, pubKeyLen) + + for _, owner := range ownersData { + sortListByXORWithRand(owner.auctionList, normRand) + addQualifiedValidatorsTopUpInMap(owner, validatorTopUpMap) + selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) + } + + als.displayOwnersSelectedNodes(ownersData) + als.sortValidators(selectedFromAuction, validatorTopUpMap, normRand) + als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) + + return selectedFromAuction[:numAvailableSlots] +} + +func getPubKeyLen(ownersData map[string]*ownerData) int { + for _, owner := range ownersData { + return len(owner.auctionList[0].GetPublicKey()) + } + + return 0 +} + +func calcNormalizedRandomness(randomness []byte, expectedLen int) []byte { + rand := randomness + randLen := len(rand) + + if expectedLen > randLen { + repeatedCt := expectedLen/randLen + 1 + rand = bytes.Repeat(randomness, repeatedCt) + } + + rand = rand[:expectedLen] + return rand +} + +func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) { + sort.SliceStable(list, func(i, j int) bool { + pubKey1 := list[i].GetPublicKey() + pubKey2 := list[j].GetPublicKey() + + return compareByXORWithRandomness(pubKey1, pubKey2, randomness) + }) +} + +func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { + xorLen := len(randomness) + + key1Xor := make([]byte, xorLen) + key2Xor := make([]byte, xorLen) + + for idx := 0; idx < xorLen; idx++ { + key1Xor[idx] = pubKey1[idx] ^ randomness[idx] + key2Xor[idx] = pubKey2[idx] ^ randomness[idx] + } + + return bytes.Compare(key1Xor, key2Xor) == 1 +} + +func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { + for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { + validatorPubKey := owner.auctionList[i].GetPublicKey() + validatorTopUpMap[string(validatorPubKey)] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) + } +} + +func (als *auctionListSelector) sortValidators( + auctionList []state.ValidatorInfoHandler, + validatorTopUpMap map[string]*big.Int, + randomness []byte, +) { + sort.SliceStable(auctionList, func(i, j int) bool { + pubKey1 := auctionList[i].GetPublicKey() + pubKey2 := auctionList[j].GetPublicKey() + + nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] + nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] + + if nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) == 0 { + return compareByXORWithRandomness(pubKey1, pubKey2, randomness) + } + + return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 + }) +} From fd6898f0ec3d849345d16362d03b3f58d7f8998e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 23 May 2022 15:57:59 +0300 Subject: [PATCH 281/958] CLN: Refactor 7 --- epochStart/errors.go | 3 + epochStart/interface.go | 1 - epochStart/metachain/auctionListDisplayer.go | 76 ++++++++-------- epochStart/metachain/auctionListSelector.go | 7 +- epochStart/metachain/auctionListSorting.go | 12 +-- epochStart/metachain/stakingDataProvider.go | 45 +--------- epochStart/metachain/systemSCs.go | 5 +- epochStart/metachain/systemSCs_test.go | 93 ++++++++++++-------- epochStart/mock/stakingDataProviderStub.go | 6 +- 9 files changed, 112 insertions(+), 136 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 92ff5cb8b18..ba89dc864c8 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -284,6 +284,9 @@ var ErrSystemValidatorSCCall = errors.New("system validator sc call failed") // ErrOwnerDoesntHaveEligibleNodesInEpoch signals that the owner doesn't have any eligible nodes in epoch var ErrOwnerDoesntHaveEligibleNodesInEpoch = errors.New("owner has no eligible nodes in epoch") +// ErrOwnerDoesntHaveNodesInEpoch signals that the owner has no nodes in epoch +var ErrOwnerDoesntHaveNodesInEpoch = errors.New("owner has no nodes in epoch") + // ErrInvalidMaxHardCapForMissingNodes signals that the maximum hardcap value for missing nodes is invalid var ErrInvalidMaxHardCapForMissingNodes = errors.New("invalid max hardcap for missing nodes") diff --git a/epochStart/interface.go b/epochStart/interface.go index 04ab154d4ee..a259d030185 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -154,7 +154,6 @@ type StakingDataProvider interface { GetNumStakedNodes(owner []byte) (int64, error) GetTotalTopUp(owner []byte) (*big.Int, error) PrepareStakingData(keys map[uint32][][]byte) error - PrepareStakingDataForStakingV4(validatorsMap state.ShardValidatorsInfoMapHandler) error FillValidatorInfo(blsKey []byte) error ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 7c73b25056c..318f43f4eaf 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -11,7 +11,7 @@ import ( const maxPubKeyDisplayableLen = 20 -func displayRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { +func displayMinRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -21,8 +21,8 @@ func displayRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { topUp = big.NewInt(0).Sub(topUp, step) } - valToIterate := big.NewInt(0).Sub(topUp, min) - iterations := big.NewInt(0).Div(valToIterate, step) + iteratedValues := big.NewInt(0).Sub(topUp, min) + iterations := big.NewInt(0).Div(iteratedValues, step) log.Info("auctionListSelector: found min required", "topUp", topUp.String(), @@ -30,22 +30,24 @@ func displayRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { ) } +func getShortKey(pubKey []byte) string { + displayablePubKey := pubKey + pubKeyLen := len(pubKey) + if pubKeyLen > maxPubKeyDisplayableLen { + displayablePubKey = make([]byte, 0) + displayablePubKey = append(displayablePubKey, pubKey[:maxPubKeyDisplayableLen/2]...) + displayablePubKey = append(displayablePubKey, []byte("...")...) + displayablePubKey = append(displayablePubKey, pubKey[pubKeyLen-maxPubKeyDisplayableLen/2:]...) + } + + return string(displayablePubKey) +} + func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { pubKeys := "" for idx, validator := range list { - pubKey := validator.GetPublicKey() - displayablePubKey := pubKey - - pubKeyLen := len(pubKey) - if pubKeyLen > maxPubKeyDisplayableLen { - displayablePubKey = make([]byte, 0) - displayablePubKey = append(displayablePubKey, pubKey[:maxPubKeyDisplayableLen/2]...) - displayablePubKey = append(displayablePubKey, []byte("...")...) - displayablePubKey = append(displayablePubKey, pubKey[pubKeyLen-maxPubKeyDisplayableLen/2:]...) - } - - pubKeys += string(displayablePubKey) // todo: hex here + pubKeys += getShortKey(validator.GetPublicKey()) // todo: hex here addDelimiter := idx != len(list)-1 if addDelimiter { pubKeys += ", " @@ -55,7 +57,7 @@ func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { return pubKeys } -func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*ownerData) { +func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerData) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -84,14 +86,7 @@ func (als *auctionListSelector) displayOwnersConfig(ownersData map[string]*owner lines = append(lines, display.NewLineData(false, line)) } - table, err := display.CreateTableString(tableHeader, lines) - if err != nil { - log.Error("could not create table", "error", err) - return - } - - message := fmt.Sprintf("Initial nodes config in auction list\n%s", table) - log.Info(message) + displayTable(tableHeader, lines, "Initial nodes config in auction list") } func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData2 map[string]*ownerData) { @@ -112,8 +107,6 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData2 map[strin } lines := make([]*display.LineData, 0, len(ownersData)) for ownerPubKey, owner := range ownersData { - selectedFromAuction := owner.auctionList[:owner.numQualifiedAuctionNodes] - line := []string{ (ownerPubKey), strconv.Itoa(int(owner.numStakedNodes)), @@ -123,22 +116,19 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData2 map[strin strconv.Itoa(int(owner.numQualifiedAuctionNodes)), strconv.Itoa(int(owner.numActiveNodes)), owner.qualifiedTopUpPerNode.String(), - getShortDisplayableBlsKeys(selectedFromAuction), + getShortDisplayableBlsKeys(owner.auctionList[:owner.numQualifiedAuctionNodes]), } lines = append(lines, display.NewLineData(false, line)) } - table, err := display.CreateTableString(tableHeader, lines) - if err != nil { - log.Error("could not create table", "error", err) - return - } - - message := fmt.Sprintf("Selected nodes config in auction list\n%s", table) - log.Info(message) + displayTable(tableHeader, lines, "Selected nodes config from auction list") } -func (als *auctionListSelector) displayAuctionList(auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfSelectedNodes uint32) { +func (als *auctionListSelector) displayAuctionList( + auctionList []state.ValidatorInfoHandler, + ownersData map[string]*ownerData, + numOfSelectedNodes uint32, +) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -150,10 +140,12 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator pubKey := validator.GetPublicKey() owner, err := als.stakingDataProvider.GetBlsKeyOwner(pubKey) - log.LogIfError(err) + if err != nil { + log.Error("auctionListSelector.displayAuctionList", "error", err) + continue + } topUp := ownersData[owner].qualifiedTopUpPerNode - log.LogIfError(err) horizontalLine = uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ @@ -164,12 +156,16 @@ func (als *auctionListSelector) displayAuctionList(auctionList []state.Validator lines = append(lines, line) } + displayTable(tableHeader, lines, "Final selected nodes from auction list") +} + +func displayTable(tableHeader []string, lines []*display.LineData, message string) { table, err := display.CreateTableString(tableHeader, lines) if err != nil { log.Error("could not create table", "error", err) return } - message := fmt.Sprintf("Final selected nodes from auction list\n%s", table) - log.Info(message) + msg := fmt.Sprintf("%s\n%s", message, table) + log.Info(msg) } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 8d1e18a9862..47eb3f57b7f 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -67,7 +67,6 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, // SelectNodesFromAuctionList will select nodes from validatorsInfoMap based on their top up. If two or more validators // have the same top-up, then sorting will be done based on blsKey XOR randomness. Selected nodes will have their list set // to common.SelectNodesFromAuctionList -// Depends that dat is filled in staking data provider func (als *auctionListSelector) SelectNodesFromAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, unqualifiedOwners map[string]struct{}, @@ -118,7 +117,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v - %v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - als.displayOwnersConfig(ownersData) + als.displayOwnersData(ownersData) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) sw := core.NewStopWatch() @@ -191,7 +190,7 @@ func (als *auctionListSelector) addOwnerData( return err } if stakedNodes == 0 { - return fmt.Errorf("auctionListSelector.getOwnersDat: error: %w, owner: %s, node: %s", + return fmt.Errorf("auctionListSelector.addOwnerData: error: %w, owner: %s, node: %s", epochStart.ErrOwnerHasNoStakedNode, hex.EncodeToString(ownerPubKey), hex.EncodeToString(validatorPubKey), @@ -295,7 +294,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } - displayRequiredTopUp(topUp, minTopUp, step) + displayMinRequiredTopUp(topUp, minTopUp, step) return previousConfig, nil } diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index f875dafd773..da0ebceb820 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -78,19 +78,19 @@ func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { - validatorPubKey := owner.auctionList[i].GetPublicKey() - validatorTopUpMap[string(validatorPubKey)] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) + validatorPubKey := string(owner.auctionList[i].GetPublicKey()) + validatorTopUpMap[validatorPubKey] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) } } func (als *auctionListSelector) sortValidators( - auctionList []state.ValidatorInfoHandler, + list []state.ValidatorInfoHandler, validatorTopUpMap map[string]*big.Int, randomness []byte, ) { - sort.SliceStable(auctionList, func(i, j int) bool { - pubKey1 := auctionList[i].GetPublicKey() - pubKey2 := auctionList[j].GetPublicKey() + sort.SliceStable(list, func(i, j int) bool { + pubKey1 := list[i].GetPublicKey() + pubKey2 := list[j].GetPublicKey() nodeTopUpPubKey1 := validatorTopUpMap[string(pubKey1)] nodeTopUpPubKey2 := validatorTopUpMap[string(pubKey2)] diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index d900db503c4..c88a5d56e09 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -10,7 +10,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/common/validatorInfo" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/state" @@ -21,7 +20,6 @@ import ( type ownerStats struct { numEligible int numStakedNodes int64 - numAuctionNodes int64 topUpValue *big.Int totalStaked *big.Int eligibleBaseStake *big.Int @@ -122,19 +120,21 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return ownerInfo.topUpPerNode, nil } +// GetNumStakedNodes returns the total number of owner's staked nodes func (sdp *stakingDataProvider) GetNumStakedNodes(owner []byte) (int64, error) { ownerInfo, ok := sdp.cache[string(owner)] if !ok { - return 0, epochStart.ErrOwnerDoesntHaveEligibleNodesInEpoch + return 0, epochStart.ErrOwnerDoesntHaveNodesInEpoch } return ownerInfo.numStakedNodes, nil } +// GetTotalTopUp returns owner's total top up func (sdp *stakingDataProvider) GetTotalTopUp(owner []byte) (*big.Int, error) { ownerInfo, ok := sdp.cache[string(owner)] if !ok { - return nil, epochStart.ErrOwnerDoesntHaveEligibleNodesInEpoch + return nil, epochStart.ErrOwnerDoesntHaveNodesInEpoch } return ownerInfo.topUpValue, nil @@ -158,21 +158,6 @@ func (sdp *stakingDataProvider) PrepareStakingData(keys map[uint32][][]byte) err return nil } -func (sdp *stakingDataProvider) PrepareStakingDataForStakingV4(validatorsMap state.ShardValidatorsInfoMapHandler) error { - sdp.Clean() - - for _, validator := range validatorsMap.GetAllValidatorsInfo() { - err := sdp.loadDataForValidatorWithStakingV4(validator) - if err != nil { - return err - } - } - - sdp.processStakingData() - - return nil -} - func (sdp *stakingDataProvider) processStakingData() { totalEligibleStake := big.NewInt(0) totalEligibleTopUpStake := big.NewInt(0) @@ -228,28 +213,6 @@ func (sdp *stakingDataProvider) getAndFillOwnerStatsFromSC(blsKey []byte) (*owne return ownerData, nil } -// loadDataForBlsKey will be called for each BLS key that took part in the consensus (no matter the shard ID) so the -// staking data can be recovered from the staking system smart contracts. -// The function will error if something went wrong. It does change the inner state of the called instance. -func (sdp *stakingDataProvider) loadDataForValidatorWithStakingV4(validator state.ValidatorInfoHandler) error { - sdp.mutStakingData.Lock() - defer sdp.mutStakingData.Unlock() - - ownerData, err := sdp.getAndFillOwnerStatsFromSC(validator.GetPublicKey()) - if err != nil { - log.Debug("error computing rewards for bls key", "step", "get owner data", "key", hex.EncodeToString(validator.GetPublicKey()), "error", err) - return err - } - - if validatorInfo.WasEligibleInCurrentEpoch(validator) { - ownerData.numEligible++ - } else if validator.GetList() == string(common.AuctionList) { - ownerData.numAuctionNodes++ - } - - return nil -} - // loadDataForBlsKey will be called for each BLS key that took part in the consensus (no matter the shard ID) so the // staking data can be recovered from the staking system smart contracts. // The function will error if something went wrong. It does change the inner state of the called instance. diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 01c6be56e79..4ff6b4b1ff6 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -131,7 +131,7 @@ func (s *systemSCProcessor) processWithNewFlags( } if s.flagStakingV4Enabled.IsSet() { - err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) // s.stakingDataProvider.PrepareStakingDataForStakingV4(validatorsInfoMap) + err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err } @@ -196,8 +196,7 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( func copyOwnerKeysInMap(mapOwnersKeys map[string][][]byte) map[string]struct{} { ret := make(map[string]struct{}) - - for owner, _ := range mapOwnersKeys { + for owner := range mapOwnersKeys { ret[owner] = struct{}{} } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 26a192daff4..c60a3447ef0 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1867,38 +1867,61 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing require.Nil(t, err) /* - - MaxNumNodes = 6 - - EligibleBlsKeys = 3 (pubKey0, pubKey1, pubKey3) - - AuctionBlsKeys = 5 - We can only select (MaxNumNodes - EligibleBlsKeys = 3) bls keys from AuctionList to be added to NewList - - Auction list is: - +--------+----------------+----------------+ - | Owner | Registered key | TopUp per node | - +--------+----------------+----------------+ - | owner1 | pubKey2 | 1000 | - | owner4 | pubKey9 | 500 | - | owner2 | pubKey4 | 0 | - +--------+----------------+----------------+ - | owner2 | pubKey5 | 0 | - | owner3 | pubKey7 | 0 | - +--------+----------------+----------------+ - The following have 0 top up per node: - - owner2 with 2 bls keys = pubKey4, pubKey5 - - owner3 with 1 bls key = pubKey7 - - Since randomness = []byte("pubKey7"), nodes will be sorted based on blsKey XOR randomness, therefore: - - XOR1 = []byte("pubKey4") XOR []byte("pubKey7") = [0 0 0 0 0 0 3] - - XOR2 = []byte("pubKey5") XOR []byte("pubKey7") = [0 0 0 0 0 0 2] - - XOR3 = []byte("pubKey7") XOR []byte("pubKey7") = [0 0 0 0 0 0 0] + - owner5 does not have enough stake for 2 nodes=> his auction node (pubKe13) will be unStaked at the end of the epoch => + will not participate in auction selection + - owner6 does not have enough stake for 2 nodes => one of his auction nodes(pubKey14) will be unStaked at the end of the epoch => + his other auction node(pubKey15) will not participate in auction selection + - MaxNumNodes = 8 + - EligibleBlsKeys = 5 (pubKey0, pubKey1, pubKey3, pubKe13, pubKey17) + - QualifiedAuctionBlsKeys = 7 (pubKey2, pubKey4, pubKey5, pubKey7, pubKey9, pubKey10, pubKey11) + We can only select (MaxNumNodes - EligibleBlsKeys = 3) bls keys from AuctionList to be added to NewList + + -> Initial nodes config in auction list is: + +--------+------------------+------------------+-------------------+--------------+-----------------+---------------------------+ + | Owner | Num staked nodes | Num active nodes | Num auction nodes | Total top up | Top up per node | Auction list nodes | + +--------+------------------+------------------+-------------------+--------------+-----------------+---------------------------+ + | owner3 | 2 | 1 | 1 | 2444 | 1222 | pubKey7 | + | owner4 | 4 | 1 | 3 | 2666 | 666 | pubKey9, pubKe10, pubKe11 | + | owner1 | 3 | 2 | 1 | 3666 | 1222 | pubKey2 | + | owner2 | 3 | 1 | 2 | 2555 | 851 | pubKey4, pubKey5 | + +--------+------------------+------------------+-------------------+--------------+-----------------+---------------------------+ + -> Min possible topUp = 666; max possible topUp = 1333, min required topUp = 1216 + -> Selected nodes config in auction list + +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ + | Owner | Num staked nodes | TopUp per node | Total top up | Num auction nodes | Num qualified auction nodes | Num active nodes | Qualified top up per node | Selected auction list nodes | + +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ + | owner1 | 3 | 1222 | 3666 | 1 | 1 | 2 | 1222 | pubKey2 | + | owner2 | 3 | 851 | 2555 | 2 | 1 | 1 | 1277 | pubKey4 | + | owner3 | 2 | 1222 | 2444 | 1 | 1 | 1 | 1222 | pubKey7 | + | owner4 | 4 | 666 | 2666 | 3 | 1 | 1 | 1333 | pubKe10 | + +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ + -> Final selected nodes from auction list + +--------+----------------+--------------------------+ + | Owner | Registered key | Qualified TopUp per node | + +--------+----------------+--------------------------+ + | owner4 | pubKe10 | 1333 | + | owner2 | pubKey4 | 1277 | + | owner1 | pubKey2 | 1222 | + +--------+----------------+--------------------------+ + | owner3 | pubKey7 | 1222 | + +--------+----------------+--------------------------+ + + The following have 1222 top up per node: + - owner1 with 1 bls keys = pubKey2 + - owner3 with 1 bls key = pubKey7 + + Since randomness = []byte("pubKey7"), nodes will be sorted based on blsKey XOR randomness, therefore: + - XOR1 = []byte("pubKey2") XOR []byte("pubKey7") = [0 0 0 0 0 0 5] + - XOR3 = []byte("pubKey7") XOR []byte("pubKey7") = [0 0 0 0 0 0 0] */ requireTopUpPerNodes(t, s.stakingDataProvider, owner1StakedKeys, big.NewInt(1222)) requireTopUpPerNodes(t, s.stakingDataProvider, owner2StakedKeys, big.NewInt(851)) requireTopUpPerNodes(t, s.stakingDataProvider, owner3StakedKeys, big.NewInt(1222)) requireTopUpPerNodes(t, s.stakingDataProvider, owner4StakedKeys, big.NewInt(666)) requireTopUpPerNodes(t, s.stakingDataProvider, owner5StakedKeys, big.NewInt(0)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner6StakedKeys, big.NewInt(0)) + requireTopUpPerNodes(t, s.stakingDataProvider, owner7StakedKeys, big.NewInt(0)) - // selected = 10, 4, 2 expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), @@ -2024,20 +2047,16 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar } func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { - owner, err := s.GetBlsKeyOwner(stakedPubKeys[0]) - require.Nil(t, err) - - totalTopUp, err := s.GetTotalTopUp([]byte(owner)) - require.Nil(t, err) + for _, pubKey := range stakedPubKeys { + owner, err := s.GetBlsKeyOwner(pubKey) + require.Nil(t, err) - topUpPerNode := big.NewInt(0).Div(totalTopUp, big.NewInt(int64(len(stakedPubKeys)))) - require.Equal(t, topUp, topUpPerNode) + totalTopUp, err := s.GetTotalTopUp([]byte(owner)) + require.Nil(t, err) - //for _, pubKey := range stakedPubKeys { - // topUpPerNode, err := s.GetNodeStakedTopUp(pubKey) - // require.Nil(t, err) - // require.Equal(t, topUpPerNode, topUp) - //} + topUpPerNode := big.NewInt(0).Div(totalTopUp, big.NewInt(int64(len(stakedPubKeys)))) + require.Equal(t, topUp, topUpPerNode) + } } // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 601e5fbc71f..4b716bf990e 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -57,10 +57,12 @@ func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int return big.NewInt(0), nil } +// GetNumStakedNodes - func (sdps *StakingDataProviderStub) GetNumStakedNodes([]byte) (int64, error) { return 0, nil } +// GetTotalTopUp - func (sdps *StakingDataProviderStub) GetTotalTopUp([]byte) (*big.Int, error) { return big.NewInt(0), nil } @@ -73,10 +75,6 @@ func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte return nil } -func (sdps *StakingDataProviderStub) PrepareStakingDataForStakingV4(state.ShardValidatorsInfoMapHandler) error { - return nil -} - // Clean - func (sdps *StakingDataProviderStub) Clean() { if sdps.CleanCalled != nil { From b1622463791b4e66803053e3478b626839e7a839 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 24 May 2022 11:56:31 +0300 Subject: [PATCH 282/958] FEAT: First test for calcSoftAuctionNodesConfig + bugfixes --- epochStart/metachain/auctionListDisplayer.go | 8 +- epochStart/metachain/auctionListSelector.go | 14 +- .../metachain/auctionListSelector_test.go | 160 +++++++++++++++++- epochStart/metachain/auctionListSorting.go | 2 +- epochStart/metachain/systemSCs.go | 5 - .../vm/staking/nodesCoordiantorCreator.go | 4 +- 6 files changed, 165 insertions(+), 28 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 318f43f4eaf..fc9e9490f8c 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -16,8 +16,7 @@ func displayMinRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { // return //} - minPossible := big.NewInt(minEGLD) - if !(topUp.Cmp(minPossible) == 0) { + if !(topUp.Cmp(min) == 0) { topUp = big.NewInt(0).Sub(topUp, step) } @@ -57,7 +56,7 @@ func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { return pubKeys } -func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerData) { +func displayOwnersData(ownersData map[string]*ownerData) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -89,11 +88,10 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerDa displayTable(tableHeader, lines, "Initial nodes config in auction list") } -func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData2 map[string]*ownerData) { +func displayOwnersSelectedNodes(ownersData map[string]*ownerData) { //if log.GetLevel() > logger.LogDebug { // return //} - ownersData := copyOwnersData(ownersData2) tableHeader := []string{ "Owner", "Num staked nodes", diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 47eb3f57b7f..26cbdd1cb0c 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -117,7 +117,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v - %v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - als.displayOwnersData(ownersData) + displayOwnersData(ownersData) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) sw := core.NewStopWatch() @@ -240,7 +240,7 @@ func (als *auctionListSelector) sortAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - softAuctionNodesConfig, err := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) + softAuctionNodesConfig, err := calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) if err != nil { return err } @@ -249,14 +249,15 @@ func (als *auctionListSelector) sortAuctionList( return markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) } -func (als *auctionListSelector) calcSoftAuctionNodesConfig( - ownersData map[string]*ownerData, +func calcSoftAuctionNodesConfig( + data map[string]*ownerData, numAvailableSlots uint32, ) (map[string]*ownerData, error) { + ownersData := copyOwnersData(data) minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? log.Info("auctionListSelector: calc min and max possible top up", - "min top up", minTopUp.String(), - "max top up", maxTopUp.String(), + "min top up per node", minTopUp.String(), + "max top up per node", maxTopUp.String(), ) step := big.NewInt(10) // todo: granulate step if max- min < step???? + 10 egld for real @@ -291,7 +292,6 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( if numNodesQualifyingForTopUp < int64(numAvailableSlots) { break } - } displayMinRequiredTopUp(topUp, minTopUp, step) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 11a9a6a3a58..8598ec2e823 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -36,14 +36,21 @@ func createFullAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) (Au nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, config) argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider return AuctionListSelectorArgs{ - ShardCoordinator: shardCoordinator, + ShardCoordinator: argsSystemSC.ShardCoordinator, StakingDataProvider: argsSystemSC.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, }, argsSystemSC } +func fillValidatorsInfo(t *testing.T, validatorsMap state.ShardValidatorsInfoMapHandler, sdp epochStart.StakingDataProvider) { + for _, validator := range validatorsMap.GetAllValidatorsInfo() { + err := sdp.FillValidatorInfo(validator.GetPublicKey()) + require.Nil(t, err) + } +} + func TestNewAuctionListSelector(t *testing.T) { t.Parallel() @@ -99,14 +106,10 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) - - err := args.StakingDataProvider.FillValidatorInfo(owner1StakedKeys[0]) - require.Nil(t, err) - err = args.StakingDataProvider.FillValidatorInfo(owner2StakedKeys[0]) - require.Nil(t, err) + fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) als, _ := NewAuctionListSelector(args) - err = als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ @@ -118,6 +121,147 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } +func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { + t.Parallel() + + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + v3 := &state.ValidatorInfo{PublicKey: []byte("pk3")} + v4 := &state.ValidatorInfo{PublicKey: []byte("pk4")} + v5 := &state.ValidatorInfo{PublicKey: []byte("pk5")} + v6 := &state.ValidatorInfo{PublicKey: []byte("pk6")} + v7 := &state.ValidatorInfo{PublicKey: []byte("pk7")} + v8 := &state.ValidatorInfo{PublicKey: []byte("pk8")} + + ownersData := map[string]*ownerData{ + "owner1": { + numActiveNodes: 2, + numAuctionNodes: 2, + numQualifiedAuctionNodes: 2, + numStakedNodes: 4, + totalTopUp: big.NewInt(1500), + topUpPerNode: big.NewInt(375), + qualifiedTopUpPerNode: big.NewInt(375), + auctionList: []state.ValidatorInfoHandler{v1, v2}, + }, + "owner2": { + numActiveNodes: 0, + numAuctionNodes: 3, + numQualifiedAuctionNodes: 3, + numStakedNodes: 3, + totalTopUp: big.NewInt(3000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v3, v4, v5}, + }, + "owner3": { + numActiveNodes: 1, + numAuctionNodes: 2, + numQualifiedAuctionNodes: 2, + numStakedNodes: 3, + totalTopUp: big.NewInt(1000), + topUpPerNode: big.NewInt(333), + qualifiedTopUpPerNode: big.NewInt(333), + auctionList: []state.ValidatorInfoHandler{v6, v7}, + }, + "owner4": { + numActiveNodes: 1, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 2, + totalTopUp: big.NewInt(0), + topUpPerNode: big.NewInt(0), + qualifiedTopUpPerNode: big.NewInt(0), + auctionList: []state.ValidatorInfoHandler{v8}, + }, + } + + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + require.Equal(t, big.NewInt(1), minTopUp) // owner3 having all nodes in auction + require.Equal(t, big.NewInt(3000), maxTopUp) // owner2 having only only one node in auction + + softAuctionConfig, err := calcSoftAuctionNodesConfig(ownersData, 10) + require.Nil(t, err) + require.Equal(t, ownersData, softAuctionConfig) // 7 nodes in auction and 10 available slots; everyone gets selected + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 9) + require.Nil(t, err) + require.Equal(t, ownersData, softAuctionConfig) // 7 nodes in auction and 10 available slots; everyone gets selected + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 8) + displayOwnersSelectedNodes(softAuctionConfig) + require.Nil(t, err) + require.Equal(t, ownersData, softAuctionConfig) // 7 nodes in auction and 8 available slots; everyone gets selected + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 7) + expectedConfig := copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) // 7 nodes in auction and 7 available slots; everyone gets selected + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 6) + displayOwnersSelectedNodes(softAuctionConfig) + expectedConfig = copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + expectedConfig["owner3"].numQualifiedAuctionNodes = 1 + expectedConfig["owner3"].qualifiedTopUpPerNode = big.NewInt(500) + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 5) + displayOwnersSelectedNodes(softAuctionConfig) + expectedConfig = copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + expectedConfig["owner3"].numQualifiedAuctionNodes = 1 + expectedConfig["owner3"].qualifiedTopUpPerNode = big.NewInt(500) + expectedConfig["owner1"].numQualifiedAuctionNodes = 1 + expectedConfig["owner1"].qualifiedTopUpPerNode = big.NewInt(500) + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 4) + displayOwnersSelectedNodes(softAuctionConfig) + expectedConfig = copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + expectedConfig["owner3"].numQualifiedAuctionNodes = 1 + expectedConfig["owner3"].qualifiedTopUpPerNode = big.NewInt(500) + expectedConfig["owner1"].numQualifiedAuctionNodes = 1 + expectedConfig["owner1"].qualifiedTopUpPerNode = big.NewInt(500) + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 3) + displayOwnersSelectedNodes(softAuctionConfig) + expectedConfig = copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + delete(expectedConfig, "owner1") + delete(expectedConfig, "owner3") + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 2) + displayOwnersSelectedNodes(softAuctionConfig) + expectedConfig = copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + delete(expectedConfig, "owner1") + delete(expectedConfig, "owner3") + expectedConfig["owner2"].numQualifiedAuctionNodes = 2 + expectedConfig["owner2"].qualifiedTopUpPerNode = big.NewInt(1500) + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) + + softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 1) + displayOwnersSelectedNodes(softAuctionConfig) + expectedConfig = copyOwnersData(ownersData) + delete(expectedConfig, "owner4") + delete(expectedConfig, "owner1") + delete(expectedConfig, "owner3") + expectedConfig["owner2"].numQualifiedAuctionNodes = 1 + expectedConfig["owner2"].qualifiedTopUpPerNode = big.NewInt(3000) + require.Nil(t, err) + require.Equal(t, expectedConfig, softAuctionConfig) +} + //TODO: probably remove this test /* func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingAuctionList(t *testing.T) { diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index da0ebceb820..c92c5251f8d 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -25,7 +25,7 @@ func (als *auctionListSelector) selectNodes( selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } - als.displayOwnersSelectedNodes(ownersData) + displayOwnersSelectedNodes(ownersData) als.sortValidators(selectedFromAuction, validatorTopUpMap, normRand) als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 4ff6b4b1ff6..fc581f915e1 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -203,11 +203,6 @@ func copyOwnerKeysInMap(mapOwnersKeys map[string][][]byte) map[string]struct{} { return ret } -func (s *systemSCProcessor) prepareStakingDataForAllNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { - allNodes := GetAllNodeKeys(validatorsInfoMap) - return s.prepareStakingData(allNodes) -} - func (s *systemSCProcessor) updateToGovernanceV2() error { vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 163e312174d..c3fadcb14a3 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -198,7 +198,7 @@ func registerValidators( list common.PeerType, ) { for shardID, validatorsInShard := range validators { - for _, val := range validatorsInShard { + for idx, val := range validatorsInShard { pubKey := val.PubKey() savePeerAcc(stateComponents, pubKey, shardID, list) @@ -207,7 +207,7 @@ func registerValidators( pubKey, pubKey, [][]byte{pubKey}, - big.NewInt(2*nodePrice), + big.NewInt(nodePrice+int64(idx)), marshaller, ) } From ba054169e8e244a9314563e12adc142c8f286523 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 24 May 2022 14:14:35 +0300 Subject: [PATCH 283/958] CLN: Test --- epochStart/metachain/auctionListDisplayer.go | 21 +- epochStart/metachain/auctionListSelector.go | 18 +- .../metachain/auctionListSelector_test.go | 179 ++++++++---------- epochStart/metachain/auctionListSorting.go | 8 +- 4 files changed, 102 insertions(+), 124 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index fc9e9490f8c..c5233efaa97 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -122,7 +122,18 @@ func displayOwnersSelectedNodes(ownersData map[string]*ownerData) { displayTable(tableHeader, lines, "Selected nodes config from auction list") } -func (als *auctionListSelector) displayAuctionList( +func getBlsKeyOwnerMap(ownersData map[string]*ownerData) map[string]string { + ret := make(map[string]string) + for ownerPubKey, owner := range ownersData { + for _, blsKey := range owner.auctionList { + ret[string(blsKey.GetPublicKey())] = ownerPubKey + } + } + + return ret +} + +func displayAuctionList( auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfSelectedNodes uint32, @@ -134,12 +145,14 @@ func (als *auctionListSelector) displayAuctionList( tableHeader := []string{"Owner", "Registered key", "Qualified TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) horizontalLine := false + blsKeysOwnerMap := getBlsKeyOwnerMap(ownersData) for idx, validator := range auctionList { pubKey := validator.GetPublicKey() - owner, err := als.stakingDataProvider.GetBlsKeyOwner(pubKey) - if err != nil { - log.Error("auctionListSelector.displayAuctionList", "error", err) + owner, found := blsKeysOwnerMap[string(pubKey)] + if !found { + log.Error("auctionListSelector.displayAuctionList could not find owner for", + "bls key", string(pubKey)) //todo: hex here continue } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 26cbdd1cb0c..783120d21a3 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -127,7 +127,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( log.Info("time measurements", sw.GetMeasurements()...) }() - return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) + return sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } func (als *auctionListSelector) getAuctionDataAndNumOfValidators( @@ -149,7 +149,7 @@ func (als *auctionListSelector) getAuctionDataAndNumOfValidators( if isUnqualified { log.Debug("auctionListSelector: found node in auction with unqualified owner, do not add it to selection", "owner", owner, - "bls key", string(validator.GetPublicKey()), + "bls key", string(validator.GetPublicKey()), //todo: hex ) continue } @@ -234,25 +234,21 @@ func safeSub(a, b uint32) (uint32, error) { return a - b, nil } -func (als *auctionListSelector) sortAuctionList( +func sortAuctionList( ownersData map[string]*ownerData, numOfAvailableNodeSlots uint32, validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - softAuctionNodesConfig, err := calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) - if err != nil { - return err - } - - selectedNodes := als.selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) + softAuctionNodesConfig := calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) + selectedNodes := selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) return markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) } func calcSoftAuctionNodesConfig( data map[string]*ownerData, numAvailableSlots uint32, -) (map[string]*ownerData, error) { +) map[string]*ownerData { ownersData := copyOwnersData(data) minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? log.Info("auctionListSelector: calc min and max possible top up", @@ -295,7 +291,7 @@ func calcSoftAuctionNodesConfig( } displayMinRequiredTopUp(topUp, minTopUp, step) - return previousConfig, nil + return previousConfig } func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 8598ec2e823..a8d1595429a 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -121,9 +121,35 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionN require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } +func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughNodesInAuctionToFillAvailableSlots(t *testing.T) { + t.Parallel() + + args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 2}}) + owner1 := []byte("owner1") + owner1StakedKeys := [][]byte{[]byte("pubKey0")} + + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.AuctionList, owner1, 0)) + + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + require.Nil(t, err) + + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.SelectedFromAuctionList, owner1, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) +} + func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { t.Parallel() + randomness := []byte("pk0") v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} v3 := &state.ValidatorInfo{PublicKey: []byte("pk3")} @@ -133,8 +159,12 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { v7 := &state.ValidatorInfo{PublicKey: []byte("pk7")} v8 := &state.ValidatorInfo{PublicKey: []byte("pk8")} + owner1 := "owner1" + owner2 := "owner2" + owner3 := "owner3" + owner4 := "owner4" ownersData := map[string]*ownerData{ - "owner1": { + owner1: { numActiveNodes: 2, numAuctionNodes: 2, numQualifiedAuctionNodes: 2, @@ -144,7 +174,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { qualifiedTopUpPerNode: big.NewInt(375), auctionList: []state.ValidatorInfoHandler{v1, v2}, }, - "owner2": { + owner2: { numActiveNodes: 0, numAuctionNodes: 3, numQualifiedAuctionNodes: 3, @@ -154,7 +184,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { qualifiedTopUpPerNode: big.NewInt(1000), auctionList: []state.ValidatorInfoHandler{v3, v4, v5}, }, - "owner3": { + owner3: { numActiveNodes: 1, numAuctionNodes: 2, numQualifiedAuctionNodes: 2, @@ -164,7 +194,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { qualifiedTopUpPerNode: big.NewInt(333), auctionList: []state.ValidatorInfoHandler{v6, v7}, }, - "owner4": { + owner4: { numActiveNodes: 1, numAuctionNodes: 1, numQualifiedAuctionNodes: 1, @@ -177,125 +207,64 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { } minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) - require.Equal(t, big.NewInt(1), minTopUp) // owner3 having all nodes in auction + require.Equal(t, big.NewInt(1), minTopUp) // owner4 having all nodes in auction require.Equal(t, big.NewInt(3000), maxTopUp) // owner2 having only only one node in auction - softAuctionConfig, err := calcSoftAuctionNodesConfig(ownersData, 10) - require.Nil(t, err) - require.Equal(t, ownersData, softAuctionConfig) // 7 nodes in auction and 10 available slots; everyone gets selected - - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 9) - require.Nil(t, err) - require.Equal(t, ownersData, softAuctionConfig) // 7 nodes in auction and 10 available slots; everyone gets selected + softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 9) + require.Equal(t, ownersData, softAuctionConfig) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 8) - displayOwnersSelectedNodes(softAuctionConfig) - require.Nil(t, err) - require.Equal(t, ownersData, softAuctionConfig) // 7 nodes in auction and 8 available slots; everyone gets selected + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 8) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 8, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6, v8}, selectedNodes) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 7) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 7) expectedConfig := copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - require.Nil(t, err) - require.Equal(t, expectedConfig, softAuctionConfig) // 7 nodes in auction and 7 available slots; everyone gets selected - - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 6) - displayOwnersSelectedNodes(softAuctionConfig) - expectedConfig = copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - expectedConfig["owner3"].numQualifiedAuctionNodes = 1 - expectedConfig["owner3"].qualifiedTopUpPerNode = big.NewInt(500) - require.Nil(t, err) + delete(expectedConfig, owner4) require.Equal(t, expectedConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 7, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6}, selectedNodes) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 5) - displayOwnersSelectedNodes(softAuctionConfig) - expectedConfig = copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - expectedConfig["owner3"].numQualifiedAuctionNodes = 1 - expectedConfig["owner3"].qualifiedTopUpPerNode = big.NewInt(500) - expectedConfig["owner1"].numQualifiedAuctionNodes = 1 - expectedConfig["owner1"].qualifiedTopUpPerNode = big.NewInt(500) - require.Nil(t, err) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 6) + expectedConfig[owner3].numQualifiedAuctionNodes = 1 + expectedConfig[owner3].qualifiedTopUpPerNode = big.NewInt(500) require.Equal(t, expectedConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 6, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v7, v2, v1}, selectedNodes) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 4) - displayOwnersSelectedNodes(softAuctionConfig) - expectedConfig = copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - expectedConfig["owner3"].numQualifiedAuctionNodes = 1 - expectedConfig["owner3"].qualifiedTopUpPerNode = big.NewInt(500) - expectedConfig["owner1"].numQualifiedAuctionNodes = 1 - expectedConfig["owner1"].qualifiedTopUpPerNode = big.NewInt(500) - require.Nil(t, err) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 5) + expectedConfig[owner1].numQualifiedAuctionNodes = 1 + expectedConfig[owner1].qualifiedTopUpPerNode = big.NewInt(500) require.Equal(t, expectedConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 5, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v7, v2}, selectedNodes) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 3) - displayOwnersSelectedNodes(softAuctionConfig) - expectedConfig = copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - delete(expectedConfig, "owner1") - delete(expectedConfig, "owner3") - require.Nil(t, err) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 4) require.Equal(t, expectedConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 4, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v7}, selectedNodes) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 2) - displayOwnersSelectedNodes(softAuctionConfig) - expectedConfig = copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - delete(expectedConfig, "owner1") - delete(expectedConfig, "owner3") - expectedConfig["owner2"].numQualifiedAuctionNodes = 2 - expectedConfig["owner2"].qualifiedTopUpPerNode = big.NewInt(1500) - require.Nil(t, err) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 3) + delete(expectedConfig, owner3) + delete(expectedConfig, owner1) require.Equal(t, expectedConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 3, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3}, selectedNodes) - softAuctionConfig, err = calcSoftAuctionNodesConfig(ownersData, 1) - displayOwnersSelectedNodes(softAuctionConfig) - expectedConfig = copyOwnersData(ownersData) - delete(expectedConfig, "owner4") - delete(expectedConfig, "owner1") - delete(expectedConfig, "owner3") - expectedConfig["owner2"].numQualifiedAuctionNodes = 1 - expectedConfig["owner2"].qualifiedTopUpPerNode = big.NewInt(3000) - require.Nil(t, err) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) + expectedConfig[owner2].numQualifiedAuctionNodes = 2 + expectedConfig[owner2].qualifiedTopUpPerNode = big.NewInt(1500) require.Equal(t, expectedConfig, softAuctionConfig) -} + selectedNodes = selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4}, selectedNodes) -//TODO: probably remove this test -/* -func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingAuctionList(t *testing.T) { - t.Parallel() - - args := createAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 10}}) - - errGetNodeTopUp := errors.New("error getting top up per node") - args.StakingDataProvider = &mock.StakingDataProviderStub{ - GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { - switch string(blsKey) { - case "pubKey0", "pubKey1": - return nil, errGetNodeTopUp - default: - require.Fail(t, "should not call this func with other params") - return nil, nil - } - }, - } - als, _ := NewAuctionListSelector(args) - - owner := []byte("owner") - ownerStakedKeys := [][]byte{[]byte("pubKey0"), []byte("pubKey1")} - - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) - _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) - - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), errGetNodeTopUp.Error())) - require.True(t, strings.Contains(err.Error(), epochStart.ErrSortAuctionList.Error())) + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + expectedConfig[owner2].numQualifiedAuctionNodes = 1 + expectedConfig[owner2].qualifiedTopUpPerNode = big.NewInt(3000) + require.Equal(t, expectedConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5}, selectedNodes) } -*/ func TestCalcNormalizedRandomness(t *testing.T) { t.Parallel() diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index c92c5251f8d..c04f9b3dccf 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -8,7 +8,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" ) -func (als *auctionListSelector) selectNodes( +func selectNodes( ownersData map[string]*ownerData, numAvailableSlots uint32, randomness []byte, @@ -26,8 +26,8 @@ func (als *auctionListSelector) selectNodes( } displayOwnersSelectedNodes(ownersData) - als.sortValidators(selectedFromAuction, validatorTopUpMap, normRand) - als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) + sortValidators(selectedFromAuction, validatorTopUpMap, normRand) + displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) return selectedFromAuction[:numAvailableSlots] } @@ -83,7 +83,7 @@ func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[st } } -func (als *auctionListSelector) sortValidators( +func sortValidators( list []state.ValidatorInfoHandler, validatorTopUpMap map[string]*big.Int, randomness []byte, From 8d324c99cd971176a6d283240a4380964489a025 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 24 May 2022 16:49:09 +0300 Subject: [PATCH 284/958] FEAT: Add edge case tests for calcSoftAuctionNodesConfig --- epochStart/metachain/auctionListSelector.go | 4 +- .../metachain/auctionListSelector_test.go | 259 ++++++++++++++++++ epochStart/metachain/systemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 4 +- 4 files changed, 264 insertions(+), 5 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 783120d21a3..93ea3eeff67 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -250,13 +250,13 @@ func calcSoftAuctionNodesConfig( numAvailableSlots uint32, ) map[string]*ownerData { ownersData := copyOwnersData(data) - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) // TODO: What happens if min>max or MIN = MAX? + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) log.Info("auctionListSelector: calc min and max possible top up", "min top up per node", minTopUp.String(), "max top up per node", maxTopUp.String(), ) - step := big.NewInt(10) // todo: granulate step if max- min < step???? + 10 egld for real + step := big.NewInt(10) // todo: 10 egld for real topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) previousConfig := copyOwnersData(ownersData) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index a8d1595429a..7d00db51010 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -145,6 +145,265 @@ func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughNodesInAuctionTo } require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) } +func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { + t.Parallel() + + randomness := []byte("pk0") + + t.Run("two validators, both have zero top up", func(t *testing.T) { + t.Parallel() + + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + + owner1 := "owner1" + owner2 := "owner2" + ownersData := map[string]*ownerData{ + owner1: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(0), + topUpPerNode: big.NewInt(0), + qualifiedTopUpPerNode: big.NewInt(0), + auctionList: []state.ValidatorInfoHandler{v1}, + }, + owner2: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(0), + topUpPerNode: big.NewInt(0), + qualifiedTopUpPerNode: big.NewInt(0), + auctionList: []state.ValidatorInfoHandler{v2}, + }, + } + + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + require.Equal(t, big.NewInt(1), minTopUp) + require.Equal(t, big.NewInt(0), maxTopUp) + + softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 2) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) + }) + + t.Run("one validator with zero top up, one with min top up, one with top up", func(t *testing.T) { + t.Parallel() + + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + v3 := &state.ValidatorInfo{PublicKey: []byte("pk3")} + + owner1 := "owner1" + owner2 := "owner2" + owner3 := "owner3" + ownersData := map[string]*ownerData{ + owner1: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(0), + topUpPerNode: big.NewInt(0), + qualifiedTopUpPerNode: big.NewInt(0), + auctionList: []state.ValidatorInfoHandler{v1}, + }, + owner2: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(1), + topUpPerNode: big.NewInt(1), + qualifiedTopUpPerNode: big.NewInt(1), + auctionList: []state.ValidatorInfoHandler{v2}, + }, + owner3: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(1000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v3}, + }, + } + + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + require.Equal(t, big.NewInt(1), minTopUp) + require.Equal(t, big.NewInt(1000), maxTopUp) + + softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 3) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 3, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v3, v2, v1}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) + expectedSoftAuctionConfig := copyOwnersData(softAuctionConfig) + delete(expectedSoftAuctionConfig, owner1) + require.Equal(t, expectedSoftAuctionConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v3, v2}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + delete(expectedSoftAuctionConfig, owner2) + require.Equal(t, expectedSoftAuctionConfig, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v3}, selectedNodes) + }) + + t.Run("two validators, both have same top up", func(t *testing.T) { + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + + owner1 := "owner1" + owner2 := "owner2" + ownersData := map[string]*ownerData{ + owner1: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(1000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v1}, + }, + owner2: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(1000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v2}, + }, + } + + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + require.Equal(t, big.NewInt(1000), minTopUp) + require.Equal(t, big.NewInt(1000), maxTopUp) + + softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 2) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) + }) + + t.Run("two validators, top up difference less than step", func(t *testing.T) { + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + + owner1 := "owner1" + owner2 := "owner2" + ownersData := map[string]*ownerData{ + owner1: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(1000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v1}, + }, + owner2: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(995), + topUpPerNode: big.NewInt(995), + qualifiedTopUpPerNode: big.NewInt(995), + auctionList: []state.ValidatorInfoHandler{v2}, + }, + } + + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + require.Equal(t, big.NewInt(995), minTopUp) + require.Equal(t, big.NewInt(1000), maxTopUp) + + softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 2) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v1, v2}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v1}, selectedNodes) + }) + + t.Run("three validators, top up difference equal to step", func(t *testing.T) { + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + v0 := &state.ValidatorInfo{PublicKey: []byte("pk0")} + + owner1 := "owner1" + owner2 := "owner2" + ownersData := map[string]*ownerData{ + owner1: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: big.NewInt(1000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v1}, + }, + owner2: { + numActiveNodes: 0, + numAuctionNodes: 2, + numQualifiedAuctionNodes: 2, + numStakedNodes: 2, + totalTopUp: big.NewInt(2000), + topUpPerNode: big.NewInt(1000), + qualifiedTopUpPerNode: big.NewInt(1000), + auctionList: []state.ValidatorInfoHandler{v2, v0}, + }, + } + + minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + require.Equal(t, big.NewInt(1000), minTopUp) + require.Equal(t, big.NewInt(2000), maxTopUp) + + softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 3) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 3, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2, v1, v0}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) + + softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + expectedSoftAuction := copyOwnersData(ownersData) + delete(expectedSoftAuction, owner1) + expectedSoftAuction[owner2].numQualifiedAuctionNodes = 1 + expectedSoftAuction[owner2].qualifiedTopUpPerNode = big.NewInt(2000) + require.Equal(t, expectedSoftAuction, softAuctionConfig) + selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) + }) +} func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { t.Parallel() diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index fc581f915e1..26cabf9000a 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -188,7 +188,7 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( } err = s.updateDelegationContracts(mapOwnersKeys) if err != nil { - + return nil, err } return copyOwnerKeysInMap(mapOwnersKeys), nil diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index c60a3447ef0..416bffd7202 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1907,8 +1907,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing +--------+----------------+--------------------------+ The following have 1222 top up per node: - - owner1 with 1 bls keys = pubKey2 - - owner3 with 1 bls key = pubKey7 + - owner1 with 1 bls key = pubKey2 + - owner3 with 1 bls key = pubKey7 Since randomness = []byte("pubKey7"), nodes will be sorted based on blsKey XOR randomness, therefore: - XOR1 = []byte("pubKey2") XOR []byte("pubKey7") = [0 0 0 0 0 0 5] From 43a833847bf10b06a76eba8bd25697f51ed24db0 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 25 May 2022 12:09:47 +0300 Subject: [PATCH 285/958] FEAT: > 99% code coverage --- epochStart/metachain/auctionListSelector.go | 33 +- .../metachain/auctionListSelector_test.go | 285 +++++++++++++++--- epochStart/mock/stakingDataProviderStub.go | 18 +- 3 files changed, 269 insertions(+), 67 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 93ea3eeff67..5a6eda08cbf 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -81,7 +81,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return err } if auctionListSize == 0 { - log.Debug("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") + log.Info("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") return nil } @@ -108,7 +108,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return nil } - log.Info("systemSCProcessor.SelectNodesFromAuctionList", + log.Info("auctionListSelector.SelectNodesFromAuctionList", "max nodes", maxNumNodes, "current number of validators", currNumOfValidators, "num of nodes which will be shuffled out", numOfShuffledNodes, @@ -139,7 +139,8 @@ func (als *auctionListSelector) getAuctionDataAndNumOfValidators( numOfNodesInAuction := uint32(0) for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { - owner, err := als.stakingDataProvider.GetBlsKeyOwner(validator.GetPublicKey()) + blsKey := validator.GetPublicKey() + owner, err := als.stakingDataProvider.GetBlsKeyOwner(blsKey) if err != nil { return nil, 0, 0, err } @@ -149,12 +150,12 @@ func (als *auctionListSelector) getAuctionDataAndNumOfValidators( if isUnqualified { log.Debug("auctionListSelector: found node in auction with unqualified owner, do not add it to selection", "owner", owner, - "bls key", string(validator.GetPublicKey()), //todo: hex + "bls key", string(blsKey), //todo: hex ) continue } - err = als.addOwnerData(validator, ownersData) + err = als.addOwnerData(owner, validator, ownersData) if err != nil { return nil, 0, 0, err } @@ -175,22 +176,22 @@ func isInAuction(validator state.ValidatorInfoHandler) bool { } func (als *auctionListSelector) addOwnerData( + owner string, validator state.ValidatorInfoHandler, ownersData map[string]*ownerData, ) error { - validatorPubKey := validator.GetPublicKey() - owner, err := als.stakingDataProvider.GetBlsKeyOwner(validatorPubKey) - if err != nil { - return err - } - ownerPubKey := []byte(owner) + validatorPubKey := validator.GetPublicKey() stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes(ownerPubKey) if err != nil { - return err + return fmt.Errorf("auctionListSelector.addOwnerData: error getting num staked nodes: %w, owner: %s, node: %s", + err, + hex.EncodeToString(ownerPubKey), + hex.EncodeToString(validatorPubKey), + ) } if stakedNodes == 0 { - return fmt.Errorf("auctionListSelector.addOwnerData: error: %w, owner: %s, node: %s", + return fmt.Errorf("auctionListSelector.addOwnerData error: %w, owner: %s, node: %s", epochStart.ErrOwnerHasNoStakedNode, hex.EncodeToString(ownerPubKey), hex.EncodeToString(validatorPubKey), @@ -199,7 +200,11 @@ func (als *auctionListSelector) addOwnerData( totalTopUp, err := als.stakingDataProvider.GetTotalTopUp(ownerPubKey) if err != nil { - return err + return fmt.Errorf("auctionListSelector.addOwnerData: error getting total top up: %w, owner: %s, node: %s", + err, + hex.EncodeToString(ownerPubKey), + hex.EncodeToString(validatorPubKey), + ) } data, exists := ownersData[owner] diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 7d00db51010..90deea2fc4c 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -1,7 +1,10 @@ package metachain import ( + "encoding/hex" + "errors" "math/big" + "strings" "testing" "github.com/ElrondNetwork/elrond-go-core/core" @@ -9,7 +12,9 @@ import ( "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" + "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" @@ -90,61 +95,239 @@ func TestNewAuctionListSelector(t *testing.T) { }) } -func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughSlotsForAuctionNodes(t *testing.T) { +func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { t.Parallel() - args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) - owner1 := []byte("owner1") - owner2 := []byte("owner2") + t.Run("nil randomness, expect error", func(t *testing.T) { + t.Parallel() + + args := createAuctionListSelectorArgs(nil) + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), nil, nil) + require.Equal(t, process.ErrNilRandSeed, err) + }) - owner1StakedKeys := [][]byte{[]byte("pubKey0")} - owner2StakedKeys := [][]byte{[]byte("pubKey1")} + t.Run("cannot get bls key owner, expect error", func(t *testing.T) { + t.Parallel() - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + stakedKey := []byte("pubKey0") + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(stakedKey, common.AuctionList, []byte("owner1"), 0)) - stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) - stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) - fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) + args := createAuctionListSelectorArgs(nil) + errGetOwner := errors.New("error getting owner") + args.StakingDataProvider = &mock.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { + require.Equal(t, stakedKey, blsKey) + return "", errGetOwner + }, + } - als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) - require.Nil(t, err) + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + require.Equal(t, errGetOwner, err) + }) - expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ - 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), - createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0), - }, - } - require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) + t.Run("cannot get owner's staked nodes, expect error", func(t *testing.T) { + t.Parallel() + + expectedOwner := []byte("owner") + stakedKey := []byte("pubKey0") + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo([]byte("pubKey0"), common.AuctionList, expectedOwner, 0)) + + args := createAuctionListSelectorArgs(nil) + errGetNumStakedNodes := errors.New("error getting number of staked nodes") + args.StakingDataProvider = &mock.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { + require.Equal(t, stakedKey, blsKey) + return string(expectedOwner), nil + }, + GetNumStakedNodesCalled: func(owner []byte) (int64, error) { + require.Equal(t, expectedOwner, owner) + return 1, errGetNumStakedNodes + }, + } + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), errGetNumStakedNodes.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) + }) + + t.Run("owner has 0 staked nodes, but has one node in auction, expect error", func(t *testing.T) { + t.Parallel() + + expectedOwner := []byte("owner") + stakedKey := []byte("pubKey0") + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo([]byte("pubKey0"), common.AuctionList, expectedOwner, 0)) + + args := createAuctionListSelectorArgs(nil) + args.StakingDataProvider = &mock.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { + require.Equal(t, stakedKey, blsKey) + return string(expectedOwner), nil + }, + GetNumStakedNodesCalled: func(owner []byte) (int64, error) { + require.Equal(t, expectedOwner, owner) + return 0, nil + }, + } + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), epochStart.ErrOwnerHasNoStakedNode.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) + }) + + t.Run("cannot get owner's total top up, expect error", func(t *testing.T) { + t.Parallel() + + expectedOwner := []byte("owner") + stakedKey := []byte("pubKey0") + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo([]byte("pubKey0"), common.AuctionList, expectedOwner, 0)) + + args := createAuctionListSelectorArgs(nil) + errGetTotalTopUp := errors.New("error getting total top up") + args.StakingDataProvider = &mock.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { + require.Equal(t, stakedKey, blsKey) + return string(expectedOwner), nil + }, + GetNumStakedNodesCalled: func(owner []byte) (int64, error) { + require.Equal(t, expectedOwner, owner) + return 1, nil + }, + GetTotalTopUpCalled: func(owner []byte) (*big.Int, error) { + require.Equal(t, expectedOwner, owner) + return nil, errGetTotalTopUp + }, + } + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), errGetTotalTopUp.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) + }) } -func TestAuctionListSelector_SelectNodesFromAuctionListNotEnoughNodesInAuctionToFillAvailableSlots(t *testing.T) { +func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { t.Parallel() - args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 2}}) - owner1 := []byte("owner1") - owner1StakedKeys := [][]byte{[]byte("pubKey0")} + t.Run("empty auction list", func(t *testing.T) { + t.Parallel() - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.AuctionList, owner1, 0)) + owner1 := []byte("owner1") + owner1StakedKeys := [][]byte{[]byte("pubKey0")} - stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) - fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) - require.Nil(t, err) + args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 2}}) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) - expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ - 0: { - createValidatorInfo(owner1StakedKeys[0], common.SelectedFromAuctionList, owner1, 0), - }, - } - require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), nil, []byte("rand")) + require.Nil(t, err) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) + }) + + t.Run("not enough available slots to select auction nodes", func(t *testing.T) { + t.Parallel() + + owner1 := []byte("owner1") + owner2 := []byte("owner2") + owner1StakedKeys := [][]byte{[]byte("pubKey0")} + owner2StakedKeys := [][]byte{[]byte("pubKey1")} + + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + + args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + require.Nil(t, err) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) + }) + + t.Run("one eligible + one auction, max num nodes = 1, number of nodes after shuffling = 0, expect node in auction is selected", func(t *testing.T) { + t.Parallel() + + owner1 := []byte("owner1") + owner2 := []byte("owner2") + owner1StakedKeys := [][]byte{[]byte("pubKey0")} + owner2StakedKeys := [][]byte{[]byte("pubKey1")} + + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + + args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1, NodesToShufflePerShard: 1}}) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner2, owner2, owner2StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + require.Nil(t, err) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner2StakedKeys[0], common.SelectedFromAuctionList, owner2, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) + }) + + t.Run("two available slots for auction nodes, but only one node in auction", func(t *testing.T) { + t.Parallel() + + owner1 := []byte("owner1") + owner1StakedKeys := [][]byte{[]byte("pubKey0")} + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.AuctionList, owner1, 0)) + + args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 2}}) + stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) + fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) + + als, _ := NewAuctionListSelector(args) + err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + require.Nil(t, err) + expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ + 0: { + createValidatorInfo(owner1StakedKeys[0], common.SelectedFromAuctionList, owner1, 0), + }, + } + require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) + }) } + func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { t.Parallel() @@ -373,32 +556,32 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { numAuctionNodes: 2, numQualifiedAuctionNodes: 2, numStakedNodes: 2, - totalTopUp: big.NewInt(2000), - topUpPerNode: big.NewInt(1000), - qualifiedTopUpPerNode: big.NewInt(1000), + totalTopUp: big.NewInt(1980), + topUpPerNode: big.NewInt(990), + qualifiedTopUpPerNode: big.NewInt(990), auctionList: []state.ValidatorInfoHandler{v2, v0}, }, } minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) - require.Equal(t, big.NewInt(1000), minTopUp) - require.Equal(t, big.NewInt(2000), maxTopUp) + require.Equal(t, big.NewInt(990), minTopUp) + require.Equal(t, big.NewInt(1980), maxTopUp) softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 3) require.Equal(t, ownersData, softAuctionConfig) selectedNodes := selectNodes(softAuctionConfig, 3, randomness) - require.Equal(t, []state.ValidatorInfoHandler{v2, v1, v0}, selectedNodes) + require.Equal(t, []state.ValidatorInfoHandler{v1, v2, v0}, selectedNodes) softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) - require.Equal(t, ownersData, softAuctionConfig) + expectedSoftAuction := copyOwnersData(ownersData) + expectedSoftAuction[owner2].numQualifiedAuctionNodes = 1 + expectedSoftAuction[owner2].qualifiedTopUpPerNode = big.NewInt(1980) + require.Equal(t, expectedSoftAuction, softAuctionConfig) selectedNodes = selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) - expectedSoftAuction := copyOwnersData(ownersData) delete(expectedSoftAuction, owner1) - expectedSoftAuction[owner2].numQualifiedAuctionNodes = 1 - expectedSoftAuction[owner2].qualifiedTopUpPerNode = big.NewInt(2000) require.Equal(t, expectedSoftAuction, softAuctionConfig) selectedNodes = selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) @@ -471,10 +654,12 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 9) require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selectNodes(softAuctionConfig, 8, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6, v8}, selectedNodes) softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 8) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 8, randomness) + selectedNodes = selectNodes(softAuctionConfig, 8, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6, v8}, selectedNodes) softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 7) diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 4b716bf990e..eb570369e10 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -15,6 +15,9 @@ type StakingDataProviderStub struct { GetNodeStakedTopUpCalled func(blsKey []byte) (*big.Int, error) FillValidatorInfoCalled func(blsKey []byte) error ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) + GetBlsKeyOwnerCalled func(blsKey []byte) (string, error) + GetNumStakedNodesCalled func(owner []byte) (int64, error) + GetTotalTopUpCalled func(owner []byte) (*big.Int, error) } // FillValidatorInfo - @@ -58,12 +61,18 @@ func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int } // GetNumStakedNodes - -func (sdps *StakingDataProviderStub) GetNumStakedNodes([]byte) (int64, error) { +func (sdps *StakingDataProviderStub) GetNumStakedNodes(owner []byte) (int64, error) { + if sdps.GetNumStakedNodesCalled != nil { + return sdps.GetNumStakedNodesCalled(owner) + } return 0, nil } // GetTotalTopUp - -func (sdps *StakingDataProviderStub) GetTotalTopUp([]byte) (*big.Int, error) { +func (sdps *StakingDataProviderStub) GetTotalTopUp(owner []byte) (*big.Int, error) { + if sdps.GetTotalTopUpCalled != nil { + return sdps.GetTotalTopUpCalled(owner) + } return big.NewInt(0), nil } @@ -83,7 +92,10 @@ func (sdps *StakingDataProviderStub) Clean() { } // GetBlsKeyOwner - -func (sdps *StakingDataProviderStub) GetBlsKeyOwner([]byte) (string, error) { +func (sdps *StakingDataProviderStub) GetBlsKeyOwner(blsKey []byte) (string, error) { + if sdps.GetBlsKeyOwnerCalled != nil { + return sdps.GetBlsKeyOwnerCalled(blsKey) + } return "", nil } From 2a760b957e5a3e6c105a47bd244b3283f3b9c7a5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 25 May 2022 16:53:53 +0300 Subject: [PATCH 286/958] FEAT: Add SoftAuctionConfig and integrate it --- cmd/node/config/config.toml | 6 + config/config.go | 8 + epochStart/metachain/auctionListDisplayer.go | 44 +++-- epochStart/metachain/auctionListSelector.go | 73 +++++-- .../metachain/auctionListSelector_test.go | 178 ++++++++++++------ epochStart/metachain/auctionListSorting.go | 6 +- epochStart/metachain/systemSCs_test.go | 13 +- factory/blockProcessorCreator.go | 2 + factory/processComponents.go | 3 + integrationTests/testProcessorNode.go | 5 + .../vm/staking/systemSCCreator.go | 5 + node/nodeRunner.go | 1 + 12 files changed, 253 insertions(+), 91 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 3ebdb6af19f..9c42e8ce587 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -887,3 +887,9 @@ NumCrossShardPeers = 2 NumIntraShardPeers = 1 NumFullHistoryPeers = 3 + +# Changing this config is not backwards compatible +[SoftAuctionConfig] + TopUpStep = "10000000000000000000" # 10 EGLD + MinTopUp = "1" # 0.00...01 EGLD , should be very low, but != zero + MaxTopUp = "32000000000000000000000000" # 32 mil EGLD diff --git a/config/config.go b/config/config.go index a14dba12dac..4007e00b23d 100644 --- a/config/config.go +++ b/config/config.go @@ -184,6 +184,7 @@ type Config struct { TrieSync TrieSyncConfig Resolvers ResolverConfig VMOutputCacher CacheConfig + SoftAuctionConfig SoftAuctionConfig } // LogsConfig will hold settings related to the logging sub-system @@ -546,3 +547,10 @@ type ResolverConfig struct { NumIntraShardPeers uint32 NumFullHistoryPeers uint32 } + +// SoftAuctionConfig represents the config options for soft auction selecting used in staking v4 +type SoftAuctionConfig struct { + TopUpStep string + MinTopUp string + MaxTopUp string +} diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index c5233efaa97..4db42ef73ba 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -4,23 +4,26 @@ import ( "fmt" "math/big" "strconv" + "strings" + "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/display" "github.com/ElrondNetwork/elrond-go/state" ) const maxPubKeyDisplayableLen = 20 +const maxNumOfDecimalsToDisplay = 5 -func displayMinRequiredTopUp(topUp *big.Int, min *big.Int, step *big.Int) { +func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, minFound *big.Int, step *big.Int) { //if log.GetLevel() > logger.LogDebug { // return //} - if !(topUp.Cmp(min) == 0) { + if !(topUp.Cmp(als.softAuctionConfig.minTopUp) == 0) { topUp = big.NewInt(0).Sub(topUp, step) } - iteratedValues := big.NewInt(0).Sub(topUp, min) + iteratedValues := big.NewInt(0).Sub(topUp, minFound) iterations := big.NewInt(0).Div(iteratedValues, step) log.Info("auctionListSelector: found min required", @@ -56,7 +59,23 @@ func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { return pubKeys } -func displayOwnersData(ownersData map[string]*ownerData) { +func getPrettyValue(val *big.Int, denominator *big.Int) string { + first := big.NewInt(0).Div(val, denominator).String() + second := big.NewInt(0).Mod(val, denominator).String() + + repeatCt := core.MaxInt(len(denominator.String())-len(second)-1, 0) + zeroes := strings.Repeat("0", repeatCt) + second2 := zeroes + second + if len(second2) > maxNumOfDecimalsToDisplay { + second2 = second2[:maxNumOfDecimalsToDisplay] + } + + return first + "." + second2 + + //return big.NewInt(0).Div(val, als.softAuctionConfig.denomination).String() +} + +func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerData) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -78,8 +97,8 @@ func displayOwnersData(ownersData map[string]*ownerData) { strconv.Itoa(int(owner.numStakedNodes)), strconv.Itoa(int(owner.numActiveNodes)), strconv.Itoa(int(owner.numAuctionNodes)), - owner.totalTopUp.String(), - owner.topUpPerNode.String(), + getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denomination), + getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denomination), getShortDisplayableBlsKeys(owner.auctionList), } lines = append(lines, display.NewLineData(false, line)) @@ -88,7 +107,7 @@ func displayOwnersData(ownersData map[string]*ownerData) { displayTable(tableHeader, lines, "Initial nodes config in auction list") } -func displayOwnersSelectedNodes(ownersData map[string]*ownerData) { +func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string]*ownerData) { //if log.GetLevel() > logger.LogDebug { // return //} @@ -108,12 +127,12 @@ func displayOwnersSelectedNodes(ownersData map[string]*ownerData) { line := []string{ (ownerPubKey), strconv.Itoa(int(owner.numStakedNodes)), - owner.topUpPerNode.String(), - owner.totalTopUp.String(), + getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denomination), + getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denomination), strconv.Itoa(int(owner.numAuctionNodes)), strconv.Itoa(int(owner.numQualifiedAuctionNodes)), strconv.Itoa(int(owner.numActiveNodes)), - owner.qualifiedTopUpPerNode.String(), + getPrettyValue(owner.qualifiedTopUpPerNode, als.softAuctionConfig.denomination), getShortDisplayableBlsKeys(owner.auctionList[:owner.numQualifiedAuctionNodes]), } lines = append(lines, display.NewLineData(false, line)) @@ -133,7 +152,7 @@ func getBlsKeyOwnerMap(ownersData map[string]*ownerData) map[string]string { return ret } -func displayAuctionList( +func (als *auctionListSelector) displayAuctionList( auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, numOfSelectedNodes uint32, @@ -157,12 +176,11 @@ func displayAuctionList( } topUp := ownersData[owner].qualifiedTopUpPerNode - horizontalLine = uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ (owner), string(pubKey), - topUp.String(), + getPrettyValue(topUp, als.softAuctionConfig.denomination), }) lines = append(lines, line) } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 5a6eda08cbf..d5fd6d2d575 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -3,21 +3,19 @@ package metachain import ( "encoding/hex" "fmt" + "math" "math/big" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" ) -const oneEGLD = 1000000000000000000 // with 18 decimals = 1 EGLD -const minEGLD = 1 // with 18 decimals = 0.00...01 egld -const allEGLD = 21000000 // without 18 decimals - type ownerData struct { numActiveNodes int64 numAuctionNodes int64 @@ -29,22 +27,53 @@ type ownerData struct { auctionList []state.ValidatorInfoHandler } +type auctionConfig struct { + step *big.Int + minTopUp *big.Int + maxTopUp *big.Int + denomination *big.Int +} + type auctionListSelector struct { shardCoordinator sharding.Coordinator stakingDataProvider epochStart.StakingDataProvider nodesConfigProvider epochStart.MaxNodesChangeConfigProvider + softAuctionConfig *auctionConfig + denomination int } -// AuctionListSelectorArgs is a struct placeholder for all arguments required to create a auctionListSelector +// AuctionListSelectorArgs is a struct placeholder for all arguments required to create an auctionListSelector type AuctionListSelectorArgs struct { ShardCoordinator sharding.Coordinator StakingDataProvider epochStart.StakingDataProvider MaxNodesChangeConfigProvider epochStart.MaxNodesChangeConfigProvider + SoftAuctionConfig config.SoftAuctionConfig + Denomination int } // NewAuctionListSelector will create a new auctionListSelector, which handles selection of nodes from auction list based // on their top up func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, error) { + step, ok := big.NewInt(0).SetString(args.SoftAuctionConfig.TopUpStep, 10) + if !ok || step.Cmp(zero) <= 0 { + return nil, process.ErrInvalidValue + } + + minTopUp, ok := big.NewInt(0).SetString(args.SoftAuctionConfig.MinTopUp, 10) + if !ok || minTopUp.Cmp(zero) <= 0 { + return nil, process.ErrInvalidValue + } + + maxTopUp, ok := big.NewInt(0).SetString(args.SoftAuctionConfig.MaxTopUp, 10) + if !ok || maxTopUp.Cmp(zero) <= 0 { + return nil, process.ErrInvalidValue + } + + if args.Denomination < 0 { + return nil, process.ErrInvalidValue + } + den := int(math.Pow10(args.Denomination)) + if check.IfNil(args.ShardCoordinator) { return nil, epochStart.ErrNilShardCoordinator } @@ -59,6 +88,13 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, shardCoordinator: args.ShardCoordinator, stakingDataProvider: args.StakingDataProvider, nodesConfigProvider: args.MaxNodesChangeConfigProvider, + softAuctionConfig: &auctionConfig{ + step: step, + minTopUp: minTopUp, + maxTopUp: maxTopUp, + denomination: big.NewInt(int64(den)), + }, + denomination: args.Denomination, } return asl, nil @@ -117,7 +153,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v - %v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - displayOwnersData(ownersData) + als.displayOwnersData(ownersData) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) sw := core.NewStopWatch() @@ -127,7 +163,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( log.Info("time measurements", sw.GetMeasurements()...) }() - return sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) + return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } func (als *auctionListSelector) getAuctionDataAndNumOfValidators( @@ -239,23 +275,23 @@ func safeSub(a, b uint32) (uint32, error) { return a - b, nil } -func sortAuctionList( +func (als *auctionListSelector) sortAuctionList( ownersData map[string]*ownerData, numOfAvailableNodeSlots uint32, validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, ) error { - softAuctionNodesConfig := calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) - selectedNodes := selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) + softAuctionNodesConfig := als.calcSoftAuctionNodesConfig(ownersData, numOfAvailableNodeSlots) + selectedNodes := als.selectNodes(softAuctionNodesConfig, numOfAvailableNodeSlots, randomness) return markAuctionNodesAsSelected(selectedNodes, validatorsInfoMap) } -func calcSoftAuctionNodesConfig( +func (als *auctionListSelector) calcSoftAuctionNodesConfig( data map[string]*ownerData, numAvailableSlots uint32, ) map[string]*ownerData { ownersData := copyOwnersData(data) - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) log.Info("auctionListSelector: calc min and max possible top up", "min top up per node", minTopUp.String(), "max top up per node", maxTopUp.String(), @@ -295,13 +331,13 @@ func calcSoftAuctionNodesConfig( } } - displayMinRequiredTopUp(topUp, minTopUp, step) + als.displayMinRequiredTopUp(topUp, minTopUp, step) return previousConfig } -func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { - min := big.NewInt(0).Mul(big.NewInt(oneEGLD), big.NewInt(allEGLD)) - max := big.NewInt(0) +func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { + min := big.NewInt(0).SetBytes(als.softAuctionConfig.maxTopUp.Bytes()) + max := big.NewInt(0).SetBytes(als.softAuctionConfig.minTopUp.Bytes()) for _, owner := range ownersData { if owner.topUpPerNode.Cmp(min) < 0 { @@ -315,9 +351,8 @@ func getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.In } } - minPossible := big.NewInt(minEGLD) - if min.Cmp(minPossible) < 0 { - min = minPossible + if min.Cmp(als.softAuctionConfig.minTopUp) < 0 { + min = als.softAuctionConfig.minTopUp } return min, max diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 90deea2fc4c..e8443aae3c6 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -3,6 +3,7 @@ package metachain import ( "encoding/hex" "errors" + "math" "math/big" "strings" "testing" @@ -21,9 +22,9 @@ import ( "github.com/stretchr/testify/require" ) -func createAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) AuctionListSelectorArgs { +func createAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeConfig) AuctionListSelectorArgs { epochNotifier := forking.NewGenericEpochNotifier() - nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, config) + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) argsStakingDataProvider := createStakingDataProviderArgs() stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) @@ -33,12 +34,17 @@ func createAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) Auction ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, } } -func createFullAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) (AuctionListSelectorArgs, ArgsNewEpochStartSystemSCProcessing) { +func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeConfig) (AuctionListSelectorArgs, ArgsNewEpochStartSystemSCProcessing) { epochNotifier := forking.NewGenericEpochNotifier() - nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, config) + nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider @@ -46,6 +52,11 @@ func createFullAuctionListSelectorArgs(config []config.MaxNodesChangeConfig) (Au ShardCoordinator: argsSystemSC.ShardCoordinator, StakingDataProvider: argsSystemSC.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, }, argsSystemSC } @@ -157,7 +168,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) }) - t.Run("owner has 0 staked nodes, but has one node in auction, expect error", func(t *testing.T) { + t.Run("owner has one node in auction, but 0 staked nodes, expect error", func(t *testing.T) { t.Parallel() expectedOwner := []byte("owner") @@ -332,6 +343,8 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { t.Parallel() randomness := []byte("pk0") + args := createAuctionListSelectorArgs(nil) + als, _ := NewAuctionListSelector(args) t.Run("two validators, both have zero top up", func(t *testing.T) { t.Parallel() @@ -364,18 +377,18 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { }, } - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) - require.Equal(t, big.NewInt(1), minTopUp) - require.Equal(t, big.NewInt(0), maxTopUp) + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) + require.Equal(t, als.softAuctionConfig.minTopUp, minTopUp) + require.Equal(t, als.softAuctionConfig.minTopUp, maxTopUp) - softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 2) + softAuctionConfig := als.calcSoftAuctionNodesConfig(ownersData, 2) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 2, randomness) + selectedNodes := als.selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 1) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) }) @@ -422,26 +435,26 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { }, } - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) require.Equal(t, big.NewInt(1), minTopUp) require.Equal(t, big.NewInt(1000), maxTopUp) - softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 3) + softAuctionConfig := als.calcSoftAuctionNodesConfig(ownersData, 3) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 3, randomness) + selectedNodes := als.selectNodes(softAuctionConfig, 3, randomness) require.Equal(t, []state.ValidatorInfoHandler{v3, v2, v1}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 2) expectedSoftAuctionConfig := copyOwnersData(softAuctionConfig) delete(expectedSoftAuctionConfig, owner1) require.Equal(t, expectedSoftAuctionConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 2, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v3, v2}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 1) delete(expectedSoftAuctionConfig, owner2) require.Equal(t, expectedSoftAuctionConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v3}, selectedNodes) }) @@ -474,18 +487,18 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { }, } - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) require.Equal(t, big.NewInt(1000), minTopUp) require.Equal(t, big.NewInt(1000), maxTopUp) - softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 2) + softAuctionConfig := als.calcSoftAuctionNodesConfig(ownersData, 2) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 2, randomness) + selectedNodes := als.selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 1) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) }) @@ -518,18 +531,18 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { }, } - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) require.Equal(t, big.NewInt(995), minTopUp) require.Equal(t, big.NewInt(1000), maxTopUp) - softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 2) + softAuctionConfig := als.calcSoftAuctionNodesConfig(ownersData, 2) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 2, randomness) + selectedNodes := als.selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v1, v2}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 1) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v1}, selectedNodes) }) @@ -563,27 +576,27 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { }, } - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) require.Equal(t, big.NewInt(990), minTopUp) require.Equal(t, big.NewInt(1980), maxTopUp) - softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 3) + softAuctionConfig := als.calcSoftAuctionNodesConfig(ownersData, 3) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 3, randomness) + selectedNodes := als.selectNodes(softAuctionConfig, 3, randomness) require.Equal(t, []state.ValidatorInfoHandler{v1, v2, v0}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 2) expectedSoftAuction := copyOwnersData(ownersData) expectedSoftAuction[owner2].numQualifiedAuctionNodes = 1 expectedSoftAuction[owner2].qualifiedTopUpPerNode = big.NewInt(1980) require.Equal(t, expectedSoftAuction, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 2, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2, v1}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 1) delete(expectedSoftAuction, owner1) require.Equal(t, expectedSoftAuction, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) }) } @@ -648,68 +661,123 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { }, } - minTopUp, maxTopUp := getMinMaxPossibleTopUp(ownersData) + args := createAuctionListSelectorArgs(nil) + als, _ := NewAuctionListSelector(args) + + minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) require.Equal(t, big.NewInt(1), minTopUp) // owner4 having all nodes in auction require.Equal(t, big.NewInt(3000), maxTopUp) // owner2 having only only one node in auction - softAuctionConfig := calcSoftAuctionNodesConfig(ownersData, 9) + softAuctionConfig := als.calcSoftAuctionNodesConfig(ownersData, 9) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes := selectNodes(softAuctionConfig, 8, randomness) + selectedNodes := als.selectNodes(softAuctionConfig, 8, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6, v8}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 8) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 8) require.Equal(t, ownersData, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 8, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 8, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6, v8}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 7) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 7) expectedConfig := copyOwnersData(ownersData) delete(expectedConfig, owner4) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 7, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 7, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v2, v1, v7, v6}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 6) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 6) expectedConfig[owner3].numQualifiedAuctionNodes = 1 expectedConfig[owner3].qualifiedTopUpPerNode = big.NewInt(500) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 6, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 6, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v7, v2, v1}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 5) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 5) expectedConfig[owner1].numQualifiedAuctionNodes = 1 expectedConfig[owner1].qualifiedTopUpPerNode = big.NewInt(500) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 5, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 5, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v7, v2}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 4) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 4) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 4, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 4, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3, v7}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 3) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 3) delete(expectedConfig, owner3) delete(expectedConfig, owner1) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 3, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 3, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4, v3}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 2) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 2) expectedConfig[owner2].numQualifiedAuctionNodes = 2 expectedConfig[owner2].qualifiedTopUpPerNode = big.NewInt(1500) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 2, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 2, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5, v4}, selectedNodes) - softAuctionConfig = calcSoftAuctionNodesConfig(ownersData, 1) + softAuctionConfig = als.calcSoftAuctionNodesConfig(ownersData, 1) expectedConfig[owner2].numQualifiedAuctionNodes = 1 expectedConfig[owner2].qualifiedTopUpPerNode = big.NewInt(3000) require.Equal(t, expectedConfig, softAuctionConfig) - selectedNodes = selectNodes(softAuctionConfig, 1, randomness) + selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5}, selectedNodes) } +func TestGetPrettyValue(t *testing.T) { + require.Equal(t, "1234.0", getPrettyValue(big.NewInt(1234), big.NewInt(1))) + require.Equal(t, "123.4", getPrettyValue(big.NewInt(1234), big.NewInt(10))) + require.Equal(t, "12.34", getPrettyValue(big.NewInt(1234), big.NewInt(100))) + require.Equal(t, "1.234", getPrettyValue(big.NewInt(1234), big.NewInt(1000))) + require.Equal(t, "0.1234", getPrettyValue(big.NewInt(1234), big.NewInt(10000))) + require.Equal(t, "0.01234", getPrettyValue(big.NewInt(1234), big.NewInt(100000))) + require.Equal(t, "0.00123", getPrettyValue(big.NewInt(1234), big.NewInt(1000000))) + require.Equal(t, "0.00012", getPrettyValue(big.NewInt(1234), big.NewInt(10000000))) + require.Equal(t, "0.00001", getPrettyValue(big.NewInt(1234), big.NewInt(100000000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1234), big.NewInt(1000000000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1234), big.NewInt(10000000000))) + + require.Equal(t, "1.0", getPrettyValue(big.NewInt(1), big.NewInt(1))) + require.Equal(t, "0.1", getPrettyValue(big.NewInt(1), big.NewInt(10))) + require.Equal(t, "0.01", getPrettyValue(big.NewInt(1), big.NewInt(100))) + require.Equal(t, "0.001", getPrettyValue(big.NewInt(1), big.NewInt(1000))) + require.Equal(t, "0.0001", getPrettyValue(big.NewInt(1), big.NewInt(10000))) + require.Equal(t, "0.00001", getPrettyValue(big.NewInt(1), big.NewInt(100000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1), big.NewInt(1000000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1), big.NewInt(10000000))) + + oneEGLD := big.NewInt(1000000000000000000) + denominationEGLD := big.NewInt(int64(math.Pow10(18))) + + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(0), denominationEGLD)) + require.Equal(t, "1.00000", getPrettyValue(oneEGLD, denominationEGLD)) + require.Equal(t, "1.10000", getPrettyValue(big.NewInt(1100000000000000000), denominationEGLD)) + require.Equal(t, "1.10000", getPrettyValue(big.NewInt(1100000000000000001), denominationEGLD)) + require.Equal(t, "1.11000", getPrettyValue(big.NewInt(1110000000000000001), denominationEGLD)) + require.Equal(t, "0.11100", getPrettyValue(big.NewInt(111000000000000001), denominationEGLD)) + require.Equal(t, "0.01110", getPrettyValue(big.NewInt(11100000000000001), denominationEGLD)) + require.Equal(t, "0.00111", getPrettyValue(big.NewInt(1110000000000001), denominationEGLD)) + require.Equal(t, "0.00011", getPrettyValue(big.NewInt(111000000000001), denominationEGLD)) + require.Equal(t, "0.00001", getPrettyValue(big.NewInt(11100000000001), denominationEGLD)) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1110000000001), denominationEGLD)) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(111000000001), denominationEGLD)) + + require.Equal(t, "2.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(2)), denominationEGLD)) + require.Equal(t, "20.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(20)), denominationEGLD)) + require.Equal(t, "2000000.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(2000000)), denominationEGLD)) + + require.Equal(t, "3.22220", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000000000)), denominationEGLD)) + require.Equal(t, "1.22222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000000000)), denominationEGLD)) + require.Equal(t, "1.02222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(22222000000000000)), denominationEGLD)) + require.Equal(t, "1.00222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000000)), denominationEGLD)) + require.Equal(t, "1.00022", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000000)), denominationEGLD)) + require.Equal(t, "1.00002", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(22222000000000)), denominationEGLD)) + require.Equal(t, "1.00000", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000)), denominationEGLD)) + require.Equal(t, "1.00000", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000)), denominationEGLD)) +} + func TestCalcNormalizedRandomness(t *testing.T) { t.Parallel() diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index c04f9b3dccf..7b6891148f7 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -8,7 +8,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" ) -func selectNodes( +func (als *auctionListSelector) selectNodes( ownersData map[string]*ownerData, numAvailableSlots uint32, randomness []byte, @@ -25,9 +25,9 @@ func selectNodes( selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } - displayOwnersSelectedNodes(ownersData) + als.displayOwnersSelectedNodes(ownersData) sortValidators(selectedFromAuction, validatorTopUpMap, normRand) - displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) + als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) return selectedFromAuction[:numAvailableSlots] } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 416bffd7202..18b6ed6bffc 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -859,6 +859,11 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, } als, _ := NewAuctionListSelector(argsAuctionListSelector) @@ -1807,6 +1812,12 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing ShardCoordinator: args.ShardCoordinator, StakingDataProvider: args.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, + Denomination: 1, } als, _ := NewAuctionListSelector(argsAuctionListSelector) args.AuctionListSelector = als @@ -1886,7 +1897,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing | owner2 | 3 | 1 | 2 | 2555 | 851 | pubKey4, pubKey5 | +--------+------------------+------------------+-------------------+--------------+-----------------+---------------------------+ -> Min possible topUp = 666; max possible topUp = 1333, min required topUp = 1216 - -> Selected nodes config in auction list + -> Selected nodes config in auction list. For each owner's auction nodes, qualified ones are selected by XOR with randomness +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ | Owner | Num staked nodes | TopUp per node | Total top up | Num auction nodes | Num qualified auction nodes | Num active nodes | Qualified top up per node | Selected auction list nodes | +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index b14e3c95ebf..94c43220c25 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -816,6 +816,8 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + SoftAuctionConfig: pcf.config.SoftAuctionConfig, + Denomination: pcf.economicsConfig.GlobalSettings.Denomination, } auctionListSelector, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelector) if err != nil { diff --git a/factory/processComponents.go b/factory/processComponents.go index 7089aad023d..0fa0e80bd90 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -114,6 +114,7 @@ type ProcessComponentsFactoryArgs struct { EpochConfig config.EpochConfig PrefConfigs config.PreferencesConfig ImportDBConfig config.ImportDbConfig + EconomicsConfig config.EconomicsConfig AccountsParser genesis.AccountsParser SmartContractParser genesis.InitialSmartContractParser GasSchedule core.GasScheduleNotifier @@ -142,6 +143,7 @@ type processComponentsFactory struct { epochConfig config.EpochConfig prefConfigs config.PreferencesConfig importDBConfig config.ImportDbConfig + economicsConfig config.EconomicsConfig accountsParser genesis.AccountsParser smartContractParser genesis.InitialSmartContractParser gasSchedule core.GasScheduleNotifier @@ -180,6 +182,7 @@ func NewProcessComponentsFactory(args ProcessComponentsFactoryArgs) (*processCom epochConfig: args.EpochConfig, prefConfigs: args.PrefConfigs, importDBConfig: args.ImportDBConfig, + economicsConfig: args.EconomicsConfig, accountsParser: args.AccountsParser, smartContractParser: args.SmartContractParser, gasSchedule: args.GasSchedule, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 08db3b3e030..e933e64c065 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2197,6 +2197,11 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { ShardCoordinator: tpn.ShardCoordinator, StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index c71bd2f747e..9a6da6e4c71 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -45,6 +45,11 @@ func createSystemSCProcessor( ShardCoordinator: shardCoordinator, StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 22cff159711..799796720d0 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -1008,6 +1008,7 @@ func (nr *nodeRunner) CreateManagedProcessComponents( EpochConfig: *configs.EpochConfig, PrefConfigs: configs.PreferencesConfig.Preferences, ImportDBConfig: *configs.ImportDbConfig, + EconomicsConfig: *configs.EconomicsConfig, AccountsParser: accountsParser, SmartContractParser: smartContractParser, GasSchedule: gasScheduleNotifier, From 09d3efc6faf5dd5d61a010e30e3461ededa14eaa Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 25 May 2022 17:36:27 +0300 Subject: [PATCH 287/958] FEAT: Add getAuctionConfig test + split test files --- epochStart/metachain/auctionListDisplayer.go | 14 +- .../metachain/auctionListDisplayer_test.go | 61 +++++ epochStart/metachain/auctionListSelector.go | 102 ++++++--- .../metachain/auctionListSelector_test.go | 216 ++++++++++-------- .../metachain/auctionListSorting_test.go | 39 ++++ 5 files changed, 295 insertions(+), 137 deletions(-) create mode 100644 epochStart/metachain/auctionListDisplayer_test.go create mode 100644 epochStart/metachain/auctionListSorting_test.go diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 4db42ef73ba..9bc004f183e 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -72,7 +72,7 @@ func getPrettyValue(val *big.Int, denominator *big.Int) string { return first + "." + second2 - //return big.NewInt(0).Div(val, als.softAuctionConfig.denomination).String() + //return big.NewInt(0).Div(val, als.softAuctionConfig.denominator).String() } func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerData) { @@ -97,8 +97,8 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerDa strconv.Itoa(int(owner.numStakedNodes)), strconv.Itoa(int(owner.numActiveNodes)), strconv.Itoa(int(owner.numAuctionNodes)), - getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denomination), - getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denomination), + getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denominator), + getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denominator), getShortDisplayableBlsKeys(owner.auctionList), } lines = append(lines, display.NewLineData(false, line)) @@ -127,12 +127,12 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string line := []string{ (ownerPubKey), strconv.Itoa(int(owner.numStakedNodes)), - getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denomination), - getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denomination), + getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denominator), + getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denominator), strconv.Itoa(int(owner.numAuctionNodes)), strconv.Itoa(int(owner.numQualifiedAuctionNodes)), strconv.Itoa(int(owner.numActiveNodes)), - getPrettyValue(owner.qualifiedTopUpPerNode, als.softAuctionConfig.denomination), + getPrettyValue(owner.qualifiedTopUpPerNode, als.softAuctionConfig.denominator), getShortDisplayableBlsKeys(owner.auctionList[:owner.numQualifiedAuctionNodes]), } lines = append(lines, display.NewLineData(false, line)) @@ -180,7 +180,7 @@ func (als *auctionListSelector) displayAuctionList( line := display.NewLineData(horizontalLine, []string{ (owner), string(pubKey), - getPrettyValue(topUp, als.softAuctionConfig.denomination), + getPrettyValue(topUp, als.softAuctionConfig.denominator), }) lines = append(lines, line) } diff --git a/epochStart/metachain/auctionListDisplayer_test.go b/epochStart/metachain/auctionListDisplayer_test.go new file mode 100644 index 00000000000..34be106005e --- /dev/null +++ b/epochStart/metachain/auctionListDisplayer_test.go @@ -0,0 +1,61 @@ +package metachain + +import ( + "math" + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetPrettyValue(t *testing.T) { + require.Equal(t, "1234.0", getPrettyValue(big.NewInt(1234), big.NewInt(1))) + require.Equal(t, "123.4", getPrettyValue(big.NewInt(1234), big.NewInt(10))) + require.Equal(t, "12.34", getPrettyValue(big.NewInt(1234), big.NewInt(100))) + require.Equal(t, "1.234", getPrettyValue(big.NewInt(1234), big.NewInt(1000))) + require.Equal(t, "0.1234", getPrettyValue(big.NewInt(1234), big.NewInt(10000))) + require.Equal(t, "0.01234", getPrettyValue(big.NewInt(1234), big.NewInt(100000))) + require.Equal(t, "0.00123", getPrettyValue(big.NewInt(1234), big.NewInt(1000000))) + require.Equal(t, "0.00012", getPrettyValue(big.NewInt(1234), big.NewInt(10000000))) + require.Equal(t, "0.00001", getPrettyValue(big.NewInt(1234), big.NewInt(100000000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1234), big.NewInt(1000000000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1234), big.NewInt(10000000000))) + + require.Equal(t, "1.0", getPrettyValue(big.NewInt(1), big.NewInt(1))) + require.Equal(t, "0.1", getPrettyValue(big.NewInt(1), big.NewInt(10))) + require.Equal(t, "0.01", getPrettyValue(big.NewInt(1), big.NewInt(100))) + require.Equal(t, "0.001", getPrettyValue(big.NewInt(1), big.NewInt(1000))) + require.Equal(t, "0.0001", getPrettyValue(big.NewInt(1), big.NewInt(10000))) + require.Equal(t, "0.00001", getPrettyValue(big.NewInt(1), big.NewInt(100000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1), big.NewInt(1000000))) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1), big.NewInt(10000000))) + + oneEGLD := big.NewInt(1000000000000000000) + denominationEGLD := big.NewInt(int64(math.Pow10(18))) + + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(0), denominationEGLD)) + require.Equal(t, "1.00000", getPrettyValue(oneEGLD, denominationEGLD)) + require.Equal(t, "1.10000", getPrettyValue(big.NewInt(1100000000000000000), denominationEGLD)) + require.Equal(t, "1.10000", getPrettyValue(big.NewInt(1100000000000000001), denominationEGLD)) + require.Equal(t, "1.11000", getPrettyValue(big.NewInt(1110000000000000001), denominationEGLD)) + require.Equal(t, "0.11100", getPrettyValue(big.NewInt(111000000000000001), denominationEGLD)) + require.Equal(t, "0.01110", getPrettyValue(big.NewInt(11100000000000001), denominationEGLD)) + require.Equal(t, "0.00111", getPrettyValue(big.NewInt(1110000000000001), denominationEGLD)) + require.Equal(t, "0.00011", getPrettyValue(big.NewInt(111000000000001), denominationEGLD)) + require.Equal(t, "0.00001", getPrettyValue(big.NewInt(11100000000001), denominationEGLD)) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1110000000001), denominationEGLD)) + require.Equal(t, "0.00000", getPrettyValue(big.NewInt(111000000001), denominationEGLD)) + + require.Equal(t, "2.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(2)), denominationEGLD)) + require.Equal(t, "20.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(20)), denominationEGLD)) + require.Equal(t, "2000000.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(2000000)), denominationEGLD)) + + require.Equal(t, "3.22220", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000000000)), denominationEGLD)) + require.Equal(t, "1.22222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000000000)), denominationEGLD)) + require.Equal(t, "1.02222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(22222000000000000)), denominationEGLD)) + require.Equal(t, "1.00222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000000)), denominationEGLD)) + require.Equal(t, "1.00022", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000000)), denominationEGLD)) + require.Equal(t, "1.00002", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(22222000000000)), denominationEGLD)) + require.Equal(t, "1.00000", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000)), denominationEGLD)) + require.Equal(t, "1.00000", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000)), denominationEGLD)) +} diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index d5fd6d2d575..56ceab6b61d 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -28,10 +28,10 @@ type ownerData struct { } type auctionConfig struct { - step *big.Int - minTopUp *big.Int - maxTopUp *big.Int - denomination *big.Int + step *big.Int + minTopUp *big.Int + maxTopUp *big.Int + denominator *big.Int } type auctionListSelector struct { @@ -39,7 +39,6 @@ type auctionListSelector struct { stakingDataProvider epochStart.StakingDataProvider nodesConfigProvider epochStart.MaxNodesChangeConfigProvider softAuctionConfig *auctionConfig - denomination int } // AuctionListSelectorArgs is a struct placeholder for all arguments required to create an auctionListSelector @@ -54,50 +53,85 @@ type AuctionListSelectorArgs struct { // NewAuctionListSelector will create a new auctionListSelector, which handles selection of nodes from auction list based // on their top up func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, error) { - step, ok := big.NewInt(0).SetString(args.SoftAuctionConfig.TopUpStep, 10) + softAuctionConfig, err := getAuctionConfig(args.SoftAuctionConfig, args.Denomination) + if err != nil { + return nil, err + } + err = checkNilArgs(args) + if err != nil { + return nil, err + } + + log.Debug("NewAuctionListSelector with config", + "step top up", softAuctionConfig.step.String(), + "min top up", softAuctionConfig.minTopUp.String(), + "max top up", softAuctionConfig.maxTopUp.String(), + "denomination", args.Denomination, + "denominator for pretty values", softAuctionConfig.denominator.String(), + ) + + asl := &auctionListSelector{ + shardCoordinator: args.ShardCoordinator, + stakingDataProvider: args.StakingDataProvider, + nodesConfigProvider: args.MaxNodesChangeConfigProvider, + softAuctionConfig: softAuctionConfig, + } + + return asl, nil +} + +func getAuctionConfig(softAuctionConfig config.SoftAuctionConfig, denomination int) (*auctionConfig, error) { + step, ok := big.NewInt(0).SetString(softAuctionConfig.TopUpStep, 10) if !ok || step.Cmp(zero) <= 0 { - return nil, process.ErrInvalidValue + return nil, fmt.Errorf("%w for step in soft auction config;expected number > 0, got %s", + process.ErrInvalidValue, + softAuctionConfig.TopUpStep, + ) } - minTopUp, ok := big.NewInt(0).SetString(args.SoftAuctionConfig.MinTopUp, 10) + minTopUp, ok := big.NewInt(0).SetString(softAuctionConfig.MinTopUp, 10) if !ok || minTopUp.Cmp(zero) <= 0 { - return nil, process.ErrInvalidValue + return nil, fmt.Errorf("%w for min top up in soft auction config;expected number > 0, got %s", + process.ErrInvalidValue, + softAuctionConfig.MinTopUp, + ) } - maxTopUp, ok := big.NewInt(0).SetString(args.SoftAuctionConfig.MaxTopUp, 10) + maxTopUp, ok := big.NewInt(0).SetString(softAuctionConfig.MaxTopUp, 10) if !ok || maxTopUp.Cmp(zero) <= 0 { - return nil, process.ErrInvalidValue + return nil, fmt.Errorf("%w for max top up in soft auction config;expected number > 0, got %s", + process.ErrInvalidValue, + softAuctionConfig.MaxTopUp, + ) } - if args.Denomination < 0 { - return nil, process.ErrInvalidValue + if denomination < 0 { + return nil, fmt.Errorf("%w for denomination soft auction config;expected number >= 0, got %d", + process.ErrInvalidValue, + denomination, + ) } - den := int(math.Pow10(args.Denomination)) + return &auctionConfig{ + step: step, + minTopUp: minTopUp, + maxTopUp: maxTopUp, + denominator: big.NewInt(int64(math.Pow10(denomination))), + }, nil +} + +func checkNilArgs(args AuctionListSelectorArgs) error { if check.IfNil(args.ShardCoordinator) { - return nil, epochStart.ErrNilShardCoordinator + return epochStart.ErrNilShardCoordinator } if check.IfNil(args.StakingDataProvider) { - return nil, epochStart.ErrNilStakingDataProvider + return epochStart.ErrNilStakingDataProvider } if check.IfNil(args.MaxNodesChangeConfigProvider) { - return nil, epochStart.ErrNilMaxNodesChangeConfigProvider + return epochStart.ErrNilMaxNodesChangeConfigProvider } - asl := &auctionListSelector{ - shardCoordinator: args.ShardCoordinator, - stakingDataProvider: args.StakingDataProvider, - nodesConfigProvider: args.MaxNodesChangeConfigProvider, - softAuctionConfig: &auctionConfig{ - step: step, - minTopUp: minTopUp, - maxTopUp: maxTopUp, - denomination: big.NewInt(int64(den)), - }, - denomination: args.Denomination, - } - - return asl, nil + return nil } // SelectNodesFromAuctionList will select nodes from validatorsInfoMap based on their top up. If two or more validators @@ -297,11 +331,9 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( "max top up per node", maxTopUp.String(), ) - step := big.NewInt(10) // todo: 10 egld for real topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) - previousConfig := copyOwnersData(ownersData) - for ; topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, step) { + for ; topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, als.softAuctionConfig.step) { numNodesQualifyingForTopUp := int64(0) previousConfig = copyOwnersData(ownersData) @@ -331,7 +363,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } } - als.displayMinRequiredTopUp(topUp, minTopUp, step) + als.displayMinRequiredTopUp(topUp, minTopUp, als.softAuctionConfig.step) return previousConfig } diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index e8443aae3c6..a8bd8e93707 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -3,7 +3,6 @@ package metachain import ( "encoding/hex" "errors" - "math" "math/big" "strings" "testing" @@ -22,6 +21,14 @@ import ( "github.com/stretchr/testify/require" ) +func createSoftAuctionConfig() config.SoftAuctionConfig { + return config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + } +} + func createAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeConfig) AuctionListSelectorArgs { epochNotifier := forking.NewGenericEpochNotifier() nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) @@ -34,11 +41,7 @@ func createAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeC ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - }, + SoftAuctionConfig: createSoftAuctionConfig(), } } @@ -52,11 +55,7 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha ShardCoordinator: argsSystemSC.ShardCoordinator, StakingDataProvider: argsSystemSC.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - }, + SoftAuctionConfig: createSoftAuctionConfig(), }, argsSystemSC } @@ -97,6 +96,15 @@ func TestNewAuctionListSelector(t *testing.T) { require.Equal(t, epochStart.ErrNilMaxNodesChangeConfigProvider, err) }) + t.Run("invalid soft auction config", func(t *testing.T) { + t.Parallel() + args := createAuctionListSelectorArgs(nil) + args.SoftAuctionConfig.TopUpStep = "0" + als, err := NewAuctionListSelector(args) + require.Nil(t, als) + requireInvalidValueError(t, err, "step") + }) + t.Run("should work", func(t *testing.T) { t.Parallel() args := createAuctionListSelectorArgs(nil) @@ -106,6 +114,108 @@ func TestNewAuctionListSelector(t *testing.T) { }) } +func requireInvalidValueError(t *testing.T, err error, msgToContain string) { + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), process.ErrInvalidValue.Error())) + require.True(t, strings.Contains(err.Error(), msgToContain)) +} + +func TestGetAuctionConfig(t *testing.T) { + t.Parallel() + + t.Run("invalid step", func(t *testing.T) { + t.Parallel() + + cfg := createSoftAuctionConfig() + + cfg.TopUpStep = "dsa" + res, err := getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "step") + + cfg.TopUpStep = "-1" + res, err = getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "step") + + cfg.TopUpStep = "0" + res, err = getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "step") + }) + + t.Run("invalid min top up", func(t *testing.T) { + t.Parallel() + + cfg := createSoftAuctionConfig() + + cfg.MinTopUp = "dsa" + res, err := getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "min top up") + + cfg.MinTopUp = "-1" + res, err = getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "min top up") + + cfg.MinTopUp = "0" + res, err = getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "min top up") + }) + + t.Run("invalid max top up", func(t *testing.T) { + t.Parallel() + + cfg := createSoftAuctionConfig() + + cfg.MaxTopUp = "dsa" + res, err := getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "max top up") + + cfg.MaxTopUp = "-1" + res, err = getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "max top up") + + cfg.MaxTopUp = "0" + res, err = getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "max top up") + }) + + t.Run("invalid denomination", func(t *testing.T) { + t.Parallel() + + cfg := createSoftAuctionConfig() + + res, err := getAuctionConfig(cfg, -1) + require.Nil(t, res) + requireInvalidValueError(t, err, "denomination") + }) + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + cfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "444", + } + + res, err := getAuctionConfig(cfg, 4) + require.Nil(t, err) + require.Equal(t, &auctionConfig{ + step: big.NewInt(10), + minTopUp: big.NewInt(1), + maxTopUp: big.NewInt(444), + denominator: big.NewInt(10000), + }, res) + }) +} + func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { t.Parallel() @@ -725,87 +835,3 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v5}, selectedNodes) } - -func TestGetPrettyValue(t *testing.T) { - require.Equal(t, "1234.0", getPrettyValue(big.NewInt(1234), big.NewInt(1))) - require.Equal(t, "123.4", getPrettyValue(big.NewInt(1234), big.NewInt(10))) - require.Equal(t, "12.34", getPrettyValue(big.NewInt(1234), big.NewInt(100))) - require.Equal(t, "1.234", getPrettyValue(big.NewInt(1234), big.NewInt(1000))) - require.Equal(t, "0.1234", getPrettyValue(big.NewInt(1234), big.NewInt(10000))) - require.Equal(t, "0.01234", getPrettyValue(big.NewInt(1234), big.NewInt(100000))) - require.Equal(t, "0.00123", getPrettyValue(big.NewInt(1234), big.NewInt(1000000))) - require.Equal(t, "0.00012", getPrettyValue(big.NewInt(1234), big.NewInt(10000000))) - require.Equal(t, "0.00001", getPrettyValue(big.NewInt(1234), big.NewInt(100000000))) - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1234), big.NewInt(1000000000))) - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1234), big.NewInt(10000000000))) - - require.Equal(t, "1.0", getPrettyValue(big.NewInt(1), big.NewInt(1))) - require.Equal(t, "0.1", getPrettyValue(big.NewInt(1), big.NewInt(10))) - require.Equal(t, "0.01", getPrettyValue(big.NewInt(1), big.NewInt(100))) - require.Equal(t, "0.001", getPrettyValue(big.NewInt(1), big.NewInt(1000))) - require.Equal(t, "0.0001", getPrettyValue(big.NewInt(1), big.NewInt(10000))) - require.Equal(t, "0.00001", getPrettyValue(big.NewInt(1), big.NewInt(100000))) - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1), big.NewInt(1000000))) - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1), big.NewInt(10000000))) - - oneEGLD := big.NewInt(1000000000000000000) - denominationEGLD := big.NewInt(int64(math.Pow10(18))) - - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(0), denominationEGLD)) - require.Equal(t, "1.00000", getPrettyValue(oneEGLD, denominationEGLD)) - require.Equal(t, "1.10000", getPrettyValue(big.NewInt(1100000000000000000), denominationEGLD)) - require.Equal(t, "1.10000", getPrettyValue(big.NewInt(1100000000000000001), denominationEGLD)) - require.Equal(t, "1.11000", getPrettyValue(big.NewInt(1110000000000000001), denominationEGLD)) - require.Equal(t, "0.11100", getPrettyValue(big.NewInt(111000000000000001), denominationEGLD)) - require.Equal(t, "0.01110", getPrettyValue(big.NewInt(11100000000000001), denominationEGLD)) - require.Equal(t, "0.00111", getPrettyValue(big.NewInt(1110000000000001), denominationEGLD)) - require.Equal(t, "0.00011", getPrettyValue(big.NewInt(111000000000001), denominationEGLD)) - require.Equal(t, "0.00001", getPrettyValue(big.NewInt(11100000000001), denominationEGLD)) - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(1110000000001), denominationEGLD)) - require.Equal(t, "0.00000", getPrettyValue(big.NewInt(111000000001), denominationEGLD)) - - require.Equal(t, "2.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(2)), denominationEGLD)) - require.Equal(t, "20.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(20)), denominationEGLD)) - require.Equal(t, "2000000.00000", getPrettyValue(big.NewInt(0).Mul(oneEGLD, big.NewInt(2000000)), denominationEGLD)) - - require.Equal(t, "3.22220", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000000000)), denominationEGLD)) - require.Equal(t, "1.22222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000000000)), denominationEGLD)) - require.Equal(t, "1.02222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(22222000000000000)), denominationEGLD)) - require.Equal(t, "1.00222", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000000)), denominationEGLD)) - require.Equal(t, "1.00022", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000000)), denominationEGLD)) - require.Equal(t, "1.00002", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(22222000000000)), denominationEGLD)) - require.Equal(t, "1.00000", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(2222200000000)), denominationEGLD)) - require.Equal(t, "1.00000", getPrettyValue(big.NewInt(0).Add(oneEGLD, big.NewInt(222220000000)), denominationEGLD)) -} - -func TestCalcNormalizedRandomness(t *testing.T) { - t.Parallel() - - t.Run("randomness longer than expected len", func(t *testing.T) { - t.Parallel() - - result := calcNormalizedRandomness([]byte("rand"), 2) - require.Equal(t, []byte("ra"), result) - }) - - t.Run("randomness length equal to expected len", func(t *testing.T) { - t.Parallel() - - result := calcNormalizedRandomness([]byte("rand"), 4) - require.Equal(t, []byte("rand"), result) - }) - - t.Run("randomness length less than expected len", func(t *testing.T) { - t.Parallel() - - result := calcNormalizedRandomness([]byte("rand"), 6) - require.Equal(t, []byte("randra"), result) - }) - - t.Run("expected len is zero", func(t *testing.T) { - t.Parallel() - - result := calcNormalizedRandomness([]byte("rand"), 0) - require.Empty(t, result) - }) -} diff --git a/epochStart/metachain/auctionListSorting_test.go b/epochStart/metachain/auctionListSorting_test.go new file mode 100644 index 00000000000..637869ea1d6 --- /dev/null +++ b/epochStart/metachain/auctionListSorting_test.go @@ -0,0 +1,39 @@ +package metachain + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCalcNormalizedRandomness(t *testing.T) { + t.Parallel() + + t.Run("randomness longer than expected len", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 2) + require.Equal(t, []byte("ra"), result) + }) + + t.Run("randomness length equal to expected len", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 4) + require.Equal(t, []byte("rand"), result) + }) + + t.Run("randomness length less than expected len", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 6) + require.Equal(t, []byte("randra"), result) + }) + + t.Run("expected len is zero", func(t *testing.T) { + t.Parallel() + + result := calcNormalizedRandomness([]byte("rand"), 0) + require.Empty(t, result) + }) +} From 8dd0ee385d76367c96b4e4b5d29e278825ed9658 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 25 May 2022 17:50:21 +0300 Subject: [PATCH 288/958] FIX: Broken tests --- factory/coreComponents_test.go | 5 +++++ factory/cryptoComponents_test.go | 5 +++++ testscommon/generalConfig.go | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/factory/coreComponents_test.go b/factory/coreComponents_test.go index 062f59a45ee..15b0fcb9b5e 100644 --- a/factory/coreComponents_test.go +++ b/factory/coreComponents_test.go @@ -253,6 +253,11 @@ func getEpochStartConfig() config.EpochStartConfig { func getCoreArgs() factory.CoreComponentsFactoryArgs { return factory.CoreComponentsFactoryArgs{ Config: config.Config{ + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, EpochStartConfig: getEpochStartConfig(), PublicKeyPeerId: config.CacheConfig{ Type: "LRU", diff --git a/factory/cryptoComponents_test.go b/factory/cryptoComponents_test.go index 3934a3c9398..84fc01810ff 100644 --- a/factory/cryptoComponents_test.go +++ b/factory/cryptoComponents_test.go @@ -391,6 +391,11 @@ func getCryptoArgs(coreComponents factory.CoreComponentsHolder) factory.CryptoCo Consensus: config.ConsensusConfig{ Type: "bls", }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, MultisigHasher: config.TypeConfig{Type: "blake2b"}, PublicKeyPIDSignature: config.CacheConfig{ Capacity: 1000, diff --git a/testscommon/generalConfig.go b/testscommon/generalConfig.go index 4ca7b49727d..eb9362c18ef 100644 --- a/testscommon/generalConfig.go +++ b/testscommon/generalConfig.go @@ -8,6 +8,11 @@ import ( // GetGeneralConfig returns the common configuration used for testing func GetGeneralConfig() config.Config { return config.Config{ + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + }, PublicKeyPeerId: config.CacheConfig{ Type: "LRU", Capacity: 5000, From 64ef32591f77be4e73d9e87a04f2f3d7bd71e2fe Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 26 May 2022 14:26:25 +0300 Subject: [PATCH 289/958] FIX: General fixes 1 --- epochStart/metachain/auctionListDisplayer.go | 88 ++++++++++---------- epochStart/metachain/auctionListSelector.go | 16 ++-- epochStart/metachain/auctionListSorting.go | 6 +- epochStart/metachain/systemSCs_test.go | 19 ++--- 4 files changed, 64 insertions(+), 65 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 9bc004f183e..255eb177456 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -1,6 +1,7 @@ package metachain import ( + "encoding/hex" "fmt" "math/big" "strconv" @@ -8,6 +9,7 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/display" + logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/state" ) @@ -15,41 +17,41 @@ const maxPubKeyDisplayableLen = 20 const maxNumOfDecimalsToDisplay = 5 func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, minFound *big.Int, step *big.Int) { - //if log.GetLevel() > logger.LogDebug { - // return - //} + if log.GetLevel() > logger.LogDebug { + return + } - if !(topUp.Cmp(als.softAuctionConfig.minTopUp) == 0) { + if topUp.Cmp(als.softAuctionConfig.minTopUp) > 0 { topUp = big.NewInt(0).Sub(topUp, step) } iteratedValues := big.NewInt(0).Sub(topUp, minFound) - iterations := big.NewInt(0).Div(iteratedValues, step) + iterations := big.NewInt(0).Div(iteratedValues, step).Int64() + iterations++ - log.Info("auctionListSelector: found min required", + log.Debug("auctionListSelector: found min required", "topUp", topUp.String(), - "after num of iterations", iterations.String(), + "after num of iterations", iterations, ) } func getShortKey(pubKey []byte) string { - displayablePubKey := pubKey - pubKeyLen := len(pubKey) + pubKeyHex := hex.EncodeToString(pubKey) + displayablePubKey := pubKeyHex + + pubKeyLen := len(displayablePubKey) if pubKeyLen > maxPubKeyDisplayableLen { - displayablePubKey = make([]byte, 0) - displayablePubKey = append(displayablePubKey, pubKey[:maxPubKeyDisplayableLen/2]...) - displayablePubKey = append(displayablePubKey, []byte("...")...) - displayablePubKey = append(displayablePubKey, pubKey[pubKeyLen-maxPubKeyDisplayableLen/2:]...) + displayablePubKey = pubKeyHex[:maxPubKeyDisplayableLen/2] + "..." + pubKeyHex[pubKeyLen-maxPubKeyDisplayableLen/2:] } - return string(displayablePubKey) + return displayablePubKey } func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { pubKeys := "" for idx, validator := range list { - pubKeys += getShortKey(validator.GetPublicKey()) // todo: hex here + pubKeys += getShortKey(validator.GetPublicKey()) addDelimiter := idx != len(list)-1 if addDelimiter { pubKeys += ", " @@ -61,24 +63,24 @@ func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { func getPrettyValue(val *big.Int, denominator *big.Int) string { first := big.NewInt(0).Div(val, denominator).String() - second := big.NewInt(0).Mod(val, denominator).String() + decimals := big.NewInt(0).Mod(val, denominator).String() - repeatCt := core.MaxInt(len(denominator.String())-len(second)-1, 0) - zeroes := strings.Repeat("0", repeatCt) - second2 := zeroes + second - if len(second2) > maxNumOfDecimalsToDisplay { - second2 = second2[:maxNumOfDecimalsToDisplay] - } + zeroesCt := (len(denominator.String()) - len(decimals)) - 1 + zeroesCt = core.MaxInt(zeroesCt, 0) + zeroes := strings.Repeat("0", zeroesCt) - return first + "." + second2 + second := zeroes + decimals + if len(second) > maxNumOfDecimalsToDisplay { + second = second[:maxNumOfDecimalsToDisplay] + } - //return big.NewInt(0).Div(val, als.softAuctionConfig.denominator).String() + return first + "." + second } func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerData) { - //if log.GetLevel() > logger.LogDebug { - // return - //} + if log.GetLevel() > logger.LogDebug { + return + } tableHeader := []string{ "Owner", @@ -89,11 +91,11 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerDa "Top up per node", "Auction list nodes", } + lines := make([]*display.LineData, 0, len(ownersData)) for ownerPubKey, owner := range ownersData { - line := []string{ - (ownerPubKey), + hex.EncodeToString([]byte(ownerPubKey)), strconv.Itoa(int(owner.numStakedNodes)), strconv.Itoa(int(owner.numActiveNodes)), strconv.Itoa(int(owner.numAuctionNodes)), @@ -108,9 +110,10 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerDa } func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string]*ownerData) { - //if log.GetLevel() > logger.LogDebug { - // return - //} + if log.GetLevel() > logger.LogDebug { + return + } + tableHeader := []string{ "Owner", "Num staked nodes", @@ -122,10 +125,11 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string "Qualified top up per node", "Selected auction list nodes", } + lines := make([]*display.LineData, 0, len(ownersData)) for ownerPubKey, owner := range ownersData { line := []string{ - (ownerPubKey), + hex.EncodeToString([]byte(ownerPubKey)), strconv.Itoa(int(owner.numStakedNodes)), getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denominator), getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denominator), @@ -157,29 +161,27 @@ func (als *auctionListSelector) displayAuctionList( ownersData map[string]*ownerData, numOfSelectedNodes uint32, ) { - //if log.GetLevel() > logger.LogDebug { - // return - //} + if log.GetLevel() > logger.LogDebug { + return + } tableHeader := []string{"Owner", "Registered key", "Qualified TopUp per node"} lines := make([]*display.LineData, 0, len(auctionList)) - horizontalLine := false blsKeysOwnerMap := getBlsKeyOwnerMap(ownersData) for idx, validator := range auctionList { pubKey := validator.GetPublicKey() - owner, found := blsKeysOwnerMap[string(pubKey)] if !found { log.Error("auctionListSelector.displayAuctionList could not find owner for", - "bls key", string(pubKey)) //todo: hex here + "bls key", hex.EncodeToString(pubKey)) continue } topUp := ownersData[owner].qualifiedTopUpPerNode - horizontalLine = uint32(idx) == numOfSelectedNodes-1 + horizontalLine := uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ - (owner), - string(pubKey), + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(pubKey), getPrettyValue(topUp, als.softAuctionConfig.denominator), }) lines = append(lines, line) @@ -196,5 +198,5 @@ func displayTable(tableHeader []string, lines []*display.LineData, message strin } msg := fmt.Sprintf("%s\n%s", message, table) - log.Info(msg) + log.Debug(msg) } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 56ceab6b61d..db04191706b 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -63,21 +63,19 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, } log.Debug("NewAuctionListSelector with config", - "step top up", softAuctionConfig.step.String(), + "top up step", softAuctionConfig.step.String(), "min top up", softAuctionConfig.minTopUp.String(), "max top up", softAuctionConfig.maxTopUp.String(), "denomination", args.Denomination, "denominator for pretty values", softAuctionConfig.denominator.String(), ) - asl := &auctionListSelector{ + return &auctionListSelector{ shardCoordinator: args.ShardCoordinator, stakingDataProvider: args.StakingDataProvider, nodesConfigProvider: args.MaxNodesChangeConfigProvider, softAuctionConfig: softAuctionConfig, - } - - return asl, nil + }, nil } func getAuctionConfig(softAuctionConfig config.SoftAuctionConfig, denomination int) (*auctionConfig, error) { @@ -194,7 +192,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( sw.Start("auctionListSelector.sortAuctionList") defer func() { sw.Stop("auctionListSelector.sortAuctionList") - log.Info("time measurements", sw.GetMeasurements()...) + log.Debug("time measurements", sw.GetMeasurements()...) }() return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) @@ -219,8 +217,8 @@ func (als *auctionListSelector) getAuctionDataAndNumOfValidators( _, isUnqualified := unqualifiedOwners[owner] if isUnqualified { log.Debug("auctionListSelector: found node in auction with unqualified owner, do not add it to selection", - "owner", owner, - "bls key", string(blsKey), //todo: hex + "owner", hex.EncodeToString([]byte(owner)), + "bls key", hex.EncodeToString(blsKey), ) continue } @@ -326,7 +324,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( ) map[string]*ownerData { ownersData := copyOwnersData(data) minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) - log.Info("auctionListSelector: calc min and max possible top up", + log.Debug("auctionListSelector: calc min and max possible top up", "min top up per node", minTopUp.String(), "max top up per node", maxTopUp.String(), ) diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index 7b6891148f7..f104ef0017b 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -20,7 +20,7 @@ func (als *auctionListSelector) selectNodes( normRand := calcNormalizedRandomness(randomness, pubKeyLen) for _, owner := range ownersData { - sortListByXORWithRand(owner.auctionList, normRand) + sortListByPubKey(owner.auctionList) addQualifiedValidatorsTopUpInMap(owner, validatorTopUpMap) selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } @@ -53,12 +53,12 @@ func calcNormalizedRandomness(randomness []byte, expectedLen int) []byte { return rand } -func sortListByXORWithRand(list []state.ValidatorInfoHandler, randomness []byte) { +func sortListByPubKey(list []state.ValidatorInfoHandler) { sort.SliceStable(list, func(i, j int) bool { pubKey1 := list[i].GetPublicKey() pubKey2 := list[j].GetPublicKey() - return compareByXORWithRandomness(pubKey1, pubKey2, randomness) + return bytes.Compare(pubKey1, pubKey2) > 0 }) } diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 18b6ed6bffc..bc9f33b61e8 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1817,7 +1817,6 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing MinTopUp: "1", MaxTopUp: "32000000", }, - Denomination: 1, } als, _ := NewAuctionListSelector(argsAuctionListSelector) args.AuctionListSelector = als @@ -1897,21 +1896,21 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing | owner2 | 3 | 1 | 2 | 2555 | 851 | pubKey4, pubKey5 | +--------+------------------+------------------+-------------------+--------------+-----------------+---------------------------+ -> Min possible topUp = 666; max possible topUp = 1333, min required topUp = 1216 - -> Selected nodes config in auction list. For each owner's auction nodes, qualified ones are selected by XOR with randomness + -> Selected nodes config in auction list. For each owner's auction nodes, qualified ones are selected by sorting the bls keys +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ | Owner | Num staked nodes | TopUp per node | Total top up | Num auction nodes | Num qualified auction nodes | Num active nodes | Qualified top up per node | Selected auction list nodes | +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ | owner1 | 3 | 1222 | 3666 | 1 | 1 | 2 | 1222 | pubKey2 | - | owner2 | 3 | 851 | 2555 | 2 | 1 | 1 | 1277 | pubKey4 | + | owner2 | 3 | 851 | 2555 | 2 | 1 | 1 | 1277 | pubKey5 | | owner3 | 2 | 1222 | 2444 | 1 | 1 | 1 | 1222 | pubKey7 | - | owner4 | 4 | 666 | 2666 | 3 | 1 | 1 | 1333 | pubKe10 | + | owner4 | 4 | 666 | 2666 | 3 | 1 | 1 | 1333 | pubKey9 | +--------+------------------+----------------+--------------+-------------------+-----------------------------+------------------+---------------------------+-----------------------------+ -> Final selected nodes from auction list +--------+----------------+--------------------------+ | Owner | Registered key | Qualified TopUp per node | +--------+----------------+--------------------------+ - | owner4 | pubKe10 | 1333 | - | owner2 | pubKey4 | 1277 | + | owner4 | pubKey9 | 1333 | + | owner2 | pubKey5 | 1277 | | owner1 | pubKey2 | 1222 | +--------+----------------+--------------------------+ | owner3 | pubKey7 | 1222 | @@ -1941,15 +1940,15 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing }, 1: { createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1), - createValidatorInfo(owner2StakedKeys[1], common.SelectedFromAuctionList, owner2, 1), - createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1), + createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2, 1), + createValidatorInfo(owner2StakedKeys[2], common.SelectedFromAuctionList, owner2, 1), createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1), createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1), createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1), - createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1), - createValidatorInfo(owner4StakedKeys[2], common.SelectedFromAuctionList, owner4, 1), + createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4, 1), + createValidatorInfo(owner4StakedKeys[2], common.AuctionList, owner4, 1), createValidatorInfo(owner4StakedKeys[3], common.AuctionList, owner4, 1), createValidatorInfo(owner5StakedKeys[0], common.EligibleList, owner5, 1), From 85d08d95d8fd953c495c753989b1a314cfdee8bb Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 26 May 2022 14:57:12 +0300 Subject: [PATCH 290/958] FIX: General fixes 2 --- epochStart/errors.go | 2 +- epochStart/metachain/auctionListDisplayer.go | 30 ++++++++++---------- epochStart/metachain/auctionListSorting.go | 28 +++++++++--------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index ba89dc864c8..caa22f7daac 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -335,7 +335,7 @@ var ErrNilMaxNodesChangeConfigProvider = errors.New("nil nodes config provider h // ErrNilAuctionListSelector signals that a nil auction list selector has been provided var ErrNilAuctionListSelector = errors.New("nil auction list selector has been provided") -// ErrOwnerHasNoStakedNode signals that an owner has no staked node +// ErrOwnerHasNoStakedNode signals that the owner has no staked node var ErrOwnerHasNoStakedNode = errors.New("owner has no staked node") // ErrUint32SubtractionOverflow signals uint32 subtraction overflowed diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 255eb177456..4294f6da432 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -16,7 +16,7 @@ import ( const maxPubKeyDisplayableLen = 20 const maxNumOfDecimalsToDisplay = 5 -func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, minFound *big.Int, step *big.Int) { +func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int, step *big.Int) { if log.GetLevel() > logger.LogDebug { return } @@ -25,7 +25,7 @@ func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, minFound topUp = big.NewInt(0).Sub(topUp, step) } - iteratedValues := big.NewInt(0).Sub(topUp, minFound) + iteratedValues := big.NewInt(0).Sub(topUp, startTopUp) iterations := big.NewInt(0).Div(iteratedValues, step).Int64() iterations++ @@ -145,17 +145,6 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string displayTable(tableHeader, lines, "Selected nodes config from auction list") } -func getBlsKeyOwnerMap(ownersData map[string]*ownerData) map[string]string { - ret := make(map[string]string) - for ownerPubKey, owner := range ownersData { - for _, blsKey := range owner.auctionList { - ret[string(blsKey.GetPublicKey())] = ownerPubKey - } - } - - return ret -} - func (als *auctionListSelector) displayAuctionList( auctionList []state.ValidatorInfoHandler, ownersData map[string]*ownerData, @@ -177,12 +166,12 @@ func (als *auctionListSelector) displayAuctionList( continue } - topUp := ownersData[owner].qualifiedTopUpPerNode + qualifiedTopUp := ownersData[owner].qualifiedTopUpPerNode horizontalLine := uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ hex.EncodeToString([]byte(owner)), hex.EncodeToString(pubKey), - getPrettyValue(topUp, als.softAuctionConfig.denominator), + getPrettyValue(qualifiedTopUp, als.softAuctionConfig.denominator), }) lines = append(lines, line) } @@ -190,6 +179,17 @@ func (als *auctionListSelector) displayAuctionList( displayTable(tableHeader, lines, "Final selected nodes from auction list") } +func getBlsKeyOwnerMap(ownersData map[string]*ownerData) map[string]string { + ret := make(map[string]string) + for ownerPubKey, owner := range ownersData { + for _, blsKey := range owner.auctionList { + ret[string(blsKey.GetPublicKey())] = ownerPubKey + } + } + + return ret +} + func displayTable(tableHeader []string, lines []*display.LineData, message string) { table, err := display.CreateTableString(tableHeader, lines) if err != nil { diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index f104ef0017b..d9f28cbf286 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -62,20 +62,6 @@ func sortListByPubKey(list []state.ValidatorInfoHandler) { }) } -func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { - xorLen := len(randomness) - - key1Xor := make([]byte, xorLen) - key2Xor := make([]byte, xorLen) - - for idx := 0; idx < xorLen; idx++ { - key1Xor[idx] = pubKey1[idx] ^ randomness[idx] - key2Xor[idx] = pubKey2[idx] ^ randomness[idx] - } - - return bytes.Compare(key1Xor, key2Xor) == 1 -} - func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { validatorPubKey := string(owner.auctionList[i].GetPublicKey()) @@ -102,3 +88,17 @@ func sortValidators( return nodeTopUpPubKey1.Cmp(nodeTopUpPubKey2) > 0 }) } + +func compareByXORWithRandomness(pubKey1, pubKey2, randomness []byte) bool { + xorLen := len(randomness) + + key1Xor := make([]byte, xorLen) + key2Xor := make([]byte, xorLen) + + for idx := 0; idx < xorLen; idx++ { + key1Xor[idx] = pubKey1[idx] ^ randomness[idx] + key2Xor[idx] = pubKey2[idx] ^ randomness[idx] + } + + return bytes.Compare(key1Xor, key2Xor) == 1 +} From a05cdd305e2bdf17795a5d73b122612a12ae39bc Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 26 May 2022 16:19:34 +0300 Subject: [PATCH 291/958] FIX: General fixes 3 --- epochStart/metachain/auctionListDisplayer.go | 6 +++--- epochStart/metachain/auctionListSelector.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 4294f6da432..5bc2585e668 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -16,17 +16,17 @@ import ( const maxPubKeyDisplayableLen = 20 const maxNumOfDecimalsToDisplay = 5 -func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int, step *big.Int) { +func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int) { if log.GetLevel() > logger.LogDebug { return } if topUp.Cmp(als.softAuctionConfig.minTopUp) > 0 { - topUp = big.NewInt(0).Sub(topUp, step) + topUp = big.NewInt(0).Sub(topUp, als.softAuctionConfig.step) } iteratedValues := big.NewInt(0).Sub(topUp, startTopUp) - iterations := big.NewInt(0).Div(iteratedValues, step).Int64() + iterations := big.NewInt(0).Div(iteratedValues, als.softAuctionConfig.step).Int64() iterations++ log.Debug("auctionListSelector: found min required", diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index db04191706b..f9bcfdbdde2 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -361,7 +361,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } } - als.displayMinRequiredTopUp(topUp, minTopUp, als.softAuctionConfig.step) + als.displayMinRequiredTopUp(topUp, minTopUp) return previousConfig } From 275bb87d531bff95399a493611bc3c8adc407d66 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 26 May 2022 17:15:40 +0300 Subject: [PATCH 292/958] FIX: Merge conflict --- integrationTests/testProcessorNode.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index ae058a64848..1f314173c16 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -5,6 +5,7 @@ import ( "context" "encoding/hex" "fmt" + "math" "math/big" "strconv" "sync" @@ -41,6 +42,7 @@ import ( "github.com/ElrondNetwork/elrond-go/dataRetriever/factory/resolverscontainer" "github.com/ElrondNetwork/elrond-go/dataRetriever/requestHandlers" "github.com/ElrondNetwork/elrond-go/dblookupext" + bootstrapDisabled "github.com/ElrondNetwork/elrond-go/epochStart/bootstrap/disabled" "github.com/ElrondNetwork/elrond-go/epochStart/metachain" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/epochStart/shardchain" @@ -60,6 +62,7 @@ import ( "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" "github.com/ElrondNetwork/elrond-go/process/block/postprocess" "github.com/ElrondNetwork/elrond-go/process/block/preprocess" + "github.com/ElrondNetwork/elrond-go/process/block/processedMb" "github.com/ElrondNetwork/elrond-go/process/coordinator" "github.com/ElrondNetwork/elrond-go/process/economics" "github.com/ElrondNetwork/elrond-go/process/factory" @@ -639,7 +642,7 @@ func NewTestProcessorNodeWithCustomDataPool(maxShards uint32, nodeShardId uint32 ArwenChangeLocker: &sync.RWMutex{}, TransactionLogProcessor: logsProcessor, PeersRatingHandler: peersRatingHandler, - PeerShardMapper: disabledBootstrap.NewPeerShardMapper(), + PeerShardMapper: bootstrapDisabled.NewPeerShardMapper(), } tpn.NodeKeys = &TestKeyPair{ From 3d8d6c3ea7fbcc36a059b7dd4f1e843ffd02f994 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 26 May 2022 17:41:45 +0300 Subject: [PATCH 293/958] FIX: Nil ProcessedMiniBlocksTracker --- integrationTests/vm/staking/metaBlockProcessorCreator.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 126d5a90c13..0c41a7f60b7 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -15,6 +15,7 @@ import ( blproc "github.com/ElrondNetwork/elrond-go/process/block" "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" "github.com/ElrondNetwork/elrond-go/process/block/postprocess" + "github.com/ElrondNetwork/elrond-go/process/block/processedMb" "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/process/scToProtocol" "github.com/ElrondNetwork/elrond-go/process/smartContract" @@ -91,6 +92,7 @@ func createMetaBlockProcessor( ScheduledMiniBlocksEnableEpoch: 10000, VMContainersFactory: metaVMFactory, VmContainer: vmContainer, + ProcessedMiniBlocksTracker: processedMb.NewProcessedMiniBlocksTracker(), }, SCToProtocol: stakingToPeer, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, From ca9994452ebd43e755a67340f5af810d3c8e9a34 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 26 May 2022 18:16:21 +0300 Subject: [PATCH 294/958] FIX: Nil NodesCoordinatorRegistryFactory --- integrationTests/testHeartbeatNode.go | 78 ++++++++++++++------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/integrationTests/testHeartbeatNode.go b/integrationTests/testHeartbeatNode.go index d22767e1911..0351863377a 100644 --- a/integrationTests/testHeartbeatNode.go +++ b/integrationTests/testHeartbeatNode.go @@ -278,25 +278,26 @@ func CreateNodesWithTestHeartbeatNode( cache, _ := storageUnit.NewCache(cacherCfg) for shardId, validatorList := range validatorsMap { argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: uint32(numShards), - EligibleNodes: validatorsForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: cache, - Shuffler: &shardingMocks.NodeShufflerMock{}, - BootStorer: CreateMemUnit(), - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - Epoch: 0, - EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: uint32(numShards), + EligibleNodes: validatorsForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: cache, + Shuffler: &shardingMocks.NodeShufflerMock{}, + BootStorer: CreateMemUnit(), + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + Epoch: 0, + EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) @@ -323,25 +324,26 @@ func CreateNodesWithTestHeartbeatNode( } argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: uint32(numShards), - EligibleNodes: validatorsForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: cache, - Shuffler: &shardingMocks.NodeShufflerMock{}, - BootStorer: CreateMemUnit(), - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - Epoch: 0, - EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - WaitingListFixEnabledEpoch: 0, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: uint32(numShards), + EligibleNodes: validatorsForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: cache, + Shuffler: &shardingMocks.NodeShufflerMock{}, + BootStorer: CreateMemUnit(), + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + Epoch: 0, + EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + WaitingListFixEnabledEpoch: 0, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) log.LogIfError(err) From eea67648cd91d1efd836a35c3dc792309481e6f7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 27 May 2022 14:04:31 +0300 Subject: [PATCH 295/958] FEAT: Initial setup up for unStake --- integrationTests/vm/staking/stakingV4_test.go | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 4203eed4b76..87201f26a23 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -536,3 +536,72 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { requireMapContains(t, currNodesConfig.waiting, owner3StakingQueue) requireSliceContains(t, currNodesConfig.auction, owner1StakingQueue) } + +func TestStakingV4_UnStakeNodes(t *testing.T) { + pubKeys := generateAddresses(0, 20) + + owner1 := "owner1" + owner1Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:2], + }, + WaitingBlsKeys: map[uint32][][]byte{ + 0: pubKeys[2:4], + }, + StakingQueueKeys: pubKeys[4:6], + TotalStake: big.NewInt(6 * nodePrice), + } + + owner2 := "owner2" + owner2Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + 0: pubKeys[6:8], + }, + WaitingBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[8:10], + }, + StakingQueueKeys: pubKeys[10:12], + TotalStake: big.NewInt(6 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 1, + ShardConsensusGroupSize: 1, + MinNumberOfEligibleShardNodes: 1, + MinNumberOfEligibleMetaNodes: 1, + NumOfShards: 1, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + owner2: owner2Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 8, + NodesToShufflePerShard: 1, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 2) + require.Len(t, currNodesConfig.waiting[0], 2) + + owner1StakingQueue := owner1Stats.StakingQueueKeys + owner2StakingQueue := owner2Stats.StakingQueueKeys + queue := make([][]byte, 0) + queue = append(queue, owner1StakingQueue...) + queue = append(queue, owner2StakingQueue...) + require.Len(t, currNodesConfig.queue, 4) + requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) +} From d1412fee3d6cea3e68b3155ba6c20569dc09ef2b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 27 May 2022 14:46:09 +0300 Subject: [PATCH 296/958] FEAT: Add owner3 --- integrationTests/vm/staking/stakingV4_test.go | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 87201f26a23..cb24145a46a 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -549,7 +549,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { 0: pubKeys[2:4], }, StakingQueueKeys: pubKeys[4:6], - TotalStake: big.NewInt(6 * nodePrice), + TotalStake: big.NewInt(10 * nodePrice), } owner2 := "owner2" @@ -558,9 +558,15 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { 0: pubKeys[6:8], }, WaitingBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[8:10], + core.MetachainShardId: pubKeys[8:12], }, - StakingQueueKeys: pubKeys[10:12], + StakingQueueKeys: pubKeys[12:15], + TotalStake: big.NewInt(10 * nodePrice), + } + + owner3 := "owner3" + owner3Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[15:17], TotalStake: big.NewInt(6 * nodePrice), } @@ -573,6 +579,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { Owners: map[string]*OwnerStats{ owner1: owner1Stats, owner2: owner2Stats, + owner3: owner3Stats, }, MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { @@ -588,18 +595,20 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { // 1. Check initial config is correct currNodesConfig := node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 4) require.Len(t, currNodesConfig.eligible[0], 2) require.Len(t, currNodesConfig.waiting[0], 2) owner1StakingQueue := owner1Stats.StakingQueueKeys owner2StakingQueue := owner2Stats.StakingQueueKeys + owner3StakingQueue := owner3Stats.StakingQueueKeys queue := make([][]byte, 0) queue = append(queue, owner1StakingQueue...) queue = append(queue, owner2StakingQueue...) - require.Len(t, currNodesConfig.queue, 4) + queue = append(queue, owner3StakingQueue...) + require.Len(t, currNodesConfig.queue, 7) requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) require.Empty(t, currNodesConfig.shuffledOut) From be6065851343dbad414ebffcfa1adb770aa5b8ba Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 27 May 2022 16:16:05 +0300 Subject: [PATCH 297/958] FEAT: Add stakingcommon.SaveNodesConfig --- .../vm/staking/baseTestMetaProcessor.go | 34 +++++++++++++++++++ .../vm/txsFee/validatorSC_test.go | 31 ++++------------- testscommon/stakingcommon/stakingCommon.go | 28 +++++++++++++++ 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 7c56eabaedc..3d20d55ecf1 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -26,6 +26,7 @@ import ( "github.com/ElrondNetwork/elrond-go/process/mock" "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" @@ -80,6 +81,14 @@ func newTestMetaProcessor( maxNodesConfig []config.MaxNodesChangeConfig, queue [][]byte, ) *TestMetaProcessor { + saveNodesConfig( + stateComponents.AccountsAdapter(), + coreComponents.InternalMarshalizer(), + nc, + maxNodesConfig, + len(queue), + ) + gasScheduleNotifier := createGasScheduleNotifier() blockChainHook := createBlockChainHook( dataComponents, @@ -345,3 +354,28 @@ func generateAddress(identifier uint32) []byte { uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) } + +func saveNodesConfig( + accountsDB state.AccountsAdapter, + marshaller marshal.Marshalizer, + nc nodesCoordinator.NodesCoordinator, + maxNodesConfig []config.MaxNodesChangeConfig, + queueSize int, +) { + eligibleMap, _ := nc.GetAllEligibleValidatorsPublicKeys(0) + waitingMap, _ := nc.GetAllWaitingValidatorsPublicKeys(0) + allStakedNodes := int64(len(getAllPubKeys(eligibleMap)) + len(getAllPubKeys(waitingMap)) + queueSize) + + maxNumNodes := allStakedNodes + if len(maxNodesConfig) > 0 { + maxNumNodes = int64(maxNodesConfig[0].MaxNumNodes) + } + + stakingcommon.SaveNodesConfig( + accountsDB, + marshaller, + allStakedNodes, + 1, + maxNumNodes, + ) +} diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index 0c355d6babf..a2afb651d2c 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -10,12 +10,12 @@ import ( "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" "github.com/ElrondNetwork/elrond-go-core/data/transaction" - "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/integrationTests/vm" "github.com/ElrondNetwork/elrond-go/integrationTests/vm/txsFee/utils" "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" vmAddr "github.com/ElrondNetwork/elrond-go/vm" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -55,7 +55,7 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondShouldRefund(t *testing.T require.Nil(t, err) defer testContextMeta.Close() - saveNodesConfig(t, testContextMeta, 1, 1, 1) + stakingcommon.SaveNodesConfig(testContextMeta.Accounts, testContextMeta.Marshalizer, 1, 1, 1) testContextMeta.BlockchainHook.(*hooks.BlockChainHookImpl).SetCurrentHeader(&block.MetaBlock{Epoch: 1}) saveDelegationManagerConfig(testContextMeta) @@ -118,7 +118,7 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes require.Nil(t, err) defer testContextMeta.Close() - saveNodesConfig(t, testContextMeta, 1, 1, 1) + stakingcommon.SaveNodesConfig(testContextMeta.Accounts, testContextMeta.Marshalizer, 1, 1, 1) saveDelegationManagerConfig(testContextMeta) testContextMeta.BlockchainHook.(*hooks.BlockChainHookImpl).SetCurrentHeader(&block.MetaBlock{Epoch: 1}) @@ -165,7 +165,7 @@ func testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *t require.Nil(t, err) defer testContextMeta.Close() - saveNodesConfig(t, testContextMeta, 1, 1, 1) + stakingcommon.SaveNodesConfig(testContextMeta.Accounts, testContextMeta.Marshalizer, 1, 1, 1) saveDelegationManagerConfig(testContextMeta) testContextMeta.BlockchainHook.(*hooks.BlockChainHookImpl).SetCurrentHeader(&block.MetaBlock{Epoch: 0}) @@ -199,7 +199,7 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens( require.Nil(t, err) defer testContextMeta.Close() - saveNodesConfig(t, testContextMeta, 1, 1, 1) + stakingcommon.SaveNodesConfig(testContextMeta.Accounts, testContextMeta.Marshalizer, 1, 1, 1) saveDelegationManagerConfig(testContextMeta) testContextMeta.BlockchainHook.(*hooks.BlockChainHookImpl).SetCurrentHeader(&block.MetaBlock{Epoch: 1}) @@ -252,7 +252,7 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeNodesAndUnBondNodesShouldRefund(t require.Nil(t, err) defer testContextMeta.Close() - saveNodesConfig(t, testContextMeta, 1, 1, 1) + stakingcommon.SaveNodesConfig(testContextMeta.Accounts, testContextMeta.Marshalizer, 1, 1, 1) saveDelegationManagerConfig(testContextMeta) testContextMeta.BlockchainHook.(*hooks.BlockChainHookImpl).SetCurrentHeader(&block.MetaBlock{Epoch: 1}) @@ -306,22 +306,3 @@ func executeTxAndCheckResults( require.Equal(t, vmCodeExpected, recCode) require.Equal(t, expectedErr, err) } - -func saveNodesConfig(t *testing.T, testContext *vm.VMTestContext, stakedNodes, minNumNodes, maxNumNodes int64) { - protoMarshalizer := &marshal.GogoProtoMarshalizer{} - - account, err := testContext.Accounts.LoadAccount(vmAddr.StakingSCAddress) - require.Nil(t, err) - userAccount, _ := account.(state.UserAccountHandler) - - nodesConfigData := &systemSmartContracts.StakingNodesConfig{ - StakedNodes: stakedNodes, - MinNumNodes: minNumNodes, - MaxNumNodes: maxNumNodes, - } - nodesDataBytes, _ := protoMarshalizer.Marshal(nodesConfigData) - - _ = userAccount.DataTrieTracker().SaveKeyValue([]byte("nodesConfig"), nodesDataBytes) - _ = testContext.Accounts.SaveAccount(account) - _, _ = testContext.Accounts.Commit() -} diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 1ffe56e9683..9ad9967952a 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -278,3 +278,31 @@ func CreateEconomicsData() process.EconomicsDataHandler { economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData } + +// SaveNodesConfig saves the nodes config in accounts db under "nodesConfig" key with provided params +func SaveNodesConfig( + accountsDB state.AccountsAdapter, + marshaller marshal.Marshalizer, + stakedNodes, + minNumNodes, + maxNumNodes int64, +) { + nodesConfigData := &systemSmartContracts.StakingNodesConfig{ + StakedNodes: stakedNodes, + MinNumNodes: minNumNodes, + MaxNumNodes: maxNumNodes, + } + nodesDataBytes, err := marshaller.Marshal(nodesConfigData) + log.LogIfError(err) + + account, err := accountsDB.LoadAccount(vm.StakingSCAddress) + log.LogIfError(err) + + userAccount, _ := account.(state.UserAccountHandler) + err = userAccount.DataTrieTracker().SaveKeyValue([]byte("nodesConfig"), nodesDataBytes) + log.LogIfError(err) + err = accountsDB.SaveAccount(account) + log.LogIfError(err) + _, err = accountsDB.Commit() + log.LogIfError(err) +} From 86f7a751524e15d533b996a0248096b009d01a74 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 27 May 2022 16:38:22 +0300 Subject: [PATCH 298/958] FEAT: Add test for staked node before staking v4 --- .../vm/staking/baseTestMetaProcessor.go | 4 +-- integrationTests/vm/staking/stakingV4_test.go | 26 +++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 3d20d55ecf1..332f64909c7 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -86,7 +86,6 @@ func newTestMetaProcessor( coreComponents.InternalMarshalizer(), nc, maxNodesConfig, - len(queue), ) gasScheduleNotifier := createGasScheduleNotifier() @@ -360,11 +359,10 @@ func saveNodesConfig( marshaller marshal.Marshalizer, nc nodesCoordinator.NodesCoordinator, maxNodesConfig []config.MaxNodesChangeConfig, - queueSize int, ) { eligibleMap, _ := nc.GetAllEligibleValidatorsPublicKeys(0) waitingMap, _ := nc.GetAllWaitingValidatorsPublicKeys(0) - allStakedNodes := int64(len(getAllPubKeys(eligibleMap)) + len(getAllPubKeys(waitingMap)) + queueSize) + allStakedNodes := int64(len(getAllPubKeys(eligibleMap)) + len(getAllPubKeys(waitingMap))) maxNumNodes := allStakedNodes if len(maxNodesConfig) > 0 { diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 4203eed4b76..0333e404e2b 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -471,7 +471,7 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { node := NewTestMetaProcessorWithCustomNodes(cfg) node.EpochStartTrigger.SetRoundsPerEpoch(4) - // 1. Check initial config is correct + // 1.1 Check initial config is correct currNodesConfig := node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) @@ -491,6 +491,21 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) + // NewOwner0 stakes 1 node with top up = 0 before staking v4; should be sent to staking queue + newOwner0 := "newOwner0" + newNodes0 := map[string]*NodesRegisterData{ + newOwner0: { + BLSKeys: [][]byte{generateAddress(333)}, + TotalStake: big.NewInt(nodePrice), + }, + } + + // 1.2 Check staked node before staking v4 is sent to staking queue + node.ProcessStake(t, newNodes0) + queue = append(queue, newNodes0[newOwner0].BLSKeys...) + currNodesConfig = node.NodesConfig + require.Len(t, currNodesConfig.queue, 4) + // NewOwner1 stakes 1 node with top up = 2*node price; should be sent to auction list newOwner1 := "newOwner1" newNodes1 := map[string]*NodesRegisterData{ @@ -500,13 +515,13 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { }, } // 2. Check config after staking v4 init when a new node is staked - node.Process(t, 5) + node.Process(t, 4) node.ProcessStake(t, newNodes1) currNodesConfig = node.NodesConfig queue = append(queue, newNodes1[newOwner1].BLSKeys...) require.Empty(t, currNodesConfig.queue) require.Empty(t, currNodesConfig.leaving) - require.Len(t, currNodesConfig.auction, 4) + require.Len(t, currNodesConfig.auction, 5) requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) // NewOwner2 stakes 2 node with top up = 2*node price; should be sent to auction list @@ -523,11 +538,11 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { currNodesConfig = node.NodesConfig queue = append(queue, newNodes2[newOwner2].BLSKeys...) require.Empty(t, currNodesConfig.queue) - requireSliceContainsNumOfElements(t, currNodesConfig.auction, queue, 6) + requireSliceContainsNumOfElements(t, currNodesConfig.auction, queue, 7) // 3. Epoch = staking v4 distribute auction to waiting // Only the new 2 owners + owner3 had enough top up to be distributed to waiting. - // Meanwhile; owner1 which had 0 top up, still has his bls keys in auction + // Meanwhile; owner1 which had 0 top up, still has his bls keys in auction, along with newOwner0 node.Process(t, 5) currNodesConfig = node.NodesConfig require.Empty(t, currNodesConfig.queue) @@ -535,4 +550,5 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { requireMapContains(t, currNodesConfig.waiting, newNodes2[newOwner2].BLSKeys) requireMapContains(t, currNodesConfig.waiting, owner3StakingQueue) requireSliceContains(t, currNodesConfig.auction, owner1StakingQueue) + requireSliceContains(t, currNodesConfig.auction, newNodes0[newOwner0].BLSKeys) } From a84c157a0e20d106494b7f4f9ac4077ec26db261 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 27 May 2022 16:42:21 +0300 Subject: [PATCH 299/958] FIX: Remove todo --- .../vm/staking/testMetaProcessorWithCustomNodesConfig.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 210e8b17a06..29e7866ed7d 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -137,8 +137,7 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes } //TODO: -// 1. Do the same for unStake/unJail -// 2. Use this func to stake initial nodes instead of hard coding them +// - Do the same for unStake/unJail func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, From 28e1f0b966c030d3e29a81866ad953828b97e42c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 30 May 2022 10:57:45 +0300 Subject: [PATCH 300/958] FEAT: UnStake + CreateDelegationManagementConfig --- .../vm/staking/baseTestMetaProcessor.go | 67 ++++++++++++------- integrationTests/vm/staking/stakingQueue.go | 14 ++-- integrationTests/vm/staking/stakingV4_test.go | 13 +++- .../testMetaProcessorWithCustomNodesConfig.go | 66 ++++++++++++++++++ 4 files changed, 128 insertions(+), 32 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 332f64909c7..6a1b641066d 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -27,6 +27,8 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/ElrondNetwork/elrond-go/vm" + "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" @@ -88,6 +90,11 @@ func newTestMetaProcessor( maxNodesConfig, ) + createDelegationManagementConfig( + stateComponents.AccountsAdapter(), + coreComponents.InternalMarshalizer(), + ) + gasScheduleNotifier := createGasScheduleNotifier() blockChainHook := createBlockChainHook( dataComponents, @@ -176,6 +183,42 @@ func newTestMetaProcessor( } } +func saveNodesConfig( + accountsDB state.AccountsAdapter, + marshaller marshal.Marshalizer, + nc nodesCoordinator.NodesCoordinator, + maxNodesConfig []config.MaxNodesChangeConfig, +) { + eligibleMap, _ := nc.GetAllEligibleValidatorsPublicKeys(0) + waitingMap, _ := nc.GetAllWaitingValidatorsPublicKeys(0) + allStakedNodes := int64(len(getAllPubKeys(eligibleMap)) + len(getAllPubKeys(waitingMap))) + + maxNumNodes := allStakedNodes + if len(maxNodesConfig) > 0 { + maxNumNodes = int64(maxNodesConfig[0].MaxNumNodes) + } + + stakingcommon.SaveNodesConfig( + accountsDB, + marshaller, + allStakedNodes, + 1, + maxNumNodes, + ) +} + +func createDelegationManagementConfig(accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer) { + delegationCfg := &systemSmartContracts.DelegationManagement{ + MinDelegationAmount: big.NewInt(10), + } + marshalledData, _ := marshaller.Marshal(delegationCfg) + + delegationAcc := stakingcommon.LoadUserAccount(accountsDB, vm.DelegationManagerSCAddress) + _ = delegationAcc.DataTrieTracker().SaveKeyValue([]byte("delegationManagement"), marshalledData) + _ = accountsDB.SaveAccount(delegationAcc) + _, _ = accountsDB.Commit() +} + func createGasScheduleNotifier() core.GasScheduleNotifier { gasSchedule := arwenConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) @@ -353,27 +396,3 @@ func generateAddress(identifier uint32) []byte { uniqueIdentifier := fmt.Sprintf("address-%d", identifier) return []byte(strings.Repeat("0", addressLength-len(uniqueIdentifier)) + uniqueIdentifier) } - -func saveNodesConfig( - accountsDB state.AccountsAdapter, - marshaller marshal.Marshalizer, - nc nodesCoordinator.NodesCoordinator, - maxNodesConfig []config.MaxNodesChangeConfig, -) { - eligibleMap, _ := nc.GetAllEligibleValidatorsPublicKeys(0) - waitingMap, _ := nc.GetAllWaitingValidatorsPublicKeys(0) - allStakedNodes := int64(len(getAllPubKeys(eligibleMap)) + len(getAllPubKeys(waitingMap))) - - maxNumNodes := allStakedNodes - if len(maxNodesConfig) > 0 { - maxNumNodes = int64(maxNodesConfig[0].MaxNumNodes) - } - - stakingcommon.SaveNodesConfig( - accountsDB, - marshaller, - allStakedNodes, - 1, - maxNumNodes, - ) -} diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index a26bafe6fa5..5247ff02d76 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -55,21 +55,21 @@ func createStakingQueueCustomNodes( queue := make([][]byte, 0) for owner, ownerStats := range owners { - stakingcommon.AddKeysToWaitingList( + stakingcommon.RegisterValidatorKeys( accountsAdapter, - ownerStats.StakingQueueKeys, - marshaller, []byte(owner), []byte(owner), + ownerStats.StakingQueueKeys, + ownerStats.TotalStake, + marshaller, ) - stakingcommon.RegisterValidatorKeys( + stakingcommon.AddKeysToWaitingList( accountsAdapter, - []byte(owner), - []byte(owner), ownerStats.StakingQueueKeys, - ownerStats.TotalStake, marshaller, + []byte(owner), + []byte(owner), ) queue = append(queue, ownerStats.StakingQueueKeys...) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index b238d0dc0a5..68c1a68ac56 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -600,7 +600,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { EpochEnable: 0, - MaxNumNodes: 8, + MaxNumNodes: 10, NodesToShufflePerShard: 1, }, }, @@ -629,4 +629,15 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) + //logger.SetLogLevel("*:DEBUG") + + node.ProcessUnStake(t, map[string]*NodesRegisterData{ + owner2: { + BLSKeys: [][]byte{owner2Stats.StakingQueueKeys[0]}, + }, + }) + currNodesConfig = node.NodesConfig + require.Len(t, currNodesConfig.queue, 6) + queue = remove(queue, owner2Stats.StakingQueueKeys[0]) + //requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 29e7866ed7d..7bd9a48d172 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -136,6 +136,57 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes tmp.currentRound += 1 } +// ProcessUnStake will create a block containing mini blocks with unStaking txs using provided nodes. +// Block will be committed + call to validator system sc will be made to unStake all nodes +func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*NodesRegisterData) { + header := tmp.createNewHeader(t, tmp.currentRound) + tmp.BlockChainHook.SetCurrentHeader(header) + + txHashes := make([][]byte, 0) + for owner, nodesData := range nodes { + numBLSKeys := int64(len(nodesData.BLSKeys)) + numBLSKeysBytes := big.NewInt(numBLSKeys).Bytes() + + txData := hex.EncodeToString([]byte("unStake")) + "@" + hex.EncodeToString(numBLSKeysBytes) + argsUnStake := make([][]byte, 0) + + for _, blsKey := range nodesData.BLSKeys { + argsUnStake = append(argsUnStake, blsKey) + txData += "@" + hex.EncodeToString(blsKey) + "@" + } + + txHash := append([]byte("txHash-unStake-"), []byte(owner)...) + txHashes = append(txHashes, txHash) + + tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(txData), + }) + + tmp.doUnStake(t, vmcommon.VMInput{ + CallerAddr: []byte(owner), + Arguments: argsUnStake, + CallValue: big.NewInt(0), + GasProvided: 10, + }) + } + _, err := tmp.AccountsAdapter.Commit() + require.Nil(t, err) + + miniBlocks := block.MiniBlockSlice{ + { + TxHashes: txHashes, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + } + tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) + tmp.createAndCommitBlock(t, header, noTime) + + tmp.currentRound += 1 +} + //TODO: // - Do the same for unStake/unJail func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { @@ -146,6 +197,21 @@ func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { } vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) require.Nil(t, err) + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + + err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) + require.Nil(t, err) +} + +func (tmp *TestMetaProcessor) doUnStake(t *testing.T, vmInput vmcommon.VMInput) { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmInput, + RecipientAddr: vm.ValidatorSCAddress, + Function: "unStake", + } + vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) + require.Nil(t, err) + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) From fbe1e79b3cc17cbd33b8aaa89c6817f2a90c4cc1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 30 May 2022 11:06:16 +0300 Subject: [PATCH 301/958] FIX: Quickfix waiting list pub keys --- integrationTests/vm/staking/stakingQueue.go | 2 +- integrationTests/vm/staking/stakingV4_test.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 5247ff02d76..759feff3309 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -103,7 +103,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { allPubKeys := make([][]byte, 0) for len(nextKey) != 0 && index <= waitingList.Length { - allPubKeys = append(allPubKeys, nextKey) + allPubKeys = append(allPubKeys, nextKey[2:]) // remove "w_" prefix element, errGet := stakingcommon.GetWaitingListElement(stakingSCAcc, tmp.Marshaller, nextKey) if errGet != nil { diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 68c1a68ac56..6573faea3f5 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -505,6 +505,7 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { queue = append(queue, newNodes0[newOwner0].BLSKeys...) currNodesConfig = node.NodesConfig require.Len(t, currNodesConfig.queue, 4) + requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) // NewOwner1 stakes 1 node with top up = 2*node price; should be sent to auction list newOwner1 := "newOwner1" @@ -639,5 +640,5 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { currNodesConfig = node.NodesConfig require.Len(t, currNodesConfig.queue, 6) queue = remove(queue, owner2Stats.StakingQueueKeys[0]) - //requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) } From 8850dc110be20734dae4d96dfdcc855191cb741f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 30 May 2022 12:33:12 +0300 Subject: [PATCH 302/958] FIX: Broken test --- integrationTests/testProcessorNode.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 1f314173c16..2a27f2e05c7 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -465,6 +465,7 @@ func newBaseTestProcessorNode( MiniBlockPartialExecutionEnableEpoch: 1000000, StakingV4InitEnableEpoch: StakingV4InitEpoch, StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, } return tpn From a546dcf67301b7198fe1faf00fe0f9dbc75f19ff Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 30 May 2022 14:36:56 +0300 Subject: [PATCH 303/958] FEAT: Add temp working version to unStake active nodes --- .../vm/staking/baseTestMetaProcessor.go | 6 ++ .../vm/staking/configDisplayer.go | 1 + integrationTests/vm/staking/stakingV4_test.go | 19 ++++++ .../testMetaProcessorWithCustomNodesConfig.go | 62 ++++++++++++++++++- 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 6a1b641066d..5bffac8c407 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -52,6 +52,7 @@ type nodesConfig struct { shuffledOut map[uint32][][]byte queue [][]byte auction [][]byte + new [][]byte } // TestMetaProcessor - @@ -368,10 +369,14 @@ func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { validatorsInfoMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) auction := make([][]byte, 0) + newList := make([][]byte, 0) for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { if validator.GetList() == string(common.AuctionList) { auction = append(auction, validator.GetPublicKey()) } + if validator.GetList() == string(common.NewList) { + newList = append(newList, validator.GetPublicKey()) + } } tmp.NodesConfig.eligible = eligible @@ -379,6 +384,7 @@ func (tmp *TestMetaProcessor) updateNodesConfig(epoch uint32) { tmp.NodesConfig.shuffledOut = shuffledOut tmp.NodesConfig.leaving = leaving tmp.NodesConfig.auction = auction + tmp.NodesConfig.new = newList tmp.NodesConfig.queue = tmp.getWaitingListKeys() } diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index 816ee2e90f3..e0750b62f8b 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -66,6 +66,7 @@ func (tmp *TestMetaProcessor) displayConfig(config nodesConfig) { headline := display.Headline("Nodes config", "", delimiter) fmt.Printf("%s\n%s\n", headline, table) + tmp.displayValidators("New", config.new) tmp.displayValidators("Auction", config.auction) tmp.displayValidators("Queue", config.queue) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 6573faea3f5..bb21605c040 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -632,6 +632,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Empty(t, currNodesConfig.auction) //logger.SetLogLevel("*:DEBUG") + // Check unStaked node is removed from waiting list node.ProcessUnStake(t, map[string]*NodesRegisterData{ owner2: { BLSKeys: [][]byte{owner2Stats.StakingQueueKeys[0]}, @@ -641,4 +642,22 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Len(t, currNodesConfig.queue, 6) queue = remove(queue, owner2Stats.StakingQueueKeys[0]) requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + + node.ProcessUnStake(t, map[string]*NodesRegisterData{ + owner2: { + BLSKeys: [][]byte{owner2Stats.WaitingBlsKeys[core.MetachainShardId][0]}, + }, + }) + currNodesConfig = node.NodesConfig + require.Len(t, currNodesConfig.new, 1) + require.Equal(t, currNodesConfig.new[0], owner1Stats.StakingQueueKeys[0]) + + node.Process(t, 6) + /* + node.Process(t, 4) + currNodesConfig = node.NodesConfig + require.Empty(t, currNodesConfig.queue) + requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) + + */ } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 7bd9a48d172..ce14d208cf1 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -1,8 +1,10 @@ package staking import ( + "bytes" "encoding/hex" "math/big" + "strconv" "testing" "github.com/ElrondNetwork/elrond-go-core/core" @@ -11,6 +13,10 @@ import ( "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/integrationTests" + "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/process/smartContract" + "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" @@ -163,12 +169,23 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*Nod Data: []byte(txData), }) - tmp.doUnStake(t, vmcommon.VMInput{ + txsData := tmp.doUnStake(t, vmcommon.VMInput{ CallerAddr: []byte(owner), Arguments: argsUnStake, CallValue: big.NewInt(0), GasProvided: 10, }) + + for i, tData := range txsData { + txHash = []byte("rrrr" + strconv.Itoa(i)) + txHashes = append(txHashes, txHash) + + tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(tData), + }) + + } } _, err := tmp.AccountsAdapter.Commit() require.Nil(t, err) @@ -203,7 +220,7 @@ func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { require.Nil(t, err) } -func (tmp *TestMetaProcessor) doUnStake(t *testing.T, vmInput vmcommon.VMInput) { +func (tmp *TestMetaProcessor) doUnStake(t *testing.T, vmInput vmcommon.VMInput) []string { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, RecipientAddr: vm.ValidatorSCAddress, @@ -213,6 +230,45 @@ func (tmp *TestMetaProcessor) doUnStake(t *testing.T, vmInput vmcommon.VMInput) require.Nil(t, err) require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) - err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) + txsData, err := ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) + return txsData +} + +func ProcessSCOutputAccounts(vmOutput *vmcommon.VMOutput, accountsDB state.AccountsAdapter) ([]string, error) { + outputAccounts := process.SortVMOutputInsideData(vmOutput) + data := make([]string, 0) + for _, outAcc := range outputAccounts { + acc := stakingcommon.LoadUserAccount(accountsDB, outAcc.Address) + + storageUpdates := process.GetSortedStorageUpdates(outAcc) + for _, storeUpdate := range storageUpdates { + err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) + if err != nil { + return nil, err + } + + if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(big.NewInt(0)) != 0 { + err = acc.AddToBalance(outAcc.BalanceDelta) + if err != nil { + return nil, err + } + } + + err = accountsDB.SaveAccount(acc) + if err != nil { + return nil, err + } + + if bytes.Equal(outAcc.Address, vm.StakingSCAddress) { + parser := smartContract.NewArgumentParser() + data2 := parser.CreateDataFromStorageUpdate(storageUpdates) + data = append(data, data2) + + } + + } + } + + return data, nil } From db12f189672994fc768f86f719b0fe405c78270e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 30 May 2022 15:01:15 +0300 Subject: [PATCH 304/958] FIX: Broken unit test --- integrationTests/testProcessorNode.go | 30 +++++++++++-------- .../vm/delegation/liquidStaking_test.go | 12 ++++---- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 2a27f2e05c7..4fbcc6a0bf4 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -444,9 +444,12 @@ func newBaseTestProcessorNode( PeersRatingHandler: peersRatingHandler, PeerShardMapper: mock.NewNetworkShardingCollectorMock(), EnableEpochs: config.EnableEpochs{ - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4EnableEpoch: StakingV4Epoch, - StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + OptimizeGasUsedInCrossMiniBlocksEnableEpoch: 10, + ScheduledMiniBlocksEnableEpoch: 1000000, + MiniBlockPartialExecutionEnableEpoch: 1000000, + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, }, } @@ -964,11 +967,13 @@ func (tpn *TestProcessorNode) createFullSCQueryService() { EpochNotifier: tpn.EpochNotifier, EpochConfig: &config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 0, - StakingV4EnableEpoch: 444, - StakeEnableEpoch: 0, - DelegationSmartContractEnableEpoch: 0, - DelegationManagerEnableEpoch: 0, + StakingV2EnableEpoch: 0, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + StakeEnableEpoch: 0, + DelegationSmartContractEnableEpoch: 0, + DelegationManagerEnableEpoch: 0, }, }, ShardCoordinator: tpn.ShardCoordinator, @@ -2302,10 +2307,11 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: StakingV2Epoch, - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4EnableEpoch: StakingV4Epoch, - ESDTEnableEpoch: 0, + StakingV2EnableEpoch: StakingV2Epoch, + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + ESDTEnableEpoch: 0, }, }, } diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index a343a1b9927..1199b4301e3 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -44,18 +44,18 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { } nrRoundsToPropagateMultiShard := 12 - time.Sleep(time.Second) + time.Sleep(2 * time.Second) nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(time.Second) + time.Sleep(2 * time.Second) // claim again for _, node := range nodes { integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txData, core.MinMetaTxExtraGasCost) } - time.Sleep(time.Second) + time.Sleep(2 * time.Second) nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(time.Second) + time.Sleep(2 * time.Second) for i := 1; i < len(nodes); i++ { checkLPPosition(t, nodes[i].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(10000)) @@ -87,10 +87,10 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { for _, node := range nodes { integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), node.OwnAccount.Address, txBuilder.ToString(), core.MinMetaTxExtraGasCost) } - time.Sleep(time.Second) + time.Sleep(2 * time.Second) finalWait := 20 _, _ = integrationTests.WaitOperationToBeDone(t, nodes, finalWait, nonce, round, idxProposers) - time.Sleep(time.Second) + time.Sleep(2 * time.Second) for _, node := range nodes { checkLPPosition(t, node.OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) From 80286239cf9f7682198913277a5500466775b52b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 30 May 2022 15:03:56 +0300 Subject: [PATCH 305/958] FIX: Revert change --- integrationTests/testProcessorNode.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 4fbcc6a0bf4..a2f96bfd846 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -444,12 +444,9 @@ func newBaseTestProcessorNode( PeersRatingHandler: peersRatingHandler, PeerShardMapper: mock.NewNetworkShardingCollectorMock(), EnableEpochs: config.EnableEpochs{ - OptimizeGasUsedInCrossMiniBlocksEnableEpoch: 10, - ScheduledMiniBlocksEnableEpoch: 1000000, - MiniBlockPartialExecutionEnableEpoch: 1000000, - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4EnableEpoch: StakingV4Epoch, - StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, + StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, }, } From 0834218e41eccbb4e672aa581745c4936ca858d4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 12:12:03 +0300 Subject: [PATCH 306/958] FEAT: Add complex test for unStake --- integrationTests/vm/staking/stakingV4_test.go | 103 +++++++++++++++--- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index bb21605c040..96efed3990c 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -590,8 +590,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { cfg := &InitialNodesConfig{ MetaConsensusGroupSize: 1, ShardConsensusGroupSize: 1, - MinNumberOfEligibleShardNodes: 1, - MinNumberOfEligibleMetaNodes: 1, + MinNumberOfEligibleShardNodes: 2, + MinNumberOfEligibleMetaNodes: 2, NumOfShards: 1, Owners: map[string]*OwnerStats{ owner1: owner1Stats, @@ -617,6 +617,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 4) require.Len(t, currNodesConfig.eligible[0], 2) require.Len(t, currNodesConfig.waiting[0], 2) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) owner1StakingQueue := owner1Stats.StakingQueueKeys owner2StakingQueue := owner2Stats.StakingQueueKeys @@ -628,21 +630,21 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Len(t, currNodesConfig.queue, 7) requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) - require.Empty(t, currNodesConfig.shuffledOut) - require.Empty(t, currNodesConfig.auction) - //logger.SetLogLevel("*:DEBUG") - - // Check unStaked node is removed from waiting list + // 1.1 Owner2 unStakes one of his staking queue nodes. Node should be removed from staking queue list node.ProcessUnStake(t, map[string]*NodesRegisterData{ owner2: { BLSKeys: [][]byte{owner2Stats.StakingQueueKeys[0]}, }, }) currNodesConfig = node.NodesConfig - require.Len(t, currNodesConfig.queue, 6) queue = remove(queue, owner2Stats.StakingQueueKeys[0]) + require.Len(t, currNodesConfig.queue, 6) requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + require.Empty(t, currNodesConfig.new) + require.Empty(t, currNodesConfig.auction) + // 1.2 Owner2 unStakes one of his waiting list keys. First node from staking queue should be added to fill its place. + copy(queue, currNodesConfig.queue) // copy queue to local variable so we have the queue in same order node.ProcessUnStake(t, map[string]*NodesRegisterData{ owner2: { BLSKeys: [][]byte{owner2Stats.WaitingBlsKeys[core.MetachainShardId][0]}, @@ -650,14 +652,83 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { }) currNodesConfig = node.NodesConfig require.Len(t, currNodesConfig.new, 1) - require.Equal(t, currNodesConfig.new[0], owner1Stats.StakingQueueKeys[0]) + require.Equal(t, currNodesConfig.new[0], queue[0]) + require.Empty(t, currNodesConfig.auction) + queue = remove(queue, queue[0]) + require.Len(t, currNodesConfig.queue, 5) + requireSameSliceDifferentOrder(t, queue, currNodesConfig.queue) - node.Process(t, 6) - /* - node.Process(t, 4) - currNodesConfig = node.NodesConfig - require.Empty(t, currNodesConfig.queue) - requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) + // 2. Check config after staking v4 init + node.Process(t, 3) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) + // owner2's waiting list which was unStaked in previous epoch is now leaving + require.Len(t, currNodesConfig.leaving, 1) + require.Equal(t, owner2Stats.WaitingBlsKeys[core.MetachainShardId][0], currNodesConfig.leaving[core.MetachainShardId][0]) + require.Len(t, currNodesConfig.auction, 5) + requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) - */ + // 2.1 Owner3 unStakes one of his nodes from auction + node.ProcessUnStake(t, map[string]*NodesRegisterData{ + owner3: { + BLSKeys: [][]byte{owner3StakingQueue[1]}, + }, + }) + unStakedNodesInStakingV4InitEpoch := make([][]byte, 0) + unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner3StakingQueue[1]) + currNodesConfig = node.NodesConfig + queue = remove(queue, owner3StakingQueue[1]) + require.Len(t, currNodesConfig.auction, 4) + requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) + require.Empty(t, currNodesConfig.queue) + require.Empty(t, currNodesConfig.new) + + // 2.2 Owner1 unStakes 2 nodes: one from auction + one active + node.ProcessUnStake(t, map[string]*NodesRegisterData{ + owner1: { + BLSKeys: [][]byte{owner1StakingQueue[1], owner1Stats.WaitingBlsKeys[0][0]}, + }, + }) + unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner1StakingQueue[1]) + unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner1Stats.WaitingBlsKeys[0][0]) + currNodesConfig = node.NodesConfig + queue = remove(queue, owner1StakingQueue[1]) + require.Len(t, currNodesConfig.auction, 3) + requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) + require.Empty(t, currNodesConfig.queue) + require.Empty(t, currNodesConfig.new) + + // 3. Check config in epoch = staking v4 epoch + node.Process(t, 3) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, getAllPubKeys(currNodesConfig.leaving), 3) + requireMapContains(t, currNodesConfig.leaving, unStakedNodesInStakingV4InitEpoch) + // 3.1 Owner2 unStakes one of his nodes from auction + node.ProcessUnStake(t, map[string]*NodesRegisterData{ + owner2: { + BLSKeys: [][]byte{owner2StakingQueue[1]}, + }, + }) + currNodesConfig = node.NodesConfig + queue = remove(queue, owner2StakingQueue[1]) + requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + requireSliceContains(t, currNodesConfig.auction, queue) + + // 4. Check config after whole staking v4 chain is ready, when one of the owners unStakes a node + node.Process(t, 4) + currNodesConfig = node.NodesConfig + node.ProcessUnStake(t, map[string]*NodesRegisterData{ + owner2: { + BLSKeys: [][]byte{owner2Stats.EligibleBlsKeys[0][0]}, + }, + }) + node.Process(t, 4) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.leaving), 1) + requireMapContains(t, currNodesConfig.leaving, [][]byte{owner2Stats.EligibleBlsKeys[0][0]}) + require.Empty(t, currNodesConfig.new) + require.Empty(t, currNodesConfig.queue) } From 58ec4a9ebc6c3fed706f0b778f59b32e9d108c5e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 13:32:58 +0300 Subject: [PATCH 307/958] FEAT: Add createSCRFromStakingSCOutput --- .../testMetaProcessorWithCustomNodesConfig.go | 75 ++++++++----------- 1 file changed, 30 insertions(+), 45 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index ce14d208cf1..f1494b21f24 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -4,19 +4,17 @@ import ( "bytes" "encoding/hex" "math/big" - "strconv" "testing" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" + "github.com/ElrondNetwork/elrond-go-core/marshal" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/dataRetriever" "github.com/ElrondNetwork/elrond-go/integrationTests" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/process/smartContract" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" @@ -169,22 +167,16 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*Nod Data: []byte(txData), }) - txsData := tmp.doUnStake(t, vmcommon.VMInput{ + scrs := tmp.doUnStake(t, vmcommon.VMInput{ CallerAddr: []byte(owner), Arguments: argsUnStake, CallValue: big.NewInt(0), GasProvided: 10, - }) - - for i, tData := range txsData { - txHash = []byte("rrrr" + strconv.Itoa(i)) - txHashes = append(txHashes, txHash) - - tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ - RcvAddr: vm.StakingSCAddress, - Data: []byte(tData), - }) + }, tmp.Marshaller) + for scrHash, scr := range scrs { + txHashes = append(txHashes, []byte(scrHash)) + tmp.TxCacher.AddTx([]byte(scrHash), scr) } } _, err := tmp.AccountsAdapter.Commit() @@ -205,7 +197,7 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*Nod } //TODO: -// - Do the same for unStake/unJail +// - Do the same for unJail func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, @@ -220,7 +212,11 @@ func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { require.Nil(t, err) } -func (tmp *TestMetaProcessor) doUnStake(t *testing.T, vmInput vmcommon.VMInput) []string { +func (tmp *TestMetaProcessor) doUnStake( + t *testing.T, + vmInput vmcommon.VMInput, + marshaller marshal.Marshalizer, +) map[string]*smartContractResult.SmartContractResult { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, RecipientAddr: vm.ValidatorSCAddress, @@ -230,45 +226,34 @@ func (tmp *TestMetaProcessor) doUnStake(t *testing.T, vmInput vmcommon.VMInput) require.Nil(t, err) require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) - txsData, err := ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) + err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) - return txsData + + return createSCRFromStakingSCOutput(vmOutput, marshaller) } -func ProcessSCOutputAccounts(vmOutput *vmcommon.VMOutput, accountsDB state.AccountsAdapter) ([]string, error) { +func createSCRFromStakingSCOutput( + vmOutput *vmcommon.VMOutput, + marshaller marshal.Marshalizer, +) map[string]*smartContractResult.SmartContractResult { + allSCR := make(map[string]*smartContractResult.SmartContractResult) + parser := smartContract.NewArgumentParser() outputAccounts := process.SortVMOutputInsideData(vmOutput) - data := make([]string, 0) for _, outAcc := range outputAccounts { - acc := stakingcommon.LoadUserAccount(accountsDB, outAcc.Address) - storageUpdates := process.GetSortedStorageUpdates(outAcc) - for _, storeUpdate := range storageUpdates { - err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) - if err != nil { - return nil, err - } - - if outAcc.BalanceDelta != nil && outAcc.BalanceDelta.Cmp(big.NewInt(0)) != 0 { - err = acc.AddToBalance(outAcc.BalanceDelta) - if err != nil { - return nil, err - } - } - - err = accountsDB.SaveAccount(acc) - if err != nil { - return nil, err - } - - if bytes.Equal(outAcc.Address, vm.StakingSCAddress) { - parser := smartContract.NewArgumentParser() - data2 := parser.CreateDataFromStorageUpdate(storageUpdates) - data = append(data, data2) + if bytes.Equal(outAcc.Address, vm.StakingSCAddress) { + scrData := parser.CreateDataFromStorageUpdate(storageUpdates) + scr := &smartContractResult.SmartContractResult{ + RcvAddr: vm.StakingSCAddress, + Data: []byte(scrData), } + scrBytes, _ := marshaller.Marshal(scr) + scrHash := hex.EncodeToString(scrBytes) + allSCR[scrHash] = scr } } - return data, nil + return allSCR } From da988a4bba112fecbe86daa68e9a1884ad1c46d3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 13:52:29 +0300 Subject: [PATCH 308/958] FEAT: Refactor doUnstake and doStake --- .../testMetaProcessorWithCustomNodesConfig.go | 88 +++++++++---------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index f1494b21f24..bee402d674a 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -95,33 +95,17 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes txHashes := make([][]byte, 0) for owner, nodesData := range nodes { - numBLSKeys := int64(len(nodesData.BLSKeys)) - numBLSKeysBytes := big.NewInt(numBLSKeys).Bytes() - - txData := hex.EncodeToString([]byte("stake")) + "@" + hex.EncodeToString(numBLSKeysBytes) - argsStake := [][]byte{numBLSKeysBytes} - - for _, blsKey := range nodesData.BLSKeys { - signature := append([]byte("signature-"), blsKey...) - - argsStake = append(argsStake, blsKey, signature) - txData += "@" + hex.EncodeToString(blsKey) + "@" + hex.EncodeToString(signature) - } - - txHash := append([]byte("txHash-stake-"), []byte(owner)...) - txHashes = append(txHashes, txHash) - - tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ - RcvAddr: vm.StakingSCAddress, - Data: []byte(txData), - }) - - tmp.doStake(t, vmcommon.VMInput{ + scrs := tmp.doStake(t, vmcommon.VMInput{ CallerAddr: []byte(owner), - Arguments: argsStake, + Arguments: createStakeArgs(nodesData.BLSKeys), CallValue: nodesData.TotalStake, GasProvided: 10, - }) + }, tmp.Marshaller) + + for scrHash, scr := range scrs { + txHashes = append(txHashes, []byte(scrHash)) + tmp.TxCacher.AddTx([]byte(scrHash), scr) + } } _, err := tmp.AccountsAdapter.Commit() require.Nil(t, err) @@ -148,28 +132,9 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*Nod txHashes := make([][]byte, 0) for owner, nodesData := range nodes { - numBLSKeys := int64(len(nodesData.BLSKeys)) - numBLSKeysBytes := big.NewInt(numBLSKeys).Bytes() - - txData := hex.EncodeToString([]byte("unStake")) + "@" + hex.EncodeToString(numBLSKeysBytes) - argsUnStake := make([][]byte, 0) - - for _, blsKey := range nodesData.BLSKeys { - argsUnStake = append(argsUnStake, blsKey) - txData += "@" + hex.EncodeToString(blsKey) + "@" - } - - txHash := append([]byte("txHash-unStake-"), []byte(owner)...) - txHashes = append(txHashes, txHash) - - tmp.TxCacher.AddTx(txHash, &smartContractResult.SmartContractResult{ - RcvAddr: vm.StakingSCAddress, - Data: []byte(txData), - }) - scrs := tmp.doUnStake(t, vmcommon.VMInput{ CallerAddr: []byte(owner), - Arguments: argsUnStake, + Arguments: createUnStakeArgs(nodesData.BLSKeys), CallValue: big.NewInt(0), GasProvided: 10, }, tmp.Marshaller) @@ -179,6 +144,7 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*Nod tmp.TxCacher.AddTx([]byte(scrHash), scr) } } + _, err := tmp.AccountsAdapter.Commit() require.Nil(t, err) @@ -196,9 +162,26 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*Nod tmp.currentRound += 1 } +func createStakeArgs(blsKeys [][]byte) [][]byte { + numBLSKeys := int64(len(blsKeys)) + numBLSKeysBytes := big.NewInt(numBLSKeys).Bytes() + argsStake := [][]byte{numBLSKeysBytes} + + for _, blsKey := range blsKeys { + signature := append([]byte("signature-"), blsKey...) + argsStake = append(argsStake, blsKey, signature) + } + + return argsStake +} + //TODO: // - Do the same for unJail -func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { +func (tmp *TestMetaProcessor) doStake( + t *testing.T, + vmInput vmcommon.VMInput, + marshaller marshal.Marshalizer, +) map[string]*smartContractResult.SmartContractResult { arguments := &vmcommon.ContractCallInput{ VMInput: vmInput, RecipientAddr: vm.ValidatorSCAddress, @@ -210,6 +193,17 @@ func (tmp *TestMetaProcessor) doStake(t *testing.T, vmInput vmcommon.VMInput) { err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) + + return createSCRsFromStakingSCOutput(vmOutput, marshaller) +} + +func createUnStakeArgs(blsKeys [][]byte) [][]byte { + argsUnStake := make([][]byte, 0) + for _, blsKey := range blsKeys { + argsUnStake = append(argsUnStake, blsKey) + } + + return argsUnStake } func (tmp *TestMetaProcessor) doUnStake( @@ -229,10 +223,10 @@ func (tmp *TestMetaProcessor) doUnStake( err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) - return createSCRFromStakingSCOutput(vmOutput, marshaller) + return createSCRsFromStakingSCOutput(vmOutput, marshaller) } -func createSCRFromStakingSCOutput( +func createSCRsFromStakingSCOutput( vmOutput *vmcommon.VMOutput, marshaller marshal.Marshalizer, ) map[string]*smartContractResult.SmartContractResult { From 9ba20b0a64093922070f5590f4de062ceb7440d4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 14:16:23 +0300 Subject: [PATCH 309/958] FEAT: Add SaveDelegationManagerConfig to stakingCommon.go --- integrationTests/testInitializer.go | 15 ++----------- .../vm/staking/baseTestMetaProcessor.go | 16 +------------- testscommon/stakingcommon/stakingCommon.go | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 9adbb247c3a..7e8af345c4e 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -62,6 +62,7 @@ import ( dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/genesisMocks" "github.com/ElrondNetwork/elrond-go/testscommon/p2pmocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/trie/hashesHolder" @@ -98,7 +99,6 @@ const ( adaptivity = false hysteresis = float32(0.2) maxTrieLevelInMemory = uint(5) - delegationManagementKey = "delegationManagement" delegationContractsList = "delegationContracts" ) @@ -2550,18 +2550,7 @@ func SaveDelegationManagerConfig(nodes []*TestProcessorNode) { continue } - acc, _ := n.AccntState.LoadAccount(vm.DelegationManagerSCAddress) - userAcc, _ := acc.(state.UserAccountHandler) - - managementData := &systemSmartContracts.DelegationManagement{ - MinDeposit: big.NewInt(100), - LastAddress: vm.FirstDelegationSCAddress, - MinDelegationAmount: big.NewInt(1), - } - marshaledData, _ := TestMarshalizer.Marshal(managementData) - _ = userAcc.DataTrieTracker().SaveKeyValue([]byte(delegationManagementKey), marshaledData) - _ = n.AccntState.SaveAccount(userAcc) - _, _ = n.AccntState.Commit() + stakingcommon.SaveDelegationManagerConfig(n.AccntState, TestMarshalizer) } } diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 5bffac8c407..e7f470d8dc7 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -27,8 +27,6 @@ import ( "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" @@ -91,7 +89,7 @@ func newTestMetaProcessor( maxNodesConfig, ) - createDelegationManagementConfig( + stakingcommon.SaveDelegationManagerConfig( stateComponents.AccountsAdapter(), coreComponents.InternalMarshalizer(), ) @@ -208,18 +206,6 @@ func saveNodesConfig( ) } -func createDelegationManagementConfig(accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer) { - delegationCfg := &systemSmartContracts.DelegationManagement{ - MinDelegationAmount: big.NewInt(10), - } - marshalledData, _ := marshaller.Marshal(delegationCfg) - - delegationAcc := stakingcommon.LoadUserAccount(accountsDB, vm.DelegationManagerSCAddress) - _ = delegationAcc.DataTrieTracker().SaveKeyValue([]byte("delegationManagement"), marshalledData) - _ = accountsDB.SaveAccount(delegationAcc) - _, _ = accountsDB.Commit() -} - func createGasScheduleNotifier() core.GasScheduleNotifier { gasSchedule := arwenConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 9ad9967952a..9c3958e8d42 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -306,3 +306,25 @@ func SaveNodesConfig( _, err = accountsDB.Commit() log.LogIfError(err) } + +// SaveDelegationManagerConfig will save a mock configuration for the delegation manager SC +func SaveDelegationManagerConfig(accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer) { + managementData := &systemSmartContracts.DelegationManagement{ + MinDeposit: big.NewInt(100), + LastAddress: vm.FirstDelegationSCAddress, + MinDelegationAmount: big.NewInt(1), + } + marshaledData, err := marshaller.Marshal(managementData) + log.LogIfError(err) + + acc, err := accountsDB.LoadAccount(vm.DelegationManagerSCAddress) + log.LogIfError(err) + delegationAcc, _ := acc.(state.UserAccountHandler) + + err = delegationAcc.DataTrieTracker().SaveKeyValue([]byte("delegationManagement"), marshaledData) + log.LogIfError(err) + err = accountsDB.SaveAccount(delegationAcc) + log.LogIfError(err) + _, err = accountsDB.Commit() + log.LogIfError(err) +} From e96c54c9cd8077a944ed980b513f307ea594069b Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 15:08:58 +0300 Subject: [PATCH 310/958] FIX: Refactor --- integrationTests/vm/staking/stakingV4_test.go | 44 +++++------ .../testMetaProcessorWithCustomNodesConfig.go | 76 +++++++++---------- 2 files changed, 56 insertions(+), 64 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 96efed3990c..ba4a7622f96 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -631,10 +631,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) // 1.1 Owner2 unStakes one of his staking queue nodes. Node should be removed from staking queue list - node.ProcessUnStake(t, map[string]*NodesRegisterData{ - owner2: { - BLSKeys: [][]byte{owner2Stats.StakingQueueKeys[0]}, - }, + node.ProcessUnStake(t, map[string][][]byte{ + owner2: {owner2Stats.StakingQueueKeys[0]}, }) currNodesConfig = node.NodesConfig queue = remove(queue, owner2Stats.StakingQueueKeys[0]) @@ -645,10 +643,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { // 1.2 Owner2 unStakes one of his waiting list keys. First node from staking queue should be added to fill its place. copy(queue, currNodesConfig.queue) // copy queue to local variable so we have the queue in same order - node.ProcessUnStake(t, map[string]*NodesRegisterData{ - owner2: { - BLSKeys: [][]byte{owner2Stats.WaitingBlsKeys[core.MetachainShardId][0]}, - }, + node.ProcessUnStake(t, map[string][][]byte{ + owner2: {owner2Stats.WaitingBlsKeys[core.MetachainShardId][0]}, }) currNodesConfig = node.NodesConfig require.Len(t, currNodesConfig.new, 1) @@ -663,17 +659,16 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) - // owner2's waiting list which was unStaked in previous epoch is now leaving + // Owner2's node from waiting list which was unStaked in previous epoch is now leaving require.Len(t, currNodesConfig.leaving, 1) require.Equal(t, owner2Stats.WaitingBlsKeys[core.MetachainShardId][0], currNodesConfig.leaving[core.MetachainShardId][0]) require.Len(t, currNodesConfig.auction, 5) + // All nodes from queue have been moved to auction requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) // 2.1 Owner3 unStakes one of his nodes from auction - node.ProcessUnStake(t, map[string]*NodesRegisterData{ - owner3: { - BLSKeys: [][]byte{owner3StakingQueue[1]}, - }, + node.ProcessUnStake(t, map[string][][]byte{ + owner3: {owner3StakingQueue[1]}, }) unStakedNodesInStakingV4InitEpoch := make([][]byte, 0) unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner3StakingQueue[1]) @@ -685,10 +680,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Empty(t, currNodesConfig.new) // 2.2 Owner1 unStakes 2 nodes: one from auction + one active - node.ProcessUnStake(t, map[string]*NodesRegisterData{ - owner1: { - BLSKeys: [][]byte{owner1StakingQueue[1], owner1Stats.WaitingBlsKeys[0][0]}, - }, + node.ProcessUnStake(t, map[string][][]byte{ + owner1: {owner1StakingQueue[1], owner1Stats.WaitingBlsKeys[0][0]}, }) unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner1StakingQueue[1]) unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner1Stats.WaitingBlsKeys[0][0]) @@ -705,25 +698,24 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) require.Len(t, getAllPubKeys(currNodesConfig.leaving), 3) + // All unStaked nodes in previous epoch are now leaving requireMapContains(t, currNodesConfig.leaving, unStakedNodesInStakingV4InitEpoch) // 3.1 Owner2 unStakes one of his nodes from auction - node.ProcessUnStake(t, map[string]*NodesRegisterData{ - owner2: { - BLSKeys: [][]byte{owner2StakingQueue[1]}, - }, + node.ProcessUnStake(t, map[string][][]byte{ + owner2: {owner2StakingQueue[1]}, }) currNodesConfig = node.NodesConfig queue = remove(queue, owner2StakingQueue[1]) - requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + shuffledOutNodes := getAllPubKeys(currNodesConfig.shuffledOut) + require.Len(t, currNodesConfig.auction, len(shuffledOutNodes)+len(queue)) + requireSliceContains(t, currNodesConfig.auction, shuffledOutNodes) requireSliceContains(t, currNodesConfig.auction, queue) // 4. Check config after whole staking v4 chain is ready, when one of the owners unStakes a node node.Process(t, 4) currNodesConfig = node.NodesConfig - node.ProcessUnStake(t, map[string]*NodesRegisterData{ - owner2: { - BLSKeys: [][]byte{owner2Stats.EligibleBlsKeys[0][0]}, - }, + node.ProcessUnStake(t, map[string][][]byte{ + owner2: {owner2Stats.EligibleBlsKeys[0][0]}, }) node.Process(t, 4) currNodesConfig = node.NodesConfig diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index bee402d674a..b909d0798de 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -124,44 +124,6 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes tmp.currentRound += 1 } -// ProcessUnStake will create a block containing mini blocks with unStaking txs using provided nodes. -// Block will be committed + call to validator system sc will be made to unStake all nodes -func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string]*NodesRegisterData) { - header := tmp.createNewHeader(t, tmp.currentRound) - tmp.BlockChainHook.SetCurrentHeader(header) - - txHashes := make([][]byte, 0) - for owner, nodesData := range nodes { - scrs := tmp.doUnStake(t, vmcommon.VMInput{ - CallerAddr: []byte(owner), - Arguments: createUnStakeArgs(nodesData.BLSKeys), - CallValue: big.NewInt(0), - GasProvided: 10, - }, tmp.Marshaller) - - for scrHash, scr := range scrs { - txHashes = append(txHashes, []byte(scrHash)) - tmp.TxCacher.AddTx([]byte(scrHash), scr) - } - } - - _, err := tmp.AccountsAdapter.Commit() - require.Nil(t, err) - - miniBlocks := block.MiniBlockSlice{ - { - TxHashes: txHashes, - SenderShardID: core.MetachainShardId, - ReceiverShardID: core.MetachainShardId, - Type: block.SmartContractResultBlock, - }, - } - tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) - tmp.createAndCommitBlock(t, header, noTime) - - tmp.currentRound += 1 -} - func createStakeArgs(blsKeys [][]byte) [][]byte { numBLSKeys := int64(len(blsKeys)) numBLSKeysBytes := big.NewInt(numBLSKeys).Bytes() @@ -197,6 +159,44 @@ func (tmp *TestMetaProcessor) doStake( return createSCRsFromStakingSCOutput(vmOutput, marshaller) } +// ProcessUnStake will create a block containing mini blocks with unStaking txs using provided nodes. +// Block will be committed + call to validator system sc will be made to unStake all nodes +func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string][][]byte) { + header := tmp.createNewHeader(t, tmp.currentRound) + tmp.BlockChainHook.SetCurrentHeader(header) + + txHashes := make([][]byte, 0) + for owner, blsKeys := range nodes { + scrs := tmp.doUnStake(t, vmcommon.VMInput{ + CallerAddr: []byte(owner), + Arguments: createUnStakeArgs(blsKeys), + CallValue: big.NewInt(0), + GasProvided: 10, + }, tmp.Marshaller) + + for scrHash, scr := range scrs { + txHashes = append(txHashes, []byte(scrHash)) + tmp.TxCacher.AddTx([]byte(scrHash), scr) + } + } + + _, err := tmp.AccountsAdapter.Commit() + require.Nil(t, err) + + miniBlocks := block.MiniBlockSlice{ + { + TxHashes: txHashes, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + } + tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) + tmp.createAndCommitBlock(t, header, noTime) + + tmp.currentRound += 1 +} + func createUnStakeArgs(blsKeys [][]byte) [][]byte { argsUnStake := make([][]byte, 0) for _, blsKey := range blsKeys { From e7154ccbc158b484fe1af56ea6a055280f94e8de Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 16:46:46 +0300 Subject: [PATCH 311/958] FIX: Revert time.Sleep change --- integrationTests/vm/delegation/liquidStaking_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 1199b4301e3..a343a1b9927 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -44,18 +44,18 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { } nrRoundsToPropagateMultiShard := 12 - time.Sleep(2 * time.Second) + time.Sleep(time.Second) nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(2 * time.Second) + time.Sleep(time.Second) // claim again for _, node := range nodes { integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txData, core.MinMetaTxExtraGasCost) } - time.Sleep(2 * time.Second) + time.Sleep(time.Second) nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(2 * time.Second) + time.Sleep(time.Second) for i := 1; i < len(nodes); i++ { checkLPPosition(t, nodes[i].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(10000)) @@ -87,10 +87,10 @@ func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { for _, node := range nodes { integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), node.OwnAccount.Address, txBuilder.ToString(), core.MinMetaTxExtraGasCost) } - time.Sleep(2 * time.Second) + time.Sleep(time.Second) finalWait := 20 _, _ = integrationTests.WaitOperationToBeDone(t, nodes, finalWait, nonce, round, idxProposers) - time.Sleep(2 * time.Second) + time.Sleep(time.Second) for _, node := range nodes { checkLPPosition(t, node.OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) From d3c492e278ed2201e57ae975521844d514e3d1b2 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 31 May 2022 16:48:36 +0300 Subject: [PATCH 312/958] FIX: handleProcessMiniBlockInit --- process/coordinator/process.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/process/coordinator/process.go b/process/coordinator/process.go index d1d13e0c85a..cf85d91ba3b 100644 --- a/process/coordinator/process.go +++ b/process/coordinator/process.go @@ -1215,10 +1215,8 @@ func (tc *transactionCoordinator) processCompleteMiniBlock( func (tc *transactionCoordinator) handleProcessMiniBlockInit(miniBlockHash []byte) int { snapshot := tc.accounts.JournalLen() - if tc.shardCoordinator.SelfId() != core.MetachainShardId { - tc.InitProcessedTxsResults(miniBlockHash) - tc.gasHandler.Reset(miniBlockHash) - } + tc.InitProcessedTxsResults(miniBlockHash) + tc.gasHandler.Reset(miniBlockHash) return snapshot } From 3dd4804f054a5ca6a5e0b37903379c0e98e5a63f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 11:20:49 +0300 Subject: [PATCH 313/958] FEAT: First version, failing tests --- epochStart/interface.go | 17 +- epochStart/metachain/auctionListDisplayer.go | 8 +- epochStart/metachain/auctionListSelector.go | 73 +++--- .../metachain/auctionListSelector_test.go | 32 +-- epochStart/metachain/auctionListSorting.go | 6 +- epochStart/metachain/legacySystemSCs.go | 31 +-- epochStart/metachain/stakingDataProvider.go | 207 ++++++++++++------ .../metachain/stakingDataProvider_test.go | 54 ++--- epochStart/metachain/systemSCs.go | 29 +-- epochStart/metachain/systemSCs_test.go | 2 +- epochStart/mock/stakingDataProviderStub.go | 22 +- .../vm/staking/configDisplayer.go | 6 +- integrationTests/vm/staking/stakingV4_test.go | 2 + 13 files changed, 282 insertions(+), 207 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index a259d030185..56e744e4db6 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -146,6 +146,16 @@ type TransactionCacher interface { IsInterfaceNil() bool } +type OwnerData struct { + NumActiveNodes int64 + NumAuctionNodes int64 + NumStakedNodes int64 + TotalTopUp *big.Int + TopUpPerNode *big.Int + AuctionList []state.ValidatorInfoHandler + Qualified bool +} + // StakingDataProvider is able to provide staking data from the system smart contracts type StakingDataProvider interface { GetTotalStakeEligibleNodes() *big.Int @@ -153,10 +163,12 @@ type StakingDataProvider interface { GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) GetNumStakedNodes(owner []byte) (int64, error) GetTotalTopUp(owner []byte) (*big.Int, error) - PrepareStakingData(keys map[uint32][][]byte) error - FillValidatorInfo(blsKey []byte) error + PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error + FillValidatorInfo(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) + GetNumOfValidatorsInCurrentEpoch() uint32 + GetOwnersStats() map[string]*OwnerData Clean() EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool @@ -216,7 +228,6 @@ type MaxNodesChangeConfigProvider interface { type AuctionListSelector interface { SelectNodesFromAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, - unqualifiedOwners map[string]struct{}, randomness []byte, ) error IsInterfaceNil() bool diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 5bc2585e668..fbe7ea7d7fa 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -77,7 +77,7 @@ func getPrettyValue(val *big.Int, denominator *big.Int) string { return first + "." + second } -func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerData) { +func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerAuctionData) { if log.GetLevel() > logger.LogDebug { return } @@ -109,7 +109,7 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerDa displayTable(tableHeader, lines, "Initial nodes config in auction list") } -func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string]*ownerData) { +func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string]*ownerAuctionData) { if log.GetLevel() > logger.LogDebug { return } @@ -147,7 +147,7 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string func (als *auctionListSelector) displayAuctionList( auctionList []state.ValidatorInfoHandler, - ownersData map[string]*ownerData, + ownersData map[string]*ownerAuctionData, numOfSelectedNodes uint32, ) { if log.GetLevel() > logger.LogDebug { @@ -179,7 +179,7 @@ func (als *auctionListSelector) displayAuctionList( displayTable(tableHeader, lines, "Final selected nodes from auction list") } -func getBlsKeyOwnerMap(ownersData map[string]*ownerData) map[string]string { +func getBlsKeyOwnerMap(ownersData map[string]*ownerAuctionData) map[string]string { ret := make(map[string]string) for ownerPubKey, owner := range ownersData { for _, blsKey := range owner.auctionList { diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index f9bcfdbdde2..96df7c806e2 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -16,7 +16,7 @@ import ( "github.com/ElrondNetwork/elrond-go/state" ) -type ownerData struct { +type ownerAuctionData struct { numActiveNodes int64 numAuctionNodes int64 numQualifiedAuctionNodes int64 @@ -137,14 +137,14 @@ func checkNilArgs(args AuctionListSelectorArgs) error { // to common.SelectNodesFromAuctionList func (als *auctionListSelector) SelectNodesFromAuctionList( validatorsInfoMap state.ShardValidatorsInfoMapHandler, - unqualifiedOwners map[string]struct{}, randomness []byte, ) error { if len(randomness) == 0 { return process.ErrNilRandSeed } - ownersData, auctionListSize, currNumOfValidators, err := als.getAuctionDataAndNumOfValidators(validatorsInfoMap, unqualifiedOwners) + ownersData, auctionListSize, err := als.getAuctionData() + currNumOfValidators := als.stakingDataProvider.GetNumOfValidatorsInCurrentEpoch() if err != nil { return err } @@ -198,45 +198,28 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } -func (als *auctionListSelector) getAuctionDataAndNumOfValidators( - validatorsInfoMap state.ShardValidatorsInfoMapHandler, - unqualifiedOwners map[string]struct{}, -) (map[string]*ownerData, uint32, uint32, error) { - ownersData := make(map[string]*ownerData) - numOfValidators := uint32(0) +func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, uint32, error) { + ownersData := make(map[string]*ownerAuctionData) numOfNodesInAuction := uint32(0) - for _, validator := range validatorsInfoMap.GetAllValidatorsInfo() { - blsKey := validator.GetPublicKey() - owner, err := als.stakingDataProvider.GetBlsKeyOwner(blsKey) - if err != nil { - return nil, 0, 0, err - } - - if isInAuction(validator) { - _, isUnqualified := unqualifiedOwners[owner] - if isUnqualified { - log.Debug("auctionListSelector: found node in auction with unqualified owner, do not add it to selection", - "owner", hex.EncodeToString([]byte(owner)), - "bls key", hex.EncodeToString(blsKey), - ) - continue + for owner, ownerData := range als.stakingDataProvider.GetOwnersStats() { + if ownerData.Qualified && ownerData.NumAuctionNodes > 0 { + ownersData[owner] = &ownerAuctionData{ + numActiveNodes: ownerData.NumActiveNodes, + numAuctionNodes: ownerData.NumAuctionNodes, + numQualifiedAuctionNodes: ownerData.NumAuctionNodes, + numStakedNodes: ownerData.NumStakedNodes, + totalTopUp: ownerData.TotalTopUp, + topUpPerNode: ownerData.TopUpPerNode, + qualifiedTopUpPerNode: ownerData.TopUpPerNode, + auctionList: make([]state.ValidatorInfoHandler, len(ownerData.AuctionList)), } - - err = als.addOwnerData(owner, validator, ownersData) - if err != nil { - return nil, 0, 0, err - } - - numOfNodesInAuction++ - continue - } - if isValidator(validator) { - numOfValidators++ + copy(ownersData[owner].auctionList, ownerData.AuctionList) + numOfNodesInAuction += uint32(ownerData.NumAuctionNodes) } } - return ownersData, numOfNodesInAuction, numOfValidators, nil + return ownersData, numOfNodesInAuction, nil } func isInAuction(validator state.ValidatorInfoHandler) bool { @@ -246,7 +229,7 @@ func isInAuction(validator state.ValidatorInfoHandler) bool { func (als *auctionListSelector) addOwnerData( owner string, validator state.ValidatorInfoHandler, - ownersData map[string]*ownerData, + ownersData map[string]*ownerAuctionData, ) error { ownerPubKey := []byte(owner) validatorPubKey := validator.GetPublicKey() @@ -284,7 +267,7 @@ func (als *auctionListSelector) addOwnerData( } else { stakedNodesBigInt := big.NewInt(stakedNodes) topUpPerNode := big.NewInt(0).Div(totalTopUp, stakedNodesBigInt) - ownersData[owner] = &ownerData{ + ownersData[owner] = &ownerAuctionData{ numAuctionNodes: 1, numQualifiedAuctionNodes: 1, numActiveNodes: stakedNodes - 1, @@ -308,7 +291,7 @@ func safeSub(a, b uint32) (uint32, error) { } func (als *auctionListSelector) sortAuctionList( - ownersData map[string]*ownerData, + ownersData map[string]*ownerAuctionData, numOfAvailableNodeSlots uint32, validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, @@ -319,9 +302,9 @@ func (als *auctionListSelector) sortAuctionList( } func (als *auctionListSelector) calcSoftAuctionNodesConfig( - data map[string]*ownerData, + data map[string]*ownerAuctionData, numAvailableSlots uint32, -) map[string]*ownerData { +) map[string]*ownerAuctionData { ownersData := copyOwnersData(data) minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) log.Debug("auctionListSelector: calc min and max possible top up", @@ -365,7 +348,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( return previousConfig } -func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*ownerData) (*big.Int, *big.Int) { +func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*ownerAuctionData) (*big.Int, *big.Int) { min := big.NewInt(0).SetBytes(als.softAuctionConfig.maxTopUp.Bytes()) max := big.NewInt(0).SetBytes(als.softAuctionConfig.minTopUp.Bytes()) @@ -388,10 +371,10 @@ func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*ow return min, max } -func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { - ret := make(map[string]*ownerData) +func copyOwnersData(ownersData map[string]*ownerAuctionData) map[string]*ownerAuctionData { + ret := make(map[string]*ownerAuctionData) for owner, data := range ownersData { - ret[owner] = &ownerData{ + ret[owner] = &ownerAuctionData{ numActiveNodes: data.numActiveNodes, numAuctionNodes: data.numAuctionNodes, numQualifiedAuctionNodes: data.numQualifiedAuctionNodes, diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index a8bd8e93707..9c20fb88b01 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -61,7 +61,7 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha func fillValidatorsInfo(t *testing.T, validatorsMap state.ShardValidatorsInfoMapHandler, sdp epochStart.StakingDataProvider) { for _, validator := range validatorsMap.GetAllValidatorsInfo() { - err := sdp.FillValidatorInfo(validator.GetPublicKey()) + err := sdp.FillValidatorInfo(validator) require.Nil(t, err) } } @@ -224,7 +224,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { args := createAuctionListSelectorArgs(nil) als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), nil, nil) + err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), nil) require.Equal(t, process.ErrNilRandSeed, err) }) @@ -245,7 +245,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { } als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) require.Equal(t, errGetOwner, err) }) @@ -271,7 +271,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { } als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) require.Error(t, err) require.True(t, strings.Contains(err.Error(), errGetNumStakedNodes.Error())) require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) @@ -299,7 +299,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { } als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) require.Error(t, err) require.True(t, strings.Contains(err.Error(), epochStart.ErrOwnerHasNoStakedNode.Error())) require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) @@ -332,7 +332,7 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { } als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rand")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) require.Error(t, err) require.True(t, strings.Contains(err.Error(), errGetTotalTopUp.Error())) require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) @@ -357,7 +357,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), nil, []byte("rand")) + err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), []byte("rand")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { @@ -385,7 +385,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { @@ -414,7 +414,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { @@ -438,7 +438,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, nil, []byte("rnd")) + err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { @@ -464,7 +464,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerData{ + ownersData := map[string]*ownerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -512,7 +512,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" owner3 := "owner3" - ownersData := map[string]*ownerData{ + ownersData := map[string]*ownerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -574,7 +574,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerData{ + ownersData := map[string]*ownerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -618,7 +618,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerData{ + ownersData := map[string]*ownerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -663,7 +663,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerData{ + ownersData := map[string]*ownerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -728,7 +728,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { owner2 := "owner2" owner3 := "owner3" owner4 := "owner4" - ownersData := map[string]*ownerData{ + ownersData := map[string]*ownerAuctionData{ owner1: { numActiveNodes: 2, numAuctionNodes: 2, diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index d9f28cbf286..cad28759fc8 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -9,7 +9,7 @@ import ( ) func (als *auctionListSelector) selectNodes( - ownersData map[string]*ownerData, + ownersData map[string]*ownerAuctionData, numAvailableSlots uint32, randomness []byte, ) []state.ValidatorInfoHandler { @@ -32,7 +32,7 @@ func (als *auctionListSelector) selectNodes( return selectedFromAuction[:numAvailableSlots] } -func getPubKeyLen(ownersData map[string]*ownerData) int { +func getPubKeyLen(ownersData map[string]*ownerAuctionData) int { for _, owner := range ownersData { return len(owner.auctionList[0].GetPublicKey()) } @@ -62,7 +62,7 @@ func sortListByPubKey(list []state.ValidatorInfoHandler) { }) } -func addQualifiedValidatorsTopUpInMap(owner *ownerData, validatorTopUpMap map[string]*big.Int) { +func addQualifiedValidatorsTopUpInMap(owner *ownerAuctionData, validatorTopUpMap map[string]*big.Int) { for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { validatorPubKey := string(owner.auctionList[i].GetPublicKey()) validatorTopUpMap[validatorPubKey] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 34daa27a50c..05aec67f85e 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -438,7 +438,7 @@ func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMa continue } - err := s.stakingDataProvider.FillValidatorInfo(validatorInfo.GetPublicKey()) + err := s.stakingDataProvider.FillValidatorInfo(validatorInfo) if err != nil { deleteCalled = true @@ -470,11 +470,15 @@ func (s *legacySystemSCProcessor) fillStakingDataForNonEligible(validatorsInfoMa } func (s *legacySystemSCProcessor) prepareStakingDataForEligibleNodes(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { - eligibleNodes := s.getEligibleNodeKeys(validatorsInfoMap) + eligibleNodes, err := getEligibleNodeKeys(validatorsInfoMap) + if err != nil { + return err + } + return s.prepareStakingData(eligibleNodes) } -func (s *legacySystemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byte) error { +func (s *legacySystemSCProcessor) prepareStakingData(validatorsInfoMap state.ShardValidatorsInfoMapHandler) error { sw := core.NewStopWatch() sw.Start("prepareStakingDataForRewards") defer func() { @@ -482,23 +486,24 @@ func (s *legacySystemSCProcessor) prepareStakingData(nodeKeys map[uint32][][]byt log.Debug("systemSCProcessor.prepareStakingDataForRewards time measurements", sw.GetMeasurements()...) }() - return s.stakingDataProvider.PrepareStakingData(nodeKeys) + return s.stakingDataProvider.PrepareStakingData(validatorsInfoMap) } -func (s *legacySystemSCProcessor) getEligibleNodeKeys( +func getEligibleNodeKeys( validatorsInfoMap state.ShardValidatorsInfoMapHandler, -) map[uint32][][]byte { - eligibleNodesKeys := make(map[uint32][][]byte) - for shardID, validatorsInfoSlice := range validatorsInfoMap.GetShardValidatorsInfoMap() { - eligibleNodesKeys[shardID] = make([][]byte, 0, s.nodesConfigProvider.ConsensusGroupSize(shardID)) - for _, validatorInfo := range validatorsInfoSlice { - if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { - eligibleNodesKeys[shardID] = append(eligibleNodesKeys[shardID], validatorInfo.GetPublicKey()) +) (state.ShardValidatorsInfoMapHandler, error) { + eligibleNodesKeys := state.NewShardValidatorsInfoMap() + for _, validatorInfo := range validatorsInfoMap.GetAllValidatorsInfo() { + if vInfo.WasEligibleInCurrentEpoch(validatorInfo) { + err := eligibleNodesKeys.Add(validatorInfo.ShallowClone()) + if err != nil { + log.Error("getEligibleNodeKeys: could not add validator info in map", "error", err) + return nil, err } } } - return eligibleNodesKeys + return eligibleNodesKeys, nil } // ProcessDelegationRewards will process the rewards which are directed towards the delegation system smart contracts diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index c88a5d56e09..1d889216f69 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -18,25 +18,31 @@ import ( ) type ownerStats struct { - numEligible int - numStakedNodes int64 - topUpValue *big.Int - totalStaked *big.Int - eligibleBaseStake *big.Int - eligibleTopUpStake *big.Int - topUpPerNode *big.Int - blsKeys [][]byte + numEligible int + numStakedNodes int64 + numActiveNodes int64 + numAuctionNodes int64 + totalTopUp *big.Int + topUpPerNode *big.Int + totalStaked *big.Int + eligibleBaseStake *big.Int + eligibleTopUpStake *big.Int + eligibleTopUpPerNode *big.Int + blsKeys [][]byte + auctionList []state.ValidatorInfoHandler + qualified bool } type stakingDataProvider struct { - mutStakingData sync.RWMutex - cache map[string]*ownerStats - systemVM vmcommon.VMExecutionHandler - totalEligibleStake *big.Int - totalEligibleTopUpStake *big.Int - minNodePrice *big.Int - stakingV4EnableEpoch uint32 - flagStakingV4Enable atomic.Flag + mutStakingData sync.RWMutex + cache map[string]*ownerStats + numOfValidatorsInCurrEpoch uint32 + systemVM vmcommon.VMExecutionHandler + totalEligibleStake *big.Int + totalEligibleTopUpStake *big.Int + minNodePrice *big.Int + stakingV4EnableEpoch uint32 + flagStakingV4Enable atomic.Flag } // StakingDataProviderArgs is a struct placeholder for all arguments required to create a NewStakingDataProvider @@ -82,6 +88,7 @@ func (sdp *stakingDataProvider) Clean() { sdp.cache = make(map[string]*ownerStats) sdp.totalEligibleStake.SetInt64(0) sdp.totalEligibleTopUpStake.SetInt64(0) + sdp.numOfValidatorsInCurrEpoch = 0 sdp.mutStakingData.Unlock() } @@ -117,7 +124,7 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return nil, epochStart.ErrOwnerDoesntHaveEligibleNodesInEpoch } - return ownerInfo.topUpPerNode, nil + return ownerInfo.eligibleTopUpPerNode, nil } // GetNumStakedNodes returns the total number of owner's staked nodes @@ -137,19 +144,17 @@ func (sdp *stakingDataProvider) GetTotalTopUp(owner []byte) (*big.Int, error) { return nil, epochStart.ErrOwnerDoesntHaveNodesInEpoch } - return ownerInfo.topUpValue, nil + return ownerInfo.totalTopUp, nil } // PrepareStakingData prepares the staking data for the given map of node keys per shard -func (sdp *stakingDataProvider) PrepareStakingData(keys map[uint32][][]byte) error { +func (sdp *stakingDataProvider) PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error { sdp.Clean() - for _, keysList := range keys { - for _, blsKey := range keysList { - err := sdp.loadDataForBlsKey(blsKey) - if err != nil { - return err - } + for _, validator := range validatorsMap.GetAllValidatorsInfo() { + err := sdp.loadDataForBlsKey(validator) + if err != nil { + return err } } @@ -181,7 +186,7 @@ func (sdp *stakingDataProvider) processStakingData() { totalEligibleStake.Add(totalEligibleStake, ownerEligibleStake) totalEligibleTopUpStake.Add(totalEligibleTopUpStake, owner.eligibleTopUpStake) - owner.topUpPerNode = big.NewInt(0).Div(owner.eligibleTopUpStake, ownerEligibleNodes) + owner.eligibleTopUpPerNode = big.NewInt(0).Div(owner.eligibleTopUpStake, ownerEligibleNodes) } sdp.totalEligibleTopUpStake = totalEligibleTopUpStake @@ -189,22 +194,23 @@ func (sdp *stakingDataProvider) processStakingData() { } // FillValidatorInfo will fill the validator info for the bls key if it was not already filled -func (sdp *stakingDataProvider) FillValidatorInfo(blsKey []byte) error { +func (sdp *stakingDataProvider) FillValidatorInfo(validator state.ValidatorInfoHandler) error { sdp.mutStakingData.Lock() defer sdp.mutStakingData.Unlock() - _, err := sdp.getAndFillOwnerStatsFromSC(blsKey) + _, err := sdp.getAndFillOwnerStats(validator) return err } -func (sdp *stakingDataProvider) getAndFillOwnerStatsFromSC(blsKey []byte) (*ownerStats, error) { +func (sdp *stakingDataProvider) getAndFillOwnerStats(validator state.ValidatorInfoHandler) (*ownerStats, error) { + blsKey := validator.GetPublicKey() owner, err := sdp.GetBlsKeyOwner(blsKey) if err != nil { log.Debug("error fill owner stats", "step", "get owner from bls", "key", hex.EncodeToString(blsKey), "error", err) return nil, err } - ownerData, err := sdp.getValidatorData(owner) + ownerData, err := sdp.addOwnerData(owner, validator) if err != nil { log.Debug("error fill owner stats", "step", "get owner data", "key", hex.EncodeToString(blsKey), "owner", hex.EncodeToString([]byte(owner)), "error", err) return nil, err @@ -216,13 +222,16 @@ func (sdp *stakingDataProvider) getAndFillOwnerStatsFromSC(blsKey []byte) (*owne // loadDataForBlsKey will be called for each BLS key that took part in the consensus (no matter the shard ID) so the // staking data can be recovered from the staking system smart contracts. // The function will error if something went wrong. It does change the inner state of the called instance. -func (sdp *stakingDataProvider) loadDataForBlsKey(blsKey []byte) error { +func (sdp *stakingDataProvider) loadDataForBlsKey(validator state.ValidatorInfoHandler) error { sdp.mutStakingData.Lock() defer sdp.mutStakingData.Unlock() - ownerData, err := sdp.getAndFillOwnerStatsFromSC(blsKey) + ownerData, err := sdp.getAndFillOwnerStats(validator) if err != nil { - log.Debug("error computing rewards for bls key", "step", "get owner data", "key", hex.EncodeToString(blsKey), "error", err) + log.Debug("error computing rewards for bls key", + "step", "get owner data", + "key", hex.EncodeToString(validator.GetPublicKey()), + "error", err) return err } ownerData.numEligible++ @@ -230,6 +239,28 @@ func (sdp *stakingDataProvider) loadDataForBlsKey(blsKey []byte) error { return nil } +// GetOwnersStats returns all owner stats +func (sdp *stakingDataProvider) GetOwnersStats() map[string]*epochStart.OwnerData { + sdp.mutStakingData.RLock() + defer sdp.mutStakingData.RUnlock() + + ret := make(map[string]*epochStart.OwnerData) + for owner, ownerData := range sdp.cache { + ret[owner] = &epochStart.OwnerData{ + NumActiveNodes: ownerData.numActiveNodes, + NumAuctionNodes: ownerData.numAuctionNodes, + NumStakedNodes: ownerData.numStakedNodes, + TotalTopUp: big.NewInt(0).SetBytes(ownerData.totalTopUp.Bytes()), + TopUpPerNode: big.NewInt(0).SetBytes(ownerData.topUpPerNode.Bytes()), + AuctionList: ownerData.auctionList, + Qualified: ownerData.qualified, + } + copy(ret[owner].AuctionList, ownerData.auctionList) + } + + return ret +} + // GetBlsKeyOwner returns the owner's public key of the provided bls key func (sdp *stakingDataProvider) GetBlsKeyOwner(blsKey []byte) (string, error) { vmInput := &vmcommon.ContractCallInput{ @@ -257,48 +288,72 @@ func (sdp *stakingDataProvider) GetBlsKeyOwner(blsKey []byte) (string, error) { return string(data[0]), nil } -func (sdp *stakingDataProvider) getValidatorData(validatorAddress string) (*ownerStats, error) { - ownerData, exists := sdp.cache[validatorAddress] +func (sdp *stakingDataProvider) addOwnerData(owner string, validator state.ValidatorInfoHandler) (*ownerStats, error) { + ownerData, exists := sdp.cache[owner] + validatorInAuction := isInAuction(validator) if exists { - return ownerData, nil - } + if validatorInAuction { + ownerData.numAuctionNodes++ + ownerData.numActiveNodes-- + ownerData.auctionList = append(ownerData.auctionList, validator.ShallowClone()) + } + } else { + topUpValue, totalStakedValue, numStakedWaiting, blsKeys, err := sdp.getOwnerInfoFromSC(owner) + if err != nil { + return nil, err + } - return sdp.getValidatorDataFromStakingSC(validatorAddress) -} + topUpPerNode := big.NewInt(0) + if numStakedWaiting.Int64() == 0 { + log.Debug("stakingDataProvider.addOwnerData: owner has no staked node %w, owner: %s, node: %s", + epochStart.ErrOwnerHasNoStakedNode, + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(validator.GetPublicKey()), + ) + } else { + topUpPerNode = big.NewInt(0).Div(topUpValue, numStakedWaiting) + } -func (sdp *stakingDataProvider) getValidatorDataFromStakingSC(validatorAddress string) (*ownerStats, error) { - topUpValue, totalStakedValue, numStakedWaiting, blsKeys, err := sdp.getValidatorInfoFromSC(validatorAddress) - if err != nil { - return nil, err - } + ownerData = &ownerStats{ + numEligible: 0, + numStakedNodes: numStakedWaiting.Int64(), + numActiveNodes: numStakedWaiting.Int64(), + totalTopUp: topUpValue, + topUpPerNode: topUpPerNode, + totalStaked: totalStakedValue, + eligibleBaseStake: big.NewInt(0).Set(sdp.minNodePrice), + eligibleTopUpStake: big.NewInt(0), + eligibleTopUpPerNode: big.NewInt(0), + qualified: true, + } + if validatorInAuction { + ownerData.numActiveNodes -= 1 + ownerData.numAuctionNodes = 1 + ownerData.auctionList = []state.ValidatorInfoHandler{validator} + } - ownerData := &ownerStats{ - numEligible: 0, - numStakedNodes: numStakedWaiting.Int64(), - topUpValue: topUpValue, - totalStaked: totalStakedValue, - eligibleBaseStake: big.NewInt(0).Set(sdp.minNodePrice), - eligibleTopUpStake: big.NewInt(0), - topUpPerNode: big.NewInt(0), - } + ownerData.blsKeys = make([][]byte, len(blsKeys)) + copy(ownerData.blsKeys, blsKeys) - ownerData.blsKeys = make([][]byte, len(blsKeys)) - copy(ownerData.blsKeys, blsKeys) + sdp.cache[owner] = ownerData + } - sdp.cache[validatorAddress] = ownerData + if isValidator(validator) { + sdp.numOfValidatorsInCurrEpoch++ + } return ownerData, nil } -func (sdp *stakingDataProvider) getValidatorInfoFromSC(validatorAddress string) (*big.Int, *big.Int, *big.Int, [][]byte, error) { - validatorAddressBytes := []byte(validatorAddress) +func (sdp *stakingDataProvider) getOwnerInfoFromSC(owner string) (*big.Int, *big.Int, *big.Int, [][]byte, error) { + ownerAddressBytes := []byte(owner) vmInput := &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ CallerAddr: vm.EndOfEpochAddress, CallValue: big.NewInt(0), GasProvided: math.MaxUint64, - Arguments: [][]byte{validatorAddressBytes}, + Arguments: [][]byte{ownerAddressBytes}, }, RecipientAddr: vm.ValidatorSCAddress, Function: "getTotalStakedTopUpStakedBlsKeys", @@ -344,7 +399,7 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha sortedKeys := sdp.arrangeBlsKeysByStatus(mapBLSKeyStatus, stakingInfo.blsKeys) numKeysToUnStake := stakingInfo.numStakedNodes - maxQualified.Int64() - selectedKeys := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) + selectedKeys, selectedKeysByStatus := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) if len(selectedKeys) == 0 { continue } @@ -353,6 +408,16 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha mapOwnersKeys[ownerAddress] = make([][]byte, len(selectedKeys)) copy(mapOwnersKeys[ownerAddress], selectedKeys) + stakingInfo.numStakedNodes -= int64(len(selectedKeys)) + + sdp.numOfValidatorsInCurrEpoch -= uint32(len(selectedKeysByStatus[string(common.WaitingList)])) + sdp.numOfValidatorsInCurrEpoch -= uint32(len(selectedKeysByStatus[string(common.EligibleList)])) + stakingInfo.numActiveNodes -= int64(len(selectedKeysByStatus[string(common.WaitingList)])) + stakingInfo.numActiveNodes -= int64(len(selectedKeysByStatus[string(common.EligibleList)])) + if sdp.flagStakingV4Enable.IsSet() { + stakingInfo.numAuctionNodes -= int64(len(selectedKeysByStatus[string(common.AuctionList)])) + } + stakingInfo.qualified = false } return keysToUnStake, mapOwnersKeys, nil @@ -377,38 +442,45 @@ func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.Shard return mapBLSKeyStatus, nil } -func (sdp *stakingDataProvider) selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) [][]byte { +func (sdp *stakingDataProvider) selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) ([][]byte, map[string][][]byte) { selectedKeys := make([][]byte, 0) newNodesList := sdp.getNewNodesList() + selectedKeysByStatus := make(map[string][][]byte) newKeys := sortedKeys[newNodesList] if len(newKeys) > 0 { + selectedKeysByStatus[newNodesList] = newKeys selectedKeys = append(selectedKeys, newKeys...) } if int64(len(selectedKeys)) >= numToSelect { - return selectedKeys[:numToSelect] + selectedKeysByStatus[newNodesList] = selectedKeysByStatus[newNodesList][:numToSelect] + return selectedKeys[:numToSelect], selectedKeysByStatus } waitingKeys := sortedKeys[string(common.WaitingList)] if len(waitingKeys) > 0 { + selectedKeysByStatus[string(common.WaitingList)] = waitingKeys selectedKeys = append(selectedKeys, waitingKeys...) } if int64(len(selectedKeys)) >= numToSelect { - return selectedKeys[:numToSelect] + selectedKeysByStatus[string(common.WaitingList)] = selectedKeysByStatus[string(common.WaitingList)][:numToSelect] + return selectedKeys[:numToSelect], selectedKeysByStatus } eligibleKeys := sortedKeys[string(common.EligibleList)] if len(eligibleKeys) > 0 { + selectedKeysByStatus[string(common.EligibleList)] = eligibleKeys selectedKeys = append(selectedKeys, eligibleKeys...) } if int64(len(selectedKeys)) >= numToSelect { - return selectedKeys[:numToSelect] + selectedKeysByStatus[string(common.EligibleList)] = selectedKeysByStatus[string(common.EligibleList)][:numToSelect] + return selectedKeys[:numToSelect], selectedKeysByStatus } - return selectedKeys + return selectedKeys, selectedKeysByStatus } func (sdp *stakingDataProvider) arrangeBlsKeysByStatus(mapBlsKeyStatus map[string]string, blsKeys [][]byte) map[string][][]byte { @@ -437,6 +509,11 @@ func (sdp *stakingDataProvider) getNewNodesList() string { return newNodesList } +// GetNumOfValidatorsInCurrentEpoch returns the number of validators(eligible + waiting) in current epoch +func (sdp *stakingDataProvider) GetNumOfValidatorsInCurrentEpoch() uint32 { + return sdp.numOfValidatorsInCurrEpoch +} + // EpochConfirmed is called whenever a new epoch is confirmed func (sdp *stakingDataProvider) EpochConfirmed(epoch uint32, _ uint64) { sdp.flagStakingV4Enable.SetValue(epoch >= sdp.stakingV4EnableEpoch) diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index e1dd08be909..a73c140c128 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -89,15 +89,15 @@ func TestStakingDataProvider_PrepareDataForBlsKeyGetBlsKeyOwnerErrorsShouldErr(t } sdp, _ := NewStakingDataProvider(args) - err := sdp.loadDataForBlsKey([]byte("bls key")) + err := sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.Equal(t, expectedErr, err) - err = sdp.loadDataForBlsKey([]byte("bls key")) + err = sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.NotNil(t, err) assert.True(t, strings.Contains(err.Error(), epochStart.ErrExecutingSystemScCode.Error())) assert.True(t, strings.Contains(err.Error(), vmcommon.UserError.String())) - err = sdp.loadDataForBlsKey([]byte("bls key")) + err = sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.NotNil(t, err) assert.True(t, strings.Contains(err.Error(), epochStart.ErrExecutingSystemScCode.Error())) assert.True(t, strings.Contains(err.Error(), "returned exactly one value: the owner address")) @@ -137,15 +137,15 @@ func TestStakingDataProvider_PrepareDataForBlsKeyLoadOwnerDataErrorsShouldErr(t } sdp, _ := NewStakingDataProvider(args) - err := sdp.loadDataForBlsKey([]byte("bls key")) + err := sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.Equal(t, expectedErr, err) - err = sdp.loadDataForBlsKey([]byte("bls key")) + err = sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.NotNil(t, err) assert.True(t, strings.Contains(err.Error(), epochStart.ErrExecutingSystemScCode.Error())) assert.True(t, strings.Contains(err.Error(), vmcommon.UserError.String())) - err = sdp.loadDataForBlsKey([]byte("bls key")) + err = sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.NotNil(t, err) assert.True(t, strings.Contains(err.Error(), epochStart.ErrExecutingSystemScCode.Error())) assert.True(t, strings.Contains(err.Error(), "getTotalStakedTopUpStakedBlsKeys function should have at least three values")) @@ -162,12 +162,12 @@ func TestStakingDataProvider_PrepareDataForBlsKeyFromSCShouldWork(t *testing.T) sdp := createStakingDataProviderWithMockArgs(t, owner, topUpVal, stakeVal, &numRunContractCalls) - err := sdp.loadDataForBlsKey([]byte("bls key")) + err := sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.Nil(t, err) assert.Equal(t, 2, numRunContractCalls) ownerData := sdp.GetFromCache(owner) require.NotNil(t, ownerData) - assert.Equal(t, topUpVal, ownerData.topUpValue) + assert.Equal(t, topUpVal, ownerData.totalTopUp) assert.Equal(t, 1, ownerData.numEligible) } @@ -182,16 +182,16 @@ func TestStakingDataProvider_PrepareDataForBlsKeyCachedResponseShouldWork(t *tes sdp := createStakingDataProviderWithMockArgs(t, owner, topUpVal, stakeVal, &numRunContractCalls) - err := sdp.loadDataForBlsKey([]byte("bls key")) + err := sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key")}) assert.Nil(t, err) - err = sdp.loadDataForBlsKey([]byte("bls key2")) + err = sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: []byte("bls key2")}) assert.Nil(t, err) assert.Equal(t, 3, numRunContractCalls) ownerData := sdp.GetFromCache(owner) require.NotNil(t, ownerData) - assert.Equal(t, topUpVal, ownerData.topUpValue) + assert.Equal(t, topUpVal, ownerData.totalTopUp) assert.Equal(t, 2, ownerData.numEligible) } @@ -203,11 +203,11 @@ func TestStakingDataProvider_PrepareDataForBlsKeyWithRealSystemVmShouldWork(t *t blsKey := []byte("bls key") sdp := createStakingDataProviderWithRealArgs(t, owner, blsKey, topUpVal) - err := sdp.loadDataForBlsKey(blsKey) + err := sdp.loadDataForBlsKey(&state.ValidatorInfo{PublicKey: blsKey}) assert.Nil(t, err) ownerData := sdp.GetFromCache(owner) require.NotNil(t, ownerData) - assert.Equal(t, topUpVal, ownerData.topUpValue) + assert.Equal(t, topUpVal, ownerData.totalTopUp) assert.Equal(t, 1, ownerData.numEligible) } @@ -435,13 +435,13 @@ func TestStakingDataProvider_GetNodeStakedTopUpShouldWork(t *testing.T) { sdp := createStakingDataProviderWithMockArgs(t, owner, topUpVal, stakeVal, &numRunContractCalls) expectedOwnerStats := &ownerStats{ - topUpPerNode: big.NewInt(37), + eligibleTopUpPerNode: big.NewInt(37), } sdp.SetInCache(owner, expectedOwnerStats) res, err := sdp.GetNodeStakedTopUp(owner) require.NoError(t, err) - require.Equal(t, expectedOwnerStats.topUpPerNode, res) + require.Equal(t, expectedOwnerStats.eligibleTopUpPerNode, res) } func TestStakingDataProvider_PrepareStakingDataForRewards(t *testing.T) { @@ -455,9 +455,9 @@ func TestStakingDataProvider_PrepareStakingDataForRewards(t *testing.T) { sdp := createStakingDataProviderWithMockArgs(t, owner, topUpVal, stakeVal, &numRunContractCalls) - keys := make(map[uint32][][]byte) - keys[0] = append(keys[0], []byte("owner")) - err := sdp.PrepareStakingData(keys) + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{PublicKey: owner, ShardId: 0}) + err := sdp.PrepareStakingData(validatorsMap) require.NoError(t, err) } @@ -472,7 +472,7 @@ func TestStakingDataProvider_FillValidatorInfo(t *testing.T) { sdp := createStakingDataProviderWithMockArgs(t, owner, topUpVal, stakeVal, &numRunContractCalls) - err := sdp.FillValidatorInfo([]byte("owner")) + err := sdp.FillValidatorInfo(&state.ValidatorInfo{PublicKey: []byte("bls key")}) require.NoError(t, err) } @@ -587,14 +587,14 @@ func updateCache(sdp *stakingDataProvider, ownerAddress []byte, blsKey []byte, l if owner == nil { owner = &ownerStats{ - numEligible: 0, - numStakedNodes: 0, - topUpValue: big.NewInt(0), - totalStaked: big.NewInt(0), - eligibleBaseStake: big.NewInt(0), - eligibleTopUpStake: big.NewInt(0), - topUpPerNode: big.NewInt(0), - blsKeys: nil, + numEligible: 0, + numStakedNodes: 0, + totalTopUp: big.NewInt(0), + totalStaked: big.NewInt(0), + eligibleBaseStake: big.NewInt(0), + eligibleTopUpStake: big.NewInt(0), + eligibleTopUpPerNode: big.NewInt(0), + blsKeys: nil, } } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 26cabf9000a..248cc1de0ea 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -141,12 +141,12 @@ func (s *systemSCProcessor) processWithNewFlags( return err } - unqualifiedOwners, err := s.unStakeNodesWithNotEnoughFundsWithStakingV4(validatorsInfoMap, header.GetEpoch()) + err = s.unStakeNodesWithNotEnoughFundsWithStakingV4(validatorsInfoMap, header.GetEpoch()) if err != nil { return err } - err = s.auctionListSelector.SelectNodesFromAuctionList(validatorsInfoMap, unqualifiedOwners, header.GetPrevRandSeed()) + err = s.auctionListSelector.SelectNodesFromAuctionList(validatorsInfoMap, header.GetPrevRandSeed()) if err != nil { return err } @@ -158,10 +158,10 @@ func (s *systemSCProcessor) processWithNewFlags( func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( validatorsInfoMap state.ShardValidatorsInfoMapHandler, epoch uint32, -) (map[string]struct{}, error) { +) error { nodesToUnStake, mapOwnersKeys, err := s.stakingDataProvider.ComputeUnQualifiedNodes(validatorsInfoMap) if err != nil { - return nil, err + return err } log.Debug("unStake nodes with not enough funds", "num", len(nodesToUnStake)) @@ -169,12 +169,12 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( log.Debug("unStake at end of epoch for node", "blsKey", blsKey) err = s.unStakeOneNode(blsKey, epoch) if err != nil { - return nil, err + return err } validatorInfo := validatorsInfoMap.GetValidator(blsKey) if validatorInfo == nil { - return nil, fmt.Errorf( + return fmt.Errorf( "%w in systemSCProcessor.unStakeNodesWithNotEnoughFundsWithStakingV4 because validator might be in additional queue after staking v4", epochStart.ErrNilValidatorInfo) } @@ -183,24 +183,11 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( validatorLeaving.SetList(string(common.LeavingList)) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { - return nil, err + return err } } - err = s.updateDelegationContracts(mapOwnersKeys) - if err != nil { - return nil, err - } - - return copyOwnerKeysInMap(mapOwnersKeys), nil -} - -func copyOwnerKeysInMap(mapOwnersKeys map[string][][]byte) map[string]struct{} { - ret := make(map[string]struct{}) - for owner := range mapOwnersKeys { - ret[owner] = struct{}{} - } - return ret + return s.updateDelegationContracts(mapOwnersKeys) } func (s *systemSCProcessor) updateToGovernanceV2() error { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index bc9f33b61e8..d852a6c3346 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1783,7 +1783,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa errProcessStakingData := errors.New("error processing staking data") args.StakingDataProvider = &mock.StakingDataProviderStub{ - PrepareStakingDataCalled: func(keys map[uint32][][]byte) error { + PrepareStakingDataCalled: func(validatorsMap state.ShardValidatorsInfoMapHandler) error { return errProcessStakingData }, } diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index eb570369e10..98e37700d6a 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -3,17 +3,18 @@ package mock import ( "math/big" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" ) // StakingDataProviderStub - type StakingDataProviderStub struct { CleanCalled func() - PrepareStakingDataCalled func(keys map[uint32][][]byte) error + PrepareStakingDataCalled func(validatorsMap state.ShardValidatorsInfoMapHandler) error GetTotalStakeEligibleNodesCalled func() *big.Int GetTotalTopUpStakeEligibleNodesCalled func() *big.Int GetNodeStakedTopUpCalled func(blsKey []byte) (*big.Int, error) - FillValidatorInfoCalled func(blsKey []byte) error + FillValidatorInfoCalled func(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwnerCalled func(blsKey []byte) (string, error) GetNumStakedNodesCalled func(owner []byte) (int64, error) @@ -21,9 +22,9 @@ type StakingDataProviderStub struct { } // FillValidatorInfo - -func (sdps *StakingDataProviderStub) FillValidatorInfo(blsKey []byte) error { +func (sdps *StakingDataProviderStub) FillValidatorInfo(validator state.ValidatorInfoHandler) error { if sdps.FillValidatorInfoCalled != nil { - return sdps.FillValidatorInfoCalled(blsKey) + return sdps.FillValidatorInfoCalled(validator) } return nil } @@ -77,9 +78,9 @@ func (sdps *StakingDataProviderStub) GetTotalTopUp(owner []byte) (*big.Int, erro } // PrepareStakingData - -func (sdps *StakingDataProviderStub) PrepareStakingData(keys map[uint32][][]byte) error { +func (sdps *StakingDataProviderStub) PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error { if sdps.PrepareStakingDataCalled != nil { - return sdps.PrepareStakingDataCalled(keys) + return sdps.PrepareStakingDataCalled(validatorsMap) } return nil } @@ -99,6 +100,15 @@ func (sdps *StakingDataProviderStub) GetBlsKeyOwner(blsKey []byte) (string, erro return "", nil } +// GetNumOfValidatorsInCurrentEpoch - +func (sdps *StakingDataProviderStub) GetNumOfValidatorsInCurrentEpoch() uint32 { + return 0 +} + +func (sdps *StakingDataProviderStub) GetOwnersStats() map[string]*epochStart.OwnerData { + return nil +} + // EpochConfirmed - func (sdps *StakingDataProviderStub) EpochConfirmed(uint32, uint64) { } diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index 816ee2e90f3..f9d52600314 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -6,7 +6,7 @@ import ( "strconv" "github.com/ElrondNetwork/elrond-go-core/display" - "github.com/ElrondNetwork/elrond-go/epochStart/metachain" + "github.com/ElrondNetwork/elrond-go/state" ) const ( @@ -37,10 +37,10 @@ func getShortPubKeysList(pubKeys [][]byte) [][]byte { return pubKeysToDisplay } -func (tmp *TestMetaProcessor) getAllNodeKeys() map[uint32][][]byte { +func (tmp *TestMetaProcessor) getAllNodeKeys() state.ShardValidatorsInfoMapHandler { rootHash, _ := tmp.ValidatorStatistics.RootHash() validatorsMap, _ := tmp.ValidatorStatistics.GetValidatorInfoForRootHash(rootHash) - return metachain.GetAllNodeKeys(validatorsMap) + return validatorsMap } func (tmp *TestMetaProcessor) displayConfig(config nodesConfig) { diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 4203eed4b76..b7c3566a132 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -536,3 +536,5 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { requireMapContains(t, currNodesConfig.waiting, owner3StakingQueue) requireSliceContains(t, currNodesConfig.auction, owner1StakingQueue) } + +// TODO: test unstake with 1 owner -> 1 bls key in auction => numStakedNodes = 0 From 0e54a398cf7c53392c005f1b20ac173aa8286b04 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 11:28:05 +0300 Subject: [PATCH 314/958] FIX: Broken tests --- epochStart/metachain/auctionListSelector.go | 68 +--------- .../metachain/auctionListSelector_test.go | 120 +----------------- 2 files changed, 5 insertions(+), 183 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 96df7c806e2..d34540e2caf 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -1,7 +1,6 @@ package metachain import ( - "encoding/hex" "fmt" "math" "math/big" @@ -143,17 +142,14 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return process.ErrNilRandSeed } - ownersData, auctionListSize, err := als.getAuctionData() - currNumOfValidators := als.stakingDataProvider.GetNumOfValidatorsInCurrentEpoch() - if err != nil { - return err - } + ownersData, auctionListSize := als.getAuctionData() if auctionListSize == 0 { log.Info("auctionListSelector.SelectNodesFromAuctionList: empty auction list; skip selection") return nil } currNodesConfig := als.nodesConfigProvider.GetCurrentNodesConfig() + currNumOfValidators := als.stakingDataProvider.GetNumOfValidatorsInCurrentEpoch() numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { @@ -198,7 +194,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } -func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, uint32, error) { +func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, uint32) { ownersData := make(map[string]*ownerAuctionData) numOfNodesInAuction := uint32(0) @@ -219,69 +215,13 @@ func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, } } - return ownersData, numOfNodesInAuction, nil + return ownersData, numOfNodesInAuction } func isInAuction(validator state.ValidatorInfoHandler) bool { return validator.GetList() == string(common.AuctionList) } -func (als *auctionListSelector) addOwnerData( - owner string, - validator state.ValidatorInfoHandler, - ownersData map[string]*ownerAuctionData, -) error { - ownerPubKey := []byte(owner) - validatorPubKey := validator.GetPublicKey() - stakedNodes, err := als.stakingDataProvider.GetNumStakedNodes(ownerPubKey) - if err != nil { - return fmt.Errorf("auctionListSelector.addOwnerData: error getting num staked nodes: %w, owner: %s, node: %s", - err, - hex.EncodeToString(ownerPubKey), - hex.EncodeToString(validatorPubKey), - ) - } - if stakedNodes == 0 { - return fmt.Errorf("auctionListSelector.addOwnerData error: %w, owner: %s, node: %s", - epochStart.ErrOwnerHasNoStakedNode, - hex.EncodeToString(ownerPubKey), - hex.EncodeToString(validatorPubKey), - ) - } - - totalTopUp, err := als.stakingDataProvider.GetTotalTopUp(ownerPubKey) - if err != nil { - return fmt.Errorf("auctionListSelector.addOwnerData: error getting total top up: %w, owner: %s, node: %s", - err, - hex.EncodeToString(ownerPubKey), - hex.EncodeToString(validatorPubKey), - ) - } - - data, exists := ownersData[owner] - if exists { - data.numAuctionNodes++ - data.numQualifiedAuctionNodes++ - data.numActiveNodes-- - data.auctionList = append(data.auctionList, validator) - } else { - stakedNodesBigInt := big.NewInt(stakedNodes) - topUpPerNode := big.NewInt(0).Div(totalTopUp, stakedNodesBigInt) - ownersData[owner] = &ownerAuctionData{ - numAuctionNodes: 1, - numQualifiedAuctionNodes: 1, - numActiveNodes: stakedNodes - 1, - numStakedNodes: stakedNodes, - totalTopUp: big.NewInt(0).SetBytes(totalTopUp.Bytes()), - topUpPerNode: topUpPerNode, - qualifiedTopUpPerNode: topUpPerNode, - auctionList: []state.ValidatorInfoHandler{validator}, - } - } - - return nil -} - // TODO: Move this in elrond-go-core func safeSub(a, b uint32) (uint32, error) { if a < b { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 9c20fb88b01..117b4019158 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -1,8 +1,6 @@ package metachain import ( - "encoding/hex" - "errors" "math/big" "strings" "testing" @@ -12,7 +10,6 @@ import ( "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" @@ -216,7 +213,7 @@ func TestGetAuctionConfig(t *testing.T) { }) } -func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { +func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { t.Parallel() t.Run("nil randomness, expect error", func(t *testing.T) { @@ -228,121 +225,6 @@ func TestAuctionListSelector_SelectNodesFromAuctionErrorCases(t *testing.T) { require.Equal(t, process.ErrNilRandSeed, err) }) - t.Run("cannot get bls key owner, expect error", func(t *testing.T) { - t.Parallel() - - stakedKey := []byte("pubKey0") - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(stakedKey, common.AuctionList, []byte("owner1"), 0)) - - args := createAuctionListSelectorArgs(nil) - errGetOwner := errors.New("error getting owner") - args.StakingDataProvider = &mock.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { - require.Equal(t, stakedKey, blsKey) - return "", errGetOwner - }, - } - - als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) - require.Equal(t, errGetOwner, err) - }) - - t.Run("cannot get owner's staked nodes, expect error", func(t *testing.T) { - t.Parallel() - - expectedOwner := []byte("owner") - stakedKey := []byte("pubKey0") - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo([]byte("pubKey0"), common.AuctionList, expectedOwner, 0)) - - args := createAuctionListSelectorArgs(nil) - errGetNumStakedNodes := errors.New("error getting number of staked nodes") - args.StakingDataProvider = &mock.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { - require.Equal(t, stakedKey, blsKey) - return string(expectedOwner), nil - }, - GetNumStakedNodesCalled: func(owner []byte) (int64, error) { - require.Equal(t, expectedOwner, owner) - return 1, errGetNumStakedNodes - }, - } - - als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), errGetNumStakedNodes.Error())) - require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) - require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) - }) - - t.Run("owner has one node in auction, but 0 staked nodes, expect error", func(t *testing.T) { - t.Parallel() - - expectedOwner := []byte("owner") - stakedKey := []byte("pubKey0") - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo([]byte("pubKey0"), common.AuctionList, expectedOwner, 0)) - - args := createAuctionListSelectorArgs(nil) - args.StakingDataProvider = &mock.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { - require.Equal(t, stakedKey, blsKey) - return string(expectedOwner), nil - }, - GetNumStakedNodesCalled: func(owner []byte) (int64, error) { - require.Equal(t, expectedOwner, owner) - return 0, nil - }, - } - - als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), epochStart.ErrOwnerHasNoStakedNode.Error())) - require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) - require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) - }) - - t.Run("cannot get owner's total top up, expect error", func(t *testing.T) { - t.Parallel() - - expectedOwner := []byte("owner") - stakedKey := []byte("pubKey0") - validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo([]byte("pubKey0"), common.AuctionList, expectedOwner, 0)) - - args := createAuctionListSelectorArgs(nil) - errGetTotalTopUp := errors.New("error getting total top up") - args.StakingDataProvider = &mock.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(blsKey []byte) (string, error) { - require.Equal(t, stakedKey, blsKey) - return string(expectedOwner), nil - }, - GetNumStakedNodesCalled: func(owner []byte) (int64, error) { - require.Equal(t, expectedOwner, owner) - return 1, nil - }, - GetTotalTopUpCalled: func(owner []byte) (*big.Int, error) { - require.Equal(t, expectedOwner, owner) - return nil, errGetTotalTopUp - }, - } - - als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(validatorsInfo, []byte("rand")) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), errGetTotalTopUp.Error())) - require.True(t, strings.Contains(err.Error(), hex.EncodeToString(expectedOwner))) - require.True(t, strings.Contains(err.Error(), hex.EncodeToString(stakedKey))) - }) -} - -func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { - t.Parallel() - t.Run("empty auction list", func(t *testing.T) { t.Parallel() From 2aa03c8e90b505cc635034c375a439d8bbf89bb5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 12:27:40 +0300 Subject: [PATCH 315/958] FIX: Refactor 1 --- epochStart/dtos.go | 18 +++ epochStart/interface.go | 13 +- epochStart/metachain/auctionListSelector.go | 4 +- .../metachain/auctionListSelector_test.go | 1 + epochStart/metachain/stakingDataProvider.go | 150 +++++++++++------- epochStart/mock/stakingDataProviderStub.go | 12 +- 6 files changed, 115 insertions(+), 83 deletions(-) create mode 100644 epochStart/dtos.go diff --git a/epochStart/dtos.go b/epochStart/dtos.go new file mode 100644 index 00000000000..0fe5bd92c22 --- /dev/null +++ b/epochStart/dtos.go @@ -0,0 +1,18 @@ +package epochStart + +import ( + "math/big" + + "github.com/ElrondNetwork/elrond-go/state" +) + +// OwnerData is a struct containing relevant information about owner's nodes data +type OwnerData struct { + NumStakedNodes int64 + NumActiveNodes int64 + NumAuctionNodes int64 + TotalTopUp *big.Int + TopUpPerNode *big.Int + AuctionList []state.ValidatorInfoHandler + Qualified bool +} diff --git a/epochStart/interface.go b/epochStart/interface.go index 56e744e4db6..70ac7cf31f2 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -146,29 +146,18 @@ type TransactionCacher interface { IsInterfaceNil() bool } -type OwnerData struct { - NumActiveNodes int64 - NumAuctionNodes int64 - NumStakedNodes int64 - TotalTopUp *big.Int - TopUpPerNode *big.Int - AuctionList []state.ValidatorInfoHandler - Qualified bool -} - // StakingDataProvider is able to provide staking data from the system smart contracts type StakingDataProvider interface { GetTotalStakeEligibleNodes() *big.Int GetTotalTopUpStakeEligibleNodes() *big.Int GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) - GetNumStakedNodes(owner []byte) (int64, error) GetTotalTopUp(owner []byte) (*big.Int, error) PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error FillValidatorInfo(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwner(blsKey []byte) (string, error) GetNumOfValidatorsInCurrentEpoch() uint32 - GetOwnersStats() map[string]*OwnerData + GetOwnersData() map[string]*OwnerData Clean() EpochConfirmed(epoch uint32, timestamp uint64) IsInterfaceNil() bool diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index d34540e2caf..7d0006c6361 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -16,10 +16,10 @@ import ( ) type ownerAuctionData struct { + numStakedNodes int64 numActiveNodes int64 numAuctionNodes int64 numQualifiedAuctionNodes int64 - numStakedNodes int64 totalTopUp *big.Int topUpPerNode *big.Int qualifiedTopUpPerNode *big.Int @@ -198,7 +198,7 @@ func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, ownersData := make(map[string]*ownerAuctionData) numOfNodesInAuction := uint32(0) - for owner, ownerData := range als.stakingDataProvider.GetOwnersStats() { + for owner, ownerData := range als.stakingDataProvider.GetOwnersData() { if ownerData.Qualified && ownerData.NumAuctionNodes > 0 { ownersData[owner] = &ownerAuctionData{ numActiveNodes: ownerData.NumActiveNodes, diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 117b4019158..24228245d37 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -47,6 +47,7 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + argsSystemSC.StakingDataProvider.EpochConfirmed(stakingV4EnableEpoch, 0) argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider return AuctionListSelectorArgs{ ShardCoordinator: argsSystemSC.ShardCoordinator, diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 1d889216f69..9d2081ba597 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -12,6 +12,7 @@ import ( "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" + "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -127,16 +128,6 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return ownerInfo.eligibleTopUpPerNode, nil } -// GetNumStakedNodes returns the total number of owner's staked nodes -func (sdp *stakingDataProvider) GetNumStakedNodes(owner []byte) (int64, error) { - ownerInfo, ok := sdp.cache[string(owner)] - if !ok { - return 0, epochStart.ErrOwnerDoesntHaveNodesInEpoch - } - - return ownerInfo.numStakedNodes, nil -} - // GetTotalTopUp returns owner's total top up func (sdp *stakingDataProvider) GetTotalTopUp(owner []byte) (*big.Int, error) { ownerInfo, ok := sdp.cache[string(owner)] @@ -210,12 +201,16 @@ func (sdp *stakingDataProvider) getAndFillOwnerStats(validator state.ValidatorIn return nil, err } - ownerData, err := sdp.addOwnerData(owner, validator) + ownerData, err := sdp.fillOwnerData(owner, validator) if err != nil { log.Debug("error fill owner stats", "step", "get owner data", "key", hex.EncodeToString(blsKey), "owner", hex.EncodeToString([]byte(owner)), "error", err) return nil, err } + if isValidator(validator) { + sdp.numOfValidatorsInCurrEpoch++ + } + return ownerData, nil } @@ -239,8 +234,8 @@ func (sdp *stakingDataProvider) loadDataForBlsKey(validator state.ValidatorInfoH return nil } -// GetOwnersStats returns all owner stats -func (sdp *stakingDataProvider) GetOwnersStats() map[string]*epochStart.OwnerData { +// GetOwnersData returns all owner stats +func (sdp *stakingDataProvider) GetOwnersData() map[string]*epochStart.OwnerData { sdp.mutStakingData.RLock() defer sdp.mutStakingData.RUnlock() @@ -288,63 +283,102 @@ func (sdp *stakingDataProvider) GetBlsKeyOwner(blsKey []byte) (string, error) { return string(data[0]), nil } -func (sdp *stakingDataProvider) addOwnerData(owner string, validator state.ValidatorInfoHandler) (*ownerStats, error) { +func (sdp *stakingDataProvider) fillOwnerData(owner string, validator state.ValidatorInfoHandler) (*ownerStats, error) { + var err error ownerData, exists := sdp.cache[owner] - validatorInAuction := isInAuction(validator) if exists { - if validatorInAuction { - ownerData.numAuctionNodes++ - ownerData.numActiveNodes-- - ownerData.auctionList = append(ownerData.auctionList, validator.ShallowClone()) - } + updateOwnerData(ownerData, validator) } else { - topUpValue, totalStakedValue, numStakedWaiting, blsKeys, err := sdp.getOwnerInfoFromSC(owner) + ownerData, err = sdp.getAndFillOwnerDataFromSC(owner, validator) if err != nil { return nil, err } + sdp.cache[owner] = ownerData + } - topUpPerNode := big.NewInt(0) - if numStakedWaiting.Int64() == 0 { - log.Debug("stakingDataProvider.addOwnerData: owner has no staked node %w, owner: %s, node: %s", - epochStart.ErrOwnerHasNoStakedNode, - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(validator.GetPublicKey()), - ) - } else { - topUpPerNode = big.NewInt(0).Div(topUpValue, numStakedWaiting) - } - - ownerData = &ownerStats{ - numEligible: 0, - numStakedNodes: numStakedWaiting.Int64(), - numActiveNodes: numStakedWaiting.Int64(), - totalTopUp: topUpValue, - topUpPerNode: topUpPerNode, - totalStaked: totalStakedValue, - eligibleBaseStake: big.NewInt(0).Set(sdp.minNodePrice), - eligibleTopUpStake: big.NewInt(0), - eligibleTopUpPerNode: big.NewInt(0), - qualified: true, - } - if validatorInAuction { - ownerData.numActiveNodes -= 1 - ownerData.numAuctionNodes = 1 - ownerData.auctionList = []state.ValidatorInfoHandler{validator} - } + return ownerData, nil +} - ownerData.blsKeys = make([][]byte, len(blsKeys)) - copy(ownerData.blsKeys, blsKeys) +func updateOwnerData(ownerData *ownerStats, validator state.ValidatorInfoHandler) { + if isInAuction(validator) { + ownerData.numAuctionNodes++ + ownerData.numActiveNodes-- + ownerData.auctionList = append(ownerData.auctionList, validator.ShallowClone()) + } +} - sdp.cache[owner] = ownerData +func (sdp *stakingDataProvider) getAndFillOwnerDataFromSC(owner string, validator state.ValidatorInfoHandler) (*ownerStats, error) { + topUpValue, totalStakedValue, numStakedWaiting, blsKeys, err := sdp.getOwnerInfoFromSC(owner) + if err != nil { + return nil, err } - if isValidator(validator) { - sdp.numOfValidatorsInCurrEpoch++ + topUpPerNode := big.NewInt(0) + numStakedNodes := numStakedWaiting.Int64() + if numStakedNodes == 0 { + log.Debug("stakingDataProvider.fillOwnerData: owner has no staked node %w, owner: %s, node: %s", + epochStart.ErrOwnerHasNoStakedNode, + hex.EncodeToString([]byte(owner)), + hex.EncodeToString(validator.GetPublicKey()), + ) + } else { + topUpPerNode = big.NewInt(0).Div(topUpValue, numStakedWaiting) + } + + ownerData := &ownerStats{ + numEligible: 0, + numStakedNodes: numStakedNodes, + numActiveNodes: numStakedNodes, + totalTopUp: topUpValue, + topUpPerNode: topUpPerNode, + totalStaked: totalStakedValue, + eligibleBaseStake: big.NewInt(0).Set(sdp.minNodePrice), + eligibleTopUpStake: big.NewInt(0), + eligibleTopUpPerNode: big.NewInt(0), + qualified: true, + } + err = sdp.checkAndFillOwnerValidatorAuctionData([]byte(owner), ownerData, validator) + if err != nil { + return nil, err } + ownerData.blsKeys = make([][]byte, len(blsKeys)) + copy(ownerData.blsKeys, blsKeys) + return ownerData, nil } +func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( + ownerPubKey []byte, + ownerData *ownerStats, + validator state.ValidatorInfoHandler, +) error { + validatorInAuction := isInAuction(validator) + if !validatorInAuction { + return nil + } + if validatorInAuction && ownerData.numStakedNodes == 0 { + return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", + epochStart.ErrOwnerHasNoStakedNode, + hex.EncodeToString(ownerPubKey), + hex.EncodeToString(validator.GetPublicKey()), + ) + } + if validatorInAuction && !sdp.flagStakingV4Enable.IsSet() { + return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", + nodesCoordinator.ErrReceivedAuctionValidatorsBeforeStakingV4, + hex.EncodeToString(ownerPubKey), + hex.EncodeToString(validator.GetPublicKey()), + ) + } + + ownerData.numActiveNodes -= 1 + ownerData.numAuctionNodes = 1 + ownerData.auctionList = []state.ValidatorInfoHandler{validator} + + return nil +} + func (sdp *stakingDataProvider) getOwnerInfoFromSC(owner string) (*big.Int, *big.Int, *big.Int, [][]byte, error) { ownerAddressBytes := []byte(owner) @@ -412,11 +446,6 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha sdp.numOfValidatorsInCurrEpoch -= uint32(len(selectedKeysByStatus[string(common.WaitingList)])) sdp.numOfValidatorsInCurrEpoch -= uint32(len(selectedKeysByStatus[string(common.EligibleList)])) - stakingInfo.numActiveNodes -= int64(len(selectedKeysByStatus[string(common.WaitingList)])) - stakingInfo.numActiveNodes -= int64(len(selectedKeysByStatus[string(common.EligibleList)])) - if sdp.flagStakingV4Enable.IsSet() { - stakingInfo.numAuctionNodes -= int64(len(selectedKeysByStatus[string(common.AuctionList)])) - } stakingInfo.qualified = false } @@ -511,6 +540,9 @@ func (sdp *stakingDataProvider) getNewNodesList() string { // GetNumOfValidatorsInCurrentEpoch returns the number of validators(eligible + waiting) in current epoch func (sdp *stakingDataProvider) GetNumOfValidatorsInCurrentEpoch() uint32 { + sdp.mutStakingData.RLock() + defer sdp.mutStakingData.RUnlock() + return sdp.numOfValidatorsInCurrEpoch } diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 98e37700d6a..5ae7407284b 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -17,7 +17,6 @@ type StakingDataProviderStub struct { FillValidatorInfoCalled func(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwnerCalled func(blsKey []byte) (string, error) - GetNumStakedNodesCalled func(owner []byte) (int64, error) GetTotalTopUpCalled func(owner []byte) (*big.Int, error) } @@ -61,14 +60,6 @@ func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int return big.NewInt(0), nil } -// GetNumStakedNodes - -func (sdps *StakingDataProviderStub) GetNumStakedNodes(owner []byte) (int64, error) { - if sdps.GetNumStakedNodesCalled != nil { - return sdps.GetNumStakedNodesCalled(owner) - } - return 0, nil -} - // GetTotalTopUp - func (sdps *StakingDataProviderStub) GetTotalTopUp(owner []byte) (*big.Int, error) { if sdps.GetTotalTopUpCalled != nil { @@ -105,7 +96,8 @@ func (sdps *StakingDataProviderStub) GetNumOfValidatorsInCurrentEpoch() uint32 { return 0 } -func (sdps *StakingDataProviderStub) GetOwnersStats() map[string]*epochStart.OwnerData { +// GetOwnersData - +func (sdps *StakingDataProviderStub) GetOwnersData() map[string]*epochStart.OwnerData { return nil } From cc06cebeaab606fbfd41c13fd49dbff1ae5a7f87 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 13:26:40 +0300 Subject: [PATCH 316/958] FIX: Refactor 2 --- epochStart/interface.go | 1 - epochStart/metachain/stakingDataProvider.go | 37 ++++++--------------- epochStart/metachain/systemSCs_test.go | 4 +-- epochStart/mock/stakingDataProviderStub.go | 9 ----- 4 files changed, 12 insertions(+), 39 deletions(-) diff --git a/epochStart/interface.go b/epochStart/interface.go index 70ac7cf31f2..6c67b5feaa0 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -151,7 +151,6 @@ type StakingDataProvider interface { GetTotalStakeEligibleNodes() *big.Int GetTotalTopUpStakeEligibleNodes() *big.Int GetNodeStakedTopUp(blsKey []byte) (*big.Int, error) - GetTotalTopUp(owner []byte) (*big.Int, error) PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error FillValidatorInfo(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 9d2081ba597..cac02a7ff2b 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -128,16 +128,6 @@ func (sdp *stakingDataProvider) GetNodeStakedTopUp(blsKey []byte) (*big.Int, err return ownerInfo.eligibleTopUpPerNode, nil } -// GetTotalTopUp returns owner's total top up -func (sdp *stakingDataProvider) GetTotalTopUp(owner []byte) (*big.Int, error) { - ownerInfo, ok := sdp.cache[string(owner)] - if !ok { - return nil, epochStart.ErrOwnerDoesntHaveNodesInEpoch - } - - return ownerInfo.totalTopUp, nil -} - // PrepareStakingData prepares the staking data for the given map of node keys per shard func (sdp *stakingDataProvider) PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error { sdp.Clean() @@ -433,7 +423,7 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha sortedKeys := sdp.arrangeBlsKeysByStatus(mapBLSKeyStatus, stakingInfo.blsKeys) numKeysToUnStake := stakingInfo.numStakedNodes - maxQualified.Int64() - selectedKeys, selectedKeysByStatus := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) + selectedKeys, removedValidators := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) if len(selectedKeys) == 0 { continue } @@ -442,11 +432,9 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha mapOwnersKeys[ownerAddress] = make([][]byte, len(selectedKeys)) copy(mapOwnersKeys[ownerAddress], selectedKeys) - stakingInfo.numStakedNodes -= int64(len(selectedKeys)) - sdp.numOfValidatorsInCurrEpoch -= uint32(len(selectedKeysByStatus[string(common.WaitingList)])) - sdp.numOfValidatorsInCurrEpoch -= uint32(len(selectedKeysByStatus[string(common.EligibleList)])) stakingInfo.qualified = false + sdp.numOfValidatorsInCurrEpoch -= uint32(removedValidators) } return keysToUnStake, mapOwnersKeys, nil @@ -471,45 +459,42 @@ func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.Shard return mapBLSKeyStatus, nil } -func (sdp *stakingDataProvider) selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) ([][]byte, map[string][][]byte) { +func (sdp *stakingDataProvider) selectKeysToUnStake(sortedKeys map[string][][]byte, numToSelect int64) ([][]byte, int) { selectedKeys := make([][]byte, 0) newNodesList := sdp.getNewNodesList() - selectedKeysByStatus := make(map[string][][]byte) newKeys := sortedKeys[newNodesList] if len(newKeys) > 0 { - selectedKeysByStatus[newNodesList] = newKeys selectedKeys = append(selectedKeys, newKeys...) } if int64(len(selectedKeys)) >= numToSelect { - selectedKeysByStatus[newNodesList] = selectedKeysByStatus[newNodesList][:numToSelect] - return selectedKeys[:numToSelect], selectedKeysByStatus + return selectedKeys[:numToSelect], 0 } waitingKeys := sortedKeys[string(common.WaitingList)] if len(waitingKeys) > 0 { - selectedKeysByStatus[string(common.WaitingList)] = waitingKeys selectedKeys = append(selectedKeys, waitingKeys...) } if int64(len(selectedKeys)) >= numToSelect { - selectedKeysByStatus[string(common.WaitingList)] = selectedKeysByStatus[string(common.WaitingList)][:numToSelect] - return selectedKeys[:numToSelect], selectedKeysByStatus + overFlowKeys := len(selectedKeys) - int(numToSelect) + removedWaiting := len(waitingKeys) - overFlowKeys + return selectedKeys[:numToSelect], removedWaiting } eligibleKeys := sortedKeys[string(common.EligibleList)] if len(eligibleKeys) > 0 { - selectedKeysByStatus[string(common.EligibleList)] = eligibleKeys selectedKeys = append(selectedKeys, eligibleKeys...) } if int64(len(selectedKeys)) >= numToSelect { - selectedKeysByStatus[string(common.EligibleList)] = selectedKeysByStatus[string(common.EligibleList)][:numToSelect] - return selectedKeys[:numToSelect], selectedKeysByStatus + overFlowKeys := len(selectedKeys) - int(numToSelect) + removedEligible := len(eligibleKeys) - overFlowKeys + return selectedKeys[:numToSelect], removedEligible + len(waitingKeys) } - return selectedKeys, selectedKeysByStatus + return selectedKeys, len(eligibleKeys) + len(waitingKeys) } func (sdp *stakingDataProvider) arrangeBlsKeysByStatus(mapBlsKeyStatus map[string]string, blsKeys [][]byte) map[string][][]byte { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index d852a6c3346..5470752800b 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2061,9 +2061,7 @@ func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, staked owner, err := s.GetBlsKeyOwner(pubKey) require.Nil(t, err) - totalTopUp, err := s.GetTotalTopUp([]byte(owner)) - require.Nil(t, err) - + totalTopUp := s.GetOwnersData()[owner].TotalTopUp topUpPerNode := big.NewInt(0).Div(totalTopUp, big.NewInt(int64(len(stakedPubKeys)))) require.Equal(t, topUp, topUpPerNode) } diff --git a/epochStart/mock/stakingDataProviderStub.go b/epochStart/mock/stakingDataProviderStub.go index 5ae7407284b..e224d5b38e6 100644 --- a/epochStart/mock/stakingDataProviderStub.go +++ b/epochStart/mock/stakingDataProviderStub.go @@ -17,7 +17,6 @@ type StakingDataProviderStub struct { FillValidatorInfoCalled func(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwnerCalled func(blsKey []byte) (string, error) - GetTotalTopUpCalled func(owner []byte) (*big.Int, error) } // FillValidatorInfo - @@ -60,14 +59,6 @@ func (sdps *StakingDataProviderStub) GetNodeStakedTopUp(blsKey []byte) (*big.Int return big.NewInt(0), nil } -// GetTotalTopUp - -func (sdps *StakingDataProviderStub) GetTotalTopUp(owner []byte) (*big.Int, error) { - if sdps.GetTotalTopUpCalled != nil { - return sdps.GetTotalTopUpCalled(owner) - } - return big.NewInt(0), nil -} - // PrepareStakingData - func (sdps *StakingDataProviderStub) PrepareStakingData(validatorsMap state.ShardValidatorsInfoMapHandler) error { if sdps.PrepareStakingDataCalled != nil { From 50ade617da906ddab3812805a722590ff493a509 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 14:23:11 +0300 Subject: [PATCH 317/958] FEAT: Unit tests --- epochStart/errors.go | 3 + epochStart/metachain/stakingDataProvider.go | 3 +- .../metachain/stakingDataProvider_test.go | 132 ++++++++++++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index caa22f7daac..4831817574a 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -340,3 +340,6 @@ var ErrOwnerHasNoStakedNode = errors.New("owner has no staked node") // ErrUint32SubtractionOverflow signals uint32 subtraction overflowed var ErrUint32SubtractionOverflow = errors.New("uint32 subtraction overflowed") + +// ErrReceivedAuctionValidatorsBeforeStakingV4 signals that an auction node has been provided before enabling staking v4 +var ErrReceivedAuctionValidatorsBeforeStakingV4 = errors.New("auction node has been provided before enabling staking v4") diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index cac02a7ff2b..60d1bbb0519 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -12,7 +12,6 @@ import ( "github.com/ElrondNetwork/elrond-go/common" "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" "github.com/ElrondNetwork/elrond-go/state" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" @@ -356,7 +355,7 @@ func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( } if validatorInAuction && !sdp.flagStakingV4Enable.IsSet() { return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", - nodesCoordinator.ErrReceivedAuctionValidatorsBeforeStakingV4, + epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4, hex.EncodeToString(ownerPubKey), hex.EncodeToString(validator.GetPublicKey()), ) diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index a73c140c128..1b496ab44c6 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -476,6 +476,138 @@ func TestStakingDataProvider_FillValidatorInfo(t *testing.T) { require.NoError(t, err) } +func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { + t.Parallel() + + t.Run("validator not in auction, expect no error, no owner data update", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + + ownerData := &ownerStats{} + err := sdp.checkAndFillOwnerValidatorAuctionData([]byte("owner"), ownerData, &state.ValidatorInfo{List: string(common.NewList)}) + require.Nil(t, err) + require.Equal(t, &ownerStats{}, ownerData) + }) + + t.Run("validator in auction, but no staked node, expect error", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + + owner := []byte("owner") + ownerData := &ownerStats{numStakedNodes: 0} + validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} + err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), epochStart.ErrOwnerHasNoStakedNode.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(owner))) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(validator.PublicKey))) + require.Equal(t, &ownerStats{numStakedNodes: 0}, ownerData) + }) + + t.Run("validator in auction, staking v4 not enabled yet, expect error", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + + owner := []byte("owner") + ownerData := &ownerStats{numStakedNodes: 1} + validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} + err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4.Error())) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(owner))) + require.True(t, strings.Contains(err.Error(), hex.EncodeToString(validator.PublicKey))) + require.Equal(t, &ownerStats{numStakedNodes: 1}, ownerData) + }) + + t.Run("should update owner's data", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + owner := []byte("owner") + ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3, numAuctionNodes: 0} + validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} + err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) + require.Nil(t, err) + require.Equal(t, &ownerStats{ + numStakedNodes: 3, + numActiveNodes: 2, + numAuctionNodes: 1, + auctionList: []state.ValidatorInfoHandler{validator}, + }, ownerData) + }) +} + +func TestSelectKeysToUnStake(t *testing.T) { + t.Parallel() + + t.Run("no validator removed", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + sortedKeys := map[string][][]byte{ + string(common.AuctionList): {[]byte("pk0")}, + } + unStakedKeys, removedValidators := sdp.selectKeysToUnStake(sortedKeys, 2) + require.Equal(t, [][]byte{[]byte("pk0")}, unStakedKeys) + require.Equal(t, 0, removedValidators) + }) + + t.Run("overflow from waiting", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + sortedKeys := map[string][][]byte{ + string(common.AuctionList): {[]byte("pk0")}, + string(common.EligibleList): {[]byte("pk2")}, + string(common.WaitingList): {[]byte("pk3"), []byte("pk4"), []byte("pk5")}, + } + unStakedKeys, removedValidators := sdp.selectKeysToUnStake(sortedKeys, 2) + require.Equal(t, [][]byte{[]byte("pk0"), []byte("pk3")}, unStakedKeys) + require.Equal(t, 1, removedValidators) + }) + + t.Run("overflow from eligible", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + sortedKeys := map[string][][]byte{ + string(common.AuctionList): {[]byte("pk0")}, + string(common.EligibleList): {[]byte("pk1"), []byte("pk2")}, + string(common.WaitingList): {[]byte("pk4"), []byte("pk5")}, + } + unStakedKeys, removedValidators := sdp.selectKeysToUnStake(sortedKeys, 4) + require.Equal(t, [][]byte{[]byte("pk0"), []byte("pk4"), []byte("pk5"), []byte("pk1")}, unStakedKeys) + require.Equal(t, 3, removedValidators) + }) + + t.Run("no overflow", func(t *testing.T) { + t.Parallel() + args := createStakingDataProviderArgs() + sdp, _ := NewStakingDataProvider(args) + sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + + sortedKeys := map[string][][]byte{ + string(common.AuctionList): {[]byte("pk0")}, + string(common.EligibleList): {[]byte("pk1")}, + string(common.WaitingList): {[]byte("pk2")}, + } + unStakedKeys, removedValidators := sdp.selectKeysToUnStake(sortedKeys, 3) + require.Equal(t, [][]byte{[]byte("pk0"), []byte("pk2"), []byte("pk1")}, unStakedKeys) + require.Equal(t, 2, removedValidators) + }) +} + func createStakingDataProviderWithMockArgs( t *testing.T, owner []byte, From 0e74cb55c233c3a5b7a25af4c075c20e74212799 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 14:35:17 +0300 Subject: [PATCH 318/958] FIX: Small fixes --- epochStart/metachain/stakingDataProvider.go | 8 ++++---- epochStart/metachain/stakingDataProvider_test.go | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 60d1bbb0519..55b69ccac1d 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -305,10 +305,10 @@ func (sdp *stakingDataProvider) getAndFillOwnerDataFromSC(owner string, validato topUpPerNode := big.NewInt(0) numStakedNodes := numStakedWaiting.Int64() if numStakedNodes == 0 { - log.Debug("stakingDataProvider.fillOwnerData: owner has no staked node %w, owner: %s, node: %s", - epochStart.ErrOwnerHasNoStakedNode, - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(validator.GetPublicKey()), + log.Debug("stakingDataProvider.fillOwnerData", + "message", epochStart.ErrOwnerHasNoStakedNode, + "owner", hex.EncodeToString([]byte(owner)), + "validator", hex.EncodeToString(validator.GetPublicKey()), ) } else { topUpPerNode = big.NewInt(0).Div(topUpValue, numStakedWaiting) diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 1b496ab44c6..ce109110ad3 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -498,6 +498,7 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { owner := []byte("owner") ownerData := &ownerStats{numStakedNodes: 0} validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} + err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) require.Error(t, err) require.True(t, strings.Contains(err.Error(), epochStart.ErrOwnerHasNoStakedNode.Error())) @@ -514,6 +515,7 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { owner := []byte("owner") ownerData := &ownerStats{numStakedNodes: 1} validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} + err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) require.Error(t, err) require.True(t, strings.Contains(err.Error(), epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4.Error())) @@ -531,6 +533,7 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { owner := []byte("owner") ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3, numAuctionNodes: 0} validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} + err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) require.Nil(t, err) require.Equal(t, &ownerStats{ From 5e24f071884d63a3058cf68c20c70c6008c68435 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 3 Jun 2022 15:34:07 +0300 Subject: [PATCH 319/958] FIX: Review findings --- epochStart/metachain/auctionListSelector.go | 50 ++++++++++++--------- epochStart/metachain/legacySystemSCs.go | 2 +- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index f9bcfdbdde2..03f79ff436f 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -332,29 +332,8 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) previousConfig := copyOwnersData(ownersData) for ; topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, als.softAuctionConfig.step) { - numNodesQualifyingForTopUp := int64(0) previousConfig = copyOwnersData(ownersData) - - for ownerPubKey, owner := range ownersData { - activeNodes := big.NewInt(owner.numActiveNodes) - topUpActiveNodes := big.NewInt(0).Mul(topUp, activeNodes) - validatorTopUpForAuction := big.NewInt(0).Sub(owner.totalTopUp, topUpActiveNodes) - if validatorTopUpForAuction.Cmp(topUp) < 0 { - delete(ownersData, ownerPubKey) - continue - } - - qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp).Int64() - if qualifiedNodes > owner.numAuctionNodes { - numNodesQualifyingForTopUp += owner.numAuctionNodes - } else { - numNodesQualifyingForTopUp += qualifiedNodes - owner.numQualifiedAuctionNodes = qualifiedNodes - - ownerRemainingNodes := big.NewInt(owner.numActiveNodes + owner.numQualifiedAuctionNodes) - owner.qualifiedTopUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) - } - } + numNodesQualifyingForTopUp := calcNodesConfig(ownersData, topUp) if numNodesQualifyingForTopUp < int64(numAvailableSlots) { break @@ -407,6 +386,33 @@ func copyOwnersData(ownersData map[string]*ownerData) map[string]*ownerData { return ret } +func calcNodesConfig(ownersData map[string]*ownerData, topUp *big.Int) int64 { + numNodesQualifyingForTopUp := int64(0) + + for ownerPubKey, owner := range ownersData { + activeNodes := big.NewInt(owner.numActiveNodes) + topUpActiveNodes := big.NewInt(0).Mul(topUp, activeNodes) + validatorTopUpForAuction := big.NewInt(0).Sub(owner.totalTopUp, topUpActiveNodes) + if validatorTopUpForAuction.Cmp(topUp) < 0 { + delete(ownersData, ownerPubKey) + continue + } + + qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp).Int64() + if qualifiedNodes > owner.numAuctionNodes { + numNodesQualifyingForTopUp += owner.numAuctionNodes + } else { + numNodesQualifyingForTopUp += qualifiedNodes + owner.numQualifiedAuctionNodes = qualifiedNodes + + ownerRemainingNodes := big.NewInt(owner.numActiveNodes + owner.numQualifiedAuctionNodes) + owner.qualifiedTopUpPerNode = big.NewInt(0).Div(owner.totalTopUp, ownerRemainingNodes) + } + } + + return numNodesQualifyingForTopUp +} + func markAuctionNodesAsSelected( selectedNodes []state.ValidatorInfoHandler, validatorsInfoMap state.ShardValidatorsInfoMapHandler, diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 34daa27a50c..8df285257ec 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -1370,7 +1370,7 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch <= s.stakingV4InitEnableEpoch) - log.Debug("legacySystemSC: stakingV2", "enabled", epoch >= s.stakingV2EnableEpoch) + log.Debug("legacySystemSC: stakingV2", "enabled", s.flagStakingV2Enabled.IsSet()) log.Debug("legacySystemSC: change of maximum number of nodes and/or shuffling percentage", "enabled", s.flagChangeMaxNodesEnabled.IsSet(), "epoch", epoch, From 9d99f23fda4446fd85e29a5a0901298aaf8aee86 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 11:06:57 +0300 Subject: [PATCH 320/958] FIX: Merge conflict --- epochStart/metachain/auctionListSelector.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 50cf40471af..99b5d346d1f 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -309,7 +309,7 @@ func copyOwnersData(ownersData map[string]*ownerAuctionData) map[string]*ownerAu return ret } -func calcNodesConfig(ownersData map[string]*ownerData, topUp *big.Int) int64 { +func calcNodesConfig(ownersData map[string]*ownerAuctionData, topUp *big.Int) int64 { numNodesQualifyingForTopUp := int64(0) for ownerPubKey, owner := range ownersData { From ae31ecddd1551f83f608d4be54f2227bed4c8238 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 13:01:38 +0300 Subject: [PATCH 321/958] FEAT: Finish TODO --- integrationTests/vm/staking/stakingV4_test.go | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index ce94299d7c0..f1ef9920b99 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -554,7 +554,6 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { requireSliceContains(t, currNodesConfig.auction, newNodes0[newOwner0].BLSKeys) } -// TODO: test unstake with 1 owner -> 1 bls key in auction => numStakedNodes = 0 func TestStakingV4_UnStakeNodes(t *testing.T) { pubKeys := generateAddresses(0, 20) @@ -724,4 +723,26 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { requireMapContains(t, currNodesConfig.leaving, [][]byte{owner2Stats.EligibleBlsKeys[0][0]}) require.Empty(t, currNodesConfig.new) require.Empty(t, currNodesConfig.queue) + + // 4.1 NewOwner stakes 1 node, should be sent to auction + newOwner := "newOwner1" + newNode := map[string]*NodesRegisterData{ + newOwner: { + BLSKeys: [][]byte{generateAddress(444)}, + TotalStake: big.NewInt(2 * nodePrice), + }, + } + node.ProcessStake(t, newNode) + currNodesConfig = node.NodesConfig + requireSliceContains(t, currNodesConfig.auction, newNode[newOwner].BLSKeys) + + // 4.2 NewOwner unStakes his node, he should not be in auction anymore + set to leaving + node.ProcessUnStake(t, map[string][][]byte{ + newOwner: {newNode[newOwner].BLSKeys[0]}, + }) + currNodesConfig = node.NodesConfig + requireSliceContainsNumOfElements(t, currNodesConfig.auction, newNode[newOwner].BLSKeys, 0) + node.Process(t, 3) + currNodesConfig = node.NodesConfig + requireMapContains(t, currNodesConfig.leaving, newNode[newOwner].BLSKeys) } From 8c829839849922b0d2c8dd096a636f0db279aa78 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 14:19:34 +0300 Subject: [PATCH 322/958] FEAT: Add addTxsToCacher --- .../testMetaProcessorWithCustomNodesConfig.go | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index b909d0798de..2b48ba56af3 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -102,10 +102,7 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes GasProvided: 10, }, tmp.Marshaller) - for scrHash, scr := range scrs { - txHashes = append(txHashes, []byte(scrHash)) - tmp.TxCacher.AddTx([]byte(scrHash), scr) - } + txHashes = append(txHashes, tmp.addTxsToCacher(scrs)...) } _, err := tmp.AccountsAdapter.Commit() require.Nil(t, err) @@ -174,10 +171,7 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string][][] GasProvided: 10, }, tmp.Marshaller) - for scrHash, scr := range scrs { - txHashes = append(txHashes, []byte(scrHash)) - tmp.TxCacher.AddTx([]byte(scrHash), scr) - } + txHashes = append(txHashes, tmp.addTxsToCacher(scrs)...) } _, err := tmp.AccountsAdapter.Commit() @@ -251,3 +245,13 @@ func createSCRsFromStakingSCOutput( return allSCR } + +func (tmp *TestMetaProcessor) addTxsToCacher(scrs map[string]*smartContractResult.SmartContractResult) [][]byte { + txHashes := make([][]byte, 0) + for scrHash, scr := range scrs { + txHashes = append(txHashes, []byte(scrHash)) + tmp.TxCacher.AddTx([]byte(scrHash), scr) + } + + return txHashes +} From 1cd26eba16cee21f2acba5d25b8f62eba6a2ce4f Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 15:07:38 +0300 Subject: [PATCH 323/958] FEAT: Add ProcessJail --- integrationTests/vm/staking/stakingV4_test.go | 72 +++++++++++++++++++ .../testMetaProcessorWithCustomNodesConfig.go | 59 +++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index f1ef9920b99..9f9d0353872 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -746,3 +746,75 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { currNodesConfig = node.NodesConfig requireMapContains(t, currNodesConfig.leaving, newNode[newOwner].BLSKeys) } + +func TestStakingV4_UnJailNodes(t *testing.T) { + pubKeys := generateAddresses(0, 20) + + owner1 := "owner1" + owner1Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:2], + }, + WaitingBlsKeys: map[uint32][][]byte{ + 0: pubKeys[2:4], + }, + StakingQueueKeys: pubKeys[4:6], + TotalStake: big.NewInt(10 * nodePrice), + } + + owner2 := "owner2" + owner2Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + 0: pubKeys[6:8], + }, + WaitingBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[8:12], + }, + StakingQueueKeys: pubKeys[12:15], + TotalStake: big.NewInt(10 * nodePrice), + } + + owner3 := "owner3" + owner3Stats := &OwnerStats{ + StakingQueueKeys: pubKeys[15:17], + TotalStake: big.NewInt(6 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 1, + ShardConsensusGroupSize: 1, + MinNumberOfEligibleShardNodes: 2, + MinNumberOfEligibleMetaNodes: 2, + NumOfShards: 1, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + owner2: owner2Stats, + owner3: owner3Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 10, + NodesToShufflePerShard: 1, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 6) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.eligible[0], 2) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + node.ProcessJail(t, owner1Stats.WaitingBlsKeys[0]) + + node.Process(t, 5) + currNodesConfig = node.NodesConfig + requireMapContains(t, currNodesConfig.leaving, owner1Stats.WaitingBlsKeys[0]) +} diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 2b48ba56af3..4b6bbe88c98 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -220,6 +220,65 @@ func (tmp *TestMetaProcessor) doUnStake( return createSCRsFromStakingSCOutput(vmOutput, marshaller) } +// ProcessJail will create a block containing mini blocks with jail txs using provided nodes. +// Block will be committed + call to validator system sc will be made to jail all nodes +func (tmp *TestMetaProcessor) ProcessJail(t *testing.T, blsKeys [][]byte) { + header := tmp.createNewHeader(t, tmp.currentRound) + tmp.BlockChainHook.SetCurrentHeader(header) + + scrs := tmp.doJail(t, vmcommon.VMInput{ + CallerAddr: vm.JailingAddress, + Arguments: createJailArgs(blsKeys), + CallValue: big.NewInt(0), + GasProvided: 10, + }, tmp.Marshaller) + _, err := tmp.AccountsAdapter.Commit() + require.Nil(t, err) + + txHashes := tmp.addTxsToCacher(scrs) + miniBlocks := block.MiniBlockSlice{ + { + TxHashes: txHashes, + SenderShardID: core.MetachainShardId, + ReceiverShardID: core.MetachainShardId, + Type: block.SmartContractResultBlock, + }, + } + tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) + tmp.createAndCommitBlock(t, header, noTime) + + tmp.currentRound += 1 +} + +func createJailArgs(blsKeys [][]byte) [][]byte { + argsUnStake := make([][]byte, 0) + for _, blsKey := range blsKeys { + argsUnStake = append(argsUnStake, blsKey) + } + + return argsUnStake +} + +func (tmp *TestMetaProcessor) doJail( + t *testing.T, + vmInput vmcommon.VMInput, + marshaller marshal.Marshalizer, +) map[string]*smartContractResult.SmartContractResult { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmInput, + RecipientAddr: vm.StakingSCAddress, + Function: "jail", + } + vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) + require.Nil(t, err) + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + + err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) + require.Nil(t, err) + + return createSCRsFromStakingSCOutput(vmOutput, marshaller) +} + func createSCRsFromStakingSCOutput( vmOutput *vmcommon.VMOutput, marshaller marshal.Marshalizer, From 51cff792518c2364235a03068978c85a0b0f2304 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 15:49:57 +0300 Subject: [PATCH 324/958] FIX: Remove createJailArgs --- .../staking/testMetaProcessorWithCustomNodesConfig.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 4b6bbe88c98..cf87cdc2d3d 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -228,7 +228,7 @@ func (tmp *TestMetaProcessor) ProcessJail(t *testing.T, blsKeys [][]byte) { scrs := tmp.doJail(t, vmcommon.VMInput{ CallerAddr: vm.JailingAddress, - Arguments: createJailArgs(blsKeys), + Arguments: blsKeys, CallValue: big.NewInt(0), GasProvided: 10, }, tmp.Marshaller) @@ -250,15 +250,6 @@ func (tmp *TestMetaProcessor) ProcessJail(t *testing.T, blsKeys [][]byte) { tmp.currentRound += 1 } -func createJailArgs(blsKeys [][]byte) [][]byte { - argsUnStake := make([][]byte, 0) - for _, blsKey := range blsKeys { - argsUnStake = append(argsUnStake, blsKey) - } - - return argsUnStake -} - func (tmp *TestMetaProcessor) doJail( t *testing.T, vmInput vmcommon.VMInput, From a2ad179c0b0009967380beefd19d629ddfbf3401 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 16:27:05 +0300 Subject: [PATCH 325/958] FIX: Big refactor, cleaner code --- .../testMetaProcessorWithCustomNodesConfig.go | 133 ++++++++---------- 1 file changed, 56 insertions(+), 77 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 2b48ba56af3..dc634df2d83 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" "github.com/ElrondNetwork/elrond-go-core/marshal" @@ -94,31 +95,33 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes tmp.BlockChainHook.SetCurrentHeader(header) txHashes := make([][]byte, 0) - for owner, nodesData := range nodes { - scrs := tmp.doStake(t, vmcommon.VMInput{ - CallerAddr: []byte(owner), - Arguments: createStakeArgs(nodesData.BLSKeys), - CallValue: nodesData.TotalStake, - GasProvided: 10, - }, tmp.Marshaller) - + for owner, registerData := range nodes { + scrs := tmp.doStake(t, []byte(owner), registerData) txHashes = append(txHashes, tmp.addTxsToCacher(scrs)...) } - _, err := tmp.AccountsAdapter.Commit() - require.Nil(t, err) - miniBlocks := block.MiniBlockSlice{ - { - TxHashes: txHashes, - SenderShardID: core.MetachainShardId, - ReceiverShardID: core.MetachainShardId, - Type: block.SmartContractResultBlock, + tmp.commitBlockTxs(t, txHashes, header) +} + +//TODO: +// - Do the same for unJail +func (tmp *TestMetaProcessor) doStake( + t *testing.T, + owner []byte, + registerData *NodesRegisterData, +) map[string]*smartContractResult.SmartContractResult { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: owner, + Arguments: createStakeArgs(registerData.BLSKeys), + CallValue: registerData.TotalStake, + GasProvided: 10, }, + RecipientAddr: vm.ValidatorSCAddress, + Function: "stake", } - tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) - tmp.createAndCommitBlock(t, header, noTime) - tmp.currentRound += 1 + return tmp.runSC(t, arguments) } func createStakeArgs(blsKeys [][]byte) [][]byte { @@ -134,28 +137,6 @@ func createStakeArgs(blsKeys [][]byte) [][]byte { return argsStake } -//TODO: -// - Do the same for unJail -func (tmp *TestMetaProcessor) doStake( - t *testing.T, - vmInput vmcommon.VMInput, - marshaller marshal.Marshalizer, -) map[string]*smartContractResult.SmartContractResult { - arguments := &vmcommon.ContractCallInput{ - VMInput: vmInput, - RecipientAddr: vm.ValidatorSCAddress, - Function: "stake", - } - vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) - require.Nil(t, err) - require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) - - err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) - require.Nil(t, err) - - return createSCRsFromStakingSCOutput(vmOutput, marshaller) -} - // ProcessUnStake will create a block containing mini blocks with unStaking txs using provided nodes. // Block will be committed + call to validator system sc will be made to unStake all nodes func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string][][]byte) { @@ -164,16 +145,43 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string][][] txHashes := make([][]byte, 0) for owner, blsKeys := range nodes { - scrs := tmp.doUnStake(t, vmcommon.VMInput{ - CallerAddr: []byte(owner), - Arguments: createUnStakeArgs(blsKeys), + scrs := tmp.doUnStake(t, []byte(owner), blsKeys) + txHashes = append(txHashes, tmp.addTxsToCacher(scrs)...) + } + + tmp.commitBlockTxs(t, txHashes, header) +} + +func (tmp *TestMetaProcessor) doUnStake( + t *testing.T, + owner []byte, + blsKeys [][]byte, +) map[string]*smartContractResult.SmartContractResult { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: owner, + Arguments: blsKeys, CallValue: big.NewInt(0), GasProvided: 10, - }, tmp.Marshaller) + }, + RecipientAddr: vm.ValidatorSCAddress, + Function: "unStake", + } - txHashes = append(txHashes, tmp.addTxsToCacher(scrs)...) + return tmp.runSC(t, arguments) +} + +func (tmp *TestMetaProcessor) addTxsToCacher(scrs map[string]*smartContractResult.SmartContractResult) [][]byte { + txHashes := make([][]byte, 0) + for scrHash, scr := range scrs { + txHashes = append(txHashes, []byte(scrHash)) + tmp.TxCacher.AddTx([]byte(scrHash), scr) } + return txHashes +} + +func (tmp *TestMetaProcessor) commitBlockTxs(t *testing.T, txHashes [][]byte, header data.HeaderHandler) { _, err := tmp.AccountsAdapter.Commit() require.Nil(t, err) @@ -187,29 +195,10 @@ func (tmp *TestMetaProcessor) ProcessUnStake(t *testing.T, nodes map[string][][] } tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) tmp.createAndCommitBlock(t, header, noTime) - tmp.currentRound += 1 } -func createUnStakeArgs(blsKeys [][]byte) [][]byte { - argsUnStake := make([][]byte, 0) - for _, blsKey := range blsKeys { - argsUnStake = append(argsUnStake, blsKey) - } - - return argsUnStake -} - -func (tmp *TestMetaProcessor) doUnStake( - t *testing.T, - vmInput vmcommon.VMInput, - marshaller marshal.Marshalizer, -) map[string]*smartContractResult.SmartContractResult { - arguments := &vmcommon.ContractCallInput{ - VMInput: vmInput, - RecipientAddr: vm.ValidatorSCAddress, - Function: "unStake", - } +func (tmp *TestMetaProcessor) runSC(t *testing.T, arguments *vmcommon.ContractCallInput) map[string]*smartContractResult.SmartContractResult { vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) require.Nil(t, err) require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) @@ -217,7 +206,7 @@ func (tmp *TestMetaProcessor) doUnStake( err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) require.Nil(t, err) - return createSCRsFromStakingSCOutput(vmOutput, marshaller) + return createSCRsFromStakingSCOutput(vmOutput, tmp.Marshaller) } func createSCRsFromStakingSCOutput( @@ -245,13 +234,3 @@ func createSCRsFromStakingSCOutput( return allSCR } - -func (tmp *TestMetaProcessor) addTxsToCacher(scrs map[string]*smartContractResult.SmartContractResult) [][]byte { - txHashes := make([][]byte, 0) - for scrHash, scr := range scrs { - txHashes = append(txHashes, []byte(scrHash)) - tmp.TxCacher.AddTx([]byte(scrHash), scr) - } - - return txHashes -} From 9056d2d8e5247fa664c697628bdef7f4e0cb5c48 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 6 Jun 2022 16:49:36 +0300 Subject: [PATCH 326/958] FEAT: Refactor after merge --- .../testMetaProcessorWithCustomNodesConfig.go | 81 +++++++------------ 1 file changed, 29 insertions(+), 52 deletions(-) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index a05a4589595..52dc824e3d5 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -103,8 +103,6 @@ func (tmp *TestMetaProcessor) ProcessStake(t *testing.T, nodes map[string]*Nodes tmp.commitBlockTxs(t, txHashes, header) } -//TODO: -// - Do the same for unJail func (tmp *TestMetaProcessor) doStake( t *testing.T, owner []byte, @@ -171,6 +169,35 @@ func (tmp *TestMetaProcessor) doUnStake( return tmp.runSC(t, arguments) } +// ProcessJail will create a block containing mini blocks with jail txs using provided nodes. +// Block will be committed + call to validator system sc will be made to jail all nodes +func (tmp *TestMetaProcessor) ProcessJail(t *testing.T, blsKeys [][]byte) { + header := tmp.createNewHeader(t, tmp.currentRound) + tmp.BlockChainHook.SetCurrentHeader(header) + + scrs := tmp.doJail(t, blsKeys) + txHashes := tmp.addTxsToCacher(scrs) + tmp.commitBlockTxs(t, txHashes, header) +} + +func (tmp *TestMetaProcessor) doJail( + t *testing.T, + blsKeys [][]byte, +) map[string]*smartContractResult.SmartContractResult { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.JailingAddress, + Arguments: blsKeys, + CallValue: big.NewInt(0), + GasProvided: 10, + }, + RecipientAddr: vm.StakingSCAddress, + Function: "jail", + } + + return tmp.runSC(t, arguments) +} + func (tmp *TestMetaProcessor) addTxsToCacher(scrs map[string]*smartContractResult.SmartContractResult) [][]byte { txHashes := make([][]byte, 0) for scrHash, scr := range scrs { @@ -209,56 +236,6 @@ func (tmp *TestMetaProcessor) runSC(t *testing.T, arguments *vmcommon.ContractCa return createSCRsFromStakingSCOutput(vmOutput, tmp.Marshaller) } -// ProcessJail will create a block containing mini blocks with jail txs using provided nodes. -// Block will be committed + call to validator system sc will be made to jail all nodes -func (tmp *TestMetaProcessor) ProcessJail(t *testing.T, blsKeys [][]byte) { - header := tmp.createNewHeader(t, tmp.currentRound) - tmp.BlockChainHook.SetCurrentHeader(header) - - scrs := tmp.doJail(t, vmcommon.VMInput{ - CallerAddr: vm.JailingAddress, - Arguments: blsKeys, - CallValue: big.NewInt(0), - GasProvided: 10, - }, tmp.Marshaller) - _, err := tmp.AccountsAdapter.Commit() - require.Nil(t, err) - - txHashes := tmp.addTxsToCacher(scrs) - miniBlocks := block.MiniBlockSlice{ - { - TxHashes: txHashes, - SenderShardID: core.MetachainShardId, - ReceiverShardID: core.MetachainShardId, - Type: block.SmartContractResultBlock, - }, - } - tmp.TxCoordinator.AddTxsFromMiniBlocks(miniBlocks) - tmp.createAndCommitBlock(t, header, noTime) - - tmp.currentRound += 1 -} - -func (tmp *TestMetaProcessor) doJail( - t *testing.T, - vmInput vmcommon.VMInput, - marshaller marshal.Marshalizer, -) map[string]*smartContractResult.SmartContractResult { - arguments := &vmcommon.ContractCallInput{ - VMInput: vmInput, - RecipientAddr: vm.StakingSCAddress, - Function: "jail", - } - vmOutput, err := tmp.SystemVM.RunSmartContractCall(arguments) - require.Nil(t, err) - require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) - - err = integrationTests.ProcessSCOutputAccounts(vmOutput, tmp.AccountsAdapter) - require.Nil(t, err) - - return createSCRsFromStakingSCOutput(vmOutput, marshaller) -} - func createSCRsFromStakingSCOutput( vmOutput *vmcommon.VMOutput, marshaller marshal.Marshalizer, From 35c6b95bcba9ebf9bc735c55e4d93c21a5cc4252 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 7 Jun 2022 12:18:20 +0300 Subject: [PATCH 327/958] FEAT: Ugly working test --- integrationTests/vm/staking/stakingV4_test.go | 75 ++++++++++++++++++- .../testMetaProcessorWithCustomNodesConfig.go | 33 ++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 9f9d0353872..1a7e1f5e68f 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -812,9 +812,78 @@ func TestStakingV4_UnJailNodes(t *testing.T) { require.Len(t, currNodesConfig.waiting[0], 2) require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - node.ProcessJail(t, owner1Stats.WaitingBlsKeys[0]) - node.Process(t, 5) + owner1StakingQueue := owner1Stats.StakingQueueKeys + owner2StakingQueue := owner2Stats.StakingQueueKeys + owner3StakingQueue := owner3Stats.StakingQueueKeys + queue := make([][]byte, 0) + queue = append(queue, owner1StakingQueue...) + queue = append(queue, owner2StakingQueue...) + queue = append(queue, owner3StakingQueue...) + require.Len(t, currNodesConfig.queue, 7) + requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + + jailedNodes := make([][]byte, 0) + jailedNodes = append(jailedNodes, owner1Stats.WaitingBlsKeys[0]...) + jailedNodes = append(jailedNodes, owner2Stats.WaitingBlsKeys[core.MetachainShardId][:2]...) + node.ProcessJail(t, jailedNodes) + + unJailedNodes := make([][]byte, 0) + unJailedNodes = append(unJailedNodes, owner1Stats.WaitingBlsKeys[0][0]) + unJailedNodes = append(unJailedNodes, owner2Stats.WaitingBlsKeys[core.MetachainShardId][0]) + node.ProcessUnJail(t, unJailedNodes) + + jailedNodes = remove(jailedNodes, unJailedNodes[0]) + jailedNodes = remove(jailedNodes, unJailedNodes[1]) + node.Process(t, 3) currNodesConfig = node.NodesConfig - requireMapContains(t, currNodesConfig.leaving, owner1Stats.WaitingBlsKeys[0]) + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Empty(t, currNodesConfig.queue) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) + requireMapContains(t, currNodesConfig.leaving, jailedNodes) + requireMapContains(t, currNodesConfig.waiting, unJailedNodes) + + node.ProcessUnJail(t, jailedNodes[:1]) + currNodesConfig = node.NodesConfig + queue = append(queue, jailedNodes[0]) + require.Empty(t, currNodesConfig.queue) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) + + node.Process(t, 4) + node.ProcessUnJail(t, jailedNodes[1:]) + currNodesConfig = node.NodesConfig + queue = append(queue, jailedNodes[1]) + require.Empty(t, currNodesConfig.queue) + requireSliceContains(t, currNodesConfig.auction, queue) + + // jail a random nodes + newJailed := getAllPubKeys(currNodesConfig.waiting)[:1] + + node.ProcessJail(t, newJailed) + node.Process(t, 4) + currNodesConfig = node.NodesConfig + requireMapContains(t, currNodesConfig.leaving, newJailed) + + node.ProcessUnJail(t, newJailed) + currNodesConfig = node.NodesConfig + requireSliceContains(t, currNodesConfig.auction, newJailed) + + node.Process(t, 4) + + currNodesConfig = node.NodesConfig + queue = currNodesConfig.auction + newJailed = queue[:1] + newUnjailed := newJailed[0] + node.ProcessJail(t, newJailed) + queue = remove(queue, newJailed[0]) + currNodesConfig = node.NodesConfig + requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) + + node.ProcessUnJail(t, [][]byte{newUnjailed}) + queue = append(queue, newUnjailed) + currNodesConfig = node.NodesConfig + requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) + + //node.Process(t, 10) } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 52dc824e3d5..63ba661c851 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -198,6 +198,39 @@ func (tmp *TestMetaProcessor) doJail( return tmp.runSC(t, arguments) } +// ProcessUnJail will create a block containing mini blocks with unJail txs using provided nodes. +// Block will be committed + call to validator system sc will be made to unJail all nodes +func (tmp *TestMetaProcessor) ProcessUnJail(t *testing.T, blsKeys [][]byte) { + header := tmp.createNewHeader(t, tmp.currentRound) + tmp.BlockChainHook.SetCurrentHeader(header) + + txHashes := make([][]byte, 0) + for _, blsKey := range blsKeys { + scrs := tmp.doUnJail(t, blsKey) + txHashes = append(txHashes, tmp.addTxsToCacher(scrs)...) + } + + tmp.commitBlockTxs(t, txHashes, header) +} + +func (tmp *TestMetaProcessor) doUnJail( + t *testing.T, + blsKey []byte, +) map[string]*smartContractResult.SmartContractResult { + arguments := &vmcommon.ContractCallInput{ + VMInput: vmcommon.VMInput{ + CallerAddr: vm.ValidatorSCAddress, + Arguments: [][]byte{blsKey}, + CallValue: big.NewInt(0), + GasProvided: 10, + }, + RecipientAddr: vm.StakingSCAddress, + Function: "unJail", + } + + return tmp.runSC(t, arguments) +} + func (tmp *TestMetaProcessor) addTxsToCacher(scrs map[string]*smartContractResult.SmartContractResult) [][]byte { txHashes := make([][]byte, 0) for scrHash, scr := range scrs { From 99557cbe146943155292eac6306678679fb073ea Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 7 Jun 2022 13:39:41 +0300 Subject: [PATCH 328/958] FIX: Refactor test --- integrationTests/vm/staking/stakingV4_test.go | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 1a7e1f5e68f..0f7850a2044 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -747,7 +747,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { requireMapContains(t, currNodesConfig.leaving, newNode[newOwner].BLSKeys) } -func TestStakingV4_UnJailNodes(t *testing.T) { +func TestStakingV4_JailAndUnJailNodes(t *testing.T) { pubKeys := generateAddresses(0, 20) owner1 := "owner1" @@ -774,12 +774,6 @@ func TestStakingV4_UnJailNodes(t *testing.T) { TotalStake: big.NewInt(10 * nodePrice), } - owner3 := "owner3" - owner3Stats := &OwnerStats{ - StakingQueueKeys: pubKeys[15:17], - TotalStake: big.NewInt(6 * nodePrice), - } - cfg := &InitialNodesConfig{ MetaConsensusGroupSize: 1, ShardConsensusGroupSize: 1, @@ -789,7 +783,6 @@ func TestStakingV4_UnJailNodes(t *testing.T) { Owners: map[string]*OwnerStats{ owner1: owner1Stats, owner2: owner2Stats, - owner3: owner3Stats, }, MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { @@ -797,6 +790,11 @@ func TestStakingV4_UnJailNodes(t *testing.T) { MaxNumNodes: 10, NodesToShufflePerShard: 1, }, + { + EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, + MaxNumNodes: 4, + NodesToShufflePerShard: 1, + }, }, } node := NewTestMetaProcessorWithCustomNodes(cfg) @@ -815,75 +813,91 @@ func TestStakingV4_UnJailNodes(t *testing.T) { owner1StakingQueue := owner1Stats.StakingQueueKeys owner2StakingQueue := owner2Stats.StakingQueueKeys - owner3StakingQueue := owner3Stats.StakingQueueKeys queue := make([][]byte, 0) queue = append(queue, owner1StakingQueue...) queue = append(queue, owner2StakingQueue...) - queue = append(queue, owner3StakingQueue...) - require.Len(t, currNodesConfig.queue, 7) + require.Len(t, currNodesConfig.queue, 5) requireSameSliceDifferentOrder(t, currNodesConfig.queue, queue) + // 1.1 Jail 4 nodes: + // - 2 nodes from waiting list shard = 0 + // - 2 nodes from waiting list shard = meta chain jailedNodes := make([][]byte, 0) jailedNodes = append(jailedNodes, owner1Stats.WaitingBlsKeys[0]...) jailedNodes = append(jailedNodes, owner2Stats.WaitingBlsKeys[core.MetachainShardId][:2]...) node.ProcessJail(t, jailedNodes) + // 1.2 UnJail 2 nodes from initial jailed nodes: + // - 1 node from waiting list shard = 0 + // - 1 node from waiting list shard = meta chain unJailedNodes := make([][]byte, 0) unJailedNodes = append(unJailedNodes, owner1Stats.WaitingBlsKeys[0][0]) unJailedNodes = append(unJailedNodes, owner2Stats.WaitingBlsKeys[core.MetachainShardId][0]) - node.ProcessUnJail(t, unJailedNodes) - jailedNodes = remove(jailedNodes, unJailedNodes[0]) jailedNodes = remove(jailedNodes, unJailedNodes[1]) + node.ProcessUnJail(t, unJailedNodes) + + // 2. Two jailed nodes are now leaving; the other two unJailed nodes are re-staked and distributed on waiting list node.Process(t, 3) currNodesConfig = node.NodesConfig + requireMapContains(t, currNodesConfig.leaving, jailedNodes) + requireMapContains(t, currNodesConfig.waiting, unJailedNodes) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) require.Empty(t, currNodesConfig.queue) - requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) - requireMapContains(t, currNodesConfig.leaving, jailedNodes) - requireMapContains(t, currNodesConfig.waiting, unJailedNodes) + // 2.1 Epoch = stakingV4Init; unJail one of the jailed nodes and expect it is sent to auction node.ProcessUnJail(t, jailedNodes[:1]) currNodesConfig = node.NodesConfig queue = append(queue, jailedNodes[0]) require.Empty(t, currNodesConfig.queue) requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) + // 3. Epoch = stakingV4; unJail the other jailed node and expect it is sent to auction node.Process(t, 4) node.ProcessUnJail(t, jailedNodes[1:]) currNodesConfig = node.NodesConfig queue = append(queue, jailedNodes[1]) + queue = append(queue, getAllPubKeys(currNodesConfig.shuffledOut)...) require.Empty(t, currNodesConfig.queue) - requireSliceContains(t, currNodesConfig.auction, queue) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) - // jail a random nodes + // 3.1 Jail a random node from waiting list newJailed := getAllPubKeys(currNodesConfig.waiting)[:1] - node.ProcessJail(t, newJailed) + + // 4. Epoch = stakingV4DistributeAuctionToWaiting; + // 4.1 Expect jailed node from waiting list is now leaving node.Process(t, 4) currNodesConfig = node.NodesConfig requireMapContains(t, currNodesConfig.leaving, newJailed) + requireSliceContainsNumOfElements(t, currNodesConfig.auction, newJailed, 0) + require.Empty(t, currNodesConfig.queue) + // 4.2 UnJail previous node and expect it is sent to auction node.ProcessUnJail(t, newJailed) currNodesConfig = node.NodesConfig requireSliceContains(t, currNodesConfig.auction, newJailed) + require.Empty(t, currNodesConfig.queue) + // 5. Epoch is now after whole staking v4 chain is activated node.Process(t, 4) - currNodesConfig = node.NodesConfig queue = currNodesConfig.auction newJailed = queue[:1] - newUnjailed := newJailed[0] + newUnJailed := newJailed[0] + + // 5.1 Take a random node from auction and jail it; expect it is removed from auction list node.ProcessJail(t, newJailed) queue = remove(queue, newJailed[0]) currNodesConfig = node.NodesConfig requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) - node.ProcessUnJail(t, [][]byte{newUnjailed}) - queue = append(queue, newUnjailed) + // 5.2 UnJail previous node; expect it is sent back to auction + node.ProcessUnJail(t, [][]byte{newUnJailed}) + queue = append(queue, newUnJailed) currNodesConfig = node.NodesConfig requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) - - //node.Process(t, 10) + require.Empty(t, node.NodesConfig.queue) } From 5965872673afea97a37970504720e8909132ce0e Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 7 Jun 2022 13:53:49 +0300 Subject: [PATCH 329/958] FIX: Auction list init --- epochStart/metachain/stakingDataProvider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 55b69ccac1d..06111e08590 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -236,7 +236,7 @@ func (sdp *stakingDataProvider) GetOwnersData() map[string]*epochStart.OwnerData NumStakedNodes: ownerData.numStakedNodes, TotalTopUp: big.NewInt(0).SetBytes(ownerData.totalTopUp.Bytes()), TopUpPerNode: big.NewInt(0).SetBytes(ownerData.topUpPerNode.Bytes()), - AuctionList: ownerData.auctionList, + AuctionList: make([]state.ValidatorInfoHandler, ownerData.numAuctionNodes), Qualified: ownerData.qualified, } copy(ret[owner].AuctionList, ownerData.auctionList) From 7a664a181db9bcca3cae4c8c323b395aa93b4ed9 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Tue, 7 Jun 2022 14:28:19 +0300 Subject: [PATCH 330/958] sort imports after merge --- factory/blockProcessorCreator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 9d2dc84df16..2ef0af7e273 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -12,8 +12,8 @@ import ( "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/epochStart/bootstrap/disabled" metachainEpochStart "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - factoryDisabled "github.com/ElrondNetwork/elrond-go/factory/disabled" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" + factoryDisabled "github.com/ElrondNetwork/elrond-go/factory/disabled" "github.com/ElrondNetwork/elrond-go/genesis" processDisabled "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" "github.com/ElrondNetwork/elrond-go/process" From 1ee604fe60e6c7d39c62ff7c7b6a5d53ea76e35b Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Tue, 7 Jun 2022 15:00:38 +0300 Subject: [PATCH 331/958] fix stub location --- epochStart/metachain/auctionListSelector_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 8713eb9815b..3b4c2a96126 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -11,10 +11,10 @@ import ( "github.com/ElrondNetwork/elrond-go/common/forking" "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/mock" "github.com/ElrondNetwork/elrond-go/epochStart/notifier" "github.com/ElrondNetwork/elrond-go/sharding" "github.com/ElrondNetwork/elrond-go/state" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) @@ -106,7 +106,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledErrSortingA args := createAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 10}}) errGetNodeTopUp := errors.New("error getting top up per node") - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ GetNodeStakedTopUpCalled: func(blsKey []byte) (*big.Int, error) { switch string(blsKey) { case "pubKey0", "pubKey1": From b6a0fc1d61dc35d7b170699f55d1239cae79be38 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 7 Jun 2022 16:15:38 +0300 Subject: [PATCH 332/958] FIX: Merge conflict --- epochStart/metachain/systemSCs_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 5470752800b..f9b5dcbe7d2 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1782,7 +1782,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) errProcessStakingData := errors.New("error processing staking data") - args.StakingDataProvider = &mock.StakingDataProviderStub{ + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ PrepareStakingDataCalled: func(validatorsMap state.ShardValidatorsInfoMapHandler) error { return errProcessStakingData }, From 45e273124107650f41f8cf6cb5546a419fce0ce6 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 7 Jun 2022 16:37:50 +0300 Subject: [PATCH 333/958] FIX: Merge conflicts 2 --- factory/disabled/stakingDataProvider.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/factory/disabled/stakingDataProvider.go b/factory/disabled/stakingDataProvider.go index 953b84d7a66..8ade3523ef8 100644 --- a/factory/disabled/stakingDataProvider.go +++ b/factory/disabled/stakingDataProvider.go @@ -3,6 +3,7 @@ package disabled import ( "math/big" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" ) @@ -32,12 +33,12 @@ func (s *stakingDataProvider) GetNodeStakedTopUp(_ []byte) (*big.Int, error) { } // PrepareStakingData returns a nil error -func (s *stakingDataProvider) PrepareStakingData(_ map[uint32][][]byte) error { +func (s *stakingDataProvider) PrepareStakingData(state.ShardValidatorsInfoMapHandler) error { return nil } // FillValidatorInfo returns a nil error -func (s *stakingDataProvider) FillValidatorInfo(_ []byte) error { +func (s *stakingDataProvider) FillValidatorInfo(state.ValidatorInfoHandler) error { return nil } @@ -51,6 +52,16 @@ func (s *stakingDataProvider) GetBlsKeyOwner(_ []byte) (string, error) { return "", nil } +// GetNumOfValidatorsInCurrentEpoch returns 0 +func (s *stakingDataProvider) GetNumOfValidatorsInCurrentEpoch() uint32 { + return 0 +} + +// GetOwnersData returns nil +func (s *stakingDataProvider) GetOwnersData() map[string]*epochStart.OwnerData { + return nil +} + // Clean does nothing func (s *stakingDataProvider) Clean() { } From 7a99fdd810330597c4dbbb9db5b9a3b55f0180c2 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 11:19:56 +0300 Subject: [PATCH 334/958] FEAT: First ugly version, tests don t work --- factory/blockProcessorCreator.go | 3 + factory/disabled/auctionListSelector.go | 21 ++++++ factory/processComponents.go | 1 + process/peer/validatorsProvider.go | 79 +++++++------------- process/peer/validatorsProviderAuction.go | 90 +++++++++++++++++++++++ 5 files changed, 142 insertions(+), 52 deletions(-) create mode 100644 factory/disabled/auctionListSelector.go create mode 100644 process/peer/validatorsProviderAuction.go diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index c8327a7f1e4..e9b8d38c304 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -425,6 +425,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( } pcf.stakingDataProvider = factoryDisabled.NewDisabledStakingDataProvider() + pcf.auctionListSelector = factoryDisabled.NewDisabledAuctionListSelector() return blockProcessorComponents, nil } @@ -842,6 +843,8 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } + pcf.auctionListSelector = auctionListSelector + argsEpochSystemSC := metachainEpochStart.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, UserAccountsDB: pcf.state.AccountsAdapter(), diff --git a/factory/disabled/auctionListSelector.go b/factory/disabled/auctionListSelector.go new file mode 100644 index 00000000000..d8920d50920 --- /dev/null +++ b/factory/disabled/auctionListSelector.go @@ -0,0 +1,21 @@ +package disabled + +import "github.com/ElrondNetwork/elrond-go/state" + +type auctionListSelector struct { +} + +// NewDisabledAuctionListSelector returns a new instance of a disabled auction list selector +func NewDisabledAuctionListSelector() *auctionListSelector { + return &auctionListSelector{} +} + +// SelectNodesFromAuctionList returns il +func (als *auctionListSelector) SelectNodesFromAuctionList(state.ShardValidatorsInfoMapHandler, []byte) error { + return nil +} + +// IsInterfaceNil returns true if the underlying pointer is nil +func (als *auctionListSelector) IsInterfaceNil() bool { + return als == nil +} diff --git a/factory/processComponents.go b/factory/processComponents.go index cedd37425e9..d03a0440b8d 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -168,6 +168,7 @@ type processComponentsFactory struct { epochNotifier process.EpochNotifier importHandler update.ImportHandler stakingDataProvider epochStart.StakingDataProvider + auctionListSelector epochStart.AuctionListSelector data DataComponentsHolder coreData CoreComponentsHolder diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index fe65033871e..d7bd0e52ed2 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -21,19 +21,25 @@ var _ process.ValidatorsProvider = (*validatorsProvider)(nil) // validatorsProvider is the main interface for validators' provider type validatorsProvider struct { - nodesCoordinator process.NodesCoordinator - validatorStatistics process.ValidatorStatisticsProcessor - cache map[string]*state.ValidatorApiResponse - cacheRefreshIntervalDuration time.Duration - refreshCache chan uint32 - lastCacheUpdate time.Time - lock sync.RWMutex - cancelFunc func() - validatorPubKeyConverter core.PubkeyConverter - addressPubKeyConverter core.PubkeyConverter - stakingDataProvider epochStart.StakingDataProvider - maxRating uint32 - currentEpoch uint32 + nodesCoordinator process.NodesCoordinator + validatorStatistics process.ValidatorStatisticsProcessor + cache map[string]*state.ValidatorApiResponse + cachedValidatorsMap state.ShardValidatorsInfoMapHandler + cachedRandomness []byte + cacheRefreshIntervalDuration time.Duration + refreshCache chan uint32 + lastCacheUpdate time.Time + lastValidatorsInfoCacheUpdate time.Time + lock sync.RWMutex + auctionLock sync.RWMutex + cancelFunc func() + validatorPubKeyConverter core.PubkeyConverter + addressPubKeyConverter core.PubkeyConverter + stakingDataProvider epochStart.StakingDataProvider + auctionListSelector epochStart.AuctionListSelector + + maxRating uint32 + currentEpoch uint32 } // ArgValidatorsProvider contains all parameters needed for creating a validatorsProvider @@ -45,6 +51,7 @@ type ArgValidatorsProvider struct { ValidatorPubKeyConverter core.PubkeyConverter AddressPubKeyConverter core.PubkeyConverter StakingDataProvider epochStart.StakingDataProvider + AuctionListSelector epochStart.AuctionListSelector StartEpoch uint32 MaxRating uint32 } @@ -72,6 +79,9 @@ func NewValidatorsProvider( if check.IfNil(args.StakingDataProvider) { return nil, process.ErrNilStakingDataProvider } + if check.IfNil(args.AuctionListSelector) { + return nil, epochStart.ErrNilAuctionListSelector + } if args.MaxRating == 0 { return nil, process.ErrMaxRatingZero } @@ -86,14 +96,18 @@ func NewValidatorsProvider( validatorStatistics: args.ValidatorStatistics, stakingDataProvider: args.StakingDataProvider, cache: make(map[string]*state.ValidatorApiResponse), + cachedValidatorsMap: state.NewShardValidatorsInfoMap(), + cachedRandomness: make([]byte, 0), cacheRefreshIntervalDuration: args.CacheRefreshIntervalDurationInSec, refreshCache: make(chan uint32), lock: sync.RWMutex{}, + auctionLock: sync.RWMutex{}, cancelFunc: cancelfunc, maxRating: args.MaxRating, validatorPubKeyConverter: args.ValidatorPubKeyConverter, addressPubKeyConverter: args.AddressPubKeyConverter, currentEpoch: args.StartEpoch, + auctionListSelector: args.AuctionListSelector, } go valProvider.startRefreshProcess(currentContext) @@ -107,44 +121,6 @@ func (vp *validatorsProvider) GetLatestValidators() map[string]*state.ValidatorA return vp.getValidators() } -// GetAuctionList returns an array containing the validators that are currently in the auction list -func (vp *validatorsProvider) GetAuctionList() []*common.AuctionListValidatorAPIResponse { - validators := vp.getValidators() - - auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) - for pubKey, val := range validators { - if string(common.AuctionList) != val.ValidatorStatus { - continue - } - - pubKeyBytes, err := vp.validatorPubKeyConverter.Decode(pubKey) - if err != nil { - log.Error("validatorsProvider.GetAuctionList: cannot decode public key of a node", "error", err) - continue - } - - owner, err := vp.stakingDataProvider.GetBlsKeyOwner(pubKeyBytes) - if err != nil { - log.Error("validatorsProvider.GetAuctionList: cannot get bls key owner", "public key", pubKey, "error", err) - continue - } - - topUp, err := vp.stakingDataProvider.GetNodeStakedTopUp(pubKeyBytes) - if err != nil { - log.Error("validatorsProvider.GetAuctionList: cannot get node top up", "public key", pubKey, "error", err) - continue - } - - auctionListValidators = append(auctionListValidators, &common.AuctionListValidatorAPIResponse{ - Owner: vp.addressPubKeyConverter.Encode([]byte(owner)), - NodeKey: pubKey, - TopUp: topUp.String(), - }) - } - - return auctionListValidators -} - func (vp *validatorsProvider) getValidators() map[string]*state.ValidatorApiResponse { vp.lock.RLock() shouldUpdate := time.Since(vp.lastCacheUpdate) > vp.cacheRefreshIntervalDuration @@ -295,7 +271,6 @@ func (vp *validatorsProvider) createValidatorApiResponseMapFromValidatorInfoMap( ShardId: validatorInfo.GetShardId(), ValidatorStatus: validatorInfo.GetList(), } - } return newCache diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go new file mode 100644 index 00000000000..484745c91e5 --- /dev/null +++ b/process/peer/validatorsProviderAuction.go @@ -0,0 +1,90 @@ +package peer + +import ( + "time" + + "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/state" +) + +// GetAuctionList returns an array containing the validators that are currently in the auction list +func (vp *validatorsProvider) GetAuctionList() []*common.AuctionListValidatorAPIResponse { + validatorsMap, _ := vp.getValidatorsInfo() //todo: error + defer vp.stakingDataProvider.Clean() + + for _, validator := range validatorsMap.GetAllValidatorsInfo() { + _ = vp.stakingDataProvider.FillValidatorInfo(validator) // todo: error + } + + vp.auctionLock.RLock() + randomness := vp.cachedRandomness + vp.auctionLock.RUnlock() + _ = vp.auctionListSelector.SelectNodesFromAuctionList(validatorsMap, randomness) //todo : error + randomness + + auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) + + for ownerPubKey, ownerData := range vp.stakingDataProvider.GetOwnersData() { + if ownerData.Qualified && ownerData.NumAuctionNodes > 0 { + auctionListValidators = append(auctionListValidators, &common.AuctionListValidatorAPIResponse{ + Owner: vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)), + // todo: if his node from auction is selected, add necessary data + }) + } + } + + return auctionListValidators +} + +func (vp *validatorsProvider) getValidatorsInfo() (state.ShardValidatorsInfoMapHandler, error) { + vp.auctionLock.RLock() + shouldUpdate := time.Since(vp.lastValidatorsInfoCacheUpdate) > vp.cacheRefreshIntervalDuration + vp.auctionLock.RUnlock() + + if shouldUpdate { + err := vp.updateValidatorsInfoCache() + if err != nil { + return nil, err + } + } + + vp.auctionLock.RLock() + defer vp.auctionLock.RUnlock() + + return cloneValidatorsMap(vp.cachedValidatorsMap) +} + +func (vp *validatorsProvider) updateValidatorsInfoCache() error { + rootHash, err := vp.validatorStatistics.RootHash() + if err != nil { + return err + } + + validatorsMap, err := vp.validatorStatistics.GetValidatorInfoForRootHash(rootHash) + if err != nil { + return err + } + + vp.auctionLock.Lock() + defer vp.auctionLock.Unlock() + + vp.lastValidatorsInfoCacheUpdate = time.Now() + vp.cachedValidatorsMap, err = cloneValidatorsMap(validatorsMap) + vp.cachedRandomness = rootHash + if err != nil { + return err + } + + return nil +} + +func cloneValidatorsMap(validatorsMap state.ShardValidatorsInfoMapHandler) (state.ShardValidatorsInfoMapHandler, error) { + ret := state.NewShardValidatorsInfoMap() + for _, validator := range validatorsMap.GetAllValidatorsInfo() { + err := ret.Add(validator.ShallowClone()) + if err != nil { + return nil, err + } + } + + return ret, nil +} From 314614e063f0946382d0cc5a4706a5759265d4f7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 13:24:02 +0300 Subject: [PATCH 335/958] FEAT: Second version --- common/dtos.go | 15 +- node/node.go | 3 +- process/interface.go | 2 +- process/peer/validatorsProviderAuction.go | 114 +++++- process/peer/validatorsProvider_test.go | 341 +++++++++--------- .../stakingcommon/auctionListSelectorStub.go | 25 ++ .../stakingcommon/validatorsProviderStub.go | 6 +- 7 files changed, 321 insertions(+), 185 deletions(-) create mode 100644 testscommon/stakingcommon/auctionListSelectorStub.go diff --git a/common/dtos.go b/common/dtos.go index 0744f7abf54..6174bd23503 100644 --- a/common/dtos.go +++ b/common/dtos.go @@ -14,9 +14,18 @@ type TransactionsPoolAPIResponse struct { Rewards []string `json:"rewards"` } +// AuctionNode holds data needed for a node in auction to respond to API calls +type AuctionNode struct { + BlsKey string `json:"blsKey"` + Qualified bool `json:"selected"` +} + // AuctionListValidatorAPIResponse holds the data needed for an auction node validator for responding to API calls type AuctionListValidatorAPIResponse struct { - Owner string `json:"owner"` - NodeKey string `json:"nodeKey"` - TopUp string `json:"topUp"` + Owner string `json:"owner"` + NumStakedNodes int64 `json:"numStakedNodes"` + TotalTopUp string `json:"totalTopUp"` + TopUpPerNode string `json:"topUpPerNode"` + QualifiedTopUp string `json:"qualifiedTopUp"` + AuctionList []AuctionNode `json:"auctionList"` } diff --git a/node/node.go b/node/node.go index 1bbbdb2d96e..fc22c7bd816 100644 --- a/node/node.go +++ b/node/node.go @@ -887,8 +887,9 @@ func (n *Node) ValidatorStatisticsApi() (map[string]*state.ValidatorApiResponse, return n.processComponents.ValidatorsProvider().GetLatestValidators(), nil } +// AuctionListApi will return the auction list config along with qualified nodes func (n *Node) AuctionListApi() ([]*common.AuctionListValidatorAPIResponse, error) { - return n.processComponents.ValidatorsProvider().GetAuctionList(), nil + return n.processComponents.ValidatorsProvider().GetAuctionList() } // DirectTrigger will start the hardfork trigger diff --git a/process/interface.go b/process/interface.go index dbded733c60..d7bebf9985c 100644 --- a/process/interface.go +++ b/process/interface.go @@ -288,7 +288,7 @@ type TransactionLogProcessorDatabase interface { // ValidatorsProvider is the main interface for validators' provider type ValidatorsProvider interface { GetLatestValidators() map[string]*state.ValidatorApiResponse - GetAuctionList() []*common.AuctionListValidatorAPIResponse + GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) IsInterfaceNil() bool Close() error } diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 484745c91e5..64d7115e676 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -1,40 +1,138 @@ package peer import ( + "bytes" + "math/big" + "sort" "time" "github.com/ElrondNetwork/elrond-go/common" + "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" ) // GetAuctionList returns an array containing the validators that are currently in the auction list -func (vp *validatorsProvider) GetAuctionList() []*common.AuctionListValidatorAPIResponse { - validatorsMap, _ := vp.getValidatorsInfo() //todo: error +func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) { + validatorsMap, err := vp.getValidatorsInfo() + if err != nil { + return nil, err + } + defer vp.stakingDataProvider.Clean() + err = vp.fillAllValidatorsInfo(validatorsMap) + if err != nil { + return nil, err + } + + selectedNodes, err := vp.getSelectedNodesFromAuction(validatorsMap) + if err != nil { + return nil, err + } + + auctionListValidators := vp.getAuctionListValidatorsAPIResponse(selectedNodes) + sortList(auctionListValidators) + return auctionListValidators, nil +} +func (vp *validatorsProvider) fillAllValidatorsInfo(validatorsMap state.ShardValidatorsInfoMapHandler) error { for _, validator := range validatorsMap.GetAllValidatorsInfo() { - _ = vp.stakingDataProvider.FillValidatorInfo(validator) // todo: error + err := vp.stakingDataProvider.FillValidatorInfo(validator) + if err != nil { + return err + } } + return nil +} + +func sortList(list []*common.AuctionListValidatorAPIResponse) { + sort.SliceStable(list, func(i, j int) bool { + qualifiedTopUpValidator1, _ := big.NewInt(0).SetString(list[i].QualifiedTopUp, 10) + qualifiedTopUpValidator2, _ := big.NewInt(0).SetString(list[j].QualifiedTopUp, 10) + + return qualifiedTopUpValidator1.Cmp(qualifiedTopUpValidator2) > 0 + }) +} + +func (vp *validatorsProvider) getSelectedNodesFromAuction(validatorsMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, error) { vp.auctionLock.RLock() randomness := vp.cachedRandomness vp.auctionLock.RUnlock() - _ = vp.auctionListSelector.SelectNodesFromAuctionList(validatorsMap, randomness) //todo : error + randomness + err := vp.auctionListSelector.SelectNodesFromAuctionList(validatorsMap, randomness) + if err != nil { + return nil, err + } + + selectedNodes := make([]state.ValidatorInfoHandler, 0) + for _, validator := range validatorsMap.GetAllValidatorsInfo() { + if validator.GetList() == string(common.SelectedFromAuctionList) { + selectedNodes = append(selectedNodes, validator.ShallowClone()) + } + } + + return selectedNodes, nil +} + +func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse(selectedNodes []state.ValidatorInfoHandler) []*common.AuctionListValidatorAPIResponse { auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) for ownerPubKey, ownerData := range vp.stakingDataProvider.GetOwnersData() { if ownerData.Qualified && ownerData.NumAuctionNodes > 0 { - auctionListValidators = append(auctionListValidators, &common.AuctionListValidatorAPIResponse{ - Owner: vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)), - // todo: if his node from auction is selected, add necessary data - }) + auctionValidator := &common.AuctionListValidatorAPIResponse{ + Owner: vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)), + NumStakedNodes: ownerData.NumStakedNodes, + TotalTopUp: ownerData.TotalTopUp.String(), + TopUpPerNode: ownerData.TopUpPerNode.String(), + QualifiedTopUp: ownerData.TopUpPerNode.String(), + AuctionList: make([]common.AuctionNode, 0, ownerData.NumAuctionNodes), + } + + vp.fillAuctionQualifiedValidatorAPIData(selectedNodes, ownerData, auctionValidator) + auctionListValidators = append(auctionListValidators, auctionValidator) } } return auctionListValidators } +func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( + selectedNodes []state.ValidatorInfoHandler, + ownerData *epochStart.OwnerData, + auctionValidatorAPI *common.AuctionListValidatorAPIResponse, +) { + auctionValidatorAPI.AuctionList = make([]common.AuctionNode, 0, ownerData.NumAuctionNodes) + numOwnerQualifiedNodes := int64(0) + for _, nodeInAuction := range ownerData.AuctionList { + auctionNode := common.AuctionNode{ + BlsKey: vp.addressPubKeyConverter.Encode(nodeInAuction.GetPublicKey()), + Qualified: false, + } + if contains(selectedNodes, nodeInAuction) { + auctionNode.Qualified = true + numOwnerQualifiedNodes++ + } + + auctionValidatorAPI.AuctionList = append(auctionValidatorAPI.AuctionList, auctionNode) + } + + if numOwnerQualifiedNodes > 0 { + activeNodes := big.NewInt(ownerData.NumActiveNodes) + qualifiedNodes := big.NewInt(numOwnerQualifiedNodes) + ownerRemainingNodes := big.NewInt(0).Add(activeNodes, qualifiedNodes) + auctionValidatorAPI.QualifiedTopUp = big.NewInt(0).Div(ownerData.TotalTopUp, ownerRemainingNodes).String() + } +} + +func contains(list []state.ValidatorInfoHandler, validator state.ValidatorInfoHandler) bool { + for _, val := range list { + if bytes.Equal(val.GetPublicKey(), validator.GetPublicKey()) { + return true + } + } + return false +} + func (vp *validatorsProvider) getValidatorsInfo() (state.ShardValidatorsInfoMapHandler, error) { vp.auctionLock.RLock() shouldUpdate := time.Since(vp.lastValidatorsInfoCacheUpdate) > vp.cacheRefreshIntervalDuration diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index bba3974c49b..aeb01d6c865 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -25,7 +25,6 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/pkg/errors" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNewValidatorsProvider_WithNilValidatorStatisticsShouldErr(t *testing.T) { @@ -634,194 +633,197 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin func TestValidatorsProvider_GetAuctionList(t *testing.T) { t.Parallel() - t.Run("no entry, should return entry map", func(t *testing.T) { - t.Parallel() + /* + t.Run("no entry, should return entry map", func(t *testing.T) { + t.Parallel() - arg := createDefaultValidatorsProviderArg() - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) + arg := createDefaultValidatorsProviderArg() + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) - response := vp.GetAuctionList() - require.Empty(t, response) - }) + response := vp.GetAuctionList() + require.Empty(t, response) + }) - t.Run("cannot get owner of key, should not fill it", func(t *testing.T) { - t.Parallel() + t.Run("cannot get owner of key, should not fill it", func(t *testing.T) { + t.Parallel() - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, + } + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil + } + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + return "", errors.New("cannot get owner") + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + return big.NewInt(10), nil + }, } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - return "", errors.New("cannot get owner") - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - return big.NewInt(10), nil - }, - } - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) - time.Sleep(arg.CacheRefreshIntervalDurationInSec) + time.Sleep(arg.CacheRefreshIntervalDurationInSec) - response := vp.GetAuctionList() - require.Empty(t, response) - }) + response := vp.GetAuctionList() + require.Empty(t, response) + }) - t.Run("cannot get top up for node, should not fill it", func(t *testing.T) { - t.Parallel() + t.Run("cannot get top up for node, should not fill it", func(t *testing.T) { + t.Parallel() - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, + } + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil + } + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + return "", nil + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + return nil, errors.New("cannot get top up") + }, } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - return "", nil - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - return nil, errors.New("cannot get top up") - }, - } - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) - time.Sleep(arg.CacheRefreshIntervalDurationInSec) + time.Sleep(arg.CacheRefreshIntervalDurationInSec) - response := vp.GetAuctionList() - require.Empty(t, response) - }) + response := vp.GetAuctionList() + require.Empty(t, response) + }) - t.Run("should work", func(t *testing.T) { - t.Parallel() + t.Run("should work", func(t *testing.T) { + t.Parallel() - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-eligible"), - List: string(common.EligibleList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-waiting"), - List: string(common.WaitingList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-leaving"), - List: string(common.LeavingList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey1-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - if "pubkey0-auction" == string(key) { - return "owner0", nil - } - if "pubkey1-auction" == string(key) { - return "owner1", nil - } - return "", nil - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - if "pubkey0-auction" == string(key) { - return big.NewInt(100), nil + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil } - if "pubkey1-auction" == string(key) { - return big.NewInt(110), nil - } - return big.NewInt(0), nil - }, - } - - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) - - time.Sleep(arg.CacheRefreshIntervalDurationInSec) + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-eligible"), + List: string(common.EligibleList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-waiting"), + List: string(common.WaitingList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-leaving"), + List: string(common.LeavingList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey1-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + if "pubkey0-auction" == string(key) { + return "owner0", nil + } + if "pubkey1-auction" == string(key) { + return "owner1", nil + } + return "", nil + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + if "pubkey0-auction" == string(key) { + return big.NewInt(100), nil + } + if "pubkey1-auction" == string(key) { + return big.NewInt(110), nil + } + return big.NewInt(0), nil + }, + } - response := vp.GetAuctionList() + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) + + time.Sleep(arg.CacheRefreshIntervalDurationInSec) + + response := vp.GetAuctionList() + + // the result should contain only auction list validators with the correct owner and top up + expectedResponse := []*common.AuctionListValidatorAPIResponse{ + { + Owner: arg.AddressPubKeyConverter.Encode([]byte("owner0")), + NodeKey: hex.EncodeToString([]byte("pubkey0-auction")), + TopUp: "100", + }, + { + Owner: arg.AddressPubKeyConverter.Encode([]byte("owner1")), + NodeKey: hex.EncodeToString([]byte("pubkey1-auction")), + TopUp: "110", + }, + } + require.Equal(t, expectedResponse, response) + }) - // the result should contain only auction list validators with the correct owner and top up - expectedResponse := []*common.AuctionListValidatorAPIResponse{ - { - Owner: arg.AddressPubKeyConverter.Encode([]byte("owner0")), - NodeKey: hex.EncodeToString([]byte("pubkey0-auction")), - TopUp: "100", - }, - { - Owner: arg.AddressPubKeyConverter.Encode([]byte("owner1")), - NodeKey: hex.EncodeToString([]byte("pubkey1-auction")), - TopUp: "110", - }, - } - require.Equal(t, expectedResponse, response) - }) + */ } func createMockValidatorInfo() *state.ValidatorInfo { @@ -862,5 +864,6 @@ func createDefaultValidatorsProviderArg() ArgValidatorsProvider { MaxRating: 100, ValidatorPubKeyConverter: mock.NewPubkeyConverterMock(32), AddressPubKeyConverter: mock.NewPubkeyConverterMock(32), + AuctionListSelector: &stakingcommon.AuctionListSelectorStub{}, } } diff --git a/testscommon/stakingcommon/auctionListSelectorStub.go b/testscommon/stakingcommon/auctionListSelectorStub.go new file mode 100644 index 00000000000..95635b3ff19 --- /dev/null +++ b/testscommon/stakingcommon/auctionListSelectorStub.go @@ -0,0 +1,25 @@ +package stakingcommon + +import "github.com/ElrondNetwork/elrond-go/state" + +// AuctionListSelectorStub - +type AuctionListSelectorStub struct { + SelectNodesFromAuctionListCalled func(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error +} + +// SelectNodesFromAuctionList - +func (als *AuctionListSelectorStub) SelectNodesFromAuctionList( + validatorsInfoMap state.ShardValidatorsInfoMapHandler, + randomness []byte, +) error { + if als.SelectNodesFromAuctionListCalled != nil { + return als.SelectNodesFromAuctionListCalled(validatorsInfoMap, randomness) + } + + return nil +} + +// IsInterfaceNil - +func (als *AuctionListSelectorStub) IsInterfaceNil() bool { + return als == nil +} diff --git a/testscommon/stakingcommon/validatorsProviderStub.go b/testscommon/stakingcommon/validatorsProviderStub.go index e22125dcacb..585946d6c2b 100644 --- a/testscommon/stakingcommon/validatorsProviderStub.go +++ b/testscommon/stakingcommon/validatorsProviderStub.go @@ -8,7 +8,7 @@ import ( // ValidatorsProviderStub - type ValidatorsProviderStub struct { GetLatestValidatorsCalled func() map[string]*state.ValidatorApiResponse - GetAuctionListCalled func() []*common.AuctionListValidatorAPIResponse + GetAuctionListCalled func() ([]*common.AuctionListValidatorAPIResponse, error) } // GetLatestValidators - @@ -21,12 +21,12 @@ func (vp *ValidatorsProviderStub) GetLatestValidators() map[string]*state.Valida } // GetAuctionList - -func (vp *ValidatorsProviderStub) GetAuctionList() []*common.AuctionListValidatorAPIResponse { +func (vp *ValidatorsProviderStub) GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) { if vp.GetAuctionListCalled != nil { return vp.GetAuctionListCalled() } - return nil + return nil, nil } // Close - From 61c426d81f15eda21c56bb9c71f082bdef71f4c5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 13:50:02 +0300 Subject: [PATCH 336/958] FEAT: Third version, correct cache --- process/peer/validatorsProvider.go | 9 +- process/peer/validatorsProviderAuction.go | 118 ++++++++++------------ process/peer/validatorsProvider_test.go | 4 +- 3 files changed, 62 insertions(+), 69 deletions(-) diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index d7bd0e52ed2..84293d3bfad 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -24,7 +24,7 @@ type validatorsProvider struct { nodesCoordinator process.NodesCoordinator validatorStatistics process.ValidatorStatisticsProcessor cache map[string]*state.ValidatorApiResponse - cachedValidatorsMap state.ShardValidatorsInfoMapHandler + cachedAuctionValidators []*common.AuctionListValidatorAPIResponse cachedRandomness []byte cacheRefreshIntervalDuration time.Duration refreshCache chan uint32 @@ -96,7 +96,7 @@ func NewValidatorsProvider( validatorStatistics: args.ValidatorStatistics, stakingDataProvider: args.StakingDataProvider, cache: make(map[string]*state.ValidatorApiResponse), - cachedValidatorsMap: state.NewShardValidatorsInfoMap(), + cachedAuctionValidators: make([]*common.AuctionListValidatorAPIResponse, 0), cachedRandomness: make([]byte, 0), cacheRefreshIntervalDuration: args.CacheRefreshIntervalDurationInSec, refreshCache: make(chan uint32), @@ -192,6 +192,11 @@ func (vp *validatorsProvider) epochStartEventHandler() nodesCoordinator.EpochSta func (vp *validatorsProvider) startRefreshProcess(ctx context.Context) { for { vp.updateCache() + err := vp.updateAuctionListCache() + if err != nil { + log.Error("could not update validators auction info cache", "error", err) + } + select { case epoch := <-vp.refreshCache: vp.lock.Lock() diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 64d7115e676..2d4d8ce60b6 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -13,13 +13,53 @@ import ( // GetAuctionList returns an array containing the validators that are currently in the auction list func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) { - validatorsMap, err := vp.getValidatorsInfo() + vp.auctionLock.RLock() + shouldUpdate := time.Since(vp.lastValidatorsInfoCacheUpdate) > vp.cacheRefreshIntervalDuration + vp.auctionLock.RUnlock() + + if shouldUpdate { + err := vp.updateAuctionListCache() + if err != nil { + return nil, err + } + } + + vp.auctionLock.RLock() + ret := make([]*common.AuctionListValidatorAPIResponse, 0, len(vp.cachedAuctionValidators)) + copy(ret, vp.cachedAuctionValidators) + vp.auctionLock.RUnlock() + + return ret, nil +} + +func (vp *validatorsProvider) updateAuctionListCache() error { + rootHash, err := vp.validatorStatistics.RootHash() if err != nil { - return nil, err + return err } + validatorsMap, err := vp.validatorStatistics.GetValidatorInfoForRootHash(rootHash) + if err != nil { + return err + } + + newCache, err := vp.createValidatorsAuctionCache(validatorsMap) + if err != nil { + return err + } + + vp.auctionLock.Lock() + vp.lastValidatorsInfoCacheUpdate = time.Now() + vp.cachedAuctionValidators = newCache + vp.cachedRandomness = rootHash + vp.auctionLock.Unlock() + + return nil +} + +func (vp *validatorsProvider) createValidatorsAuctionCache(validatorsMap state.ShardValidatorsInfoMapHandler) ([]*common.AuctionListValidatorAPIResponse, error) { defer vp.stakingDataProvider.Clean() - err = vp.fillAllValidatorsInfo(validatorsMap) + err := vp.fillAllValidatorsInfo(validatorsMap) if err != nil { return nil, err } @@ -45,15 +85,6 @@ func (vp *validatorsProvider) fillAllValidatorsInfo(validatorsMap state.ShardVal return nil } -func sortList(list []*common.AuctionListValidatorAPIResponse) { - sort.SliceStable(list, func(i, j int) bool { - qualifiedTopUpValidator1, _ := big.NewInt(0).SetString(list[i].QualifiedTopUp, 10) - qualifiedTopUpValidator2, _ := big.NewInt(0).SetString(list[j].QualifiedTopUp, 10) - - return qualifiedTopUpValidator1.Cmp(qualifiedTopUpValidator2) > 0 - }) -} - func (vp *validatorsProvider) getSelectedNodesFromAuction(validatorsMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, error) { vp.auctionLock.RLock() randomness := vp.cachedRandomness @@ -74,6 +105,15 @@ func (vp *validatorsProvider) getSelectedNodesFromAuction(validatorsMap state.Sh return selectedNodes, nil } +func sortList(list []*common.AuctionListValidatorAPIResponse) { + sort.SliceStable(list, func(i, j int) bool { + qualifiedTopUpValidator1, _ := big.NewInt(0).SetString(list[i].QualifiedTopUp, 10) + qualifiedTopUpValidator2, _ := big.NewInt(0).SetString(list[j].QualifiedTopUp, 10) + + return qualifiedTopUpValidator1.Cmp(qualifiedTopUpValidator2) > 0 + }) +} + func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse(selectedNodes []state.ValidatorInfoHandler) []*common.AuctionListValidatorAPIResponse { auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) @@ -132,57 +172,3 @@ func contains(list []state.ValidatorInfoHandler, validator state.ValidatorInfoHa } return false } - -func (vp *validatorsProvider) getValidatorsInfo() (state.ShardValidatorsInfoMapHandler, error) { - vp.auctionLock.RLock() - shouldUpdate := time.Since(vp.lastValidatorsInfoCacheUpdate) > vp.cacheRefreshIntervalDuration - vp.auctionLock.RUnlock() - - if shouldUpdate { - err := vp.updateValidatorsInfoCache() - if err != nil { - return nil, err - } - } - - vp.auctionLock.RLock() - defer vp.auctionLock.RUnlock() - - return cloneValidatorsMap(vp.cachedValidatorsMap) -} - -func (vp *validatorsProvider) updateValidatorsInfoCache() error { - rootHash, err := vp.validatorStatistics.RootHash() - if err != nil { - return err - } - - validatorsMap, err := vp.validatorStatistics.GetValidatorInfoForRootHash(rootHash) - if err != nil { - return err - } - - vp.auctionLock.Lock() - defer vp.auctionLock.Unlock() - - vp.lastValidatorsInfoCacheUpdate = time.Now() - vp.cachedValidatorsMap, err = cloneValidatorsMap(validatorsMap) - vp.cachedRandomness = rootHash - if err != nil { - return err - } - - return nil -} - -func cloneValidatorsMap(validatorsMap state.ShardValidatorsInfoMapHandler) (state.ShardValidatorsInfoMapHandler, error) { - ret := state.NewShardValidatorsInfoMap() - for _, validator := range validatorsMap.GetAllValidatorsInfo() { - err := ret.Add(validator.ShallowClone()) - if err != nil { - return nil, err - } - } - - return ret, nil -} diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index aeb01d6c865..3d1314bf378 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -201,7 +201,7 @@ func TestValidatorsProvider_CallsPopulateAndRegister(t *testing.T) { time.Sleep(time.Millisecond) - assert.Equal(t, int32(1), atomic.LoadInt32(&numPopulateCacheCalled)) + assert.Equal(t, int32(2), atomic.LoadInt32(&numPopulateCacheCalled)) assert.Equal(t, int32(1), atomic.LoadInt32(&numRegisterHandlerCalled)) } @@ -253,6 +253,8 @@ func TestValidatorsProvider_Cancel_startRefreshProcess(t *testing.T) { cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, refreshCache: make(chan uint32), lock: sync.RWMutex{}, + stakingDataProvider: &stakingcommon.StakingDataProviderStub{}, + auctionListSelector: &stakingcommon.AuctionListSelectorStub{}, } ctx, cancelFunc := context.WithCancel(context.Background()) From 2d8cd9495cb824dd855c6224f7f973fe6d7cf78d Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 15:01:52 +0300 Subject: [PATCH 337/958] FEAT: First test --- process/peer/validatorsProviderAuction.go | 7 +- process/peer/validatorsProvider_test.go | 236 ++++-------------- .../stakingcommon/stakingDataProviderStub.go | 4 + 3 files changed, 58 insertions(+), 189 deletions(-) diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 2d4d8ce60b6..e1ba4da32cf 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -43,6 +43,10 @@ func (vp *validatorsProvider) updateAuctionListCache() error { return err } + vp.auctionLock.Lock() + vp.cachedRandomness = rootHash + vp.auctionLock.Unlock() + newCache, err := vp.createValidatorsAuctionCache(validatorsMap) if err != nil { return err @@ -51,7 +55,6 @@ func (vp *validatorsProvider) updateAuctionListCache() error { vp.auctionLock.Lock() vp.lastValidatorsInfoCacheUpdate = time.Now() vp.cachedAuctionValidators = newCache - vp.cachedRandomness = rootHash vp.auctionLock.Unlock() return nil @@ -118,7 +121,7 @@ func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse(selectedNodes auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) for ownerPubKey, ownerData := range vp.stakingDataProvider.GetOwnersData() { - if ownerData.Qualified && ownerData.NumAuctionNodes > 0 { + if ownerData.NumAuctionNodes > 0 { auctionValidator := &common.AuctionListValidatorAPIResponse{ Owner: vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)), NumStakedNodes: ownerData.NumStakedNodes, diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 3d1314bf378..300567ce6c3 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -25,6 +25,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNewValidatorsProvider_WithNilValidatorStatisticsShouldErr(t *testing.T) { @@ -635,197 +636,58 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin func TestValidatorsProvider_GetAuctionList(t *testing.T) { t.Parallel() - /* - t.Run("no entry, should return entry map", func(t *testing.T) { - t.Parallel() + t.Run("empty list, check normal flow is executed", func(t *testing.T) { + args := createDefaultValidatorsProviderArg() - arg := createDefaultValidatorsProviderArg() - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) + expectedRootHash := []byte("rootHash") + ctRootHashCalled := uint32(0) + ctGetValidatorsInfoForRootHash := uint32(0) + ctSelectNodesFromAuctionList := uint32(0) + ctFillValidatorInfoCalled := uint32(0) + ctGetOwnersDataCalled := uint32(0) - response := vp.GetAuctionList() - require.Empty(t, response) - }) - - t.Run("cannot get owner of key, should not fill it", func(t *testing.T) { - t.Parallel() - - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil - } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - return "", errors.New("cannot get owner") - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - return big.NewInt(10), nil - }, - } - - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) - - time.Sleep(arg.CacheRefreshIntervalDurationInSec) - - response := vp.GetAuctionList() - require.Empty(t, response) - }) - - t.Run("cannot get top up for node, should not fill it", func(t *testing.T) { - t.Parallel() - - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil - } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - return "", nil - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - return nil, errors.New("cannot get top up") - }, - } - - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) - - time.Sleep(arg.CacheRefreshIntervalDurationInSec) - - response := vp.GetAuctionList() - require.Empty(t, response) - }) - - t.Run("should work", func(t *testing.T) { - t.Parallel() - - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil - } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-eligible"), - List: string(common.EligibleList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-waiting"), - List: string(common.WaitingList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-leaving"), - List: string(common.LeavingList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey1-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - if "pubkey0-auction" == string(key) { - return "owner0", nil - } - if "pubkey1-auction" == string(key) { - return "owner1", nil - } - return "", nil - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - if "pubkey0-auction" == string(key) { - return big.NewInt(100), nil - } - if "pubkey1-auction" == string(key) { - return big.NewInt(110), nil - } - return big.NewInt(0), nil - }, - } + args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + RootHashCalled: func() ([]byte, error) { + atomic.AddUint32(&ctRootHashCalled, 1) + return expectedRootHash, nil + }, + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + atomic.AddUint32(&ctGetValidatorsInfoForRootHash, 1) + require.Equal(t, expectedRootHash, rootHash) + return state.NewShardValidatorsInfoMap(), nil + }, + } + args.AuctionListSelector = &stakingcommon.AuctionListSelectorStub{ + SelectNodesFromAuctionListCalled: func(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { + atomic.AddUint32(&ctSelectNodesFromAuctionList, 1) + require.Equal(t, expectedRootHash, randomness) + return nil + }, + } + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + FillValidatorInfoCalled: func(validator state.ValidatorInfoHandler) error { + atomic.AddUint32(&ctFillValidatorInfoCalled, 1) + return nil + }, + GetOwnersDataCalled: func() map[string]*epochStart.OwnerData { + atomic.AddUint32(&ctGetOwnersDataCalled, 1) + return nil + }, + } + vp, _ := NewValidatorsProvider(args) + time.Sleep(args.CacheRefreshIntervalDurationInSec) + + list, err := vp.GetAuctionList() + require.Nil(t, err) + require.Empty(t, list) + require.Equal(t, ctRootHashCalled, uint32(2)) + require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(2)) + require.Equal(t, ctFillValidatorInfoCalled, uint32(0)) + require.Equal(t, ctGetOwnersDataCalled, uint32(2)) + require.Equal(t, expectedRootHash, vp.cachedRandomness) - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) - - time.Sleep(arg.CacheRefreshIntervalDurationInSec) - - response := vp.GetAuctionList() - - // the result should contain only auction list validators with the correct owner and top up - expectedResponse := []*common.AuctionListValidatorAPIResponse{ - { - Owner: arg.AddressPubKeyConverter.Encode([]byte("owner0")), - NodeKey: hex.EncodeToString([]byte("pubkey0-auction")), - TopUp: "100", - }, - { - Owner: arg.AddressPubKeyConverter.Encode([]byte("owner1")), - NodeKey: hex.EncodeToString([]byte("pubkey1-auction")), - TopUp: "110", - }, - } - require.Equal(t, expectedResponse, response) - }) + }) - */ } func createMockValidatorInfo() *state.ValidatorInfo { diff --git a/testscommon/stakingcommon/stakingDataProviderStub.go b/testscommon/stakingcommon/stakingDataProviderStub.go index e911f21d348..d05715e7d41 100644 --- a/testscommon/stakingcommon/stakingDataProviderStub.go +++ b/testscommon/stakingcommon/stakingDataProviderStub.go @@ -17,6 +17,7 @@ type StakingDataProviderStub struct { FillValidatorInfoCalled func(validator state.ValidatorInfoHandler) error ComputeUnQualifiedNodesCalled func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) GetBlsKeyOwnerCalled func(blsKey []byte) (string, error) + GetOwnersDataCalled func() map[string]*epochStart.OwnerData } // FillValidatorInfo - @@ -89,6 +90,9 @@ func (sdps *StakingDataProviderStub) GetNumOfValidatorsInCurrentEpoch() uint32 { // GetOwnersData - func (sdps *StakingDataProviderStub) GetOwnersData() map[string]*epochStart.OwnerData { + if sdps.GetOwnersDataCalled != nil { + return sdps.GetOwnersDataCalled() + } return nil } From 61285b1da2de5afe40429e9b6c93c66ae5b8baf1 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 16:44:24 +0300 Subject: [PATCH 338/958] FEAT: Add complex happy path test --- process/peer/validatorsProviderAuction.go | 4 +- process/peer/validatorsProvider_test.go | 189 ++++++++++++++++++++++ 2 files changed, 191 insertions(+), 2 deletions(-) diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index e1ba4da32cf..4ac08167ad6 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -25,7 +25,7 @@ func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAP } vp.auctionLock.RLock() - ret := make([]*common.AuctionListValidatorAPIResponse, 0, len(vp.cachedAuctionValidators)) + ret := make([]*common.AuctionListValidatorAPIResponse, len(vp.cachedAuctionValidators)) copy(ret, vp.cachedAuctionValidators) vp.auctionLock.RUnlock() @@ -151,7 +151,7 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( BlsKey: vp.addressPubKeyConverter.Encode(nodeInAuction.GetPublicKey()), Qualified: false, } - if contains(selectedNodes, nodeInAuction) { + if ownerData.Qualified && contains(selectedNodes, nodeInAuction) { auctionNode.Qualified = true numOwnerQualifiedNodes++ } diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 300567ce6c3..9f570730345 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -685,6 +685,195 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { require.Equal(t, ctFillValidatorInfoCalled, uint32(0)) require.Equal(t, ctGetOwnersDataCalled, uint32(2)) require.Equal(t, expectedRootHash, vp.cachedRandomness) + }) + + t.Run("normal flow, check data is correctly computed", func(t *testing.T) { + args := createDefaultValidatorsProviderArg() + + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1"), List: string(common.AuctionList)} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2"), List: string(common.AuctionList)} + v3 := &state.ValidatorInfo{PublicKey: []byte("pk3"), List: string(common.AuctionList)} + v4 := &state.ValidatorInfo{PublicKey: []byte("pk4"), List: string(common.AuctionList)} + v5 := &state.ValidatorInfo{PublicKey: []byte("pk5"), List: string(common.AuctionList)} + v6 := &state.ValidatorInfo{PublicKey: []byte("pk6"), List: string(common.AuctionList)} + v7 := &state.ValidatorInfo{PublicKey: []byte("pk7"), List: string(common.EligibleList)} + v8 := &state.ValidatorInfo{PublicKey: []byte("pk8"), List: string(common.WaitingList)} + v9 := &state.ValidatorInfo{PublicKey: []byte("pk9"), List: string(common.LeavingList)} + v10 := &state.ValidatorInfo{PublicKey: []byte("pk10"), List: string(common.JailedList)} + + owner1 := "owner1" + owner2 := "owner2" + owner3 := "owner3" + owner4 := "owner4" + owner5 := "owner5" + ownersData := map[string]*epochStart.OwnerData{ + owner1: { + NumStakedNodes: 3, + NumActiveNodes: 1, + NumAuctionNodes: 2, + TotalTopUp: big.NewInt(7500), + TopUpPerNode: big.NewInt(2500), + AuctionList: []state.ValidatorInfoHandler{v1, v2}, // owner1 will have v1 & v2 selected + Qualified: true, // with qualifiedTopUp = 2500 + }, + owner2: { + NumStakedNodes: 3, + NumActiveNodes: 1, + NumAuctionNodes: 2, + TotalTopUp: big.NewInt(3000), + TopUpPerNode: big.NewInt(1000), + AuctionList: []state.ValidatorInfoHandler{v3, v4}, // owner2 will have v3 selected + Qualified: true, // with qualifiedTopUp = 1500 + }, + owner3: { + NumStakedNodes: 2, + NumActiveNodes: 0, + NumAuctionNodes: 2, + TotalTopUp: big.NewInt(4000), + TopUpPerNode: big.NewInt(2000), + AuctionList: []state.ValidatorInfoHandler{v5, v6}, // owner3 will have v5 selected + Qualified: true, // with qualifiedTopUp = 4000 + }, + owner4: { + NumStakedNodes: 3, + NumActiveNodes: 2, + NumAuctionNodes: 1, + TotalTopUp: big.NewInt(0), + TopUpPerNode: big.NewInt(0), + AuctionList: []state.ValidatorInfoHandler{v7}, + Qualified: false, + }, + owner5: { + NumStakedNodes: 5, + NumActiveNodes: 5, + NumAuctionNodes: 0, + TotalTopUp: big.NewInt(5000), + TopUpPerNode: big.NewInt(1000), + AuctionList: []state.ValidatorInfoHandler{}, + Qualified: true, + }, + } + + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(v1) + _ = validatorsMap.Add(v2) + _ = validatorsMap.Add(v3) + _ = validatorsMap.Add(v4) + _ = validatorsMap.Add(v5) + _ = validatorsMap.Add(v6) + _ = validatorsMap.Add(v7) + _ = validatorsMap.Add(v8) + _ = validatorsMap.Add(v9) + _ = validatorsMap.Add(v10) + + args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + return validatorsMap, nil + }, + } + args.AuctionListSelector = &stakingcommon.AuctionListSelectorStub{ + SelectNodesFromAuctionListCalled: func(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { + selectedV1 := v1.ShallowClone() + selectedV1.SetList(string(common.SelectedFromAuctionList)) + _ = validatorsInfoMap.Replace(v1, selectedV1) + + selectedV2 := v2.ShallowClone() + selectedV2.SetList(string(common.SelectedFromAuctionList)) + _ = validatorsInfoMap.Replace(v2, selectedV2) + + selectedV3 := v3.ShallowClone() + selectedV3.SetList(string(common.SelectedFromAuctionList)) + _ = validatorsInfoMap.Replace(v3, selectedV3) + + selectedV5 := v5.ShallowClone() + selectedV5.SetList(string(common.SelectedFromAuctionList)) + _ = validatorsInfoMap.Replace(v5, selectedV5) + + return nil + }, + } + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetOwnersDataCalled: func() map[string]*epochStart.OwnerData { + return ownersData + }, + } + + vp, _ := NewValidatorsProvider(args) + time.Sleep(args.CacheRefreshIntervalDurationInSec) + + expectedList := []*common.AuctionListValidatorAPIResponse{ + { + Owner: args.AddressPubKeyConverter.Encode([]byte(owner3)), + NumStakedNodes: 2, + TotalTopUp: "4000", + TopUpPerNode: "2000", + QualifiedTopUp: "4000", + AuctionList: []common.AuctionNode{ + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v5.PublicKey), + Qualified: true, + }, + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v6.PublicKey), + Qualified: false, + }, + }, + }, + + { + Owner: args.AddressPubKeyConverter.Encode([]byte(owner1)), + NumStakedNodes: 3, + TotalTopUp: "7500", + TopUpPerNode: "2500", + QualifiedTopUp: "2500", + AuctionList: []common.AuctionNode{ + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v1.PublicKey), + Qualified: true, + }, + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v2.PublicKey), + Qualified: true, + }, + }, + }, + + { + Owner: args.AddressPubKeyConverter.Encode([]byte(owner2)), + NumStakedNodes: 3, + TotalTopUp: "3000", + TopUpPerNode: "1000", + QualifiedTopUp: "1500", + AuctionList: []common.AuctionNode{ + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v3.PublicKey), + Qualified: true, + }, + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v4.PublicKey), + Qualified: false, + }, + }, + }, + + { + Owner: args.AddressPubKeyConverter.Encode([]byte(owner4)), + NumStakedNodes: 3, + TotalTopUp: "0", + TopUpPerNode: "0", + QualifiedTopUp: "0", + AuctionList: []common.AuctionNode{ + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v7.PublicKey), + Qualified: false, + }, + }, + }, + } + + list, err := vp.GetAuctionList() + require.Nil(t, err) + require.Equal(t, expectedList, list) }) From 2bbc7a95b9317101ab33304248b88ff9813d9b1c Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 17:13:32 +0300 Subject: [PATCH 339/958] FEAT: Full branch coverage --- process/peer/validatorsProvider_test.go | 101 ++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 9f570730345..5962ad9aa71 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/ElrondNetwork/elrond-go-core/core" + coreAtomic "github.com/ElrondNetwork/elrond-go-core/core/atomic" "github.com/ElrondNetwork/elrond-go-core/core/check" "github.com/ElrondNetwork/elrond-go-core/data/block" "github.com/ElrondNetwork/elrond-go/common" @@ -636,7 +637,99 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin func TestValidatorsProvider_GetAuctionList(t *testing.T) { t.Parallel() + t.Run("error getting root hash", func(t *testing.T) { + t.Parallel() + args := createDefaultValidatorsProviderArg() + expectedErr := errors.New("local error") + args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + RootHashCalled: func() ([]byte, error) { + return nil, expectedErr + }, + } + vp, _ := NewValidatorsProvider(args) + time.Sleep(args.CacheRefreshIntervalDurationInSec) + + list, err := vp.GetAuctionList() + require.Nil(t, list) + require.Equal(t, expectedErr, err) + }) + + t.Run("error getting validators info for root hash", func(t *testing.T) { + t.Parallel() + args := createDefaultValidatorsProviderArg() + expectedErr := errors.New("local error") + args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + return nil, expectedErr + }, + } + vp, _ := NewValidatorsProvider(args) + time.Sleep(args.CacheRefreshIntervalDurationInSec) + + list, err := vp.GetAuctionList() + require.Nil(t, list) + require.Equal(t, expectedErr, err) + }) + + t.Run("error filling validator info, staking data provider cache should be cleaned", func(t *testing.T) { + t.Parallel() + args := createDefaultValidatorsProviderArg() + + cleanCalled := &coreAtomic.Flag{} + expectedValidator := &state.ValidatorInfo{PublicKey: []byte("pubKey"), List: string(common.AuctionList)} + expectedErr := errors.New("local error") + args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(expectedValidator) + return validatorsMap, nil + }, + } + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + FillValidatorInfoCalled: func(validator state.ValidatorInfoHandler) error { + require.Equal(t, expectedValidator, validator) + return expectedErr + }, + CleanCalled: func() { + cleanCalled.SetValue(true) + }, + } + vp, _ := NewValidatorsProvider(args) + time.Sleep(args.CacheRefreshIntervalDurationInSec) + + list, err := vp.GetAuctionList() + require.Nil(t, list) + require.Equal(t, expectedErr, err) + require.True(t, cleanCalled.IsSet()) + }) + + t.Run("error selecting nodes from auction, staking data provider cache should be cleaned", func(t *testing.T) { + t.Parallel() + args := createDefaultValidatorsProviderArg() + + cleanCalled := &coreAtomic.Flag{} + expectedErr := errors.New("local error") + args.AuctionListSelector = &stakingcommon.AuctionListSelectorStub{ + SelectNodesFromAuctionListCalled: func(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { + return expectedErr + }, + } + args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + CleanCalled: func() { + cleanCalled.SetValue(true) + }, + } + vp, _ := NewValidatorsProvider(args) + time.Sleep(args.CacheRefreshIntervalDurationInSec) + + list, err := vp.GetAuctionList() + require.Nil(t, list) + require.Equal(t, expectedErr, err) + require.True(t, cleanCalled.IsSet()) + }) + t.Run("empty list, check normal flow is executed", func(t *testing.T) { + t.Parallel() args := createDefaultValidatorsProviderArg() expectedRootHash := []byte("rootHash") @@ -675,11 +768,12 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }, } vp, _ := NewValidatorsProvider(args) - time.Sleep(args.CacheRefreshIntervalDurationInSec) + time.Sleep(2 * args.CacheRefreshIntervalDurationInSec) list, err := vp.GetAuctionList() require.Nil(t, err) require.Empty(t, list) + // updateCache is called on constructor, that's why the expected counter is 2 require.Equal(t, ctRootHashCalled, uint32(2)) require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(2)) require.Equal(t, ctFillValidatorInfoCalled, uint32(0)) @@ -688,6 +782,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }) t.Run("normal flow, check data is correctly computed", func(t *testing.T) { + t.Parallel() args := createDefaultValidatorsProviderArg() v1 := &state.ValidatorInfo{PublicKey: []byte("pk1"), List: string(common.AuctionList)} @@ -819,7 +914,6 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }, }, }, - { Owner: args.AddressPubKeyConverter.Encode([]byte(owner1)), NumStakedNodes: 3, @@ -837,7 +931,6 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }, }, }, - { Owner: args.AddressPubKeyConverter.Encode([]byte(owner2)), NumStakedNodes: 3, @@ -855,7 +948,6 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }, }, }, - { Owner: args.AddressPubKeyConverter.Encode([]byte(owner4)), NumStakedNodes: 3, @@ -874,7 +966,6 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { list, err := vp.GetAuctionList() require.Nil(t, err) require.Equal(t, expectedList, list) - }) } From 138779901934d190b072078e6714fc818a344bd3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 17:20:26 +0300 Subject: [PATCH 340/958] FIX: Broken test --- factory/processComponents.go | 1 + 1 file changed, 1 insertion(+) diff --git a/factory/processComponents.go b/factory/processComponents.go index d03a0440b8d..cc4eb2e5e1f 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -543,6 +543,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { MaxRating: pcf.maxRating, ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), + AuctionListSelector: pcf.auctionListSelector, } validatorsProvider, err := peer.NewValidatorsProvider(argVSP) From 2052033154f91b36aa31a98102e1f470cb2b34a3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 8 Jun 2022 17:43:46 +0300 Subject: [PATCH 341/958] FIX: Small fixes + test nil --- process/peer/validatorsProvider.go | 34 +++++++++++------------ process/peer/validatorsProviderAuction.go | 25 +++++++++-------- process/peer/validatorsProvider_test.go | 15 ++++++++-- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 84293d3bfad..a34e78d9bdf 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -21,22 +21,22 @@ var _ process.ValidatorsProvider = (*validatorsProvider)(nil) // validatorsProvider is the main interface for validators' provider type validatorsProvider struct { - nodesCoordinator process.NodesCoordinator - validatorStatistics process.ValidatorStatisticsProcessor - cache map[string]*state.ValidatorApiResponse - cachedAuctionValidators []*common.AuctionListValidatorAPIResponse - cachedRandomness []byte - cacheRefreshIntervalDuration time.Duration - refreshCache chan uint32 - lastCacheUpdate time.Time - lastValidatorsInfoCacheUpdate time.Time - lock sync.RWMutex - auctionLock sync.RWMutex - cancelFunc func() - validatorPubKeyConverter core.PubkeyConverter - addressPubKeyConverter core.PubkeyConverter - stakingDataProvider epochStart.StakingDataProvider - auctionListSelector epochStart.AuctionListSelector + nodesCoordinator process.NodesCoordinator + validatorStatistics process.ValidatorStatisticsProcessor + cache map[string]*state.ValidatorApiResponse + cachedAuctionValidators []*common.AuctionListValidatorAPIResponse + cachedRandomness []byte + cacheRefreshIntervalDuration time.Duration + refreshCache chan uint32 + lastCacheUpdate time.Time + lastAuctionCacheUpdate time.Time + lock sync.RWMutex + auctionMutex sync.RWMutex + cancelFunc func() + validatorPubKeyConverter core.PubkeyConverter + addressPubKeyConverter core.PubkeyConverter + stakingDataProvider epochStart.StakingDataProvider + auctionListSelector epochStart.AuctionListSelector maxRating uint32 currentEpoch uint32 @@ -101,7 +101,7 @@ func NewValidatorsProvider( cacheRefreshIntervalDuration: args.CacheRefreshIntervalDurationInSec, refreshCache: make(chan uint32), lock: sync.RWMutex{}, - auctionLock: sync.RWMutex{}, + auctionMutex: sync.RWMutex{}, cancelFunc: cancelfunc, maxRating: args.MaxRating, validatorPubKeyConverter: args.ValidatorPubKeyConverter, diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 4ac08167ad6..6054deaed0b 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -13,9 +13,9 @@ import ( // GetAuctionList returns an array containing the validators that are currently in the auction list func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) { - vp.auctionLock.RLock() - shouldUpdate := time.Since(vp.lastValidatorsInfoCacheUpdate) > vp.cacheRefreshIntervalDuration - vp.auctionLock.RUnlock() + vp.auctionMutex.RLock() + shouldUpdate := time.Since(vp.lastAuctionCacheUpdate) > vp.cacheRefreshIntervalDuration + vp.auctionMutex.RUnlock() if shouldUpdate { err := vp.updateAuctionListCache() @@ -24,10 +24,10 @@ func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAP } } - vp.auctionLock.RLock() + vp.auctionMutex.RLock() ret := make([]*common.AuctionListValidatorAPIResponse, len(vp.cachedAuctionValidators)) copy(ret, vp.cachedAuctionValidators) - vp.auctionLock.RUnlock() + vp.auctionMutex.RUnlock() return ret, nil } @@ -43,25 +43,26 @@ func (vp *validatorsProvider) updateAuctionListCache() error { return err } - vp.auctionLock.Lock() + vp.auctionMutex.Lock() vp.cachedRandomness = rootHash - vp.auctionLock.Unlock() + vp.auctionMutex.Unlock() newCache, err := vp.createValidatorsAuctionCache(validatorsMap) if err != nil { return err } - vp.auctionLock.Lock() - vp.lastValidatorsInfoCacheUpdate = time.Now() + vp.auctionMutex.Lock() + vp.lastAuctionCacheUpdate = time.Now() vp.cachedAuctionValidators = newCache - vp.auctionLock.Unlock() + vp.auctionMutex.Unlock() return nil } func (vp *validatorsProvider) createValidatorsAuctionCache(validatorsMap state.ShardValidatorsInfoMapHandler) ([]*common.AuctionListValidatorAPIResponse, error) { defer vp.stakingDataProvider.Clean() + err := vp.fillAllValidatorsInfo(validatorsMap) if err != nil { return nil, err @@ -89,9 +90,9 @@ func (vp *validatorsProvider) fillAllValidatorsInfo(validatorsMap state.ShardVal } func (vp *validatorsProvider) getSelectedNodesFromAuction(validatorsMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, error) { - vp.auctionLock.RLock() + vp.auctionMutex.RLock() randomness := vp.cachedRandomness - vp.auctionLock.RUnlock() + vp.auctionMutex.RUnlock() err := vp.auctionListSelector.SelectNodesFromAuctionList(validatorsMap, randomness) if err != nil { diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 5962ad9aa71..29763533a3c 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -45,7 +45,7 @@ func TestNewValidatorsProvider_WithMaxRatingZeroShouldErr(t *testing.T) { assert.Nil(t, vp) } -func TestNewValidatorsProvider_WithNilValidatorPubkeyConverterShouldErr(t *testing.T) { +func TestNewValidatorsProvider_WithNilValidatorPubKeyConverterShouldErr(t *testing.T) { arg := createDefaultValidatorsProviderArg() arg.ValidatorPubKeyConverter = nil vp, err := NewValidatorsProvider(arg) @@ -74,7 +74,7 @@ func TestNewValidatorsProvider_WithNilStakingDataProviderShouldErr(t *testing.T) assert.True(t, check.IfNil(vp)) } -func TestNewValidatorsProvider_WithNilNodesCoordinatorrShouldErr(t *testing.T) { +func TestNewValidatorsProvider_WithNilNodesCoordinatorShouldErr(t *testing.T) { arg := createDefaultValidatorsProviderArg() arg.NodesCoordinator = nil vp, err := NewValidatorsProvider(arg) @@ -92,7 +92,7 @@ func TestNewValidatorsProvider_WithNilStartOfEpochTriggerShouldErr(t *testing.T) assert.True(t, check.IfNil(vp)) } -func TestNewValidatorsProvider_WithNilRefresCacheIntervalInSecShouldErr(t *testing.T) { +func TestNewValidatorsProvider_WithZeroRefreshCacheIntervalInSecShouldErr(t *testing.T) { arg := createDefaultValidatorsProviderArg() arg.CacheRefreshIntervalDurationInSec = 0 vp, err := NewValidatorsProvider(arg) @@ -101,6 +101,15 @@ func TestNewValidatorsProvider_WithNilRefresCacheIntervalInSecShouldErr(t *testi assert.True(t, check.IfNil(vp)) } +func TestNewValidatorsProvider_WithNilAuctionListSelectorShouldErr(t *testing.T) { + arg := createDefaultValidatorsProviderArg() + arg.AuctionListSelector = nil + vp, err := NewValidatorsProvider(arg) + + require.Nil(t, vp) + require.Equal(t, epochStart.ErrNilAuctionListSelector, err) +} + func TestValidatorsProvider_GetLatestValidatorsSecondHashDoesNotExist(t *testing.T) { mut := sync.Mutex{} root := []byte("rootHash") From 178290f519652955842d5c030edcd829d65ee550 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 9 Jun 2022 12:21:36 +0300 Subject: [PATCH 342/958] FIX: Remove updateCache on construct --- process/peer/validatorsProvider.go | 4 ---- process/peer/validatorsProvider_test.go | 9 ++++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index a34e78d9bdf..15a956ba8c3 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -192,10 +192,6 @@ func (vp *validatorsProvider) epochStartEventHandler() nodesCoordinator.EpochSta func (vp *validatorsProvider) startRefreshProcess(ctx context.Context) { for { vp.updateCache() - err := vp.updateAuctionListCache() - if err != nil { - log.Error("could not update validators auction info cache", "error", err) - } select { case epoch := <-vp.refreshCache: diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 29763533a3c..2d5a88b8f1d 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -212,7 +212,7 @@ func TestValidatorsProvider_CallsPopulateAndRegister(t *testing.T) { time.Sleep(time.Millisecond) - assert.Equal(t, int32(2), atomic.LoadInt32(&numPopulateCacheCalled)) + assert.Equal(t, int32(1), atomic.LoadInt32(&numPopulateCacheCalled)) assert.Equal(t, int32(1), atomic.LoadInt32(&numRegisterHandlerCalled)) } @@ -782,11 +782,10 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { list, err := vp.GetAuctionList() require.Nil(t, err) require.Empty(t, list) - // updateCache is called on constructor, that's why the expected counter is 2 - require.Equal(t, ctRootHashCalled, uint32(2)) - require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(2)) + require.Equal(t, ctRootHashCalled, uint32(1)) + require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(1)) require.Equal(t, ctFillValidatorInfoCalled, uint32(0)) - require.Equal(t, ctGetOwnersDataCalled, uint32(2)) + require.Equal(t, ctGetOwnersDataCalled, uint32(1)) require.Equal(t, expectedRootHash, vp.cachedRandomness) }) From 30388701d4f5b49e136a64522dac63b34ee40ab4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 9 Jun 2022 12:38:14 +0300 Subject: [PATCH 343/958] FIX: Build --- api/groups/validatorGroup_test.go | 8 +++++--- factory/disabled/auctionListSelector.go | 2 +- process/peer/validatorsProvider.go | 1 - process/peer/validatorsProvider_test.go | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/api/groups/validatorGroup_test.go b/api/groups/validatorGroup_test.go index 67cf8c5613a..5bb21ad51fc 100644 --- a/api/groups/validatorGroup_test.go +++ b/api/groups/validatorGroup_test.go @@ -141,9 +141,11 @@ func TestAuctionList_ReturnsSuccessfully(t *testing.T) { auctionListToReturn := []*common.AuctionListValidatorAPIResponse{ { - Owner: "owner", - NodeKey: "nodeKey", - TopUp: "112233", + Owner: "owner", + NumStakedNodes: 4, + TotalTopUp: "1234", + TopUpPerNode: "4321", + QualifiedTopUp: "4444", }, } facade := mock.FacadeStub{ diff --git a/factory/disabled/auctionListSelector.go b/factory/disabled/auctionListSelector.go index d8920d50920..a5f4b7412a7 100644 --- a/factory/disabled/auctionListSelector.go +++ b/factory/disabled/auctionListSelector.go @@ -10,7 +10,7 @@ func NewDisabledAuctionListSelector() *auctionListSelector { return &auctionListSelector{} } -// SelectNodesFromAuctionList returns il +// SelectNodesFromAuctionList returns nil func (als *auctionListSelector) SelectNodesFromAuctionList(state.ShardValidatorsInfoMapHandler, []byte) error { return nil } diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 15a956ba8c3..7eba7cbb188 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -192,7 +192,6 @@ func (vp *validatorsProvider) epochStartEventHandler() nodesCoordinator.EpochSta func (vp *validatorsProvider) startRefreshProcess(ctx context.Context) { for { vp.updateCache() - select { case epoch := <-vp.refreshCache: vp.lock.Lock() diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 2d5a88b8f1d..718d1071f7c 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -777,7 +777,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }, } vp, _ := NewValidatorsProvider(args) - time.Sleep(2 * args.CacheRefreshIntervalDurationInSec) + time.Sleep(args.CacheRefreshIntervalDurationInSec) list, err := vp.GetAuctionList() require.Nil(t, err) From 7fff5b8ba76548151c53bdc95c8633850dfbf442 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 9 Jun 2022 15:35:24 +0300 Subject: [PATCH 344/958] FIX: Package import --- epochStart/metachain/systemSCs_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index d419a068abf..ec8c56f6c3a 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -45,6 +45,7 @@ import ( dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" "github.com/ElrondNetwork/elrond-go/testscommon/shardingMocks" + "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" "github.com/ElrondNetwork/elrond-go/trie" "github.com/ElrondNetwork/elrond-go/vm" @@ -748,7 +749,7 @@ func createFullArgumentsForSystemSCProcessing(stakingV2EnableEpoch uint32, trieS }}, EpochNotifier: &epochNotifier.EpochNotifierStub{}, } - builtInFuncs, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) + builtInFuncs, _, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) testDataPool := dataRetrieverMock.NewPoolsHolderMock() argsHook := hooks.ArgBlockChainHook{ From 4a19f66ef35bebbc8d1a6891d405d0d5c40073a4 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 9 Jun 2022 16:43:18 +0300 Subject: [PATCH 345/958] FIX: Merge conflict --- .../vm/staking/systemSCCreator.go | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 9a6da6e4c71..95a3a0e72ec 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -25,6 +25,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" "github.com/ElrondNetwork/elrond-go/vm" vmcommon "github.com/ElrondNetwork/elrond-vm-common" + vmcommonMock "github.com/ElrondNetwork/elrond-vm-common/mock" ) func createSystemSCProcessor( @@ -142,22 +143,23 @@ func createBlockChainHook( ShardCoordinator: shardCoordinator, EpochNotifier: coreComponents.EpochNotifier(), } - builtInFunctionsContainer, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) + builtInFunctionsContainer, _, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) argsHook := hooks.ArgBlockChainHook{ - Accounts: accountsAdapter, - PubkeyConv: coreComponents.AddressPubKeyConverter(), - StorageService: dataComponents.StorageService(), - BlockChain: dataComponents.Blockchain(), - ShardCoordinator: shardCoordinator, - Marshalizer: coreComponents.InternalMarshalizer(), - Uint64Converter: coreComponents.Uint64ByteSliceConverter(), - NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, - BuiltInFunctions: builtInFunctionsContainer, - DataPool: dataComponents.Datapool(), - CompiledSCPool: dataComponents.Datapool().SmartContracts(), - EpochNotifier: coreComponents.EpochNotifier(), - NilCompiledSCStore: true, + Accounts: accountsAdapter, + PubkeyConv: coreComponents.AddressPubKeyConverter(), + StorageService: dataComponents.StorageService(), + BlockChain: dataComponents.Blockchain(), + ShardCoordinator: shardCoordinator, + Marshalizer: coreComponents.InternalMarshalizer(), + Uint64Converter: coreComponents.Uint64ByteSliceConverter(), + NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, + BuiltInFunctions: builtInFunctionsContainer, + DataPool: dataComponents.Datapool(), + CompiledSCPool: dataComponents.Datapool().SmartContracts(), + EpochNotifier: coreComponents.EpochNotifier(), + GlobalSettingsHandler: &vmcommonMock.GlobalSettingsHandlerStub{}, + NilCompiledSCStore: true, } blockChainHook, _ := hooks.NewBlockChainHookImpl(argsHook) From 174f9db2cd24be3b6644c69bbd1f1b77d51847e7 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 10 Jun 2022 11:49:54 +0300 Subject: [PATCH 346/958] FIX: After review + ComputeUnqualifiedNodes --- common/dtos.go | 12 +++---- factory/blockProcessorCreator.go | 9 ++++-- factory/disabled/stakingDataProvider.go | 38 ----------------------- factory/processComponents.go | 4 +-- process/peer/interface.go | 11 +++++++ process/peer/validatorsProvider.go | 20 ++++++------ process/peer/validatorsProviderAuction.go | 33 ++++++++++++-------- process/peer/validatorsProvider_test.go | 14 ++++++--- 8 files changed, 66 insertions(+), 75 deletions(-) diff --git a/common/dtos.go b/common/dtos.go index 6174bd23503..6dc635cc275 100644 --- a/common/dtos.go +++ b/common/dtos.go @@ -22,10 +22,10 @@ type AuctionNode struct { // AuctionListValidatorAPIResponse holds the data needed for an auction node validator for responding to API calls type AuctionListValidatorAPIResponse struct { - Owner string `json:"owner"` - NumStakedNodes int64 `json:"numStakedNodes"` - TotalTopUp string `json:"totalTopUp"` - TopUpPerNode string `json:"topUpPerNode"` - QualifiedTopUp string `json:"qualifiedTopUp"` - AuctionList []AuctionNode `json:"auctionList"` + Owner string `json:"owner"` + NumStakedNodes int64 `json:"numStakedNodes"` + TotalTopUp string `json:"totalTopUp"` + TopUpPerNode string `json:"topUpPerNode"` + QualifiedTopUp string `json:"qualifiedTopUp"` + AuctionList []*AuctionNode `json:"auctionList"` } diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index e9b8d38c304..402e78562f1 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -424,7 +424,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( vmFactoryForProcessing: vmFactory, } - pcf.stakingDataProvider = factoryDisabled.NewDisabledStakingDataProvider() + pcf.stakingDataProviderAPI = factoryDisabled.NewDisabledStakingDataProvider() pcf.auctionListSelector = factoryDisabled.NewDisabledAuctionListSelector() return blockProcessorComponents, nil @@ -742,7 +742,12 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } - pcf.stakingDataProvider = stakingDataProvider + stakingDataProviderAPI, err := metachainEpochStart.NewStakingDataProvider(argsStakingDataProvider) + if err != nil { + return nil, err + } + + pcf.stakingDataProviderAPI = stakingDataProviderAPI rewardsStorage := pcf.data.StorageService().GetStorer(dataRetriever.RewardTransactionUnit) miniBlockStorage := pcf.data.StorageService().GetStorer(dataRetriever.MiniBlockUnit) diff --git a/factory/disabled/stakingDataProvider.go b/factory/disabled/stakingDataProvider.go index 8ade3523ef8..0adf81a61ba 100644 --- a/factory/disabled/stakingDataProvider.go +++ b/factory/disabled/stakingDataProvider.go @@ -1,14 +1,10 @@ package disabled import ( - "math/big" - "github.com/ElrondNetwork/elrond-go/epochStart" "github.com/ElrondNetwork/elrond-go/state" ) -var zeroBI = big.NewInt(0) - type stakingDataProvider struct { } @@ -17,26 +13,6 @@ func NewDisabledStakingDataProvider() *stakingDataProvider { return &stakingDataProvider{} } -// GetTotalStakeEligibleNodes returns an empty big integer -func (s *stakingDataProvider) GetTotalStakeEligibleNodes() *big.Int { - return zeroBI -} - -// GetTotalTopUpStakeEligibleNodes returns an empty big integer -func (s *stakingDataProvider) GetTotalTopUpStakeEligibleNodes() *big.Int { - return zeroBI -} - -// GetNodeStakedTopUp returns an empty big integer and a nil error -func (s *stakingDataProvider) GetNodeStakedTopUp(_ []byte) (*big.Int, error) { - return zeroBI, nil -} - -// PrepareStakingData returns a nil error -func (s *stakingDataProvider) PrepareStakingData(state.ShardValidatorsInfoMapHandler) error { - return nil -} - // FillValidatorInfo returns a nil error func (s *stakingDataProvider) FillValidatorInfo(state.ValidatorInfoHandler) error { return nil @@ -47,16 +23,6 @@ func (s *stakingDataProvider) ComputeUnQualifiedNodes(_ state.ShardValidatorsInf return nil, nil, nil } -// GetBlsKeyOwner returns an empty key and a nil error -func (s *stakingDataProvider) GetBlsKeyOwner(_ []byte) (string, error) { - return "", nil -} - -// GetNumOfValidatorsInCurrentEpoch returns 0 -func (s *stakingDataProvider) GetNumOfValidatorsInCurrentEpoch() uint32 { - return 0 -} - // GetOwnersData returns nil func (s *stakingDataProvider) GetOwnersData() map[string]*epochStart.OwnerData { return nil @@ -66,10 +32,6 @@ func (s *stakingDataProvider) GetOwnersData() map[string]*epochStart.OwnerData { func (s *stakingDataProvider) Clean() { } -// EpochConfirmed does nothing -func (s *stakingDataProvider) EpochConfirmed(_ uint32, _ uint64) { -} - // IsInterfaceNil returns true if there is no value under the interface func (s *stakingDataProvider) IsInterfaceNil() bool { return s == nil diff --git a/factory/processComponents.go b/factory/processComponents.go index cc4eb2e5e1f..e50e5cfbbd8 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -167,7 +167,7 @@ type processComponentsFactory struct { historyRepo dblookupext.HistoryRepository epochNotifier process.EpochNotifier importHandler update.ImportHandler - stakingDataProvider epochStart.StakingDataProvider + stakingDataProviderAPI peer.StakingDataProviderAPI auctionListSelector epochStart.AuctionListSelector data DataComponentsHolder @@ -539,7 +539,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { EpochStartEventNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), CacheRefreshIntervalDurationInSec: cacheRefreshDuration, ValidatorStatistics: validatorStatisticsProcessor, - StakingDataProvider: pcf.stakingDataProvider, + StakingDataProvider: pcf.stakingDataProviderAPI, MaxRating: pcf.maxRating, ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), diff --git a/process/peer/interface.go b/process/peer/interface.go index c166fdd5e58..9400740259c 100644 --- a/process/peer/interface.go +++ b/process/peer/interface.go @@ -2,6 +2,8 @@ package peer import ( "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/ElrondNetwork/elrond-go/epochStart" + "github.com/ElrondNetwork/elrond-go/state" ) // DataPool indicates the main functionality needed in order to fetch the required blocks from the pool @@ -9,3 +11,12 @@ type DataPool interface { Headers() dataRetriever.HeadersPool IsInterfaceNil() bool } + +// StakingDataProviderAPI is able to provide staking data from the system smart contracts +type StakingDataProviderAPI interface { + ComputeUnQualifiedNodes(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) + FillValidatorInfo(validator state.ValidatorInfoHandler) error + GetOwnersData() map[string]*epochStart.OwnerData + Clean() + IsInterfaceNil() bool +} diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 7eba7cbb188..ed44297992b 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -35,7 +35,7 @@ type validatorsProvider struct { cancelFunc func() validatorPubKeyConverter core.PubkeyConverter addressPubKeyConverter core.PubkeyConverter - stakingDataProvider epochStart.StakingDataProvider + stakingDataProvider StakingDataProviderAPI auctionListSelector epochStart.AuctionListSelector maxRating uint32 @@ -50,7 +50,7 @@ type ArgValidatorsProvider struct { ValidatorStatistics process.ValidatorStatisticsProcessor ValidatorPubKeyConverter core.PubkeyConverter AddressPubKeyConverter core.PubkeyConverter - StakingDataProvider epochStart.StakingDataProvider + StakingDataProvider StakingDataProviderAPI AuctionListSelector epochStart.AuctionListSelector StartEpoch uint32 MaxRating uint32 @@ -118,10 +118,16 @@ func NewValidatorsProvider( // GetLatestValidators gets the latest configuration of validators from the peerAccountsTrie func (vp *validatorsProvider) GetLatestValidators() map[string]*state.ValidatorApiResponse { - return vp.getValidators() + vp.updateCacheIfNeeded() + + vp.lock.RLock() + clonedMap := cloneMap(vp.cache) + vp.lock.RUnlock() + + return clonedMap } -func (vp *validatorsProvider) getValidators() map[string]*state.ValidatorApiResponse { +func (vp *validatorsProvider) updateCacheIfNeeded() { vp.lock.RLock() shouldUpdate := time.Since(vp.lastCacheUpdate) > vp.cacheRefreshIntervalDuration vp.lock.RUnlock() @@ -129,12 +135,6 @@ func (vp *validatorsProvider) getValidators() map[string]*state.ValidatorApiResp if shouldUpdate { vp.updateCache() } - - vp.lock.RLock() - clonedMap := cloneMap(vp.cache) - vp.lock.RUnlock() - - return clonedMap } func cloneMap(cache map[string]*state.ValidatorApiResponse) map[string]*state.ValidatorApiResponse { diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 6054deaed0b..4eaec309bec 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -13,15 +13,9 @@ import ( // GetAuctionList returns an array containing the validators that are currently in the auction list func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) { - vp.auctionMutex.RLock() - shouldUpdate := time.Since(vp.lastAuctionCacheUpdate) > vp.cacheRefreshIntervalDuration - vp.auctionMutex.RUnlock() - - if shouldUpdate { - err := vp.updateAuctionListCache() - if err != nil { - return nil, err - } + err := vp.updateAuctionListCacheIfNeeded() + if err != nil { + return nil, err } vp.auctionMutex.RLock() @@ -32,6 +26,18 @@ func (vp *validatorsProvider) GetAuctionList() ([]*common.AuctionListValidatorAP return ret, nil } +func (vp *validatorsProvider) updateAuctionListCacheIfNeeded() error { + vp.auctionMutex.RLock() + shouldUpdate := time.Since(vp.lastAuctionCacheUpdate) > vp.cacheRefreshIntervalDuration + vp.auctionMutex.RUnlock() + + if shouldUpdate { + return vp.updateAuctionListCache() + } + + return nil +} + func (vp *validatorsProvider) updateAuctionListCache() error { rootHash, err := vp.validatorStatistics.RootHash() if err != nil { @@ -86,7 +92,8 @@ func (vp *validatorsProvider) fillAllValidatorsInfo(validatorsMap state.ShardVal } } - return nil + _, _, err := vp.stakingDataProvider.ComputeUnQualifiedNodes(validatorsMap) + return err } func (vp *validatorsProvider) getSelectedNodesFromAuction(validatorsMap state.ShardValidatorsInfoMapHandler) ([]state.ValidatorInfoHandler, error) { @@ -129,7 +136,7 @@ func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse(selectedNodes TotalTopUp: ownerData.TotalTopUp.String(), TopUpPerNode: ownerData.TopUpPerNode.String(), QualifiedTopUp: ownerData.TopUpPerNode.String(), - AuctionList: make([]common.AuctionNode, 0, ownerData.NumAuctionNodes), + AuctionList: make([]*common.AuctionNode, 0, ownerData.NumAuctionNodes), } vp.fillAuctionQualifiedValidatorAPIData(selectedNodes, ownerData, auctionValidator) @@ -145,10 +152,10 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( ownerData *epochStart.OwnerData, auctionValidatorAPI *common.AuctionListValidatorAPIResponse, ) { - auctionValidatorAPI.AuctionList = make([]common.AuctionNode, 0, ownerData.NumAuctionNodes) + auctionValidatorAPI.AuctionList = make([]*common.AuctionNode, 0, ownerData.NumAuctionNodes) numOwnerQualifiedNodes := int64(0) for _, nodeInAuction := range ownerData.AuctionList { - auctionNode := common.AuctionNode{ + auctionNode := &common.AuctionNode{ BlsKey: vp.addressPubKeyConverter.Encode(nodeInAuction.GetPublicKey()), Qualified: false, } diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 718d1071f7c..b02ad8b1420 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -747,6 +747,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { ctSelectNodesFromAuctionList := uint32(0) ctFillValidatorInfoCalled := uint32(0) ctGetOwnersDataCalled := uint32(0) + ctComputeUnqualifiedNodes := uint32(0) args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ RootHashCalled: func() ([]byte, error) { @@ -775,6 +776,10 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { atomic.AddUint32(&ctGetOwnersDataCalled, 1) return nil }, + ComputeUnQualifiedNodesCalled: func(validatorInfos state.ShardValidatorsInfoMapHandler) ([][]byte, map[string][][]byte, error) { + atomic.AddUint32(&ctComputeUnqualifiedNodes, 1) + return nil, nil, nil + }, } vp, _ := NewValidatorsProvider(args) time.Sleep(args.CacheRefreshIntervalDurationInSec) @@ -786,6 +791,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(1)) require.Equal(t, ctFillValidatorInfoCalled, uint32(0)) require.Equal(t, ctGetOwnersDataCalled, uint32(1)) + require.Equal(t, ctComputeUnqualifiedNodes, uint32(1)) require.Equal(t, expectedRootHash, vp.cachedRandomness) }) @@ -911,7 +917,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "4000", TopUpPerNode: "2000", QualifiedTopUp: "4000", - AuctionList: []common.AuctionNode{ + AuctionList: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.Encode(v5.PublicKey), Qualified: true, @@ -928,7 +934,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "7500", TopUpPerNode: "2500", QualifiedTopUp: "2500", - AuctionList: []common.AuctionNode{ + AuctionList: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.Encode(v1.PublicKey), Qualified: true, @@ -945,7 +951,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "3000", TopUpPerNode: "1000", QualifiedTopUp: "1500", - AuctionList: []common.AuctionNode{ + AuctionList: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.Encode(v3.PublicKey), Qualified: true, @@ -962,7 +968,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", - AuctionList: []common.AuctionNode{ + AuctionList: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.Encode(v7.PublicKey), Qualified: false, From 1f0d05ecc20ba127ed58ea905e5ab1a30436de02 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 16 Jun 2022 13:29:16 +0300 Subject: [PATCH 347/958] FIX: Review findings --- epochStart/dtos.go | 13 ++--- epochStart/metachain/auctionListDisplayer.go | 2 +- epochStart/metachain/auctionListSelector.go | 16 ++--- .../metachain/auctionListSelector_test.go | 2 +- epochStart/metachain/stakingDataProvider.go | 58 +++++++++++-------- .../metachain/stakingDataProvider_test.go | 9 ++- 6 files changed, 54 insertions(+), 46 deletions(-) diff --git a/epochStart/dtos.go b/epochStart/dtos.go index 0fe5bd92c22..5ae7b1d355d 100644 --- a/epochStart/dtos.go +++ b/epochStart/dtos.go @@ -8,11 +8,10 @@ import ( // OwnerData is a struct containing relevant information about owner's nodes data type OwnerData struct { - NumStakedNodes int64 - NumActiveNodes int64 - NumAuctionNodes int64 - TotalTopUp *big.Int - TopUpPerNode *big.Int - AuctionList []state.ValidatorInfoHandler - Qualified bool + NumStakedNodes int64 + NumActiveNodes int64 + TotalTopUp *big.Int + TopUpPerNode *big.Int + AuctionList []state.ValidatorInfoHandler + Qualified bool } diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index fbe7ea7d7fa..7447dfcf3df 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -30,7 +30,7 @@ func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, startTop iterations++ log.Debug("auctionListSelector: found min required", - "topUp", topUp.String(), + "topUp", getPrettyValue(topUp, als.softAuctionConfig.denominator), "after num of iterations", iterations, ) } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 99b5d346d1f..bd6c37d8b4e 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -199,19 +199,21 @@ func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, numOfNodesInAuction := uint32(0) for owner, ownerData := range als.stakingDataProvider.GetOwnersData() { - if ownerData.Qualified && ownerData.NumAuctionNodes > 0 { + if ownerData.Qualified && len(ownerData.AuctionList) > 0 { + numAuctionNodes := len(ownerData.AuctionList) + ownersData[owner] = &ownerAuctionData{ numActiveNodes: ownerData.NumActiveNodes, - numAuctionNodes: ownerData.NumAuctionNodes, - numQualifiedAuctionNodes: ownerData.NumAuctionNodes, + numAuctionNodes: int64(numAuctionNodes), + numQualifiedAuctionNodes: int64(numAuctionNodes), numStakedNodes: ownerData.NumStakedNodes, totalTopUp: ownerData.TotalTopUp, topUpPerNode: ownerData.TopUpPerNode, qualifiedTopUpPerNode: ownerData.TopUpPerNode, - auctionList: make([]state.ValidatorInfoHandler, len(ownerData.AuctionList)), + auctionList: make([]state.ValidatorInfoHandler, numAuctionNodes), } copy(ownersData[owner].auctionList, ownerData.AuctionList) - numOfNodesInAuction += uint32(ownerData.NumAuctionNodes) + numOfNodesInAuction += uint32(numAuctionNodes) } } @@ -248,8 +250,8 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( ownersData := copyOwnersData(data) minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) log.Debug("auctionListSelector: calc min and max possible top up", - "min top up per node", minTopUp.String(), - "max top up per node", maxTopUp.String(), + "min top up per node", getPrettyValue(minTopUp, als.softAuctionConfig.denominator), + "max top up per node", getPrettyValue(maxTopUp, als.softAuctionConfig.denominator), ) topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 24228245d37..ae575045a2b 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -240,7 +240,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { fillValidatorsInfo(t, validatorsInfo, argsSystemSC.StakingDataProvider) als, _ := NewAuctionListSelector(args) - err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), []byte("rand")) + err := als.SelectNodesFromAuctionList(state.NewShardValidatorsInfoMap(), []byte("rnd")) require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 06111e08590..f981b7b5a0a 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -21,7 +21,6 @@ type ownerStats struct { numEligible int numStakedNodes int64 numActiveNodes int64 - numAuctionNodes int64 totalTopUp *big.Int topUpPerNode *big.Int totalStaked *big.Int @@ -33,14 +32,21 @@ type ownerStats struct { qualified bool } +type ownerInfoSC struct { + topUpValue *big.Int + totalStakedValue *big.Int + numStakedWaiting *big.Int + blsKeys [][]byte +} + type stakingDataProvider struct { mutStakingData sync.RWMutex cache map[string]*ownerStats - numOfValidatorsInCurrEpoch uint32 systemVM vmcommon.VMExecutionHandler totalEligibleStake *big.Int totalEligibleTopUpStake *big.Int minNodePrice *big.Int + numOfValidatorsInCurrEpoch uint32 stakingV4EnableEpoch uint32 flagStakingV4Enable atomic.Flag } @@ -231,13 +237,12 @@ func (sdp *stakingDataProvider) GetOwnersData() map[string]*epochStart.OwnerData ret := make(map[string]*epochStart.OwnerData) for owner, ownerData := range sdp.cache { ret[owner] = &epochStart.OwnerData{ - NumActiveNodes: ownerData.numActiveNodes, - NumAuctionNodes: ownerData.numAuctionNodes, - NumStakedNodes: ownerData.numStakedNodes, - TotalTopUp: big.NewInt(0).SetBytes(ownerData.totalTopUp.Bytes()), - TopUpPerNode: big.NewInt(0).SetBytes(ownerData.topUpPerNode.Bytes()), - AuctionList: make([]state.ValidatorInfoHandler, ownerData.numAuctionNodes), - Qualified: ownerData.qualified, + NumActiveNodes: ownerData.numActiveNodes, + NumStakedNodes: ownerData.numStakedNodes, + TotalTopUp: big.NewInt(0).SetBytes(ownerData.totalTopUp.Bytes()), + TopUpPerNode: big.NewInt(0).SetBytes(ownerData.topUpPerNode.Bytes()), + AuctionList: make([]state.ValidatorInfoHandler, len(ownerData.auctionList)), + Qualified: ownerData.qualified, } copy(ret[owner].AuctionList, ownerData.auctionList) } @@ -290,20 +295,19 @@ func (sdp *stakingDataProvider) fillOwnerData(owner string, validator state.Vali func updateOwnerData(ownerData *ownerStats, validator state.ValidatorInfoHandler) { if isInAuction(validator) { - ownerData.numAuctionNodes++ ownerData.numActiveNodes-- ownerData.auctionList = append(ownerData.auctionList, validator.ShallowClone()) } } func (sdp *stakingDataProvider) getAndFillOwnerDataFromSC(owner string, validator state.ValidatorInfoHandler) (*ownerStats, error) { - topUpValue, totalStakedValue, numStakedWaiting, blsKeys, err := sdp.getOwnerInfoFromSC(owner) + ownerInfo, err := sdp.getOwnerInfoFromSC(owner) if err != nil { return nil, err } topUpPerNode := big.NewInt(0) - numStakedNodes := numStakedWaiting.Int64() + numStakedNodes := ownerInfo.numStakedWaiting.Int64() if numStakedNodes == 0 { log.Debug("stakingDataProvider.fillOwnerData", "message", epochStart.ErrOwnerHasNoStakedNode, @@ -311,16 +315,16 @@ func (sdp *stakingDataProvider) getAndFillOwnerDataFromSC(owner string, validato "validator", hex.EncodeToString(validator.GetPublicKey()), ) } else { - topUpPerNode = big.NewInt(0).Div(topUpValue, numStakedWaiting) + topUpPerNode = big.NewInt(0).Div(ownerInfo.topUpValue, ownerInfo.numStakedWaiting) } ownerData := &ownerStats{ numEligible: 0, numStakedNodes: numStakedNodes, numActiveNodes: numStakedNodes, - totalTopUp: topUpValue, + totalTopUp: ownerInfo.topUpValue, topUpPerNode: topUpPerNode, - totalStaked: totalStakedValue, + totalStaked: ownerInfo.totalStakedValue, eligibleBaseStake: big.NewInt(0).Set(sdp.minNodePrice), eligibleTopUpStake: big.NewInt(0), eligibleTopUpPerNode: big.NewInt(0), @@ -331,8 +335,8 @@ func (sdp *stakingDataProvider) getAndFillOwnerDataFromSC(owner string, validato return nil, err } - ownerData.blsKeys = make([][]byte, len(blsKeys)) - copy(ownerData.blsKeys, blsKeys) + ownerData.blsKeys = make([][]byte, len(ownerInfo.blsKeys)) + copy(ownerData.blsKeys, ownerInfo.blsKeys) return ownerData, nil } @@ -362,13 +366,12 @@ func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( } ownerData.numActiveNodes -= 1 - ownerData.numAuctionNodes = 1 ownerData.auctionList = []state.ValidatorInfoHandler{validator} return nil } -func (sdp *stakingDataProvider) getOwnerInfoFromSC(owner string) (*big.Int, *big.Int, *big.Int, [][]byte, error) { +func (sdp *stakingDataProvider) getOwnerInfoFromSC(owner string) (*ownerInfoSC, error) { ownerAddressBytes := []byte(owner) vmInput := &vmcommon.ContractCallInput{ @@ -384,21 +387,26 @@ func (sdp *stakingDataProvider) getOwnerInfoFromSC(owner string) (*big.Int, *big vmOutput, err := sdp.systemVM.RunSmartContractCall(vmInput) if err != nil { - return nil, nil, nil, nil, err + return nil, err } if vmOutput.ReturnCode != vmcommon.Ok { - return nil, nil, nil, nil, fmt.Errorf("%w, error: %v message: %s", epochStart.ErrExecutingSystemScCode, vmOutput.ReturnCode, vmOutput.ReturnMessage) + return nil, fmt.Errorf("%w, error: %v message: %s", epochStart.ErrExecutingSystemScCode, vmOutput.ReturnCode, vmOutput.ReturnMessage) } if len(vmOutput.ReturnData) < 3 { - return nil, nil, nil, nil, fmt.Errorf("%w, getTotalStakedTopUpStakedBlsKeys function should have at least three values", epochStart.ErrExecutingSystemScCode) + return nil, fmt.Errorf("%w, getTotalStakedTopUpStakedBlsKeys function should have at least three values", epochStart.ErrExecutingSystemScCode) } topUpValue := big.NewInt(0).SetBytes(vmOutput.ReturnData[0]) totalStakedValue := big.NewInt(0).SetBytes(vmOutput.ReturnData[1]) numStakedWaiting := big.NewInt(0).SetBytes(vmOutput.ReturnData[2]) - return topUpValue, totalStakedValue, numStakedWaiting, vmOutput.ReturnData[3:], nil + return &ownerInfoSC{ + topUpValue: topUpValue, + totalStakedValue: totalStakedValue, + numStakedWaiting: numStakedWaiting, + blsKeys: vmOutput.ReturnData[3:], + }, nil } // ComputeUnQualifiedNodes will compute which nodes are not qualified - do not have enough tokens to be validators @@ -422,7 +430,7 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha sortedKeys := sdp.arrangeBlsKeysByStatus(mapBLSKeyStatus, stakingInfo.blsKeys) numKeysToUnStake := stakingInfo.numStakedNodes - maxQualified.Int64() - selectedKeys, removedValidators := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) + selectedKeys, numRemovedValidators := sdp.selectKeysToUnStake(sortedKeys, numKeysToUnStake) if len(selectedKeys) == 0 { continue } @@ -433,7 +441,7 @@ func (sdp *stakingDataProvider) ComputeUnQualifiedNodes(validatorsInfo state.Sha copy(mapOwnersKeys[ownerAddress], selectedKeys) stakingInfo.qualified = false - sdp.numOfValidatorsInCurrEpoch -= uint32(removedValidators) + sdp.numOfValidatorsInCurrEpoch -= uint32(numRemovedValidators) } return keysToUnStake, mapOwnersKeys, nil diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index ce109110ad3..46f7a0b2106 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -531,16 +531,15 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { sdp.EpochConfirmed(stakingV4EnableEpoch, 0) owner := []byte("owner") - ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3, numAuctionNodes: 0} + ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3} validator := &state.ValidatorInfo{PublicKey: []byte("validatorPubKey"), List: string(common.AuctionList)} err := sdp.checkAndFillOwnerValidatorAuctionData(owner, ownerData, validator) require.Nil(t, err) require.Equal(t, &ownerStats{ - numStakedNodes: 3, - numActiveNodes: 2, - numAuctionNodes: 1, - auctionList: []state.ValidatorInfoHandler{validator}, + numStakedNodes: 3, + numActiveNodes: 2, + auctionList: []state.ValidatorInfoHandler{validator}, }, ownerData) }) } From c44b90db13c844e9d3284370578cd5020c86b5dc Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Thu, 16 Jun 2022 14:08:50 +0300 Subject: [PATCH 348/958] FIX: Merge conflicts --- process/peer/validatorsProviderAuction.go | 7 +-- process/peer/validatorsProvider_test.go | 65 +++++++++++------------ 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 4eaec309bec..29b82b98f88 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -129,14 +129,15 @@ func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse(selectedNodes auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) for ownerPubKey, ownerData := range vp.stakingDataProvider.GetOwnersData() { - if ownerData.NumAuctionNodes > 0 { + numAuctionNodes := len(ownerData.AuctionList) + if numAuctionNodes > 0 { auctionValidator := &common.AuctionListValidatorAPIResponse{ Owner: vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)), NumStakedNodes: ownerData.NumStakedNodes, TotalTopUp: ownerData.TotalTopUp.String(), TopUpPerNode: ownerData.TopUpPerNode.String(), QualifiedTopUp: ownerData.TopUpPerNode.String(), - AuctionList: make([]*common.AuctionNode, 0, ownerData.NumAuctionNodes), + AuctionList: make([]*common.AuctionNode, 0, numAuctionNodes), } vp.fillAuctionQualifiedValidatorAPIData(selectedNodes, ownerData, auctionValidator) @@ -152,7 +153,7 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( ownerData *epochStart.OwnerData, auctionValidatorAPI *common.AuctionListValidatorAPIResponse, ) { - auctionValidatorAPI.AuctionList = make([]*common.AuctionNode, 0, ownerData.NumAuctionNodes) + auctionValidatorAPI.AuctionList = make([]*common.AuctionNode, 0, len(ownerData.AuctionList)) numOwnerQualifiedNodes := int64(0) for _, nodeInAuction := range ownerData.AuctionList { auctionNode := &common.AuctionNode{ diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index b02ad8b1420..53dc7e296a0 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -817,49 +817,44 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { owner5 := "owner5" ownersData := map[string]*epochStart.OwnerData{ owner1: { - NumStakedNodes: 3, - NumActiveNodes: 1, - NumAuctionNodes: 2, - TotalTopUp: big.NewInt(7500), - TopUpPerNode: big.NewInt(2500), - AuctionList: []state.ValidatorInfoHandler{v1, v2}, // owner1 will have v1 & v2 selected - Qualified: true, // with qualifiedTopUp = 2500 + NumStakedNodes: 3, + NumActiveNodes: 1, + TotalTopUp: big.NewInt(7500), + TopUpPerNode: big.NewInt(2500), + AuctionList: []state.ValidatorInfoHandler{v1, v2}, // owner1 will have v1 & v2 selected + Qualified: true, // with qualifiedTopUp = 2500 }, owner2: { - NumStakedNodes: 3, - NumActiveNodes: 1, - NumAuctionNodes: 2, - TotalTopUp: big.NewInt(3000), - TopUpPerNode: big.NewInt(1000), - AuctionList: []state.ValidatorInfoHandler{v3, v4}, // owner2 will have v3 selected - Qualified: true, // with qualifiedTopUp = 1500 + NumStakedNodes: 3, + NumActiveNodes: 1, + TotalTopUp: big.NewInt(3000), + TopUpPerNode: big.NewInt(1000), + AuctionList: []state.ValidatorInfoHandler{v3, v4}, // owner2 will have v3 selected + Qualified: true, // with qualifiedTopUp = 1500 }, owner3: { - NumStakedNodes: 2, - NumActiveNodes: 0, - NumAuctionNodes: 2, - TotalTopUp: big.NewInt(4000), - TopUpPerNode: big.NewInt(2000), - AuctionList: []state.ValidatorInfoHandler{v5, v6}, // owner3 will have v5 selected - Qualified: true, // with qualifiedTopUp = 4000 + NumStakedNodes: 2, + NumActiveNodes: 0, + TotalTopUp: big.NewInt(4000), + TopUpPerNode: big.NewInt(2000), + AuctionList: []state.ValidatorInfoHandler{v5, v6}, // owner3 will have v5 selected + Qualified: true, // with qualifiedTopUp = 4000 }, owner4: { - NumStakedNodes: 3, - NumActiveNodes: 2, - NumAuctionNodes: 1, - TotalTopUp: big.NewInt(0), - TopUpPerNode: big.NewInt(0), - AuctionList: []state.ValidatorInfoHandler{v7}, - Qualified: false, + NumStakedNodes: 3, + NumActiveNodes: 2, + TotalTopUp: big.NewInt(0), + TopUpPerNode: big.NewInt(0), + AuctionList: []state.ValidatorInfoHandler{v7}, + Qualified: false, }, owner5: { - NumStakedNodes: 5, - NumActiveNodes: 5, - NumAuctionNodes: 0, - TotalTopUp: big.NewInt(5000), - TopUpPerNode: big.NewInt(1000), - AuctionList: []state.ValidatorInfoHandler{}, - Qualified: true, + NumStakedNodes: 5, + NumActiveNodes: 5, + TotalTopUp: big.NewInt(5000), + TopUpPerNode: big.NewInt(1000), + AuctionList: []state.ValidatorInfoHandler{}, + Qualified: true, }, } From 54b182bb01a8259493b1bf2827e682fca7082752 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Fri, 17 Jun 2022 16:29:14 +0300 Subject: [PATCH 349/958] FIX: ValidatorPubKeyConverter --- process/peer/validatorsProviderAuction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 29b82b98f88..60f798b9774 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -157,7 +157,7 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( numOwnerQualifiedNodes := int64(0) for _, nodeInAuction := range ownerData.AuctionList { auctionNode := &common.AuctionNode{ - BlsKey: vp.addressPubKeyConverter.Encode(nodeInAuction.GetPublicKey()), + BlsKey: vp.validatorPubKeyConverter.Encode(nodeInAuction.GetPublicKey()), Qualified: false, } if ownerData.Qualified && contains(selectedNodes, nodeInAuction) { From 5c630d9a1b00accb71d0ee9d4631d9577671d972 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 20 Jun 2022 12:54:28 +0300 Subject: [PATCH 350/958] FIX: Use new comp for selection AuctionListSelectorAPI --- factory/blockProcessorCreator.go | 16 ++++++++++++++-- factory/processComponents.go | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 6c40a085f90..f010bc87cc3 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -423,7 +423,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( } pcf.stakingDataProviderAPI = factoryDisabled.NewDisabledStakingDataProvider() - pcf.auctionListSelector = factoryDisabled.NewDisabledAuctionListSelector() + pcf.auctionListSelectorAPI = factoryDisabled.NewDisabledAuctionListSelector() return blockProcessorComponents, nil } @@ -844,7 +844,19 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } - pcf.auctionListSelector = auctionListSelector + argsAuctionListSelectorAPI := metachainEpochStart.AuctionListSelectorArgs{ + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + StakingDataProvider: stakingDataProviderAPI, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + SoftAuctionConfig: pcf.config.SoftAuctionConfig, + Denomination: pcf.economicsConfig.GlobalSettings.Denomination, + } + auctionListSelectorAPI, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelectorAPI) + if err != nil { + return nil, err + } + + pcf.auctionListSelectorAPI = auctionListSelectorAPI argsEpochSystemSC := metachainEpochStart.ArgsNewEpochStartSystemSCProcessing{ SystemVM: systemVM, diff --git a/factory/processComponents.go b/factory/processComponents.go index e50e5cfbbd8..00ac42adba8 100644 --- a/factory/processComponents.go +++ b/factory/processComponents.go @@ -168,7 +168,7 @@ type processComponentsFactory struct { epochNotifier process.EpochNotifier importHandler update.ImportHandler stakingDataProviderAPI peer.StakingDataProviderAPI - auctionListSelector epochStart.AuctionListSelector + auctionListSelectorAPI epochStart.AuctionListSelector data DataComponentsHolder coreData CoreComponentsHolder @@ -543,7 +543,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { MaxRating: pcf.maxRating, ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), - AuctionListSelector: pcf.auctionListSelector, + AuctionListSelector: pcf.auctionListSelectorAPI, } validatorsProvider, err := peer.NewValidatorsProvider(argVSP) From fa8186faacc657c46045613091326fe682a0a227 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Mon, 20 Jun 2022 16:13:53 +0300 Subject: [PATCH 351/958] FIX: Validator shallow clone + add todo --- epochStart/metachain/auctionListSelector.go | 2 +- epochStart/metachain/stakingDataProvider.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index bd6c37d8b4e..7b5b7ef0ada 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -343,7 +343,7 @@ func markAuctionNodesAsSelected( validatorsInfoMap state.ShardValidatorsInfoMapHandler, ) error { for _, node := range selectedNodes { - newNode := node + newNode := node.ShallowClone() newNode.SetList(string(common.SelectedFromAuctionList)) err := validatorsInfoMap.Replace(node, newNode) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index f981b7b5a0a..2997a8ac3f8 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -357,7 +357,7 @@ func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( hex.EncodeToString(validator.GetPublicKey()), ) } - if validatorInAuction && !sdp.flagStakingV4Enable.IsSet() { + if validatorInAuction && !sdp.flagStakingV4Enable.IsSet() { // todo: here starting staking v4 init + remove if validatorInAuction check return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4, hex.EncodeToString(ownerPubKey), From 9dcbbea2f83e0b4f05441fd1a118ee07452826ee Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 21 Jun 2022 17:02:35 +0300 Subject: [PATCH 352/958] FIX: stakingDataProvider.checkAndFillOwnerValidatorAuctionData flag check --- epochStart/metachain/stakingDataProvider.go | 21 +++++++++++++------ .../metachain/stakingDataProvider_test.go | 12 ++++++----- factory/blockProcessorCreator.go | 9 ++++---- integrationTests/testProcessorNode.go | 9 ++++---- .../vm/staking/systemSCCreator.go | 9 ++++---- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 2997a8ac3f8..17fc37ed252 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -49,14 +49,17 @@ type stakingDataProvider struct { numOfValidatorsInCurrEpoch uint32 stakingV4EnableEpoch uint32 flagStakingV4Enable atomic.Flag + stakingV4InitEpoch uint32 + flagStakingV4Initialized atomic.Flag } // StakingDataProviderArgs is a struct placeholder for all arguments required to create a NewStakingDataProvider type StakingDataProviderArgs struct { - EpochNotifier process.EpochNotifier - SystemVM vmcommon.VMExecutionHandler - MinNodePrice string - StakingV4EnableEpoch uint32 + EpochNotifier process.EpochNotifier + SystemVM vmcommon.VMExecutionHandler + MinNodePrice string + StakingV4InitEnableEpoch uint32 + StakingV4EnableEpoch uint32 } // NewStakingDataProvider will create a new instance of a staking data provider able to aid in the final rewards @@ -81,8 +84,11 @@ func NewStakingDataProvider(args StakingDataProviderArgs) (*stakingDataProvider, totalEligibleStake: big.NewInt(0), totalEligibleTopUpStake: big.NewInt(0), stakingV4EnableEpoch: args.StakingV4EnableEpoch, + stakingV4InitEpoch: args.StakingV4InitEnableEpoch, } + log.Debug("stakingDataProvider: enable epoch for staking v4 init", "epoch", sdp.stakingV4InitEpoch) log.Debug("stakingDataProvider: enable epoch for staking v4", "epoch", sdp.stakingV4EnableEpoch) + args.EpochNotifier.RegisterNotifyHandler(sdp) return sdp, nil @@ -350,14 +356,14 @@ func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( if !validatorInAuction { return nil } - if validatorInAuction && ownerData.numStakedNodes == 0 { + if ownerData.numStakedNodes == 0 { return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", epochStart.ErrOwnerHasNoStakedNode, hex.EncodeToString(ownerPubKey), hex.EncodeToString(validator.GetPublicKey()), ) } - if validatorInAuction && !sdp.flagStakingV4Enable.IsSet() { // todo: here starting staking v4 init + remove if validatorInAuction check + if !sdp.flagStakingV4Initialized.IsSet() { return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4, hex.EncodeToString(ownerPubKey), @@ -542,6 +548,9 @@ func (sdp *stakingDataProvider) GetNumOfValidatorsInCurrentEpoch() uint32 { func (sdp *stakingDataProvider) EpochConfirmed(epoch uint32, _ uint64) { sdp.flagStakingV4Enable.SetValue(epoch >= sdp.stakingV4EnableEpoch) log.Debug("stakingDataProvider: staking v4 enable epoch", "enabled", sdp.flagStakingV4Enable.IsSet()) + + sdp.flagStakingV4Initialized.SetValue(epoch >= sdp.stakingV4InitEpoch) + log.Debug("stakingDataProvider: staking v4 initialized", "enabled", sdp.flagStakingV4Initialized.IsSet()) } // IsInterfaceNil return true if underlying object is nil diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 46f7a0b2106..a4f067fc2df 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -23,14 +23,16 @@ import ( "github.com/stretchr/testify/require" ) +const stakingV4EInitEnableEpoch = 444 const stakingV4EnableEpoch = 444 func createStakingDataProviderArgs() StakingDataProviderArgs { return StakingDataProviderArgs{ - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - SystemVM: &mock.VMExecutionHandlerStub{}, - MinNodePrice: "2500", - StakingV4EnableEpoch: stakingV4EnableEpoch, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + SystemVM: &mock.VMExecutionHandlerStub{}, + MinNodePrice: "2500", + StakingV4InitEnableEpoch: stakingV4EInitEnableEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, } } @@ -528,7 +530,7 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.EpochConfirmed(stakingV4EInitEnableEpoch, 0) owner := []byte("owner") ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3} diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index f010bc87cc3..34fbf914d49 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -726,10 +726,11 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( } argsStakingDataProvider := metachainEpochStart.StakingDataProviderArgs{ - EpochNotifier: pcf.coreData.EpochNotifier(), - SystemVM: systemVM, - MinNodePrice: pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, - StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + EpochNotifier: pcf.coreData.EpochNotifier(), + SystemVM: systemVM, + MinNodePrice: pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, + StakingV4InitEnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4InitEnableEpoch, + StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, } // TODO: in case of changing the minimum node price, make sure to update the staking data provider diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 2d10c4ab56f..5834b939217 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2236,10 +2236,11 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { } argsStakingDataProvider := metachain.StakingDataProviderArgs{ - EpochNotifier: coreComponents.EpochNotifier(), - SystemVM: systemVM, - MinNodePrice: "1000", - StakingV4EnableEpoch: StakingV4Epoch, + EpochNotifier: coreComponents.EpochNotifier(), + SystemVM: systemVM, + MinNodePrice: "1000", + StakingV4InitEnableEpoch: StakingV4InitEpoch, + StakingV4EnableEpoch: StakingV4Epoch, } stakingDataProvider, errRsp := metachain.NewStakingDataProvider(argsStakingDataProvider) if errRsp != nil { diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 95a3a0e72ec..3f10ffb7a3f 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -90,10 +90,11 @@ func createStakingDataProvider( systemVM vmcommon.VMExecutionHandler, ) epochStart.StakingDataProvider { argsStakingDataProvider := metachain.StakingDataProviderArgs{ - EpochNotifier: epochNotifier, - SystemVM: systemVM, - MinNodePrice: strconv.Itoa(nodePrice), - StakingV4EnableEpoch: stakingV4EnableEpoch, + EpochNotifier: epochNotifier, + SystemVM: systemVM, + MinNodePrice: strconv.Itoa(nodePrice), + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4EnableEpoch: stakingV4EnableEpoch, } stakingSCProvider, _ := metachain.NewStakingDataProvider(argsStakingDataProvider) From a7e0adae6232d2b1b8546fe61ba89c10865dd572 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 21 Jun 2022 17:37:19 +0300 Subject: [PATCH 353/958] CLN: Do some refactor + add extra logs --- epochStart/bootstrap/baseStorageHandler.go | 2 +- process/peer/validatorsProviderAuction.go | 6 ++-- process/peer/validatorsProvider_test.go | 31 +++++++++++++------ .../indexHashedNodesCoordinator.go | 3 +- .../nodesCoordinatorRegistryFactory.go | 7 +++-- state/validatorsInfoMap.go | 4 +++ 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/epochStart/bootstrap/baseStorageHandler.go b/epochStart/bootstrap/baseStorageHandler.go index 7541bb1facd..4cbdf8f4220 100644 --- a/epochStart/bootstrap/baseStorageHandler.go +++ b/epochStart/bootstrap/baseStorageHandler.go @@ -112,7 +112,7 @@ func (bsh *baseStorageHandler) saveNodesCoordinatorRegistry( return nil, err } - log.Debug("saving nodes coordinator config", "key", key) + log.Debug("saving nodes coordinator config", "key", key, "epoch", metaBlock.GetEpoch()) return metaBlock.GetPrevRandSeed(), nil } diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 60f798b9774..2bafaf1fb8c 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -39,9 +39,9 @@ func (vp *validatorsProvider) updateAuctionListCacheIfNeeded() error { } func (vp *validatorsProvider) updateAuctionListCache() error { - rootHash, err := vp.validatorStatistics.RootHash() - if err != nil { - return err + rootHash := vp.validatorStatistics.LastFinalizedRootHash() + if len(rootHash) == 0 { + return state.ErrNilRootHash } validatorsMap, err := vp.validatorStatistics.GetValidatorInfoForRootHash(rootHash) diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 53dc7e296a0..9147d11c7e4 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -649,10 +649,9 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { t.Run("error getting root hash", func(t *testing.T) { t.Parallel() args := createDefaultValidatorsProviderArg() - expectedErr := errors.New("local error") args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ - RootHashCalled: func() ([]byte, error) { - return nil, expectedErr + LastFinalizedRootHashCalled: func() []byte { + return nil }, } vp, _ := NewValidatorsProvider(args) @@ -660,15 +659,20 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { list, err := vp.GetAuctionList() require.Nil(t, list) - require.Equal(t, expectedErr, err) + require.Equal(t, state.ErrNilRootHash, err) }) t.Run("error getting validators info for root hash", func(t *testing.T) { t.Parallel() args := createDefaultValidatorsProviderArg() expectedErr := errors.New("local error") + expectedRootHash := []byte("root hash") args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return expectedRootHash + }, GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + require.Equal(t, expectedRootHash, rootHash) return nil, expectedErr }, } @@ -687,8 +691,13 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { cleanCalled := &coreAtomic.Flag{} expectedValidator := &state.ValidatorInfo{PublicKey: []byte("pubKey"), List: string(common.AuctionList)} expectedErr := errors.New("local error") + expectedRootHash := []byte("root hash") args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return expectedRootHash + }, GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + require.Equal(t, expectedRootHash, rootHash) validatorsMap := state.NewShardValidatorsInfoMap() _ = validatorsMap.Add(expectedValidator) return validatorsMap, nil @@ -741,7 +750,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { t.Parallel() args := createDefaultValidatorsProviderArg() - expectedRootHash := []byte("rootHash") + expectedRootHash := []byte("root hash") ctRootHashCalled := uint32(0) ctGetValidatorsInfoForRootHash := uint32(0) ctSelectNodesFromAuctionList := uint32(0) @@ -750,9 +759,9 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { ctComputeUnqualifiedNodes := uint32(0) args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ - RootHashCalled: func() ([]byte, error) { + LastFinalizedRootHashCalled: func() []byte { atomic.AddUint32(&ctRootHashCalled, 1) - return expectedRootHash, nil + return expectedRootHash }, GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { atomic.AddUint32(&ctGetValidatorsInfoForRootHash, 1) @@ -787,8 +796,8 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { list, err := vp.GetAuctionList() require.Nil(t, err) require.Empty(t, list) - require.Equal(t, ctRootHashCalled, uint32(1)) - require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(1)) + require.Equal(t, ctRootHashCalled, uint32(2)) // another call is from constructor in startRefreshProcess.updateCache + require.Equal(t, ctGetValidatorsInfoForRootHash, uint32(2)) // another call is from constructor in startRefreshProcess.updateCache require.Equal(t, ctFillValidatorInfoCalled, uint32(0)) require.Equal(t, ctGetOwnersDataCalled, uint32(1)) require.Equal(t, ctComputeUnqualifiedNodes, uint32(1)) @@ -870,7 +879,11 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { _ = validatorsMap.Add(v9) _ = validatorsMap.Add(v10) + rootHash := []byte("root hash") args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return rootHash + }, GetValidatorInfoForRootHashCalled: func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { return validatorsMap, nil }, diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index e5893d81ef0..225afa43307 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -599,7 +599,8 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa allValidatorInfo, err := createValidatorInfoFromBody(body, ihnc.marshalizer, ihnc.numTotalEligible) if err != nil { - log.Error("could not create validator info from body - do nothing on nodesCoordinator epochStartPrepare") + log.Error("could not create validator info from body - do nothing on nodesCoordinator epochStartPrepare", + "error", err) return } diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index 8e7429a7409..fa993d9c4e3 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -34,10 +34,11 @@ func NewNodesCoordinatorRegistryFactory( func (ncf *nodesCoordinatorRegistryFactory) CreateNodesCoordinatorRegistry(buff []byte) (NodesCoordinatorRegistryHandler, error) { registry, err := ncf.createRegistryWithAuction(buff) if err == nil { - log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created registry with auction") + log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created registry with auction", + "epoch", registry.CurrentEpoch) return registry, nil } - log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created old registry") + log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry creating old registry") return createOldRegistry(buff) } @@ -48,6 +49,8 @@ func (ncf *nodesCoordinatorRegistryFactory) createRegistryWithAuction(buff []byt return nil, err } + log.Debug("nodesCoordinatorRegistryFactory.CreateNodesCoordinatorRegistry created old registry", + "epoch", registry.CurrentEpoch) return registry, nil } diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index 4f39f7a23d0..cdac286090a 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -101,6 +101,10 @@ func (vi *shardValidatorsInfoMap) Replace(old ValidatorInfoHandler, new Validato } shardID := old.GetShardId() + log.Debug("shardValidatorsInfoMap.Replace", + "old validator", hex.EncodeToString(old.GetPublicKey()), "shard", old.GetShardId(), "list", old.GetList(), + "with new validator", hex.EncodeToString(new.GetPublicKey()), "shard", new.GetShardId(), "list", new.GetList(), + ) vi.mutex.Lock() defer vi.mutex.Unlock() From 56d163c172b0f15f2ccf34b6c8f8e6d182c300a3 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 22 Jun 2022 14:12:52 +0300 Subject: [PATCH 354/958] FIX: API order list if validators have same qualifiedTopUp --- process/peer/validatorsProviderAuction.go | 48 +++++++++++++++--- process/peer/validatorsProvider_test.go | 59 +++++++++++++++++++++-- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 2bafaf1fb8c..98e4af36faf 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -79,8 +79,8 @@ func (vp *validatorsProvider) createValidatorsAuctionCache(validatorsMap state.S return nil, err } - auctionListValidators := vp.getAuctionListValidatorsAPIResponse(selectedNodes) - sortList(auctionListValidators) + auctionListValidators, qualifiedOwners := vp.getAuctionListValidatorsAPIResponse(selectedNodes) + sortList(auctionListValidators, qualifiedOwners) return auctionListValidators, nil } @@ -116,36 +116,70 @@ func (vp *validatorsProvider) getSelectedNodesFromAuction(validatorsMap state.Sh return selectedNodes, nil } -func sortList(list []*common.AuctionListValidatorAPIResponse) { +func sortList(list []*common.AuctionListValidatorAPIResponse, qualifiedOwners map[string]bool) { sort.SliceStable(list, func(i, j int) bool { qualifiedTopUpValidator1, _ := big.NewInt(0).SetString(list[i].QualifiedTopUp, 10) qualifiedTopUpValidator2, _ := big.NewInt(0).SetString(list[j].QualifiedTopUp, 10) + if qualifiedTopUpValidator1.Cmp(qualifiedTopUpValidator2) == 0 { + return compareByNumQualified(list[i], list[j], qualifiedOwners) + } return qualifiedTopUpValidator1.Cmp(qualifiedTopUpValidator2) > 0 }) } -func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse(selectedNodes []state.ValidatorInfoHandler) []*common.AuctionListValidatorAPIResponse { +func compareByNumQualified(owner1Nodes, owner2Nodes *common.AuctionListValidatorAPIResponse, qualifiedOwners map[string]bool) bool { + owner1Qualified := qualifiedOwners[owner1Nodes.Owner] + owner2Qualified := qualifiedOwners[owner2Nodes.Owner] + + bothQualified := owner1Qualified && owner2Qualified + if !bothQualified { + return owner1Qualified + } + + owner1NumQualified := getNumQualified(owner1Nodes.AuctionList) + owner2NumQualified := getNumQualified(owner2Nodes.AuctionList) + + return owner1NumQualified > owner2NumQualified +} + +func getNumQualified(nodes []*common.AuctionNode) uint32 { + numQualified := uint32(0) + for _, node := range nodes { + if node.Qualified { + numQualified++ + } + } + + return numQualified +} + +func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse( + selectedNodes []state.ValidatorInfoHandler, +) ([]*common.AuctionListValidatorAPIResponse, map[string]bool) { auctionListValidators := make([]*common.AuctionListValidatorAPIResponse, 0) + qualifiedOwners := make(map[string]bool) for ownerPubKey, ownerData := range vp.stakingDataProvider.GetOwnersData() { numAuctionNodes := len(ownerData.AuctionList) if numAuctionNodes > 0 { + ownerEncodedPubKey := vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)) auctionValidator := &common.AuctionListValidatorAPIResponse{ - Owner: vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)), + Owner: ownerEncodedPubKey, NumStakedNodes: ownerData.NumStakedNodes, TotalTopUp: ownerData.TotalTopUp.String(), TopUpPerNode: ownerData.TopUpPerNode.String(), QualifiedTopUp: ownerData.TopUpPerNode.String(), AuctionList: make([]*common.AuctionNode, 0, numAuctionNodes), } - vp.fillAuctionQualifiedValidatorAPIData(selectedNodes, ownerData, auctionValidator) auctionListValidators = append(auctionListValidators, auctionValidator) + + qualifiedOwners[ownerEncodedPubKey] = ownerData.Qualified } } - return auctionListValidators + return auctionListValidators, qualifiedOwners } func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 9147d11c7e4..58bce8d5aaa 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -818,12 +818,16 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { v8 := &state.ValidatorInfo{PublicKey: []byte("pk8"), List: string(common.WaitingList)} v9 := &state.ValidatorInfo{PublicKey: []byte("pk9"), List: string(common.LeavingList)} v10 := &state.ValidatorInfo{PublicKey: []byte("pk10"), List: string(common.JailedList)} + v11 := &state.ValidatorInfo{PublicKey: []byte("pk11"), List: string(common.AuctionList)} + v12 := &state.ValidatorInfo{PublicKey: []byte("pk12"), List: string(common.AuctionList)} owner1 := "owner1" owner2 := "owner2" owner3 := "owner3" owner4 := "owner4" owner5 := "owner5" + owner6 := "owner6" + owner7 := "owner7" ownersData := map[string]*epochStart.OwnerData{ owner1: { NumStakedNodes: 3, @@ -854,15 +858,32 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { NumActiveNodes: 2, TotalTopUp: big.NewInt(0), TopUpPerNode: big.NewInt(0), - AuctionList: []state.ValidatorInfoHandler{v7}, - Qualified: false, + AuctionList: []state.ValidatorInfoHandler{v7}, // owner4 has one node in auction, but is not qualified + Qualified: false, // should be sent at the bottom of the list }, owner5: { NumStakedNodes: 5, NumActiveNodes: 5, TotalTopUp: big.NewInt(5000), TopUpPerNode: big.NewInt(1000), - AuctionList: []state.ValidatorInfoHandler{}, + AuctionList: []state.ValidatorInfoHandler{}, // owner5 has no nodes in auction, will not appear in API list + Qualified: true, + }, + // owner6 has same stats as owner7. After selection, owner7 will have its node selected => should be listed above owner 6 + owner6: { + NumStakedNodes: 1, + NumActiveNodes: 0, + TotalTopUp: big.NewInt(0), + TopUpPerNode: big.NewInt(0), + AuctionList: []state.ValidatorInfoHandler{v11}, + Qualified: true, // should be added + }, + owner7: { + NumStakedNodes: 1, + NumActiveNodes: 0, + TotalTopUp: big.NewInt(0), + TopUpPerNode: big.NewInt(0), + AuctionList: []state.ValidatorInfoHandler{v12}, Qualified: true, }, } @@ -878,6 +899,8 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { _ = validatorsMap.Add(v8) _ = validatorsMap.Add(v9) _ = validatorsMap.Add(v10) + _ = validatorsMap.Add(v11) + _ = validatorsMap.Add(v12) rootHash := []byte("root hash") args.ValidatorStatistics = &testscommon.ValidatorStatisticsProcessorStub{ @@ -906,6 +929,10 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { selectedV5.SetList(string(common.SelectedFromAuctionList)) _ = validatorsInfoMap.Replace(v5, selectedV5) + selectedV12 := v12.ShallowClone() + selectedV12.SetList(string(common.SelectedFromAuctionList)) + _ = validatorsInfoMap.Replace(v12, selectedV12) + return nil }, } @@ -970,6 +997,32 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { }, }, }, + { + Owner: args.AddressPubKeyConverter.Encode([]byte(owner7)), + NumStakedNodes: 1, + TotalTopUp: "0", + TopUpPerNode: "0", + QualifiedTopUp: "0", + AuctionList: []*common.AuctionNode{ + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v12.PublicKey), + Qualified: true, + }, + }, + }, + { + Owner: args.AddressPubKeyConverter.Encode([]byte(owner6)), + NumStakedNodes: 1, + TotalTopUp: "0", + TopUpPerNode: "0", + QualifiedTopUp: "0", + AuctionList: []*common.AuctionNode{ + { + BlsKey: args.ValidatorPubKeyConverter.Encode(v11.PublicKey), + Qualified: false, + }, + }, + }, { Owner: args.AddressPubKeyConverter.Encode([]byte(owner4)), NumStakedNodes: 3, From dae4018b44a4e932528d75a9826d9354a6a2b8c5 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Wed, 22 Jun 2022 16:43:11 +0300 Subject: [PATCH 355/958] FIX: Comment obsolete non-working test --- process/peer/validatorsProvider_test.go | 175 ++++++++++++------------ 1 file changed, 88 insertions(+), 87 deletions(-) diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index bba3974c49b..927f4208384 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -732,96 +732,97 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { response := vp.GetAuctionList() require.Empty(t, response) }) - - t.Run("should work", func(t *testing.T) { - t.Parallel() - - callNumber := 0 - arg := createDefaultValidatorsProviderArg() - validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ - LastFinalizedRootHashCalled: func() []byte { - return []byte("rootHash") - }, - } - validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { - callNumber++ - // first call comes from the constructor - if callNumber == 1 { - return state.NewShardValidatorsInfoMap(), nil + /* + t.Run("should work", func(t *testing.T) { + t.Parallel() + + callNumber := 0 + arg := createDefaultValidatorsProviderArg() + validatorStatisticsProcessor := &testscommon.ValidatorStatisticsProcessorStub{ + LastFinalizedRootHashCalled: func() []byte { + return []byte("rootHash") + }, } - validatorsMap := state.NewShardValidatorsInfoMap() - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-eligible"), - List: string(common.EligibleList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-waiting"), - List: string(common.WaitingList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey-leaving"), - List: string(common.LeavingList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey0-auction"), - List: string(common.AuctionList), - }) - _ = validatorsMap.Add(&state.ValidatorInfo{ - ShardId: 0, - PublicKey: []byte("pubkey1-auction"), - List: string(common.AuctionList), - }) - return validatorsMap, nil - } - arg.ValidatorStatistics = validatorStatisticsProcessor - - arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ - GetBlsKeyOwnerCalled: func(key []byte) (string, error) { - if "pubkey0-auction" == string(key) { - return "owner0", nil + validatorStatisticsProcessor.GetValidatorInfoForRootHashCalled = func(rootHash []byte) (state.ShardValidatorsInfoMapHandler, error) { + callNumber++ + // first call comes from the constructor + if callNumber == 1 { + return state.NewShardValidatorsInfoMap(), nil } - if "pubkey1-auction" == string(key) { - return "owner1", nil - } - return "", nil - }, - GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { - if "pubkey0-auction" == string(key) { - return big.NewInt(100), nil - } - if "pubkey1-auction" == string(key) { - return big.NewInt(110), nil - } - return big.NewInt(0), nil - }, - } - - vp, err := NewValidatorsProvider(arg) - require.NoError(t, err) - - time.Sleep(arg.CacheRefreshIntervalDurationInSec) - - response := vp.GetAuctionList() + validatorsMap := state.NewShardValidatorsInfoMap() + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-eligible"), + List: string(common.EligibleList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-waiting"), + List: string(common.WaitingList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey-leaving"), + List: string(common.LeavingList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey0-auction"), + List: string(common.AuctionList), + }) + _ = validatorsMap.Add(&state.ValidatorInfo{ + ShardId: 0, + PublicKey: []byte("pubkey1-auction"), + List: string(common.AuctionList), + }) + return validatorsMap, nil + } + arg.ValidatorStatistics = validatorStatisticsProcessor + + arg.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ + GetBlsKeyOwnerCalled: func(key []byte) (string, error) { + if "pubkey0-auction" == string(key) { + return "owner0", nil + } + if "pubkey1-auction" == string(key) { + return "owner1", nil + } + return "", nil + }, + GetNodeStakedTopUpCalled: func(key []byte) (*big.Int, error) { + if "pubkey0-auction" == string(key) { + return big.NewInt(100), nil + } + if "pubkey1-auction" == string(key) { + return big.NewInt(110), nil + } + return big.NewInt(0), nil + }, + } - // the result should contain only auction list validators with the correct owner and top up - expectedResponse := []*common.AuctionListValidatorAPIResponse{ - { - Owner: arg.AddressPubKeyConverter.Encode([]byte("owner0")), - NodeKey: hex.EncodeToString([]byte("pubkey0-auction")), - TopUp: "100", - }, - { - Owner: arg.AddressPubKeyConverter.Encode([]byte("owner1")), - NodeKey: hex.EncodeToString([]byte("pubkey1-auction")), - TopUp: "110", - }, - } - require.Equal(t, expectedResponse, response) - }) + vp, err := NewValidatorsProvider(arg) + require.NoError(t, err) + + time.Sleep(arg.CacheRefreshIntervalDurationInSec) + + response := vp.GetAuctionList() + + // the result should contain only auction list validators with the correct owner and top up + expectedResponse := []*common.AuctionListValidatorAPIResponse{ + { + Owner: arg.AddressPubKeyConverter.Encode([]byte("owner0")), + NodeKey: hex.EncodeToString([]byte("pubkey0-auction")), + TopUp: "100", + }, + { + Owner: arg.AddressPubKeyConverter.Encode([]byte("owner1")), + NodeKey: hex.EncodeToString([]byte("pubkey1-auction")), + TopUp: "110", + }, + } + require.Equal(t, expectedResponse, response) + }) + */ } func createMockValidatorInfo() *state.ValidatorInfo { From e0d3a85766501a64ef4f845eaa8eaeb466f549c8 Mon Sep 17 00:00:00 2001 From: Elrond/ Date: Tue, 28 Jun 2022 15:33:01 +0300 Subject: [PATCH 356/958] FIX: After review --- common/dtos.go | 2 +- epochStart/metachain/auctionListSelector.go | 4 ++-- process/peer/validatorsProvider.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/dtos.go b/common/dtos.go index 6dc635cc275..4695cc3fa66 100644 --- a/common/dtos.go +++ b/common/dtos.go @@ -17,7 +17,7 @@ type TransactionsPoolAPIResponse struct { // AuctionNode holds data needed for a node in auction to respond to API calls type AuctionNode struct { BlsKey string `json:"blsKey"` - Qualified bool `json:"selected"` + Qualified bool `json:"qualified"` } // AuctionListValidatorAPIResponse holds the data needed for an auction node validator for responding to API calls diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 7b5b7ef0ada..5c57da0aeac 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -153,7 +153,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( numOfShuffledNodes := currNodesConfig.NodesToShufflePerShard * (als.shardCoordinator.NumberOfShards() + 1) numOfValidatorsAfterShuffling, err := safeSub(currNumOfValidators, numOfShuffledNodes) if err != nil { - log.Warn(fmt.Sprintf("%v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", + log.Warn(fmt.Sprintf("auctionListSelector.SelectNodesFromAuctionList: %v when trying to compute numOfValidatorsAfterShuffling = %v - %v (currNumOfValidators - numOfShuffledNodes)", err, currNumOfValidators, numOfShuffledNodes, @@ -164,7 +164,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( maxNumNodes := currNodesConfig.MaxNumNodes availableSlots, err := safeSub(maxNumNodes, numOfValidatorsAfterShuffling) if availableSlots == 0 || err != nil { - log.Info(fmt.Sprintf("%v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", + log.Info(fmt.Sprintf("auctionListSelector.SelectNodesFromAuctionList: %v or zero value when trying to compute availableSlots = %v - %v (maxNodes - numOfValidatorsAfterShuffling); skip selecting nodes from auction list", err, maxNumNodes, numOfValidatorsAfterShuffling, diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index ed44297992b..fb2378244ec 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -236,13 +236,13 @@ func (vp *validatorsProvider) createNewCache( nodesMapEligible, err := vp.nodesCoordinator.GetAllEligibleValidatorsPublicKeys(epoch) if err != nil { - log.Debug("validatorsProvider - GetAllEligibleValidatorsPublicKeys failed", "epoch", epoch) + log.Debug("validatorsProvider - GetAllEligibleValidatorsPublicKeys failed", "epoch", epoch, "error", err) } vp.aggregateLists(newCache, nodesMapEligible, common.EligibleList) nodesMapWaiting, err := vp.nodesCoordinator.GetAllWaitingValidatorsPublicKeys(epoch) if err != nil { - log.Debug("validatorsProvider - GetAllWaitingValidatorsPublicKeys failed", "epoch", epoch) + log.Debug("validatorsProvider - GetAllWaitingValidatorsPublicKeys failed", "epoch", epoch, "error", err) } vp.aggregateLists(newCache, nodesMapWaiting, common.WaitingList) From fd415368256016d2d19142c6a83e4987d84d7a41 Mon Sep 17 00:00:00 2001 From: Marius C Date: Fri, 13 Jan 2023 09:47:14 +0200 Subject: [PATCH 357/958] FIX: Imports after merge --- epochStart/dtos.go | 2 +- epochStart/metachain/auctionListDisplayer.go | 8 +-- epochStart/metachain/auctionListSelector.go | 16 ++--- .../metachain/auctionListSelector_test.go | 20 +++--- epochStart/metachain/auctionListSorting.go | 2 +- epochStart/metachain/common.go | 2 +- epochStart/metachain/legacySystemSCs.go | 32 +++++----- .../metachain/rewardsCreatorProxy_test.go | 1 - epochStart/metachain/stakingDataProvider.go | 2 +- epochStart/metachain/validatorList.go | 2 +- epochStart/notifier/nodesConfigProvider.go | 8 +-- .../notifier/nodesConfigProvider_test.go | 8 +-- factory/disabled/auctionListSelector.go | 2 +- factory/disabled/stakingDataProvider.go | 4 +- integrationTests/common.go | 8 +-- .../vm/delegation/liquidStaking_test.go | 14 ++--- .../vm/staking/baseTestMetaProcessor.go | 42 ++++++------- .../vm/staking/componentsHolderCreator.go | 62 +++++++++---------- .../vm/staking/configDisplayer.go | 4 +- .../vm/staking/metaBlockProcessorCreator.go | 42 ++++++------- .../vm/staking/nodesCoordiantorCreator.go | 22 +++---- integrationTests/vm/staking/stakingQueue.go | 10 +-- integrationTests/vm/staking/stakingV4_test.go | 14 ++--- .../vm/staking/systemSCCreator.go | 44 ++++++------- .../vm/staking/testMetaProcessor.go | 4 +- .../testMetaProcessorWithCustomNodesConfig.go | 24 +++---- process/peer/process_test.go | 4 +- process/peer/validatorsProviderAuction.go | 6 +- process/peer/validatorsProvider_test.go | 6 +- ...ndexHashedNodesCoordinatorRegistry_test.go | 2 +- .../nodesCoordinatorRegistryFactory.go | 4 +- .../nodesCoordinatorRegistryWithAuction.go | 2 +- state/validatorsInfoMap.go | 2 +- state/validatorsInfoMap_test.go | 2 +- .../nodesCoordRegistryFactoryMock.go | 2 +- .../stakingcommon/auctionListSelectorStub.go | 2 +- testscommon/stakingcommon/stakingCommon.go | 20 +++--- vm/systemSmartContracts/liquidStaking.go | 21 +++---- vm/systemSmartContracts/liquidStaking_test.go | 16 ++--- vm/systemSmartContracts/stakingWaitingList.go | 6 +- 40 files changed, 245 insertions(+), 249 deletions(-) diff --git a/epochStart/dtos.go b/epochStart/dtos.go index 5ae7b1d355d..ea5aa95f626 100644 --- a/epochStart/dtos.go +++ b/epochStart/dtos.go @@ -3,7 +3,7 @@ package epochStart import ( "math/big" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-go/state" ) // OwnerData is a struct containing relevant information about owner's nodes data diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 7447dfcf3df..ed612ce16d9 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -7,10 +7,10 @@ import ( "strconv" "strings" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/display" - logger "github.com/ElrondNetwork/elrond-go-logger" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/display" + "github.com/multiversx/mx-chain-go/state" + logger "github.com/multiversx/mx-chain-logger-go" ) const maxPubKeyDisplayableLen = 20 diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 5c57da0aeac..1bd87398cc2 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -5,14 +5,14 @@ import ( "math" "math/big" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/state" ) type ownerAuctionData struct { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index ae575045a2b..5e5da2307e6 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -5,16 +5,16 @@ import ( "strings" "testing" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/common/forking" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/notifier" - "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/epochStart/notifier" + "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/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index cad28759fc8..d871558b063 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -5,7 +5,7 @@ import ( "math/big" "sort" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-go/state" ) func (als *auctionListSelector) selectNodes( diff --git a/epochStart/metachain/common.go b/epochStart/metachain/common.go index e030ac1e979..9eb614772ab 100644 --- a/epochStart/metachain/common.go +++ b/epochStart/metachain/common.go @@ -1,6 +1,6 @@ package metachain -import "github.com/ElrondNetwork/elrond-go/state" +import "github.com/multiversx/mx-chain-go/state" // GetAllNodeKeys returns all from the provided map func GetAllNodeKeys(validatorsInfo state.ShardValidatorsInfoMapHandler) map[uint32][][]byte { diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index a3547cc8620..74af6023b28 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -9,22 +9,22 @@ import ( "math/big" "sort" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/core/atomic" - "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/common" - vInfo "github.com/ElrondNetwork/elrond-go/common/validatorInfo" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" + vInfo "github.com/multiversx/mx-chain-go/common/validatorInfo" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/vm" + "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) type legacySystemSCProcessor struct { diff --git a/epochStart/metachain/rewardsCreatorProxy_test.go b/epochStart/metachain/rewardsCreatorProxy_test.go index bf27324d40c..637621cfaaa 100644 --- a/epochStart/metachain/rewardsCreatorProxy_test.go +++ b/epochStart/metachain/rewardsCreatorProxy_test.go @@ -14,7 +14,6 @@ import ( "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/mock" "github.com/multiversx/mx-chain-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 1d719c0ffed..4f415cc2193 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -7,7 +7,7 @@ import ( "math/big" "sync" - "github.com/ElrondNetwork/elrond-go-core/core/atomic" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/epochStart" diff --git a/epochStart/metachain/validatorList.go b/epochStart/metachain/validatorList.go index b703ddd3018..75c38a1b3c2 100644 --- a/epochStart/metachain/validatorList.go +++ b/epochStart/metachain/validatorList.go @@ -3,7 +3,7 @@ package metachain import ( "bytes" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-go/state" ) type validatorList []state.ValidatorInfoHandler diff --git a/epochStart/notifier/nodesConfigProvider.go b/epochStart/notifier/nodesConfigProvider.go index 0ebcc5c49d6..bdae9af17a3 100644 --- a/epochStart/notifier/nodesConfigProvider.go +++ b/epochStart/notifier/nodesConfigProvider.go @@ -4,10 +4,10 @@ import ( "sort" "sync" - "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/process" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/process" ) type nodesConfigProvider struct { diff --git a/epochStart/notifier/nodesConfigProvider_test.go b/epochStart/notifier/nodesConfigProvider_test.go index 2c3f7ac4dec..a813ff4b48d 100644 --- a/epochStart/notifier/nodesConfigProvider_test.go +++ b/epochStart/notifier/nodesConfigProvider_test.go @@ -3,10 +3,10 @@ package notifier import ( "testing" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/common/forking" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/process" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/process" "github.com/stretchr/testify/require" ) diff --git a/factory/disabled/auctionListSelector.go b/factory/disabled/auctionListSelector.go index a5f4b7412a7..281102a4a7f 100644 --- a/factory/disabled/auctionListSelector.go +++ b/factory/disabled/auctionListSelector.go @@ -1,6 +1,6 @@ package disabled -import "github.com/ElrondNetwork/elrond-go/state" +import "github.com/multiversx/mx-chain-go/state" type auctionListSelector struct { } diff --git a/factory/disabled/stakingDataProvider.go b/factory/disabled/stakingDataProvider.go index 0adf81a61ba..f24b7b735b2 100644 --- a/factory/disabled/stakingDataProvider.go +++ b/factory/disabled/stakingDataProvider.go @@ -1,8 +1,8 @@ package disabled import ( - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/state" ) type stakingDataProvider struct { diff --git a/integrationTests/common.go b/integrationTests/common.go index 6f5602de789..4624e0b2bfa 100644 --- a/integrationTests/common.go +++ b/integrationTests/common.go @@ -1,10 +1,10 @@ package integrationTests import ( - "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) // ProcessSCOutputAccounts will save account changes in accounts db from vmOutput diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index a343a1b9927..87be301b03b 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -9,13 +9,13 @@ import ( "testing" "time" - "github.com/ElrondNetwork/elrond-go-core/core" - logger "github.com/ElrondNetwork/elrond-go-logger" - "github.com/ElrondNetwork/elrond-go/integrationTests" - "github.com/ElrondNetwork/elrond-go/integrationTests/vm/esdt" - "github.com/ElrondNetwork/elrond-go/testscommon/txDataBuilder" - "github.com/ElrondNetwork/elrond-go/vm" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/integrationTests" + "github.com/multiversx/mx-chain-go/integrationTests/vm/esdt" + "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" + "github.com/multiversx/mx-chain-go/vm" + logger "github.com/multiversx/mx-chain-logger-go" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/require" ) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index e7f470d8dc7..20a79032590 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -8,27 +8,27 @@ import ( "testing" "time" - arwenConfig "github.com/ElrondNetwork/arwen-wasm-vm/v1_4/config" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/display" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - "github.com/ElrondNetwork/elrond-go/factory" - "github.com/ElrondNetwork/elrond-go/integrationTests" - "github.com/ElrondNetwork/elrond-go/process" - vmFactory "github.com/ElrondNetwork/elrond-go/process/factory" - "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts/defaults" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-core-go/display" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/epochStart/metachain" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/integrationTests" + "github.com/multiversx/mx-chain-go/process" + vmFactory "github.com/multiversx/mx-chain-go/process/factory" + "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + "github.com/multiversx/mx-chain-go/vm/systemSmartContracts/defaults" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + arwenConfig "github.com/multiversx/mx-chain-vm-v1_4-go/config" "github.com/stretchr/testify/require" ) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 75ad541f378..4a03134498b 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -3,37 +3,37 @@ package staking import ( "time" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/core/nodetype" - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/endProcess" - "github.com/ElrondNetwork/elrond-go-core/data/typeConverters/uint64ByteSlice" - "github.com/ElrondNetwork/elrond-go-core/hashing/sha256" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/common/forking" - "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/dataRetriever/blockchain" - "github.com/ElrondNetwork/elrond-go/epochStart/notifier" - "github.com/ElrondNetwork/elrond-go/factory" - "github.com/ElrondNetwork/elrond-go/integrationTests" - integrationMocks "github.com/ElrondNetwork/elrond-go/integrationTests/mock" - mockFactory "github.com/ElrondNetwork/elrond-go/node/mock/factory" - "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - stateFactory "github.com/ElrondNetwork/elrond-go/state/factory" - "github.com/ElrondNetwork/elrond-go/state/storagePruningManager" - "github.com/ElrondNetwork/elrond-go/state/storagePruningManager/evictionWaitingList" - "github.com/ElrondNetwork/elrond-go/statusHandler" - "github.com/ElrondNetwork/elrond-go/testscommon" - dataRetrieverMock "github.com/ElrondNetwork/elrond-go/testscommon/dataRetriever" - "github.com/ElrondNetwork/elrond-go/testscommon/mainFactoryMocks" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - statusHandlerMock "github.com/ElrondNetwork/elrond-go/testscommon/statusHandler" - "github.com/ElrondNetwork/elrond-go/trie" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/nodetype" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-core-go/data/typeConverters/uint64ByteSlice" + "github.com/multiversx/mx-chain-core-go/hashing/sha256" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" + "github.com/multiversx/mx-chain-go/epochStart/notifier" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/integrationTests" + integrationMocks "github.com/multiversx/mx-chain-go/integrationTests/mock" + mockFactory "github.com/multiversx/mx-chain-go/node/mock/factory" + "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" + stateFactory "github.com/multiversx/mx-chain-go/state/factory" + "github.com/multiversx/mx-chain-go/state/storagePruningManager" + "github.com/multiversx/mx-chain-go/state/storagePruningManager/evictionWaitingList" + "github.com/multiversx/mx-chain-go/statusHandler" + "github.com/multiversx/mx-chain-go/testscommon" + dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/multiversx/mx-chain-go/trie" ) func createComponentHolders(numOfShards uint32) ( diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index 3c5d554d68c..cd25b8c0a0e 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -5,8 +5,8 @@ import ( "fmt" "strconv" - "github.com/ElrondNetwork/elrond-go-core/display" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-core-go/display" + "github.com/multiversx/mx-chain-go/state" ) const ( diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 0c41a7f60b7..716d83a2f9c 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -3,27 +3,27 @@ package staking import ( "math/big" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - "github.com/ElrondNetwork/elrond-go/factory" - integrationMocks "github.com/ElrondNetwork/elrond-go/integrationTests/mock" - "github.com/ElrondNetwork/elrond-go/process" - blproc "github.com/ElrondNetwork/elrond-go/process/block" - "github.com/ElrondNetwork/elrond-go/process/block/bootstrapStorage" - "github.com/ElrondNetwork/elrond-go/process/block/postprocess" - "github.com/ElrondNetwork/elrond-go/process/block/processedMb" - "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/process/scToProtocol" - "github.com/ElrondNetwork/elrond-go/process/smartContract" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon" - "github.com/ElrondNetwork/elrond-go/testscommon/dblookupext" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/epochStart/metachain" + "github.com/multiversx/mx-chain-go/factory" + integrationMocks "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/process" + blproc "github.com/multiversx/mx-chain-go/process/block" + "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" + "github.com/multiversx/mx-chain-go/process/block/postprocess" + "github.com/multiversx/mx-chain-go/process/block/processedMb" + "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/process/scToProtocol" + "github.com/multiversx/mx-chain-go/process/smartContract" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/dblookupext" ) func createMetaBlockProcessor( diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index c3fadcb14a3..cb2b20746f4 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -3,17 +3,17 @@ package staking import ( "math/big" - "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/config" - "github.com/ElrondNetwork/elrond-go/factory" - integrationMocks "github.com/ElrondNetwork/elrond-go/integrationTests/mock" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/storage" - "github.com/ElrondNetwork/elrond-go/storage/lrucache" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/factory" + integrationMocks "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/storage" + "github.com/multiversx/mx-chain-go/storage/lrucache" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" ) const ( diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 759feff3309..588a94911de 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -3,11 +3,11 @@ package staking import ( "math/big" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + "github.com/multiversx/mx-chain-go/vm" + "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" ) func createStakingQueue( diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 0f7850a2044..7c2f49556d5 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -5,13 +5,13 @@ import ( "math/big" "testing" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + "github.com/multiversx/mx-chain-go/vm" + "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" "github.com/stretchr/testify/require" ) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 3f10ffb7a3f..476f487cebf 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -4,28 +4,28 @@ import ( "bytes" "strconv" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/epochStart/metachain" - epochStartMock "github.com/ElrondNetwork/elrond-go/epochStart/mock" - "github.com/ElrondNetwork/elrond-go/epochStart/notifier" - "github.com/ElrondNetwork/elrond-go/factory" - "github.com/ElrondNetwork/elrond-go/genesis/process/disabled" - "github.com/ElrondNetwork/elrond-go/process" - metaProcess "github.com/ElrondNetwork/elrond-go/process/factory/metachain" - "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/process/peer" - "github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions" - "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" - "github.com/ElrondNetwork/elrond-go/sharding" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon" - "github.com/ElrondNetwork/elrond-go/testscommon/cryptoMocks" - "github.com/ElrondNetwork/elrond-go/vm" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" - vmcommonMock "github.com/ElrondNetwork/elrond-vm-common/mock" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/epochStart/metachain" + epochStartMock "github.com/multiversx/mx-chain-go/epochStart/mock" + "github.com/multiversx/mx-chain-go/epochStart/notifier" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/genesis/process/disabled" + "github.com/multiversx/mx-chain-go/process" + metaProcess "github.com/multiversx/mx-chain-go/process/factory/metachain" + "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/process/peer" + "github.com/multiversx/mx-chain-go/process/smartContract/builtInFunctions" + "github.com/multiversx/mx-chain-go/process/smartContract/hooks" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" + "github.com/multiversx/mx-chain-go/vm" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + vmcommonMock "github.com/multiversx/mx-chain-vm-common-go/mock" ) func createSystemSCProcessor( diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 5038a3738f6..480e898f967 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -1,8 +1,8 @@ package staking import ( - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/dataRetriever" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever" ) // NewTestMetaProcessor - diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 63ba661c851..1739fd7a328 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -6,18 +6,18 @@ import ( "math/big" "testing" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/data" - "github.com/ElrondNetwork/elrond-go-core/data/block" - "github.com/ElrondNetwork/elrond-go-core/data/smartContractResult" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/dataRetriever" - "github.com/ElrondNetwork/elrond-go/integrationTests" - "github.com/ElrondNetwork/elrond-go/process" - "github.com/ElrondNetwork/elrond-go/process/smartContract" - "github.com/ElrondNetwork/elrond-go/vm" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-core-go/data/smartContractResult" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/integrationTests" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/process/smartContract" + "github.com/multiversx/mx-chain-go/vm" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/require" ) diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 2ad24a4f589..a5ef0e75322 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/multiversx/mx-chain-core-go/core" - "github.com/ElrondNetwork/elrond-go-core/core/atomic" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/keyValStorage" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" @@ -123,7 +123,7 @@ func createMockArguments() peer.ArgValidatorStatisticsProcessor { IsSwitchJailWaitingFlagEnabledField: true, IsBelowSignedThresholdFlagEnabledField: true, }, - StakingV4EnableEpoch: 444, + StakingV4EnableEpoch: 444, } return arguments } diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 98e4af36faf..6234a22cfef 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -6,9 +6,9 @@ import ( "sort" "time" - "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/epochStart" - "github.com/ElrondNetwork/elrond-go/state" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/state" ) // GetAuctionList returns an array containing the validators that are currently in the auction list diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 1b5d387d326..7325926075f 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + coreAtomic "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-go/common" @@ -20,13 +21,12 @@ import ( "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ElrondNetwork/elrond-go/testscommon/stakingcommon" - "github.com/multiversx/mx-chain-go/testscommon" - coreAtomic "github.com/multiversx/mx-chain-core-go/core/atomic" ) func TestNewValidatorsProvider_WithNilValidatorStatisticsShouldErr(t *testing.T) { diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go index de1b4f7a2f4..3315afa12b4 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "github.com/ElrondNetwork/elrond-go/common" + "github.com/multiversx/mx-chain-go/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index fa993d9c4e3..72669b3ea6b 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -3,8 +3,8 @@ package nodesCoordinator import ( "encoding/json" - "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/ElrondNetwork/elrond-go-core/marshal" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/marshal" ) type nodesCoordinatorRegistryFactory struct { diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go index 21a41afd033..d9bea843a16 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryWithAuction.go @@ -1,4 +1,4 @@ -//go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/ElrondNetwork/protobuf/protobuf --gogoslick_out=. nodesCoordinatorRegistryWithAuction.proto +//go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. nodesCoordinatorRegistryWithAuction.proto package nodesCoordinator func protoValidatorsMapToSliceMap(validators map[string]Validators) map[string][]*SerializableValidator { diff --git a/state/validatorsInfoMap.go b/state/validatorsInfoMap.go index cdac286090a..e6c492d9d39 100644 --- a/state/validatorsInfoMap.go +++ b/state/validatorsInfoMap.go @@ -6,7 +6,7 @@ import ( "fmt" "sync" - "github.com/ElrondNetwork/elrond-go-core/core/check" + "github.com/multiversx/mx-chain-core-go/core/check" ) type shardValidatorsInfoMap struct { diff --git a/state/validatorsInfoMap_test.go b/state/validatorsInfoMap_test.go index f4325cbd93e..e90c01993cd 100644 --- a/state/validatorsInfoMap_test.go +++ b/state/validatorsInfoMap_test.go @@ -7,7 +7,7 @@ import ( "sync" "testing" - "github.com/ElrondNetwork/elrond-go-core/core" + "github.com/multiversx/mx-chain-core-go/core" "github.com/stretchr/testify/require" ) diff --git a/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go b/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go index cceb0232680..2ed51dc9188 100644 --- a/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go +++ b/testscommon/shardingMocks/nodesCoordRegistryFactoryMock.go @@ -3,7 +3,7 @@ package shardingMocks import ( "encoding/json" - "github.com/ElrondNetwork/elrond-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" ) // NodesCoordinatorRegistryFactoryMock - diff --git a/testscommon/stakingcommon/auctionListSelectorStub.go b/testscommon/stakingcommon/auctionListSelectorStub.go index 95635b3ff19..8cc24960c82 100644 --- a/testscommon/stakingcommon/auctionListSelectorStub.go +++ b/testscommon/stakingcommon/auctionListSelectorStub.go @@ -1,6 +1,6 @@ package stakingcommon -import "github.com/ElrondNetwork/elrond-go/state" +import "github.com/multiversx/mx-chain-go/state" // AuctionListSelectorStub - type AuctionListSelectorStub struct { diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 9c3958e8d42..c1fef2a34e2 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -4,16 +4,16 @@ import ( "math/big" "strconv" - "github.com/ElrondNetwork/elrond-go-core/marshal" - logger "github.com/ElrondNetwork/elrond-go-logger" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/process" - economicsHandler "github.com/ElrondNetwork/elrond-go/process/economics" - "github.com/ElrondNetwork/elrond-go/process/mock" - "github.com/ElrondNetwork/elrond-go/state" - "github.com/ElrondNetwork/elrond-go/testscommon/epochNotifier" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/systemSmartContracts" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/process" + economicsHandler "github.com/multiversx/mx-chain-go/process/economics" + "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" + "github.com/multiversx/mx-chain-go/vm" + "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" + logger "github.com/multiversx/mx-chain-logger-go" ) var log = logger.GetOrCreate("testscommon/stakingCommon") diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index bb49be1eb53..f665b141b0c 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -1,4 +1,4 @@ -//go:generate protoc -I=proto -I=$GOPATH/src -I=$GOPATH/src/github.com/ElrondNetwork/protobuf/protobuf --gogoslick_out=. liquidStaking.proto +//go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. liquidStaking.proto package systemSmartContracts import ( @@ -8,14 +8,14 @@ import ( "math/big" "sync" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go-core/core/atomic" - "github.com/ElrondNetwork/elrond-go-core/core/check" - "github.com/ElrondNetwork/elrond-go-core/hashing" - "github.com/ElrondNetwork/elrond-go-core/marshal" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/vm" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/hashing" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/vm" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) const tokenIDKey = "tokenID" @@ -61,9 +61,6 @@ func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) if check.IfNil(args.Hasher) { return nil, vm.ErrNilHasher } - if check.IfNil(args.EpochNotifier) { - return nil, vm.ErrNilEpochNotifier - } l := &liquidStaking{ eei: args.Eei, diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go index 557919093d4..ff3c0a86ec2 100644 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -6,14 +6,14 @@ import ( "math/big" "testing" - "github.com/ElrondNetwork/elrond-go-core/core" - "github.com/ElrondNetwork/elrond-go/config" - "github.com/ElrondNetwork/elrond-go/process/smartContract/hooks" - "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" - stateMock "github.com/ElrondNetwork/elrond-go/testscommon/state" - "github.com/ElrondNetwork/elrond-go/vm" - "github.com/ElrondNetwork/elrond-go/vm/mock" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/process/smartContract/hooks" + "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" + stateMock "github.com/multiversx/mx-chain-go/testscommon/state" + "github.com/multiversx/mx-chain-go/vm" + "github.com/multiversx/mx-chain-go/vm/mock" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" ) diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index a9909bebf87..ecc4eb8e24e 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -8,9 +8,9 @@ import ( "math/big" "strconv" - "github.com/ElrondNetwork/elrond-go/common" - "github.com/ElrondNetwork/elrond-go/vm" - vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/vm" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) const waitingListHeadKey = "waitingList" From f3fbf0aba164fb381e5e19f0728d136f431a74bc Mon Sep 17 00:00:00 2001 From: Marius C Date: Fri, 13 Jan 2023 09:53:10 +0200 Subject: [PATCH 358/958] FIX: DataTrieTracker --- epochStart/metachain/legacySystemSCs.go | 2 +- integrationTests/common.go | 2 +- integrationTests/vm/staking/stakingQueue.go | 2 +- integrationTests/vm/staking/stakingV4_test.go | 4 +-- testscommon/stakingcommon/stakingCommon.go | 25 +++++++++---------- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 74af6023b28..7c3bb20f77b 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -829,7 +829,7 @@ func (s *legacySystemSCProcessor) processSCOutputAccounts( storageUpdates := process.GetSortedStorageUpdates(outAcc) for _, storeUpdate := range storageUpdates { - err = acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) + err = acc.SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) if err != nil { return err } diff --git a/integrationTests/common.go b/integrationTests/common.go index 4624e0b2bfa..e4365471cd7 100644 --- a/integrationTests/common.go +++ b/integrationTests/common.go @@ -15,7 +15,7 @@ func ProcessSCOutputAccounts(vmOutput *vmcommon.VMOutput, accountsDB state.Accou storageUpdates := process.GetSortedStorageUpdates(outAcc) for _, storeUpdate := range storageUpdates { - err := acc.DataTrieTracker().SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) + err := acc.SaveKeyValue(storeUpdate.Offset, storeUpdate.Data) if err != nil { return err } diff --git a/integrationTests/vm/staking/stakingQueue.go b/integrationTests/vm/staking/stakingQueue.go index 588a94911de..7544e18cf40 100644 --- a/integrationTests/vm/staking/stakingQueue.go +++ b/integrationTests/vm/staking/stakingQueue.go @@ -87,7 +87,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte { Length: 0, LastJailedKey: make([]byte, 0), } - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + marshaledData, _, _ := stakingSCAcc.RetrieveValue([]byte("waitingList")) if len(marshaledData) == 0 { return nil } diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 7c2f49556d5..6d9f9854cae 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -88,7 +88,7 @@ func remove(slice [][]byte, elem []byte) [][]byte { func unStake(t *testing.T, owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { validatorSC := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) - ownerStoredData, err := validatorSC.DataTrieTracker().RetrieveValue(owner) + ownerStoredData, _, err := validatorSC.RetrieveValue(owner) require.Nil(t, err) validatorData := &systemSmartContracts.ValidatorDataV2{} @@ -97,7 +97,7 @@ func unStake(t *testing.T, owner []byte, accountsDB state.AccountsAdapter, marsh validatorData.TotalStakeValue.Sub(validatorData.TotalStakeValue, stake) marshaledData, _ := marshaller.Marshal(validatorData) - err = validatorSC.DataTrieTracker().SaveKeyValue(owner, marshaledData) + err = validatorSC.SaveKeyValue(owner, marshaledData) require.Nil(t, err) err = accountsDB.SaveAccount(validatorSC) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index c1fef2a34e2..1ff99a1d263 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -42,7 +42,7 @@ func AddValidatorData( marshaller marshal.Marshalizer, ) { validatorSC := LoadUserAccount(accountsDB, vm.ValidatorSCAddress) - ownerStoredData, _ := validatorSC.DataTrieTracker().RetrieveValue(ownerKey) + ownerStoredData, _, _ := validatorSC.RetrieveValue(ownerKey) validatorData := &systemSmartContracts.ValidatorDataV2{} if len(ownerStoredData) != 0 { _ = marshaller.Unmarshal(validatorData, ownerStoredData) @@ -62,7 +62,7 @@ func AddValidatorData( } marshaledData, _ := marshaller.Marshal(validatorData) - _ = validatorSC.DataTrieTracker().SaveKeyValue(ownerKey, marshaledData) + _ = validatorSC.SaveKeyValue(ownerKey, marshaledData) _ = accountsDB.SaveAccount(validatorSC) } @@ -85,7 +85,7 @@ func AddStakingData( stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress) for _, key := range stakedKeys { - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) + _ = stakingSCAcc.SaveKeyValue(key, marshaledData) } _ = accountsDB.SaveAccount(stakingSCAcc) @@ -151,7 +151,7 @@ func getWaitingList( stakingSCAcc state.UserAccountHandler, marshaller marshal.Marshalizer, ) *systemSmartContracts.WaitingList { - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList")) + marshaledData, _, _ := stakingSCAcc.RetrieveValue([]byte("waitingList")) waitingList := &systemSmartContracts.WaitingList{} _ = marshaller.Unmarshal(waitingList, marshaledData) @@ -164,7 +164,7 @@ func saveWaitingList( waitingList *systemSmartContracts.WaitingList, ) { marshaledData, _ := marshaller.Marshal(waitingList) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData) + _ = stakingSCAcc.SaveKeyValue([]byte("waitingList"), marshaledData) } func getPrefixedWaitingKey(key []byte) []byte { @@ -186,7 +186,7 @@ func saveStakedWaitingKey( } marshaledData, _ := marshaller.Marshal(stakedData) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) + _ = stakingSCAcc.SaveKeyValue(key, marshaledData) } func saveElemInList( @@ -196,7 +196,7 @@ func saveElemInList( key []byte, ) { marshaledData, _ := marshaller.Marshal(elem) - _ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData) + _ = stakingSCAcc.SaveKeyValue(key, marshaledData) } // GetWaitingListElement returns the element in waiting list saved at the provided key @@ -205,7 +205,7 @@ func GetWaitingListElement( marshaller marshal.Marshalizer, key []byte, ) (*systemSmartContracts.ElementInList, error) { - marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key) + marshaledData, _, _ := stakingSCAcc.RetrieveValue(key) if len(marshaledData) == 0 { return nil, vm.ErrElementNotFound } @@ -271,9 +271,8 @@ func CreateEconomicsData() process.EconomicsDataHandler { GasPriceModifier: 1.0, }, }, - PenalizedTooMuchGasEnableEpoch: 0, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, } economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData @@ -299,7 +298,7 @@ func SaveNodesConfig( log.LogIfError(err) userAccount, _ := account.(state.UserAccountHandler) - err = userAccount.DataTrieTracker().SaveKeyValue([]byte("nodesConfig"), nodesDataBytes) + err = userAccount.SaveKeyValue([]byte("nodesConfig"), nodesDataBytes) log.LogIfError(err) err = accountsDB.SaveAccount(account) log.LogIfError(err) @@ -321,7 +320,7 @@ func SaveDelegationManagerConfig(accountsDB state.AccountsAdapter, marshaller ma log.LogIfError(err) delegationAcc, _ := acc.(state.UserAccountHandler) - err = delegationAcc.DataTrieTracker().SaveKeyValue([]byte("delegationManagement"), marshaledData) + err = delegationAcc.SaveKeyValue([]byte("delegationManagement"), marshaledData) log.LogIfError(err) err = accountsDB.SaveAccount(delegationAcc) log.LogIfError(err) From 6b79d9d85516668dee066df1f2d0d4f0ba070158 Mon Sep 17 00:00:00 2001 From: Marius C Date: Fri, 13 Jan 2023 13:25:46 +0200 Subject: [PATCH 359/958] FIX: Add stakingV4Flags + small fixes + trie --- common/enablers/enableEpochsHandler.go | 4 ++ common/enablers/enableEpochsHandler_test.go | 21 +++++++++- common/enablers/epochFlags.go | 28 +++++++++++++ common/interface.go | 4 ++ epochStart/interface.go | 1 + epochStart/metachain/legacySystemSCs.go | 16 ++++++-- process/mock/epochStartSystemSCStub.go | 0 process/peer/process.go | 13 +++--- sharding/mock/enableEpochsHandlerMock.go | 20 ++++++++++ .../nodesCoordinator/hashValidatorShuffler.go | 1 + .../indexHashedNodesCoordinator.go | 1 - state/validatorInfo_test.go | 0 testscommon/enableEpochsHandlerStub.go | 40 ++++++++++++++++++- testscommon/epochValidatorInfoCreatorStub.go | 2 +- update/genesis/common.go | 3 +- vm/systemSmartContracts/esdt.go | 14 ++++--- vm/systemSmartContracts/validator.go | 9 +++-- 17 files changed, 151 insertions(+), 26 deletions(-) delete mode 100644 process/mock/epochStartSystemSCStub.go delete mode 100644 state/validatorInfo_test.go diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index c64b887727e..128203eb936 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -116,6 +116,10 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.RuntimeMemStoreLimitEnableEpoch, handler.runtimeMemStoreLimitFlag, "runtimeMemStoreLimitFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.MaxBlockchainHookCountersEnableEpoch, handler.maxBlockchainHookCountersFlag, "maxBlockchainHookCountersFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.WipeSingleNFTLiquidityDecreaseEnableEpoch, handler.wipeSingleNFTLiquidityDecreaseFlag, "wipeSingleNFTLiquidityDecreaseFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakeLimitsEnableEpoch, handler.stakeLimitsFlag, "stakeLimitsFlag") + handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4InitFlag, "stakingV4InitFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4EnableEpoch, handler.stakingV4Flag, "stakingV4Flag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") } func (handler *enableEpochsHandler) setFlagValue(value bool, flag *atomic.Flag, flagName string) { diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 5dbc829c2c9..46ebd7980e1 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -89,6 +89,10 @@ func createEnableEpochsConfig() config.EnableEpochs { RuntimeMemStoreLimitEnableEpoch: 73, MaxBlockchainHookCountersEnableEpoch: 74, WipeSingleNFTLiquidityDecreaseEnableEpoch: 75, + StakeLimitsEnableEpoch: 76, + StakingV4InitEnableEpoch: 77, + StakingV4EnableEpoch: 78, + StakingV4DistributeAuctionToWaitingEpoch: 79, } } @@ -127,7 +131,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) require.False(t, check.IfNil(handler)) - handler.EpochConfirmed(76, 0) + handler.EpochConfirmed(80, 0) assert.Equal(t, cfg.BlockGasAndFeesReCheckEnableEpoch, handler.BlockGasAndFeesReCheckEnableEpoch()) assert.True(t, handler.IsSCDeployFlagEnabled()) @@ -209,16 +213,21 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsFixOldTokenLiquidityEnabled()) assert.True(t, handler.IsRuntimeMemStoreLimitEnabled()) assert.True(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) + assert.True(t, handler.IsStakeLimitsEnabled()) + assert.False(t, handler.IsStakingV4InitEnabled()) // epoch == limit + assert.True(t, handler.IsStakingV4Enabled()) + assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingFlagEnabled()) }) t.Run("flags with == condition should be set, along with all >=", func(t *testing.T) { t.Parallel() - epoch := uint32(77) + epoch := uint32(81) cfg := createEnableEpochsConfig() cfg.StakingV2EnableEpoch = epoch cfg.ESDTEnableEpoch = epoch cfg.GovernanceEnableEpoch = epoch cfg.CorrectLastUnjailedEnableEpoch = epoch + cfg.StakingV4InitEnableEpoch = epoch handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) require.False(t, check.IfNil(handler)) @@ -307,6 +316,10 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsRuntimeMemStoreLimitEnabled()) assert.True(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.True(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) + assert.True(t, handler.IsStakeLimitsEnabled()) + assert.True(t, handler.IsStakingV4InitEnabled()) + assert.True(t, handler.IsStakingV4Enabled()) + assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingFlagEnabled()) }) t.Run("flags with < should be set", func(t *testing.T) { t.Parallel() @@ -400,5 +413,9 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsRuntimeMemStoreLimitEnabled()) assert.False(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.False(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) + assert.False(t, handler.IsStakeLimitsEnabled()) + assert.False(t, handler.IsStakingV4InitEnabled()) + assert.False(t, handler.IsStakingV4Enabled()) + assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingFlagEnabled()) }) } diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index f2ccf4cc5e1..f4b15e2c468 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -88,6 +88,10 @@ type epochFlagsHolder struct { runtimeMemStoreLimitFlag *atomic.Flag maxBlockchainHookCountersFlag *atomic.Flag wipeSingleNFTLiquidityDecreaseFlag *atomic.Flag + stakeLimitsFlag *atomic.Flag + stakingV4InitFlag *atomic.Flag + stakingV4Flag *atomic.Flag + stakingV4DistributeAuctionToWaitingFlag *atomic.Flag } func newEpochFlagsHolder() *epochFlagsHolder { @@ -175,6 +179,10 @@ func newEpochFlagsHolder() *epochFlagsHolder { runtimeMemStoreLimitFlag: &atomic.Flag{}, maxBlockchainHookCountersFlag: &atomic.Flag{}, wipeSingleNFTLiquidityDecreaseFlag: &atomic.Flag{}, + stakeLimitsFlag: &atomic.Flag{}, + stakingV4InitFlag: &atomic.Flag{}, + stakingV4Flag: &atomic.Flag{}, + stakingV4DistributeAuctionToWaitingFlag: &atomic.Flag{}, } } @@ -645,3 +653,23 @@ func (holder *epochFlagsHolder) IsMaxBlockchainHookCountersFlagEnabled() bool { func (holder *epochFlagsHolder) IsWipeSingleNFTLiquidityDecreaseEnabled() bool { return holder.wipeSingleNFTLiquidityDecreaseFlag.IsSet() } + +// IsStakeLimitsEnabled returns true if stakeLimitsFlag is enabled +func (holder *epochFlagsHolder) IsStakeLimitsEnabled() bool { + return holder.stakeLimitsFlag.IsSet() +} + +// IsStakingV4InitEnabled returns true if stakingV4InitFlag is enabled +func (holder *epochFlagsHolder) IsStakingV4InitEnabled() bool { + return holder.stakingV4InitFlag.IsSet() +} + +// IsStakingV4Enabled returns true if stakingV4Flag is enabled +func (holder *epochFlagsHolder) IsStakingV4Enabled() bool { + return holder.stakingV4Flag.IsSet() +} + +// IsStakingV4DistributeAuctionToWaitingFlagEnabled returns true if stakeLimitsFlag is enabled +func (holder *epochFlagsHolder) IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool { + return holder.stakingV4DistributeAuctionToWaitingFlag.IsSet() +} diff --git a/common/interface.go b/common/interface.go index 10e27a836e7..e245c01cc9c 100644 --- a/common/interface.go +++ b/common/interface.go @@ -335,6 +335,10 @@ type EnableEpochsHandler interface { IsRuntimeMemStoreLimitEnabled() bool IsMaxBlockchainHookCountersFlagEnabled() bool IsWipeSingleNFTLiquidityDecreaseEnabled() bool + IsStakeLimitsEnabled() bool + IsStakingV4InitEnabled() bool + IsStakingV4Enabled() bool + IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool IsInterfaceNil() bool } diff --git a/epochStart/interface.go b/epochStart/interface.go index e0e88d62ba2..0264f39f268 100644 --- a/epochStart/interface.go +++ b/epochStart/interface.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/state" vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 7c3bb20f77b..94b16652b6c 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -22,6 +22,7 @@ import ( "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/trie/keyBuilder" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -67,6 +68,8 @@ type legacySystemSCProcessor struct { flagESDTEnabled atomic.Flag flagSaveJailedAlwaysEnabled atomic.Flag flagStakingQueueEnabled atomic.Flag + + enableEpochsHandler common.EnableEpochsHandler } func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*legacySystemSCProcessor, error) { @@ -101,6 +104,7 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, maxNodesChangeConfigProvider: args.MaxNodesChangeConfigProvider, + enableEpochsHandler: args.EnableEpochsHandler, } log.Debug("legacySystemSC: enable epoch for switch jail waiting", "epoch", legacy.switchEnableEpoch) @@ -155,6 +159,9 @@ func checkLegacyArgs(args ArgsNewEpochStartSystemSCProcessing) error { if check.IfNil(args.MaxNodesChangeConfigProvider) { return epochStart.ErrNilMaxNodesChangeConfigProvider } + if check.IfNil(args.EnableEpochsHandler) { + return process.ErrNilEnableEpochsHandler + } if len(args.ESDTOwnerAddressBytes) == 0 { return epochStart.ErrEmptyESDTOwnerAddress } @@ -1012,12 +1019,15 @@ func (s *legacySystemSCProcessor) getArgumentsForSetOwnerFunctionality(userValid return nil, err } - chLeaves := make(chan core.KeyValueHolder, common.TrieLeavesChannelDefaultCapacity) - err = userValidatorAccount.DataTrie().GetAllLeavesOnChannel(chLeaves, context.Background(), rootHash) + leavesChannels := &common.TrieIteratorChannels{ + LeavesChan: make(chan core.KeyValueHolder, common.TrieLeavesChannelDefaultCapacity), + ErrChan: make(chan error, 1), + } + err = userValidatorAccount.DataTrie().GetAllLeavesOnChannel(leavesChannels, context.Background(), rootHash, keyBuilder.NewKeyBuilder()) if err != nil { return nil, err } - for leaf := range chLeaves { + for leaf := range leavesChannels.LeavesChan { validatorData := &systemSmartContracts.ValidatorDataV2{} value, errTrim := leaf.ValueWithoutSuffix(append(leaf.Key(), vm.ValidatorSCAddress...)) if errTrim != nil { diff --git a/process/mock/epochStartSystemSCStub.go b/process/mock/epochStartSystemSCStub.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/process/peer/process.go b/process/peer/process.go index 72f03337cb4..9c4ad438a00 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -9,6 +9,7 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" @@ -54,7 +55,7 @@ type ArgValidatorStatisticsProcessor struct { GenesisNonce uint64 RatingEnableEpoch uint32 EnableEpochsHandler common.EnableEpochsHandler - StakingV4EnableEpoch uint32 + StakingV4EnableEpoch uint32 } type validatorStatistics struct { @@ -75,8 +76,8 @@ type validatorStatistics struct { ratingEnableEpoch uint32 lastFinalizedRootHash []byte enableEpochsHandler common.EnableEpochsHandler - flagStakingV4 atomic.Flag - stakingV4EnableEpoch uint32 + flagStakingV4 atomic.Flag + stakingV4EnableEpoch uint32 } // NewValidatorStatisticsProcessor instantiates a new validatorStatistics structure responsible for keeping account of @@ -137,7 +138,7 @@ func NewValidatorStatisticsProcessor(arguments ArgValidatorStatisticsProcessor) maxConsecutiveRoundsOfRatingDecrease: arguments.MaxConsecutiveRoundsOfRatingDecrease, genesisNonce: arguments.GenesisNonce, enableEpochsHandler: arguments.EnableEpochsHandler, - stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, + stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, } err := vs.saveInitialState(arguments.NodesSetup) @@ -440,10 +441,10 @@ func (vs *validatorStatistics) RootHash() ([]byte, error) { } func (vs *validatorStatistics) getValidatorDataFromLeaves( - leavesChannel chan core.KeyValueHolder, + leavesChannels *common.TrieIteratorChannels, ) (state.ShardValidatorsInfoMapHandler, error) { validators := state.NewShardValidatorsInfoMap() - for pa := range leavesChannel { + for pa := range leavesChannels.LeavesChan { peerAccount, err := vs.unmarshalPeer(pa.Value()) if err != nil { return nil, err diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 8ef7ae34e58..4780cb22c96 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -556,6 +556,26 @@ func (mock *EnableEpochsHandlerMock) IsWipeSingleNFTLiquidityDecreaseEnabled() b return false } +// IsStakeLimitsEnabled - +func (mock *EnableEpochsHandlerMock) IsStakeLimitsEnabled() bool { + return false +} + +// IsStakingV4InitEnabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4InitEnabled() bool { + return false +} + +// IsStakingV4Enabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4Enabled() bool { + return false +} + +// IsStakingV4DistributeAuctionToWaitingFlagEnabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool { + return false +} + // IsInterfaceNil returns true if there is no value under the interface func (mock *EnableEpochsHandlerMock) IsInterfaceNil() bool { return mock == nil diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index cfd1c69d369..d4c752cb135 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -34,6 +34,7 @@ type shuffleNodesArg struct { unstakeLeaving []Validator additionalLeaving []Validator newNodes []Validator + auction []Validator randomness []byte distributor ValidatorsDistributor nodesMeta uint32 diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 1ce33993b21..a4c21089f62 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -287,7 +287,6 @@ func (ihnc *indexHashedNodesCoordinator) setNodesPerShards( nodesConfig.waitingMap = waiting nodesConfig.leavingMap = leaving nodesConfig.shuffledOutMap = shuffledOut - nodesConfig.shardID, isValidator = ihnc.computeShardForSelfPublicKey(nodesConfig) nodesConfig.shardID, isCurrentNodeValidator = ihnc.computeShardForSelfPublicKey(nodesConfig) nodesConfig.selectors, err = ihnc.createSelectors(nodesConfig) if err != nil { diff --git a/state/validatorInfo_test.go b/state/validatorInfo_test.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index ae9b8ed4dc4..adbf7141990 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -1,6 +1,8 @@ package testscommon -import "sync" +import ( + "sync" +) // EnableEpochsHandlerStub - type EnableEpochsHandlerStub struct { @@ -115,6 +117,10 @@ type EnableEpochsHandlerStub struct { IsRuntimeMemStoreLimitEnabledField bool IsMaxBlockchainHookCountersFlagEnabledField bool IsWipeSingleNFTLiquidityDecreaseEnabledField bool + IsStakeLimitsFlagEnabledField bool + IsStakingV4InitFlagEnabledField bool + IsStakingV4FlagEnabledField bool + IsStakingV4DistributeAuctionToWaitingFlagEnabledField bool } // ResetPenalizedTooMuchGasFlag - @@ -996,6 +1002,38 @@ func (stub *EnableEpochsHandlerStub) IsWipeSingleNFTLiquidityDecreaseEnabled() b return stub.IsWipeSingleNFTLiquidityDecreaseEnabledField } +// IsStakeLimitsEnabled - +func (stub *EnableEpochsHandlerStub) IsStakeLimitsEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakeLimitsFlagEnabledField +} + +// IsStakingV4InitEnabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4InitEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingV4InitFlagEnabledField +} + +// IsStakingV4Enabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4Enabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingV4FlagEnabledField +} + +// IsStakingV4DistributeAuctionToWaitingFlagEnabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingV4DistributeAuctionToWaitingFlagEnabledField +} + // IsInterfaceNil - func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { return stub == nil diff --git a/testscommon/epochValidatorInfoCreatorStub.go b/testscommon/epochValidatorInfoCreatorStub.go index 59a49d2096c..31c07037f1e 100644 --- a/testscommon/epochValidatorInfoCreatorStub.go +++ b/testscommon/epochValidatorInfoCreatorStub.go @@ -28,7 +28,7 @@ func (e *EpochValidatorInfoCreatorStub) CreateValidatorInfoMiniBlocks(validatorI } // VerifyValidatorInfoMiniBlocks - -func (e *EpochValidatorInfoCreatorStub) VerifyValidatorInfoMiniBlocks(miniblocks []*block.MiniBlock, validatorsInfo state.ShardValidatorsInfoMapHandler) error { +func (e *EpochValidatorInfoCreatorStub) VerifyValidatorInfoMiniBlocks(miniBlocks []*block.MiniBlock, validatorsInfo state.ShardValidatorsInfoMapHandler) error { if e.VerifyValidatorInfoMiniBlocksCalled != nil { return e.VerifyValidatorInfoMiniBlocksCalled(miniBlocks, validatorsInfo) } diff --git a/update/genesis/common.go b/update/genesis/common.go index 9eca3c63e37..47497906c18 100644 --- a/update/genesis/common.go +++ b/update/genesis/common.go @@ -3,10 +3,9 @@ package genesis import ( "math/big" - "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/state" ) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 0308bcb7ef5..d23e3439bc9 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -10,6 +10,7 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" @@ -59,6 +60,7 @@ type esdt struct { enableEpochsHandler common.EnableEpochsHandler esdtOnMetachainEnableEpoch uint32 flagESDTOnMeta atomic.Flag + delegationTicker string } // ArgsNewESDTSmartContract defines the arguments needed for the esdt contract @@ -109,7 +111,7 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { // we should have called pubkeyConverter.Decode here instead of a byte slice cast. Since that change would break // backwards compatibility, the fix was carried in the epochStart/metachain/systemSCs.go ownerAddress: []byte(args.ESDTSCConfig.OwnerAddress), - eSDTSCAddress: args.ESDTSCAddress, + esdtSCAddress: args.ESDTSCAddress, hasher: args.Hasher, marshalizer: args.Marshalizer, endOfEpochSCAddress: args.EndOfEpochSCAddress, @@ -1127,7 +1129,7 @@ func (e *esdt) saveTokenAndSendForAll(token *ESDTDataV2, tokenID []byte, builtIn } esdtTransferData := builtInCall + "@" + hex.EncodeToString(tokenID) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) return vmcommon.Ok } @@ -1182,7 +1184,7 @@ func (e *esdt) addBurnRoleAndSendToAllShards(token *ESDTDataV2, tokenID []byte) token.SpecialRoles = append(token.SpecialRoles, burnForAllRole) esdtTransferData := vmcommon.BuiltInFunctionESDTSetBurnRoleForAll + "@" + hex.EncodeToString(tokenID) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } func (e *esdt) configChange(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { @@ -1856,7 +1858,7 @@ func (e *esdt) sendNewTransferRoleAddressToSystemAccount(token []byte, address [ } esdtTransferData := vmcommon.BuiltInFunctionESDTTransferRoleAddAddress + "@" + hex.EncodeToString(token) + "@" + hex.EncodeToString(address) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } func (e *esdt) deleteTransferRoleAddressFromSystemAccount(token []byte, address []byte) { @@ -1866,7 +1868,7 @@ func (e *esdt) deleteTransferRoleAddressFromSystemAccount(token []byte, address } esdtTransferData := vmcommon.BuiltInFunctionESDTTransferRoleDeleteAddress + "@" + hex.EncodeToString(token) + "@" + hex.EncodeToString(address) - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } func (e *esdt) sendAllTransferRoleAddresses(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { @@ -1902,7 +1904,7 @@ func (e *esdt) sendAllTransferRoleAddresses(args *vmcommon.ContractCallInput) vm return vmcommon.UserError } - e.eei.SendGlobalSettingToAll(e.eSDTSCAddress, []byte(esdtTransferData)) + e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) return vmcommon.Ok } diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 9ccb4cdd594..170caaf2344 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -10,6 +10,7 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" @@ -173,10 +174,10 @@ func NewValidatorSmartContract( governanceSCAddress: args.GovernanceSCAddress, shardCoordinator: args.ShardCoordinator, enableEpochsHandler: args.EnableEpochsHandler, - stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, - nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, - nodesCoordinator: args.NodesCoordinator, - }, + stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, + nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, + nodesCoordinator: args.NodesCoordinator, + } reg.totalStakeLimit = core.GetIntTrimmedPercentageOfValue(args.GenesisTotalSupply, args.StakingSCConfig.StakeLimitPercentage) if reg.totalStakeLimit.Cmp(baseConfig.NodePrice) < 0 { From db37d9c78d7c95bddeed55cee86fdc5c4343be04 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 13 Jan 2023 15:21:32 +0200 Subject: [PATCH 360/958] FIX: legacySystemSCs.go + systemSCs.go flags --- common/enablers/enableEpochsHandler.go | 2 + common/enablers/enableEpochsHandler_test.go | 13 ++- common/enablers/epochFlags.go | 18 +++- common/interface.go | 4 +- epochStart/metachain/legacySystemSCs.go | 96 +++------------------ epochStart/metachain/systemSCs.go | 41 ++------- sharding/mock/enableEpochsHandlerMock.go | 14 ++- testscommon/enableEpochsHandlerStub.go | 26 +++++- 8 files changed, 86 insertions(+), 128 deletions(-) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 128203eb936..7de705d8920 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -120,6 +120,8 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4InitFlag, "stakingV4InitFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4EnableEpoch, handler.stakingV4Flag, "stakingV4Flag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") + handler.setFlagValue(epoch == handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, handler.initLiquidStakingFlag, "initLiquidStakingFlag") + handler.setFlagValue(epoch < handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingQueueEnabledFlag, "stakingQueueEnabledFlag") } func (handler *enableEpochsHandler) setFlagValue(value bool, flag *atomic.Flag, flagName string) { diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 46ebd7980e1..476e7b1bffa 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -216,7 +216,9 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsStakeLimitsEnabled()) assert.False(t, handler.IsStakingV4InitEnabled()) // epoch == limit assert.True(t, handler.IsStakingV4Enabled()) - assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingFlagEnabled()) + assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) + assert.False(t, handler.IsStakingQueueEnabled()) + assert.False(t, handler.IsInitLiquidStakingEnabled()) }) t.Run("flags with == condition should be set, along with all >=", func(t *testing.T) { t.Parallel() @@ -228,6 +230,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { cfg.GovernanceEnableEpoch = epoch cfg.CorrectLastUnjailedEnableEpoch = epoch cfg.StakingV4InitEnableEpoch = epoch + cfg.BuiltInFunctionOnMetaEnableEpoch = epoch handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) require.False(t, check.IfNil(handler)) @@ -319,7 +322,9 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsStakeLimitsEnabled()) assert.True(t, handler.IsStakingV4InitEnabled()) assert.True(t, handler.IsStakingV4Enabled()) - assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingFlagEnabled()) + assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) + assert.False(t, handler.IsStakingQueueEnabled()) + assert.True(t, handler.IsInitLiquidStakingEnabled()) }) t.Run("flags with < should be set", func(t *testing.T) { t.Parallel() @@ -416,6 +421,8 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsStakeLimitsEnabled()) assert.False(t, handler.IsStakingV4InitEnabled()) assert.False(t, handler.IsStakingV4Enabled()) - assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingFlagEnabled()) + assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) + assert.True(t, handler.IsStakingQueueEnabled()) + assert.False(t, handler.IsInitLiquidStakingEnabled()) }) } diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index f4b15e2c468..e1b23c67452 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -92,6 +92,8 @@ type epochFlagsHolder struct { stakingV4InitFlag *atomic.Flag stakingV4Flag *atomic.Flag stakingV4DistributeAuctionToWaitingFlag *atomic.Flag + stakingQueueEnabledFlag *atomic.Flag + initLiquidStakingFlag *atomic.Flag } func newEpochFlagsHolder() *epochFlagsHolder { @@ -183,6 +185,8 @@ func newEpochFlagsHolder() *epochFlagsHolder { stakingV4InitFlag: &atomic.Flag{}, stakingV4Flag: &atomic.Flag{}, stakingV4DistributeAuctionToWaitingFlag: &atomic.Flag{}, + stakingQueueEnabledFlag: &atomic.Flag{}, + initLiquidStakingFlag: &atomic.Flag{}, } } @@ -669,7 +673,17 @@ func (holder *epochFlagsHolder) IsStakingV4Enabled() bool { return holder.stakingV4Flag.IsSet() } -// IsStakingV4DistributeAuctionToWaitingFlagEnabled returns true if stakeLimitsFlag is enabled -func (holder *epochFlagsHolder) IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool { +// IsStakingV4DistributeAuctionToWaitingEnabled returns true if stakeLimitsFlag is enabled +func (holder *epochFlagsHolder) IsStakingV4DistributeAuctionToWaitingEnabled() bool { return holder.stakingV4DistributeAuctionToWaitingFlag.IsSet() } + +// IsInitLiquidStakingEnabled returns true if initLiquidStakingFlag is enabled +func (holder *epochFlagsHolder) IsInitLiquidStakingEnabled() bool { + return holder.initLiquidStakingFlag.IsSet() +} + +// IsStakingQueueEnabled returns true if stakingQueueEnabledFlag is enabled +func (holder *epochFlagsHolder) IsStakingQueueEnabled() bool { + return holder.stakingQueueEnabledFlag.IsSet() +} diff --git a/common/interface.go b/common/interface.go index e245c01cc9c..dba8fc55bb8 100644 --- a/common/interface.go +++ b/common/interface.go @@ -338,7 +338,9 @@ type EnableEpochsHandler interface { IsStakeLimitsEnabled() bool IsStakingV4InitEnabled() bool IsStakingV4Enabled() bool - IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool + IsStakingV4DistributeAuctionToWaitingEnabled() bool + IsInitLiquidStakingEnabled() bool + IsStakingQueueEnabled() bool IsInterfaceNil() bool } diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 94b16652b6c..2d08de3780a 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -48,28 +48,8 @@ type legacySystemSCProcessor struct { mapNumSwitchablePerShard map[uint32]uint32 maxNodes uint32 - switchEnableEpoch uint32 - hystNodesEnableEpoch uint32 - delegationEnableEpoch uint32 - stakingV2EnableEpoch uint32 - correctLastUnJailEpoch uint32 - esdtEnableEpoch uint32 - saveJailedAlwaysEnableEpoch uint32 - stakingV4InitEnableEpoch uint32 - - flagSwitchJailedWaiting atomic.Flag - flagHystNodesEnabled atomic.Flag - flagDelegationEnabled atomic.Flag - flagSetOwnerEnabled atomic.Flag - flagChangeMaxNodesEnabled atomic.Flag - flagStakingV2Enabled atomic.Flag - flagCorrectLastUnjailedEnabled atomic.Flag - flagCorrectNumNodesToStake atomic.Flag - flagESDTEnabled atomic.Flag - flagSaveJailedAlwaysEnabled atomic.Flag - flagStakingQueueEnabled atomic.Flag - - enableEpochsHandler common.EnableEpochsHandler + flagChangeMaxNodesEnabled atomic.Flag + enableEpochsHandler common.EnableEpochsHandler } func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*legacySystemSCProcessor, error) { @@ -91,31 +71,14 @@ func newLegacySystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*lega chanceComputer: args.ChanceComputer, mapNumSwitchedPerShard: make(map[uint32]uint32), mapNumSwitchablePerShard: make(map[uint32]uint32), - switchEnableEpoch: args.EpochConfig.EnableEpochs.SwitchJailWaitingEnableEpoch, - hystNodesEnableEpoch: args.EpochConfig.EnableEpochs.SwitchHysteresisForMinNodesEnableEpoch, - delegationEnableEpoch: args.EpochConfig.EnableEpochs.DelegationSmartContractEnableEpoch, - stakingV2EnableEpoch: args.EpochConfig.EnableEpochs.StakingV2EnableEpoch, - esdtEnableEpoch: args.EpochConfig.EnableEpochs.ESDTEnableEpoch, stakingDataProvider: args.StakingDataProvider, nodesConfigProvider: args.NodesConfigProvider, shardCoordinator: args.ShardCoordinator, - correctLastUnJailEpoch: args.EpochConfig.EnableEpochs.CorrectLastUnjailedEnableEpoch, esdtOwnerAddressBytes: args.ESDTOwnerAddressBytes, - saveJailedAlwaysEnableEpoch: args.EpochConfig.EnableEpochs.SaveJailedAlwaysEnableEpoch, - stakingV4InitEnableEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, maxNodesChangeConfigProvider: args.MaxNodesChangeConfigProvider, enableEpochsHandler: args.EnableEpochsHandler, } - log.Debug("legacySystemSC: enable epoch for switch jail waiting", "epoch", legacy.switchEnableEpoch) - log.Debug("legacySystemSC: enable epoch for switch hysteresis for min nodes", "epoch", legacy.hystNodesEnableEpoch) - log.Debug("legacySystemSC: enable epoch for delegation manager", "epoch", legacy.delegationEnableEpoch) - log.Debug("legacySystemSC: enable epoch for staking v2", "epoch", legacy.stakingV2EnableEpoch) - log.Debug("legacySystemSC: enable epoch for ESDT", "epoch", legacy.esdtEnableEpoch) - log.Debug("legacySystemSC: enable epoch for correct last unjailed", "epoch", legacy.correctLastUnJailEpoch) - log.Debug("legacySystemSC: enable epoch for save jailed always", "epoch", legacy.saveJailedAlwaysEnableEpoch) - log.Debug("legacySystemSC: enable epoch for initializing staking v4", "epoch", legacy.stakingV4InitEnableEpoch) - return legacy, nil } @@ -174,14 +137,14 @@ func (s *legacySystemSCProcessor) processLegacy( nonce uint64, epoch uint32, ) error { - if s.flagHystNodesEnabled.IsSet() { + if s.enableEpochsHandler.IsSwitchHysteresisForMinNodesFlagEnabledForCurrentEpoch() { err := s.updateSystemSCConfigMinNodes() if err != nil { return err } } - if s.flagSetOwnerEnabled.IsSet() { + if s.enableEpochsHandler.IsStakingV2OwnerFlagEnabled() { err := s.updateOwnersForBlsKeys() if err != nil { return err @@ -195,28 +158,28 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.flagCorrectLastUnjailedEnabled.IsSet() { + if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabledForCurrentEpoch() { err := s.resetLastUnJailed() if err != nil { return err } } - if s.flagDelegationEnabled.IsSet() { + if s.enableEpochsHandler.IsDelegationSmartContractFlagEnabledForCurrentEpoch() { err := s.initDelegationSystemSC() if err != nil { return err } } - if s.flagCorrectNumNodesToStake.IsSet() { + if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Enabled() { err := s.cleanAdditionalQueue() if err != nil { return err } } - if s.flagSwitchJailedWaiting.IsSet() { + if s.enableEpochsHandler.IsSwitchJailWaitingFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Enabled() { err := s.computeNumWaitingPerShard(validatorsInfoMap) if err != nil { return err @@ -228,7 +191,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.flagStakingV2Enabled.IsSet() { + if s.enableEpochsHandler.IsStakingV2FlagEnabled() && !s.enableEpochsHandler.IsStakingV4Enabled() { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err @@ -244,7 +207,7 @@ func (s *legacySystemSCProcessor) processLegacy( return err } - if s.flagStakingQueueEnabled.IsSet() { + if s.enableEpochsHandler.IsStakingQueueEnabled() { err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) if err != nil { return err @@ -252,7 +215,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.flagESDTEnabled.IsSet() { + if s.enableEpochsHandler.IsESDTFlagEnabledForCurrentEpoch() { err := s.initESDT() if err != nil { // not a critical error @@ -265,7 +228,7 @@ func (s *legacySystemSCProcessor) processLegacy( // ToggleUnStakeUnBond will pause/unPause the unStake/unBond functions on the validator system sc func (s *legacySystemSCProcessor) ToggleUnStakeUnBond(value bool) error { - if !s.flagStakingV2Enabled.IsSet() { + if !s.enableEpochsHandler.IsStakingV2FlagEnabled() { return nil } @@ -623,7 +586,7 @@ func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap state.ShardVa return err } - if s.flagStakingQueueEnabled.IsSet() { + if s.enableEpochsHandler.IsStakingQueueEnabled() { sw.Start("stakeNodesFromQueue") err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) sw.Stop("stakeNodesFromQueue") @@ -722,7 +685,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } if activeStorageUpdate == nil { log.Debug("no one in waiting suitable for switch") - if s.flagSaveJailedAlwaysEnabled.IsSet() { + if s.enableEpochsHandler.IsSaveJailedAlwaysFlagEnabled() { err := s.processSCOutputAccounts(vmOutput) if err != nil { return nil, err @@ -1361,12 +1324,6 @@ func getRewardsMiniBlockForMeta(miniBlocks block.MiniBlockSlice) *block.MiniBloc } func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { - s.flagSwitchJailedWaiting.SetValue(epoch >= s.switchEnableEpoch && epoch <= s.stakingV4InitEnableEpoch) - log.Debug("legacySystemSC: switch jail with waiting", "enabled", s.flagSwitchJailedWaiting.IsSet()) - - // only toggle on exact epoch. In future epochs the config should have already been synchronized from peers - s.flagHystNodesEnabled.SetValue(epoch == s.hystNodesEnableEpoch) - s.flagChangeMaxNodesEnabled.SetValue(false) for _, maxNodesConfig := range s.maxNodesChangeConfigProvider.GetAllNodesConfig() { if epoch == maxNodesConfig.EpochEnable { @@ -1376,34 +1333,9 @@ func (s *legacySystemSCProcessor) legacyEpochConfirmed(epoch uint32) { } s.maxNodes = s.maxNodesChangeConfigProvider.GetCurrentNodesConfig().MaxNumNodes - log.Debug("legacySystemSC: consider also (minimum) hysteresis nodes for minimum number of nodes", - "enabled", epoch >= s.hystNodesEnableEpoch) - - // only toggle on exact epoch as init should be called only once - s.flagDelegationEnabled.SetValue(epoch == s.delegationEnableEpoch) - log.Debug("systemSCProcessor: delegation", "enabled", epoch >= s.delegationEnableEpoch) - - s.flagSetOwnerEnabled.SetValue(epoch == s.stakingV2EnableEpoch) - s.flagStakingV2Enabled.SetValue(epoch >= s.stakingV2EnableEpoch && epoch <= s.stakingV4InitEnableEpoch) - log.Debug("legacySystemSC: stakingV2", "enabled", s.flagStakingV2Enabled.IsSet()) log.Debug("legacySystemSC: change of maximum number of nodes and/or shuffling percentage", "enabled", s.flagChangeMaxNodesEnabled.IsSet(), "epoch", epoch, "maxNodes", s.maxNodes, ) - - s.flagCorrectLastUnjailedEnabled.SetValue(epoch == s.correctLastUnJailEpoch) - log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectLastUnjailedEnabled.IsSet()) - - s.flagCorrectNumNodesToStake.SetValue(epoch >= s.correctLastUnJailEpoch && epoch <= s.stakingV4InitEnableEpoch) - log.Debug("legacySystemSC: correct last unjailed", "enabled", s.flagCorrectNumNodesToStake.IsSet()) - - s.flagESDTEnabled.SetValue(epoch == s.esdtEnableEpoch) - log.Debug("legacySystemSC: ESDT initialization", "enabled", s.flagESDTEnabled.IsSet()) - - s.flagSaveJailedAlwaysEnabled.SetValue(epoch >= s.saveJailedAlwaysEnableEpoch) - log.Debug("legacySystemSC: save jailed always", "enabled", s.flagSaveJailedAlwaysEnabled.IsSet()) - - s.flagStakingQueueEnabled.SetValue(epoch < s.stakingV4InitEnableEpoch) - log.Debug("legacySystemSC: staking queue on meta", "enabled", s.flagStakingQueueEnabled.IsSet()) } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 8ffd77ba6aa..27409981fd9 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -5,23 +5,16 @@ import ( "math" "math/big" - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" - "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - vInfo "github.com/multiversx/mx-chain-go/common/validatorInfo" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" - "github.com/multiversx/mx-chain-go/trie/keyBuilder" "github.com/multiversx/mx-chain-go/vm" - "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) @@ -57,11 +50,6 @@ type systemSCProcessor struct { builtInOnMetaEnableEpoch uint32 stakingV4EnableEpoch uint32 - flagGovernanceEnabled atomic.Flag - flagBuiltInOnMetaEnabled atomic.Flag - flagInitStakingV4Enabled atomic.Flag - flagStakingV4Enabled atomic.Flag - enableEpochsHandler common.EnableEpochsHandler } @@ -83,12 +71,9 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr } s := &systemSCProcessor{ - legacySystemSCProcessor: legacy, - governanceEnableEpoch: args.EpochConfig.EnableEpochs.GovernanceEnableEpoch, - builtInOnMetaEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, - stakingV4EnableEpoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, - auctionListSelector: args.AuctionListSelector, - enableEpochsHandler: args.EnableEpochsHandler, + legacySystemSCProcessor: legacy, + auctionListSelector: args.AuctionListSelector, + enableEpochsHandler: args.EnableEpochsHandler, } args.EpochNotifier.RegisterNotifyHandler(s) @@ -111,14 +96,14 @@ func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - if s.flagGovernanceEnabled.IsSet() { + if s.enableEpochsHandler.IsGovernanceFlagEnabledForCurrentEpoch() { err := s.updateToGovernanceV2() if err != nil { return err } } - if s.flagBuiltInOnMetaEnabled.IsSet() { + if s.enableEpochsHandler.IsInitLiquidStakingEnabled() { tokenID, err := s.initTokenOnMeta() if err != nil { return err @@ -130,14 +115,14 @@ func (s *systemSCProcessor) processWithNewFlags( } } - if s.flagInitStakingV4Enabled.IsSet() { + if s.enableEpochsHandler.IsStakingV4InitEnabled() { err := s.stakeNodesFromQueue(validatorsInfoMap, math.MaxUint32, header.GetNonce(), common.AuctionList) if err != nil { return err } } - if s.flagStakingV4Enabled.IsSet() { + if s.enableEpochsHandler.IsStakingV4Enabled() { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err @@ -299,16 +284,4 @@ func (s *systemSCProcessor) IsInterfaceNil() bool { // EpochConfirmed is called whenever a new epoch is confirmed func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.legacyEpochConfirmed(epoch) - - s.flagGovernanceEnabled.SetValue(epoch == s.governanceEnableEpoch) - log.Debug("systemProcessor: governanceV2", "enabled", s.flagGovernanceEnabled.IsSet()) - - s.flagBuiltInOnMetaEnabled.SetValue(epoch == s.builtInOnMetaEnableEpoch) - log.Debug("systemProcessor: create NFT on meta", "enabled", s.flagBuiltInOnMetaEnabled.IsSet()) - - s.flagInitStakingV4Enabled.SetValue(epoch == s.stakingV4InitEnableEpoch) - log.Debug("systemProcessor: init staking v4", "enabled", s.flagInitStakingV4Enabled.IsSet()) - - s.flagStakingV4Enabled.SetValue(epoch >= s.stakingV4EnableEpoch) - log.Debug("systemProcessor: staking v4", "enabled", s.flagStakingV4Enabled.IsSet()) } diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 4780cb22c96..68a2be4198a 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -571,8 +571,18 @@ func (mock *EnableEpochsHandlerMock) IsStakingV4Enabled() bool { return false } -// IsStakingV4DistributeAuctionToWaitingFlagEnabled - -func (mock *EnableEpochsHandlerMock) IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool { +// IsStakingV4DistributeAuctionToWaitingEnabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4DistributeAuctionToWaitingEnabled() bool { + return false +} + +// IsInitLiquidStakingEnabled - +func (mock *EnableEpochsHandlerMock) IsInitLiquidStakingEnabled() bool { + return false +} + +// IsStakingQueueEnabled - +func (mock *EnableEpochsHandlerMock) IsStakingQueueEnabled() bool { return false } diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index adbf7141990..7def0dab368 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -120,7 +120,9 @@ type EnableEpochsHandlerStub struct { IsStakeLimitsFlagEnabledField bool IsStakingV4InitFlagEnabledField bool IsStakingV4FlagEnabledField bool - IsStakingV4DistributeAuctionToWaitingFlagEnabledField bool + IsStakingV4DistributeAuctionToWaitingEnabledField bool + IsInitLiquidStakingEnabledField bool + IsStakingQueueEnabledField bool } // ResetPenalizedTooMuchGasFlag - @@ -1026,12 +1028,28 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Enabled() bool { return stub.IsStakingV4FlagEnabledField } -// IsStakingV4DistributeAuctionToWaitingFlagEnabled - -func (stub *EnableEpochsHandlerStub) IsStakingV4DistributeAuctionToWaitingFlagEnabled() bool { +// IsStakingV4DistributeAuctionToWaitingEnabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4DistributeAuctionToWaitingEnabled() bool { stub.RLock() defer stub.RUnlock() - return stub.IsStakingV4DistributeAuctionToWaitingFlagEnabledField + return stub.IsStakingV4DistributeAuctionToWaitingEnabledField +} + +// IsInitLiquidStakingEnabled - +func (stub *EnableEpochsHandlerStub) IsInitLiquidStakingEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsInitLiquidStakingEnabledField +} + +// IsStakingQueueEnabled - +func (stub *EnableEpochsHandlerStub) IsStakingQueueEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingQueueEnabledField } // IsInterfaceNil - From 530f4fc30d7393cb9fcad48e3f18b877c70bd76a Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 13 Jan 2023 16:26:47 +0200 Subject: [PATCH 361/958] FIX: Make systemSCs_test.go build --- epochStart/metachain/systemSCs_test.go | 73 ++++++++------------------ 1 file changed, 23 insertions(+), 50 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 6dda522495e..5ef3ec93e54 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -26,9 +26,8 @@ import ( "github.com/multiversx/mx-chain-go/dataRetriever/dataPool" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/mock" + "github.com/multiversx/mx-chain-go/epochStart/notifier" "github.com/multiversx/mx-chain-go/genesis/process/disabled" - "github.com/multiversx/mx-chain-go/process" - economicsHandler "github.com/multiversx/mx-chain-go/process/economics" vmFactory "github.com/multiversx/mx-chain-go/process/factory" metaProcess "github.com/multiversx/mx-chain-go/process/factory/metachain" "github.com/multiversx/mx-chain-go/process/peer" @@ -43,8 +42,8 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" - "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" stateMock "github.com/multiversx/mx-chain-go/testscommon/storage" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" @@ -743,6 +742,9 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp userAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewAccountCreator(), trieFactoryManager) peerAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewPeerAccountCreator(), trieFactoryManager) en := forking.NewGenericEpochNotifier() + enableEpochsConfig.StakeLimitsEnableEpoch = 10 + enableEpochsConfig.StakingV4InitEnableEpoch = 444 + enableEpochsConfig.StakingV4EnableEpoch = 445 epochsConfig := &config.EpochConfig{ EnableEpochs: enableEpochsConfig, } @@ -766,28 +768,13 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) - gasSchedule := arwenConfig.MakeGasMapForTests() - gasScheduleNotifier := mock.NewGasScheduleNotifierMock(gasSchedule) - argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: gasScheduleNotifier, - MapDNSAddresses: make(map[string]struct{}), - Marshalizer: marshalizer, - Accounts: userAccountsDB, - ShardCoordinator: &mock.ShardCoordinatorStub{SelfIdCalled: func() uint32 { - return core.MetachainShardId - }}, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - } - builtInFuncs, _, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) - + gasSchedule := wasmConfig.MakeGasMapForTests() + gasScheduleNotifier := testscommon.NewGasScheduleNotifierMock(gasSchedule) testDataPool := dataRetrieverMock.NewPoolsHolderMock() - gasSchedule := wasmConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) - gasScheduleNotifier := testscommon.NewGasScheduleNotifierMock(gasSchedule) - nodesSetup := &mock.NodesSetupStub{} argsHook := hooks.ArgBlockChainHook{ @@ -799,7 +786,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp Marshalizer: marshalizer, Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, - BuiltInFunctions: builtInFuncs, + BuiltInFunctions: vmcommonBuiltInFunctions.NewBuiltInFunctionContainer(), DataPool: testDataPool, GlobalSettingsHandler: &testscommon.ESDTGlobalSettingsHandlerStub{}, CompiledSCPool: testDataPool.SmartContracts(), @@ -811,9 +798,6 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp } defaults.FillGasMapInternal(gasSchedule, 1) - signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) - - nodesSetup := &mock.NodesSetupStub{} blockChainHookImpl, _ := hooks.NewBlockChainHookImpl(argsHook) argsNewVMContainerFactory := metaProcess.ArgsNewVMContainerFactory{ @@ -869,10 +853,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp ChanceComputer: &mock.ChanceComputerStub{}, ShardCoordinator: &mock.ShardCoordinatorStub{}, EnableEpochsHandler: enableEpochsHandler, - StakeLimitsEnableEpoch: 10, - StakingV4InitEnableEpoch: 444, - StakingV4EnableEpoch: 445, - NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) @@ -923,18 +904,10 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp return 63 }, }, - ShardCoordinator: shardCoordinator, - ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), - EpochConfig: config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: 1000000, - ESDTEnableEpoch: 1000000, - StakingV4InitEnableEpoch: 444, - StakingV4EnableEpoch: 445, - }, - }, + ShardCoordinator: shardCoordinator, + ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), MaxNodesChangeConfigProvider: nodesConfigProvider, - EnableEpochsHandler: enableEpochsHandler, + EnableEpochsHandler: enableEpochsHandler, } return args, metaVmFactory.SystemSmartContractContainer() } @@ -947,7 +920,6 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin }, createMemUnit()) s, _ := NewSystemSCProcessor(args) - _ = s.flagDelegationEnabled.SetReturningPrevious() validatorsInfo := state.NewShardValidatorsInfoMap() err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) @@ -1133,11 +1105,12 @@ func getTotalNumberOfRegisteredNodes(t *testing.T, s *systemSCProcessor) int { func TestSystemSCProcessor_ProcessSystemSmartContractMaxNodesStakedFromQueueOwnerNotSet(t *testing.T) { t.Parallel() + maxNodesChangeConfig := []config.MaxNodesChangeConfig{{EpochEnable: 10, MaxNumNodes: 10}} args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - StakingV2EnableEpoch: 10, + MaxNodesChangeEnableEpoch: maxNodesChangeConfig, + StakingV2EnableEpoch: 10, }, createMemUnit()) - args.MaxNodesEnableConfig = []config.MaxNodesChangeConfig{{EpochEnable: 10, MaxNumNodes: 10}} - args.MaxNodesChangeConfigProvider = nodesConfigProvider + args.MaxNodesChangeConfigProvider, _ = notifier.NewNodesConfigProvider(args.EpochNotifier, maxNodesChangeConfig) s, _ := NewSystemSCProcessor(args) prepareStakingContractWithData( @@ -1762,7 +1735,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) s, _ := NewSystemSCProcessor(args) owner1 := []byte("owner1") @@ -1799,7 +1772,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) - s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) + s.EpochConfirmed(stakingV4EInitEnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) @@ -1827,7 +1800,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepareStakingData(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) errProcessStakingData := errors.New("error processing staking data") args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ @@ -1845,7 +1818,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) s, _ := NewSystemSCProcessor(args) - s.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + s.EpochConfirmed(stakingV4EnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Equal(t, errProcessStakingData, err) @@ -1854,7 +1827,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 8}}) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: args.ShardCoordinator, @@ -1920,7 +1893,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[1], common.EligibleList, owner7, 2)) s, _ := NewSystemSCProcessor(args) - args.EpochNotifier.CheckEpoch(&block.Header{Epoch: args.EpochConfig.EnableEpochs.StakingV4EnableEpoch}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4EnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("pubKey7")}) require.Nil(t, err) @@ -2017,7 +1990,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) nodesConfigEpoch0 := config.MaxNodesChangeConfig{ EpochEnable: 0, MaxNumNodes: 36, From 05a06fba24690e6203f70b4e3defef75dd4dccd3 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 13 Jan 2023 17:07:40 +0200 Subject: [PATCH 362/958] FIX: staking, delegation, validator + new flags --- common/enablers/enableEpochsHandler.go | 2 + common/enablers/enableEpochsHandler_test.go | 6 +++ common/enablers/epochFlags.go | 14 ++++++ common/interface.go | 2 + .../metachain/stakingDataProvider_test.go | 2 +- sharding/mock/enableEpochsHandlerMock.go | 10 ++++ testscommon/enableEpochsHandlerStub.go | 18 ++++++++ vm/systemSmartContracts/delegation.go | 7 +-- vm/systemSmartContracts/delegation_test.go | 44 ++++-------------- vm/systemSmartContracts/esdt.go | 46 +++++++++---------- vm/systemSmartContracts/staking.go | 40 ++-------------- vm/systemSmartContracts/stakingWaitingList.go | 42 ++++++++--------- vm/systemSmartContracts/validator.go | 8 +--- 13 files changed, 111 insertions(+), 130 deletions(-) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 7de705d8920..163d9aa5709 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -122,6 +122,8 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") handler.setFlagValue(epoch == handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, handler.initLiquidStakingFlag, "initLiquidStakingFlag") handler.setFlagValue(epoch < handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingQueueEnabledFlag, "stakingQueueEnabledFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, handler.liquidStakingFlag, "liquidStakingFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4StartedFlag, "stakingV4StartedFlag") } func (handler *enableEpochsHandler) setFlagValue(value bool, flag *atomic.Flag, flagName string) { diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 476e7b1bffa..861bf3fecd4 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -219,6 +219,8 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) assert.False(t, handler.IsStakingQueueEnabled()) assert.False(t, handler.IsInitLiquidStakingEnabled()) + assert.True(t, handler.IsLiquidStakingEnabled()) + assert.True(t, handler.IsStakingV4Started()) }) t.Run("flags with == condition should be set, along with all >=", func(t *testing.T) { t.Parallel() @@ -325,6 +327,8 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) assert.False(t, handler.IsStakingQueueEnabled()) assert.True(t, handler.IsInitLiquidStakingEnabled()) + assert.True(t, handler.IsLiquidStakingEnabled()) + assert.True(t, handler.IsStakingV4Started()) }) t.Run("flags with < should be set", func(t *testing.T) { t.Parallel() @@ -424,5 +428,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) assert.True(t, handler.IsStakingQueueEnabled()) assert.False(t, handler.IsInitLiquidStakingEnabled()) + assert.False(t, handler.IsLiquidStakingEnabled()) + assert.False(t, handler.IsStakingV4Started()) }) } diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index e1b23c67452..f2ffa4d3183 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -94,6 +94,8 @@ type epochFlagsHolder struct { stakingV4DistributeAuctionToWaitingFlag *atomic.Flag stakingQueueEnabledFlag *atomic.Flag initLiquidStakingFlag *atomic.Flag + liquidStakingFlag *atomic.Flag + stakingV4StartedFlag *atomic.Flag } func newEpochFlagsHolder() *epochFlagsHolder { @@ -187,6 +189,8 @@ func newEpochFlagsHolder() *epochFlagsHolder { stakingV4DistributeAuctionToWaitingFlag: &atomic.Flag{}, stakingQueueEnabledFlag: &atomic.Flag{}, initLiquidStakingFlag: &atomic.Flag{}, + liquidStakingFlag: &atomic.Flag{}, + stakingV4StartedFlag: &atomic.Flag{}, } } @@ -687,3 +691,13 @@ func (holder *epochFlagsHolder) IsInitLiquidStakingEnabled() bool { func (holder *epochFlagsHolder) IsStakingQueueEnabled() bool { return holder.stakingQueueEnabledFlag.IsSet() } + +// IsLiquidStakingEnabled returns true if liquidStakingFlag is enabled +func (holder *epochFlagsHolder) IsLiquidStakingEnabled() bool { + return holder.liquidStakingFlag.IsSet() +} + +// IsStakingV4Started returns true if liquidStakingFlag is enabled +func (holder *epochFlagsHolder) IsStakingV4Started() bool { + return holder.stakingV4StartedFlag.IsSet() +} diff --git a/common/interface.go b/common/interface.go index dba8fc55bb8..26a0402b356 100644 --- a/common/interface.go +++ b/common/interface.go @@ -341,6 +341,8 @@ type EnableEpochsHandler interface { IsStakingV4DistributeAuctionToWaitingEnabled() bool IsInitLiquidStakingEnabled() bool IsStakingQueueEnabled() bool + IsLiquidStakingEnabled() bool + IsStakingV4Started() bool IsInterfaceNil() bool } diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 433d5a45645..1e97848e061 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -25,7 +25,7 @@ import ( ) const stakingV4EInitEnableEpoch = 444 -const stakingV4EnableEpoch = 444 +const stakingV4EnableEpoch = 445 func createStakingDataProviderArgs() StakingDataProviderArgs { return StakingDataProviderArgs{ diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 68a2be4198a..0309a1822dd 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -586,6 +586,16 @@ func (mock *EnableEpochsHandlerMock) IsStakingQueueEnabled() bool { return false } +// IsLiquidStakingEnabled - +func (mock *EnableEpochsHandlerMock) IsLiquidStakingEnabled() bool { + return false +} + +// IsStakingV4Started - +func (mock *EnableEpochsHandlerMock) IsStakingV4Started() bool { + return false +} + // IsInterfaceNil returns true if there is no value under the interface func (mock *EnableEpochsHandlerMock) IsInterfaceNil() bool { return mock == nil diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 7def0dab368..4c60e1f8558 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -123,6 +123,8 @@ type EnableEpochsHandlerStub struct { IsStakingV4DistributeAuctionToWaitingEnabledField bool IsInitLiquidStakingEnabledField bool IsStakingQueueEnabledField bool + IsLiquidStakingEnabledField bool + IsStakingV4StartedField bool } // ResetPenalizedTooMuchGasFlag - @@ -1052,6 +1054,22 @@ func (stub *EnableEpochsHandlerStub) IsStakingQueueEnabled() bool { return stub.IsStakingQueueEnabledField } +// IsLiquidStakingEnabled - +func (stub *EnableEpochsHandlerStub) IsLiquidStakingEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsLiquidStakingEnabledField +} + +// IsStakingV4Started - +func (stub *EnableEpochsHandlerStub) IsStakingV4Started() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingV4StartedField +} + // IsInterfaceNil - func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { return stub == nil diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 08b83b0dbb9..8fa3d40e586 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -60,8 +60,6 @@ type delegation struct { minStakeValue *big.Int enableEpochsHandler common.EnableEpochsHandler mutExecution sync.RWMutex - liquidStakingEnableEpoch uint32 - flagLiquidStaking atomic.Flag } // ArgsNewDelegation defines the arguments to create the delegation smart contract @@ -132,7 +130,6 @@ func NewDelegationSystemSC(args ArgsNewDelegation) (*delegation, error) { governanceSCAddr: args.GovernanceSCAddress, addTokensAddr: args.AddTokensAddress, enableEpochsHandler: args.EnableEpochsHandler, - liquidStakingEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, } var okValue bool @@ -1911,7 +1908,7 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De delegator.RewardsCheckpoint = currentEpoch + 1 } // nothing to calculate as no active funds - all were computed before - if d.flagLiquidStaking.IsSet() { + if d.enableEpochsHandler.IsLiquidStakingEnabled() { delegator.RewardsCheckpoint = currentEpoch + 1 } return nil @@ -2858,7 +2855,7 @@ func (d *delegation) addTokens(args *vmcommon.ContractCallInput) vmcommon.Return } func (d *delegation) basicCheckForLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.flagLiquidStaking.IsSet() { + if !d.enableEpochsHandler.IsLiquidStakingEnabled() { d.eei.AddReturnMessage(args.Function + " is an unknown function") return vmcommon.UserError } diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index cd8c992b8f7..2790f63c9d0 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -155,6 +155,14 @@ func createDelegationContractAndEEI() (*delegation, *vmContext) { args.DelegationSCConfig.MaxServiceFee = 10000 args.DelegationSCConfig.MinServiceFee = 0 d, _ := NewDelegationSystemSC(args) + + managementData := &DelegationManagement{ + MinDeposit: big.NewInt(10), + MinDelegationAmount: big.NewInt(10), + } + marshaledData, _ := d.marshalizer.Marshal(managementData) + eei.SetStorageForAddress(d.delegationMgrSCAddress, []byte(delegationManagementKey), marshaledData) + return d, eei } @@ -4901,42 +4909,6 @@ func TestDelegationSystemSC_ExecuteChangeOwner(t *testing.T) { assert.Equal(t, boolToSlice(true), eei.logs[1].Topics[4]) } -func createDelegationContractAndEEI() (*delegation, *vmContext) { - args := createMockArgumentsForDelegation() - eei, _ := NewVMContext( - &mock.BlockChainHookStub{ - CurrentEpochCalled: func() uint32 { - return 2 - }, - }, - hooks.NewVMCryptoHook(), - &mock.ArgumentParserMock{}, - &stateMock.AccountsStub{}, - &mock.RaterMock{}, - ) - systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - - _ = eei.SetSystemSCContainer(systemSCContainerStub) - - args.Eei = eei - args.DelegationSCConfig.MaxServiceFee = 10000 - args.DelegationSCConfig.MinServiceFee = 0 - d, _ := NewDelegationSystemSC(args) - - managementData := &DelegationManagement{ - MinDeposit: big.NewInt(10), - MinDelegationAmount: big.NewInt(10), - } - marshaledData, _ := d.marshalizer.Marshal(managementData) - eei.SetStorageForAddress(d.delegationMgrSCAddress, []byte(delegationManagementKey), marshaledData) - - return d, eei -} - func TestDelegation_FailsIfESDTTransfers(t *testing.T) { d, eei := createDelegationContractAndEEI() diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index d23e3439bc9..366d6dcba72 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -10,7 +10,6 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" @@ -47,20 +46,18 @@ const conversionBase = 10 const metaESDT = "MetaESDT" type esdt struct { - eei vm.SystemEI - gasCost vm.GasCost - baseIssuingCost *big.Int - ownerAddress []byte // do not use this in functions. Should use e.getEsdtOwner() - esdtSCAddress []byte - endOfEpochSCAddress []byte - marshalizer marshal.Marshalizer - hasher hashing.Hasher - mutExecution sync.RWMutex - addressPubKeyConverter core.PubkeyConverter - enableEpochsHandler common.EnableEpochsHandler - esdtOnMetachainEnableEpoch uint32 - flagESDTOnMeta atomic.Flag - delegationTicker string + eei vm.SystemEI + gasCost vm.GasCost + baseIssuingCost *big.Int + ownerAddress []byte // do not use this in functions. Should use e.getEsdtOwner() + esdtSCAddress []byte + endOfEpochSCAddress []byte + marshalizer marshal.Marshalizer + hasher hashing.Hasher + mutExecution sync.RWMutex + addressPubKeyConverter core.PubkeyConverter + enableEpochsHandler common.EnableEpochsHandler + delegationTicker string } // ArgsNewESDTSmartContract defines the arguments needed for the esdt contract @@ -110,15 +107,14 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { baseIssuingCost: baseIssuingCost, // we should have called pubkeyConverter.Decode here instead of a byte slice cast. Since that change would break // backwards compatibility, the fix was carried in the epochStart/metachain/systemSCs.go - ownerAddress: []byte(args.ESDTSCConfig.OwnerAddress), - esdtSCAddress: args.ESDTSCAddress, - hasher: args.Hasher, - marshalizer: args.Marshalizer, - endOfEpochSCAddress: args.EndOfEpochSCAddress, - addressPubKeyConverter: args.AddressPubKeyConverter, - enableEpochsHandler: args.EnableEpochsHandler, - esdtOnMetachainEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, - delegationTicker: args.ESDTSCConfig.DelegationTicker, + ownerAddress: []byte(args.ESDTSCConfig.OwnerAddress), + esdtSCAddress: args.ESDTSCAddress, + hasher: args.Hasher, + marshalizer: args.Marshalizer, + endOfEpochSCAddress: args.EndOfEpochSCAddress, + addressPubKeyConverter: args.AddressPubKeyConverter, + enableEpochsHandler: args.EnableEpochsHandler, + delegationTicker: args.ESDTSCConfig.DelegationTicker, }, nil } @@ -229,7 +225,7 @@ func (e *esdt) init(_ *vmcommon.ContractCallInput) vmcommon.ReturnCode { } func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !e.flagESDTOnMeta.IsSet() { + if !e.enableEpochsHandler.IsBuiltInFunctionOnMetaFlagEnabled() { e.eei.AddReturnMessage("invalid method to call") return vmcommon.FunctionNotFound } diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index 19fe188d382..37db4f4bc6a 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -43,10 +43,6 @@ type stakingSC struct { mutExecution sync.RWMutex minNodePrice *big.Int enableEpochsHandler common.EnableEpochsHandler - - flagStakingV4 atomic.Flag - flagStakingV4Init atomic.Flag - stakingV4InitEpoch uint32 } // ArgsNewStakingSmartContract holds the arguments needed to create a StakingSmartContract @@ -115,7 +111,6 @@ func NewStakingSmartContract( walletAddressLen: len(args.StakingAccessAddr), minNodePrice: minStakeValue, enableEpochsHandler: args.EnableEpochsHandler, - stakingV4InitEpoch: args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, } var conversionOk bool @@ -228,7 +223,7 @@ func (s *stakingSC) numSpareNodes() int64 { } func (s *stakingSC) canStake() bool { - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { return true } @@ -557,7 +552,7 @@ func (s *stakingSC) activeStakingFor(stakingData *StakedDataV2_0) { } func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { return s.processStakeV2(registrationData) } @@ -577,7 +572,7 @@ func (s *stakingSC) processStakeV2(registrationData *StakedDataV2_0) error { } func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { return s.unStakeV2(args) } @@ -901,7 +896,7 @@ func (s *stakingSC) getBLSKeyStatus(args *vmcommon.ContractCallInput) vmcommon.R } func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { + if !s.enableEpochsHandler.IsStakingV2FlagEnabled() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } @@ -1142,33 +1137,6 @@ func (s *stakingSC) checkValidatorFunds( return validatorInfo, nil } -// EpochConfirmed is called whenever a new epoch is confirmed -func (s *stakingSC) EpochConfirmed(epoch uint32, _ uint64) { - s.flagEnableStaking.SetValue(epoch >= s.enableStakingEpoch) - log.Debug("stakingSC: stake/unstake/unbond", "enabled", s.flagEnableStaking.IsSet()) - - s.flagStakingV2.SetValue(epoch >= s.stakingV2Epoch) - log.Debug("stakingSC: set owner", "enabled", s.flagStakingV2.IsSet()) - - s.flagCorrectLastUnjailed.SetValue(epoch >= s.correctLastUnjailedEpoch) - log.Debug("stakingSC: correct last unjailed", "enabled", s.flagCorrectLastUnjailed.IsSet()) - - s.flagValidatorToDelegation.SetValue(epoch >= s.validatorToDelegationEnableEpoch) - log.Debug("stakingSC: validator to delegation", "enabled", s.flagValidatorToDelegation.IsSet()) - - s.flagCorrectFirstQueued.SetValue(epoch >= s.correctFirstQueuedEpoch) - log.Debug("stakingSC: correct first queued", "enabled", s.flagCorrectFirstQueued.IsSet()) - - s.flagCorrectJailedNotUnstakedEmptyQueue.SetValue(epoch >= s.correctJailedNotUnstakedEmptyQueueEpoch) - log.Debug("stakingSC: correct jailed not unstaked with empty queue", "enabled", s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet()) - - s.flagStakingV4Init.SetValue(epoch == s.stakingV4InitEpoch) - log.Debug("stakingSC: staking v4 init", "enabled", s.flagStakingV4Init.IsSet()) - - s.flagStakingV4.SetValue(epoch >= s.stakingV4InitEpoch) - log.Debug("stakingSC: staking v4", "enabled", s.flagStakingV4.IsSet()) -} - // CanUseContract returns true if contract can be used func (s *stakingSC) CanUseContract() bool { return true diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index ecc4eb8e24e..b3d3d5f9c3f 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -76,7 +76,7 @@ func (s *stakingSC) unStakeV1(args *vmcommon.ContractCallInput) vmcommon.ReturnC return vmcommon.Ok } - addOneFromQueue := !s.flagCorrectLastUnjailed.IsSet() || s.canStakeIfOneRemoved() + addOneFromQueue := !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() || s.canStakeIfOneRemoved() if addOneFromQueue { _, err = s.moveFirstFromWaitingToStaked() if err != nil { @@ -220,7 +220,7 @@ func (s *stakingSC) insertAfterLastJailed( NextKey: previousFirstKey, } - if s.flagCorrectFirstQueued.IsSet() && len(previousFirstKey) > 0 { + if s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && len(previousFirstKey) > 0 { previousFirstElement, err := s.getWaitingListElement(previousFirstKey) if err != nil { return err @@ -314,8 +314,8 @@ func (s *stakingSC) removeFromWaitingList(blsKey []byte) error { } // remove the first element - isFirstElementBeforeFix := !s.flagCorrectFirstQueued.IsSet() && bytes.Equal(elementToRemove.PreviousKey, inWaitingListKey) - isFirstElementAfterFix := s.flagCorrectFirstQueued.IsSet() && bytes.Equal(waitingList.FirstKey, inWaitingListKey) + isFirstElementBeforeFix := !s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && bytes.Equal(elementToRemove.PreviousKey, inWaitingListKey) + isFirstElementAfterFix := s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && bytes.Equal(waitingList.FirstKey, inWaitingListKey) if isFirstElementBeforeFix || isFirstElementAfterFix { if bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { waitingList.LastJailedKey = make([]byte, 0) @@ -331,14 +331,14 @@ func (s *stakingSC) removeFromWaitingList(blsKey []byte) error { return s.saveElementAndList(elementToRemove.NextKey, nextElement, waitingList) } - if !s.flagCorrectLastUnjailed.IsSet() || bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { + if !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() || bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { waitingList.LastJailedKey = make([]byte, len(elementToRemove.PreviousKey)) copy(waitingList.LastJailedKey, elementToRemove.PreviousKey) } previousElement, _ := s.getWaitingListElement(elementToRemove.PreviousKey) // search the other way around for the element in front - if s.flagCorrectFirstQueued.IsSet() && previousElement == nil { + if s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && previousElement == nil { previousElement, err = s.searchPreviousFromHead(waitingList, inWaitingListKey, elementToRemove) if err != nil { return err @@ -458,7 +458,7 @@ func createWaitingListKey(blsKey []byte) []byte { } func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -498,7 +498,7 @@ func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vm registrationData.Jailed = true registrationData.JailedNonce = s.eei.BlockChainHook().CurrentNonce() - if !switched && !s.flagCorrectJailedNotUnstakedEmptyQueue.IsSet() { + if !switched && !s.enableEpochsHandler.IsCorrectJailedNotUnStakedEmptyQueueFlagEnabled() { s.eei.AddReturnMessage("did not switch as nobody in waiting, but jailed") } else { s.tryRemoveJailedNodeFromStaked(registrationData) @@ -514,7 +514,7 @@ func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vm } func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -582,7 +582,7 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm } func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -638,11 +638,11 @@ func (s *stakingSC) getWaitingListRegisterNonceAndRewardAddress(args *vmcommon.C } func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectLastUnjailed.IsSet() { + if !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() { // backward compatibility return vmcommon.UserError } - if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -726,11 +726,11 @@ func (s *stakingSC) cleanAdditionalQueueNotEnoughFunds( } func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagStakingV2.IsSet() { + if !s.enableEpochsHandler.IsStakingV2FlagEnabled() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -755,7 +755,7 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm } nodePriceToUse := big.NewInt(0).Set(s.minNodePrice) - if s.flagCorrectLastUnjailed.IsSet() { + if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() { nodePriceToUse.Set(s.stakeValue) } @@ -802,11 +802,11 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm } func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectLastUnjailed.IsSet() { + if !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() && !s.flagStakingV4Init.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -898,11 +898,11 @@ func (s *stakingSC) getFirstElementsFromWaitingList(numNodes uint32) (*waitingLi } func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectFirstQueued.IsSet() { + if !s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -973,11 +973,11 @@ func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vm } func (s *stakingSC) addMissingNodeToQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.flagCorrectFirstQueued.IsSet() { + if !s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.flagStakingV4.IsSet() { + if s.enableEpochsHandler.IsStakingV4Started() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 170caaf2344..d6f267bf220 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -10,7 +10,6 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" @@ -53,8 +52,6 @@ type validatorSC struct { governanceSCAddress []byte shardCoordinator sharding.Coordinator enableEpochsHandler common.EnableEpochsHandler - stakeLimitsEnableEpoch uint32 - flagStakeLimits atomic.Flag nodesCoordinator vm.NodesCoordinator totalStakeLimit *big.Int nodeLimitPercentage float64 @@ -174,7 +171,6 @@ func NewValidatorSmartContract( governanceSCAddress: args.GovernanceSCAddress, shardCoordinator: args.ShardCoordinator, enableEpochsHandler: args.EnableEpochsHandler, - stakeLimitsEnableEpoch: args.EpochConfig.EnableEpochs.StakeLimitsEnableEpoch, nodeLimitPercentage: args.StakingSCConfig.NodeLimitPercentage, nodesCoordinator: args.NodesCoordinator, } @@ -915,7 +911,7 @@ func (v *validatorSC) checkAllGivenKeysAreUnStaked(registrationData *ValidatorDa } func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { - if !v.flagStakeLimits.IsSet() { + if !v.enableEpochsHandler.IsStakeLimitsEnabled() { return false } @@ -923,7 +919,7 @@ func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { } func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) bool { - if !v.flagStakeLimits.IsSet() { + if !v.enableEpochsHandler.IsStakeLimitsEnabled() { return false } From b0e02f1d414bea9d287e3b86f9fa3f7d55281d09 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 13 Jan 2023 17:14:24 +0200 Subject: [PATCH 363/958] FIX: Can build systemSCs_test.go --- epochStart/metachain/auctionListSelector_test.go | 7 +++++-- epochStart/metachain/validators.go | 4 ++-- vm/factory/systemSCFactory.go | 3 +-- vm/systemSmartContracts/liquidStaking.go | 3 +++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 5e5da2307e6..23ac04ee6db 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -14,6 +14,7 @@ import ( "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/testscommon" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) @@ -46,8 +47,10 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha epochNotifier := forking.NewGenericEpochNotifier() nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) - argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(0, createMemUnit()) - argsSystemSC.StakingDataProvider.EpochConfirmed(stakingV4EnableEpoch, 0) + argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + epochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ + EpochField: stakingV4EnableEpoch, + }) argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider return AuctionListSelectorArgs{ ShardCoordinator: argsSystemSC.ShardCoordinator, diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index 54e63b38d1d..b77a72f55a8 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -185,10 +185,10 @@ func createShardValidatorInfo(validator state.ValidatorInfoHandler) *state.Shard // VerifyValidatorInfoMiniBlocks verifies if received validator info mini blocks are correct func (vic *validatorInfoCreator) VerifyValidatorInfoMiniBlocks( - miniblocks []*block.MiniBlock, + miniBlocks []*block.MiniBlock, validatorsInfo state.ShardValidatorsInfoMapHandler, ) error { - if len(miniblocks) == 0 { + if len(miniBlocks) == 0 { return epochStart.ErrNilMiniblocks } diff --git a/vm/factory/systemSCFactory.go b/vm/factory/systemSCFactory.go index 02c0f99a346..3cc7e078c20 100644 --- a/vm/factory/systemSCFactory.go +++ b/vm/factory/systemSCFactory.go @@ -301,8 +301,7 @@ func (scf *systemSCFactory) createLiquidStakingContract() (vm.SystemSmartContrac GasCost: scf.gasCost, Marshalizer: scf.marshalizer, Hasher: scf.hasher, - EpochNotifier: scf.epochNotifier, - EpochConfig: *scf.epochConfig, + EnableEpochsHandler: scf.enableEpochsHandler, } liquidStaking, err := systemSmartContracts.NewLiquidStakingSystemSC(argsLiquidStaking) return liquidStaking, err diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index f665b141b0c..b9d70506543 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -13,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -31,6 +32,7 @@ type liquidStaking struct { mutExecution sync.RWMutex liquidStakingEnableEpoch uint32 flagLiquidStaking atomic.Flag + enableEpochsHandler common.EnableEpochsHandler } // ArgsNewLiquidStaking defines the arguments to create the liquid staking smart contract @@ -42,6 +44,7 @@ type ArgsNewLiquidStaking struct { Marshalizer marshal.Marshalizer Hasher hashing.Hasher EpochNotifier vm.EpochNotifier + EnableEpochsHandler common.EnableEpochsHandler } // TODO: resolve errors if multi transfer from metachain fails. should it return - restore position or should remain at destination From 1dd9c8553c7b435e10e91d30d4288a0742ea3452 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 11:47:21 +0200 Subject: [PATCH 364/958] FIX: Some tests in systemSCs_test.go --- epochStart/metachain/systemSCs_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 5ef3ec93e54..e0586dcd22e 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -745,6 +745,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp enableEpochsConfig.StakeLimitsEnableEpoch = 10 enableEpochsConfig.StakingV4InitEnableEpoch = 444 enableEpochsConfig.StakingV4EnableEpoch = 445 + enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch = 400 epochsConfig := &config.EpochConfig{ EnableEpochs: enableEpochsConfig, } @@ -1153,7 +1154,7 @@ func TestSystemSCProcessor_ESDTInitShouldWork(t *testing.T) { require.Equal(t, 4, len(initialContractConfig)) require.Equal(t, []byte("aaaaaa"), initialContractConfig[0]) - err = s.ProcessSystemSmartContract(nil, &block.Header{Nonce: 1, Epoch: 1}) + err = s.ProcessSystemSmartContract(state.NewShardValidatorsInfoMap(), &block.Header{Nonce: 1, Epoch: 1}) require.Nil(t, err) @@ -1772,7 +1773,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) - s.EpochConfirmed(stakingV4EInitEnableEpoch, 0) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4EInitEnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) @@ -1990,7 +1991,9 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + StakingV2EnableEpoch: 100, + }, createMemUnit()) nodesConfigEpoch0 := config.MaxNodesChangeConfig{ EpochEnable: 0, MaxNumNodes: 36, From ea216e8f5d1244b40a48a88bd102d2a75928a78d Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 13:21:20 +0200 Subject: [PATCH 365/958] FIX: Tests in systemSCs_test.go --- epochStart/metachain/systemSCs_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index e0586dcd22e..7e9fac8bbc8 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1991,9 +1991,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - StakingV2EnableEpoch: 100, - }, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) nodesConfigEpoch0 := config.MaxNodesChangeConfig{ EpochEnable: 0, MaxNumNodes: 36, @@ -2017,7 +2015,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar nodesConfigEpoch6, }) args.MaxNodesChangeConfigProvider = nodesConfigProvider - + args.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV2FlagEnabledField: true} validatorsInfoMap := state.NewShardValidatorsInfoMap() s, _ := NewSystemSCProcessor(args) From bde0726d9f1338fb24b63662d619662fc8df178b Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 13:45:19 +0200 Subject: [PATCH 366/958] FIX: Tests in staking_test.go --- vm/systemSmartContracts/staking_test.go | 61 +++++++++++++++++++------ 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 223616dba1d..701dbddea18 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -17,6 +17,7 @@ import ( "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/process/smartContract/hooks" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" @@ -60,9 +61,8 @@ func createMockStakingScArgumentsWithSystemScAddresses( IsCorrectFirstQueuedFlagEnabledField: true, IsCorrectJailedNotUnStakedEmptyQueueFlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, - StakingV4InitEnableEpoch : false, - StakingV4EnableEpoch: false, - + IsStakingV4FlagEnabledField: false, + IsStakingV4InitFlagEnabledField: false, }, } } @@ -98,6 +98,17 @@ func CreateVmContractCallInput() *vmcommon.ContractCallInput { } } +func createArgsVMContext() VMContextArgs { + return VMContextArgs{ + BlockChainHook: &mock.BlockChainHookStub{}, + CryptoHook: hooks.NewVMCryptoHook(), + InputParser: &mock.ArgumentParserMock{}, + ValidatorAccountsDB: &stateMock.AccountsStub{}, + ChanceComputer: &mock.RaterMock{}, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + } +} + func TestNewStakingSmartContract_NilSystemEIShouldErr(t *testing.T) { t.Parallel() @@ -993,15 +1004,20 @@ func TestStakingSc_ExecuteIsStaked(t *testing.T) { func TestStakingSc_StakeWithStakingV4(t *testing.T) { t.Parallel() + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsStakingV2FlagEnabledField: true} + args := createMockStakingScArguments() stakingAccessAddress := []byte("stakingAccessAddress") args.StakingAccessAddr = stakingAccessAddress args.StakingSCConfig.MaxNumberOfNodesForStake = 4 - eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) + args.EnableEpochsHandler = enableEpochsHandler + + argsVMContext := createArgsVMContext() + argsVMContext.EnableEpochsHandler = enableEpochsHandler + eei, _ := NewVMContext(argsVMContext) args.Eei = eei stakingSmartContract, _ := NewStakingSmartContract(args) - stakingSmartContract.flagStakingV2.SetValue(true) for i := 0; i < 10; i++ { idxStr := strconv.Itoa(i) @@ -1021,7 +1037,7 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("addr0"), []byte("addr0"), vmcommon.Ok) requireRegisteredNodes(t, stakingSmartContract, eei, 4, 5) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) + enableEpochsHandler.IsStakingV4StartedField = true for i := 5; i < 10; i++ { idxStr := strconv.Itoa(i) addr := []byte("addr" + idxStr) @@ -1044,23 +1060,27 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { func TestStakingSc_UnStakeNodeFromWaitingListAfterStakingV4ShouldError(t *testing.T) { t.Parallel() + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsStakingV2FlagEnabledField: true} + args := createMockStakingScArguments() stakingAccessAddress := []byte("stakingAccessAddress") args.StakingAccessAddr = stakingAccessAddress args.StakingSCConfig.MaxNumberOfNodesForStake = 2 - eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) + args.EnableEpochsHandler = enableEpochsHandler + + argsVMContext := createArgsVMContext() + argsVMContext.EnableEpochsHandler = enableEpochsHandler + eei, _ := NewVMContext(argsVMContext) args.Eei = eei stakingSmartContract, _ := NewStakingSmartContract(args) - stakingSmartContract.flagStakingV2.SetValue(true) doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address0"), []byte("address0")) doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address1"), []byte("address1")) doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2")) requireRegisteredNodes(t, stakingSmartContract, eei, 2, 1) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) - + enableEpochsHandler.IsStakingV4StartedField = true eei.returnMessage = "" doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2"), vmcommon.ExecutionFailed) require.Equal(t, eei.returnMessage, vm.ErrWaitingListDisabled.Error()) @@ -3379,12 +3399,25 @@ func TestStakingSc_fixMissingNodeAddOneNodeOnly(t *testing.T) { func TestStakingSC_StakingV4Flags(t *testing.T) { t.Parallel() + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ + IsStakeFlagEnabledField: true, + IsCorrectLastUnJailedFlagEnabledField: true, + IsCorrectFirstQueuedFlagEnabledField: true, + IsCorrectJailedNotUnStakedEmptyQueueFlagEnabledField: true, + IsSwitchJailWaitingFlagEnabledField: true, + IsValidatorToDelegationFlagEnabledField: true, + IsStakingV4InitFlagEnabledField: true, + IsStakingV4StartedField: true, + IsStakingV2FlagEnabledField: true, + } + argsVMContext := createArgsVMContext() + argsVMContext.EnableEpochsHandler = enableEpochsHandler + eei, _ := NewVMContext(argsVMContext) + args := createMockStakingScArguments() - eei, _ := NewVMContext(&mock.BlockChainHookStub{}, hooks.NewVMCryptoHook(), &mock.ArgumentParserMock{}, &stateMock.AccountsStub{}, &mock.RaterMock{}) args.Eei = eei - + args.EnableEpochsHandler = enableEpochsHandler stakingSmartContract, _ := NewStakingSmartContract(args) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4InitEnableEpoch, 0) // Functions which are not allowed starting STAKING V4 INIT arguments := CreateVmContractCallInput() @@ -3436,7 +3469,7 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) - stakingSmartContract.EpochConfirmed(args.EpochConfig.EnableEpochs.StakingV4EnableEpoch, 0) + enableEpochsHandler.IsStakingV4InitFlagEnabledField = false // All functions from above are not allowed anymore starting STAKING V4 epoch eei.CleanCache() arguments.Function = "getQueueIndex" From 2b0313fcbe660c9305d2228f6cd8da60606faced Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 13:46:12 +0200 Subject: [PATCH 367/958] FIX: stakingCommon.go --- testscommon/stakingcommon/stakingCommon.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 1ff99a1d263..edcc713d33b 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -10,6 +10,7 @@ import ( economicsHandler "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" @@ -273,6 +274,7 @@ func CreateEconomicsData() process.EconomicsDataHandler { }, EpochNotifier: &epochNotifier.EpochNotifierStub{}, BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, } economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData From 22a0f475d9b2f2496e8aa51b58bdbd9b831ec039 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 13:53:09 +0200 Subject: [PATCH 368/958] FIX: validator_test.go --- vm/systemSmartContracts/validator_test.go | 27 +++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index f8b963b8cbb..dbf3fcfcdc0 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -65,6 +65,7 @@ func createMockArgumentsForValidatorSCWithSystemScAddresses( IsUnBondTokensV2FlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, IsDoubleKeyProtectionFlagEnabledField: true, + IsStakeLimitsFlagEnabledField: true, }, NodesCoordinator: &mock.NodesCoordinatorStub{}, } @@ -5259,17 +5260,16 @@ func TestStakingValidatorSC_MergeValidatorData(t *testing.T) { func TestStakingValidatorSC_MergeValidatorDataTooMuchStake(t *testing.T) { t.Parallel() - blockChainHook := &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 100000 - }, + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ + IsStakingV2FlagEnabledField: false, } - atArgParser := parsers.NewCallArgsParser() - eei, _ := NewVMContext(blockChainHook, hooks.NewVMCryptoHook(), atArgParser, &stateMock.AccountsStub{}, &mock.RaterMock{}) + argsVMContext := createArgsVMContext() + argsVMContext.InputParser = parsers.NewCallArgsParser() + argsVMContext.EnableEpochsHandler = enableEpochsHandler + eei, _ := NewVMContext(argsVMContext) argsStaking := createMockStakingScArguments() argsStaking.Eei = eei - argsStaking.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 stakingSc, _ := NewStakingSmartContract(argsStaking) eei.SetSCAddress([]byte("addr")) _ = eei.SetSystemSCContainer(&mock.SystemSCContainerStub{GetCalled: func(key []byte) (contract vm.SystemSmartContract, err error) { @@ -5308,17 +5308,16 @@ func TestStakingValidatorSC_MergeValidatorDataTooMuchStake(t *testing.T) { func TestStakingValidatorSC_MergeValidatorDataTooMuchNodes(t *testing.T) { t.Parallel() - blockChainHook := &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 100000 - }, + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ + IsStakingV2FlagEnabledField: false, } - atArgParser := parsers.NewCallArgsParser() - eei, _ := NewVMContext(blockChainHook, hooks.NewVMCryptoHook(), atArgParser, &stateMock.AccountsStub{}, &mock.RaterMock{}) + argsVMContext := createArgsVMContext() + argsVMContext.InputParser = parsers.NewCallArgsParser() + argsVMContext.EnableEpochsHandler = enableEpochsHandler + eei, _ := NewVMContext(argsVMContext) argsStaking := createMockStakingScArguments() argsStaking.Eei = eei - argsStaking.EpochConfig.EnableEpochs.StakingV2EnableEpoch = 0 stakingSc, _ := NewStakingSmartContract(argsStaking) eei.SetSCAddress([]byte("addr")) _ = eei.SetSystemSCContainer(&mock.SystemSCContainerStub{GetCalled: func(key []byte) (contract vm.SystemSmartContract, err error) { From 5d8feeb52fb2908a33e309bc86c0030c4b6da239 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 15:13:32 +0200 Subject: [PATCH 369/958] FIX: tests in systemSmartContracts --- vm/systemSmartContracts/delegation_test.go | 6 ++- vm/systemSmartContracts/eei_test.go | 9 ++-- vm/systemSmartContracts/esdt_test.go | 26 +++++------ vm/systemSmartContracts/liquidStaking.go | 46 ++++++++----------- vm/systemSmartContracts/liquidStaking_test.go | 33 ++++++------- 5 files changed, 52 insertions(+), 68 deletions(-) diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 2790f63c9d0..31f44e0d1f5 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -53,6 +53,7 @@ func createMockArgumentsForDelegation() ArgsNewDelegation { IsComputeRewardCheckpointFlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, IsReDelegateBelowMinCheckFlagEnabledField: true, + IsLiquidStakingEnabledField: true, }, } } @@ -4921,17 +4922,18 @@ func TestDelegation_FailsIfESDTTransfers(t *testing.T) { } func TestDelegation_BasicCheckForLiquidStaking(t *testing.T) { + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: false, IsDelegationSmartContractFlagEnabledField: true} d, eei := createDelegationContractAndEEI() + d.enableEpochsHandler = enableEpochsHandler vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - d.flagLiquidStaking.Reset() returnCode := d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, vmInput.Function+" is an unknown function") eei.returnMessage = "" - d.flagLiquidStaking.SetValue(true) + enableEpochsHandler.IsLiquidStakingEnabledField = true returnCode = d.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") diff --git a/vm/systemSmartContracts/eei_test.go b/vm/systemSmartContracts/eei_test.go index 189cea88828..6b322048e25 100644 --- a/vm/systemSmartContracts/eei_test.go +++ b/vm/systemSmartContracts/eei_test.go @@ -277,12 +277,9 @@ func TestVmContext_ProcessBuiltInFunction(t *testing.T) { }, } - vmCtx, _ := NewVMContext( - blockChainHook, - hooks.NewVMCryptoHook(), - &mock.ArgumentParserMock{}, - &stateMock.AccountsStub{}, - &mock.RaterMock{}) + argsVMContext := createArgsVMContext() + argsVMContext.BlockChainHook = blockChainHook + vmCtx, _ := NewVMContext(argsVMContext) vmOutput, err := vmCtx.ProcessBuiltInFunction(vm.LiquidStakingSCAddress, vm.LiquidStakingSCAddress, "function", [][]byte{}) assert.Nil(t, vmOutput) diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index b0469545a3e..7e23c348990 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -45,6 +45,7 @@ func createMockArgumentsForESDT() ArgsNewESDTSmartContract { IsESDTNFTCreateOnMultiShardFlagEnabledField: true, IsESDTTransferRoleFlagEnabledField: true, IsESDTMetadataContinuousCleanupFlagEnabledField: true, + IsLiquidStakingEnabledField: true, }, } } @@ -4352,19 +4353,19 @@ func TestEsdt_CheckRolesOnMetaESDT(t *testing.T) { func TestEsdt_ExecuteInitDelegationESDT(t *testing.T) { t.Parallel() + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ + IsDelegationSmartContractFlagEnabledField: true, + IsESDTFlagEnabledField: true, + IsBuiltInFunctionOnMetaFlagEnabledField: false, + } + args := createMockArgumentsForESDT() args.ESDTSCAddress = vm.ESDTSCAddress - eei, _ := NewVMContext( - &mock.BlockChainHookStub{ - CurrentEpochCalled: func() uint32 { - return 2 - }, - }, - hooks.NewVMCryptoHook(), - &mock.ArgumentParserMock{}, - &stateMock.AccountsStub{}, - &mock.RaterMock{}, - ) + args.EnableEpochsHandler = enableEpochsHandler + + argsVMContext := createArgsVMContext() + argsVMContext.EnableEpochsHandler = enableEpochsHandler + eei, _ := NewVMContext(argsVMContext) args.Eei = eei e, _ := NewESDTSmartContract(args) @@ -4378,13 +4379,12 @@ func TestEsdt_ExecuteInitDelegationESDT(t *testing.T) { } eei.returnMessage = "" - e.flagESDTOnMeta.Reset() returnCode := e.Execute(vmInput) assert.Equal(t, vmcommon.FunctionNotFound, returnCode) assert.Equal(t, eei.returnMessage, "invalid method to call") eei.returnMessage = "" - e.flagESDTOnMeta.SetValue(true) + enableEpochsHandler.IsBuiltInFunctionOnMetaFlagEnabledField = true returnCode = e.Execute(vmInput) assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, "only system address can call this") diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go index b9d70506543..0549d48fe25 100644 --- a/vm/systemSmartContracts/liquidStaking.go +++ b/vm/systemSmartContracts/liquidStaking.go @@ -9,7 +9,6 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" @@ -24,15 +23,13 @@ const nonceAttributesPrefix = "n" const attributesNoncePrefix = "a" type liquidStaking struct { - eei vm.SystemEI - liquidStakingSCAddress []byte - gasCost vm.GasCost - marshalizer marshal.Marshalizer - hasher hashing.Hasher - mutExecution sync.RWMutex - liquidStakingEnableEpoch uint32 - flagLiquidStaking atomic.Flag - enableEpochsHandler common.EnableEpochsHandler + eei vm.SystemEI + liquidStakingSCAddress []byte + gasCost vm.GasCost + marshalizer marshal.Marshalizer + hasher hashing.Hasher + mutExecution sync.RWMutex + enableEpochsHandler common.EnableEpochsHandler } // ArgsNewLiquidStaking defines the arguments to create the liquid staking smart contract @@ -43,7 +40,6 @@ type ArgsNewLiquidStaking struct { GasCost vm.GasCost Marshalizer marshal.Marshalizer Hasher hashing.Hasher - EpochNotifier vm.EpochNotifier EnableEpochsHandler common.EnableEpochsHandler } @@ -64,18 +60,18 @@ func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) if check.IfNil(args.Hasher) { return nil, vm.ErrNilHasher } + if check.IfNil(args.EnableEpochsHandler) { + return nil, vm.ErrNilEnableEpochsHandler + } l := &liquidStaking{ - eei: args.Eei, - liquidStakingSCAddress: args.LiquidStakingSCAddress, - gasCost: args.GasCost, - marshalizer: args.Marshalizer, - hasher: args.Hasher, - liquidStakingEnableEpoch: args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, + eei: args.Eei, + liquidStakingSCAddress: args.LiquidStakingSCAddress, + gasCost: args.GasCost, + marshalizer: args.Marshalizer, + hasher: args.Hasher, + enableEpochsHandler: args.EnableEpochsHandler, } - log.Debug("liquid staking: enable epoch", "epoch", l.liquidStakingEnableEpoch) - - args.EpochNotifier.RegisterNotifyHandler(l) return l, nil } @@ -90,7 +86,7 @@ func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.Retur l.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } - if !l.flagLiquidStaking.IsSet() { + if !l.enableEpochsHandler.IsLiquidStakingEnabled() { l.eei.AddReturnMessage("liquid staking contract is not enabled") return vmcommon.UserError } @@ -571,15 +567,9 @@ func (l *liquidStaking) SetNewGasCost(gasCost vm.GasCost) { l.mutExecution.Unlock() } -// EpochConfirmed is called whenever a new epoch is confirmed -func (l *liquidStaking) EpochConfirmed(epoch uint32, _ uint64) { - l.flagLiquidStaking.SetValue(epoch >= l.liquidStakingEnableEpoch) - log.Debug("liquid staking system sc", "enabled", l.flagLiquidStaking.IsSet()) -} - // CanUseContract returns true if contract can be used func (l *liquidStaking) CanUseContract() bool { - return l.flagLiquidStaking.IsSet() + return l.enableEpochsHandler.IsLiquidStakingEnabled() } // IsInterfaceNil returns true if underlying object is nil diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go index ff3c0a86ec2..9491c428adc 100644 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ b/vm/systemSmartContracts/liquidStaking_test.go @@ -8,9 +8,8 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/config" - "github.com/multiversx/mx-chain-go/process/smartContract/hooks" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" - stateMock "github.com/multiversx/mx-chain-go/testscommon/state" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/mock" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -25,23 +24,15 @@ func createMockArgumentsForLiquidStaking() ArgsNewLiquidStaking { GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{LiquidStakingOps: 10}}, Marshalizer: &mock.MarshalizerMock{}, Hasher: &hashingMocks.HasherMock{}, - EpochNotifier: &mock.EpochNotifierStub{}, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: true}, } } func createLiquidStakingContractAndEEI() (*liquidStaking, *vmContext) { args := createMockArgumentsForLiquidStaking() - eei, _ := NewVMContext( - &mock.BlockChainHookStub{ - CurrentEpochCalled: func() uint32 { - return 2 - }, - }, - hooks.NewVMCryptoHook(), - &mock.ArgumentParserMock{}, - &stateMock.AccountsStub{}, - &mock.RaterMock{}, - ) + argsVMContext := createArgsVMContext() + argsVMContext.EnableEpochsHandler = args.EnableEpochsHandler + eei, _ := NewVMContext(argsVMContext) systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { return vmcommon.Ok @@ -96,9 +87,9 @@ func TestLiquidStaking_NilEpochNotifier(t *testing.T) { t.Parallel() args := createMockArgumentsForLiquidStaking() - args.EpochNotifier = nil + args.EnableEpochsHandler = nil l, err := NewLiquidStakingSystemSC(args) - assert.True(t, errors.Is(err, vm.ErrNilEpochNotifier)) + assert.True(t, errors.Is(err, vm.ErrNilEnableEpochsHandler)) assert.True(t, l.IsInterfaceNil()) } @@ -115,11 +106,14 @@ func TestLiquidStaking_New(t *testing.T) { func TestLiquidStaking_CanUseContract(t *testing.T) { t.Parallel() + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: false} + args := createMockArgumentsForLiquidStaking() - args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch = 10 + args.EnableEpochsHandler = enableEpochsHandler l, _ := NewLiquidStakingSystemSC(args) assert.False(t, l.CanUseContract()) + enableEpochsHandler.IsLiquidStakingEnabledField = true args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch = 0 l, _ = NewLiquidStakingSystemSC(args) assert.True(t, l.CanUseContract()) @@ -140,20 +134,21 @@ func TestLiquidStaking_SetNewGasConfig(t *testing.T) { func TestLiquidStaking_NotActiveWrongCalls(t *testing.T) { t.Parallel() + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: false} l, eei := createLiquidStakingContractAndEEI() + l.enableEpochsHandler = enableEpochsHandler returnCode := l.Execute(nil) assert.Equal(t, returnCode, vmcommon.UserError) assert.Equal(t, eei.returnMessage, vm.ErrInputArgsIsNil.Error()) - l.flagLiquidStaking.Reset() eei.returnMessage = "" vmInput := getDefaultVmInputForFunc("returnViaLiquidStaking", make([][]byte, 0)) returnCode = l.Execute(vmInput) assert.Equal(t, returnCode, vmcommon.UserError) assert.Equal(t, eei.returnMessage, "liquid staking contract is not enabled") - l.flagLiquidStaking.SetValue(true) + enableEpochsHandler.IsLiquidStakingEnabledField = true eei.returnMessage = "" returnCode = l.Execute(vmInput) assert.Equal(t, returnCode, vmcommon.UserError) From 3a04835ec92aec12c0c8be107da394c914aa00c1 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 16 Jan 2023 15:39:46 +0200 Subject: [PATCH 370/958] FIX: stakingToPeer --- process/scToProtocol/stakingToPeer.go | 17 +---------------- process/scToProtocol/stakingToPeer_test.go | 14 ++++++++++---- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index 22c54ced82f..cdb68eeb582 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -53,8 +53,6 @@ type stakingToPeer struct { unJailRating uint32 jailRating uint32 enableEpochsHandler common.EnableEpochsHandler - stakingV4InitEpoch uint32 - flagStakingV4 atomic.Flag } // NewStakingToPeer creates the component which moves from staking sc state to peer state @@ -76,7 +74,6 @@ func NewStakingToPeer(args ArgStakingToPeer) (*stakingToPeer, error) { unJailRating: args.RatingsData.StartRating(), jailRating: args.RatingsData.MinRating(), enableEpochsHandler: args.EnableEpochsHandler, - stakingV4InitEpoch: args.StakingV4InitEpoch, } return st, nil @@ -327,7 +324,7 @@ func (stp *stakingToPeer) updatePeerState( } newNodesList := common.NewList - if stp.flagStakingV4.IsSet() { + if stp.enableEpochsHandler.IsStakingV4Enabled() { newNodesList = common.AuctionList } @@ -420,18 +417,6 @@ func (stp *stakingToPeer) getAllModifiedStates(body *block.Body) ([]string, erro return affectedStates, nil } -// EpochConfirmed is called whenever a new epoch is confirmed -func (stp *stakingToPeer) EpochConfirmed(epoch uint32, _ uint64) { - stp.flagStaking.SetValue(epoch >= stp.stakeEnableEpoch) - log.Debug("stakingToPeer: stake", "enabled", stp.flagStaking.IsSet()) - - stp.flagValidatorToDelegation.SetValue(epoch >= stp.validatorToDelegationEnableEpoch) - log.Debug("stakingToPeer: validator to delegation", "enabled", stp.flagValidatorToDelegation.IsSet()) - - stp.flagStakingV4.SetValue(epoch >= stp.stakingV4InitEpoch) - log.Debug("stakingToPeer: staking v4 init", "enabled", stp.flagStakingV4.IsSet()) -} - // IsInterfaceNil returns true if there is no value under the interface func (stp *stakingToPeer) IsInterfaceNil() bool { return stp == nil diff --git a/process/scToProtocol/stakingToPeer_test.go b/process/scToProtocol/stakingToPeer_test.go index fefd0458a18..44b3d5efdc6 100644 --- a/process/scToProtocol/stakingToPeer_test.go +++ b/process/scToProtocol/stakingToPeer_test.go @@ -651,8 +651,14 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { }, } + enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ + IsStakeFlagEnabledField: true, + IsValidatorToDelegationFlagEnabledField: true, + } + arguments := createMockArgumentsNewStakingToPeer() arguments.PeerState = peerAccountsDB + arguments.EnableEpochsHandler = enableEpochsHandler stp, _ := NewStakingToPeer(arguments) stakingData := systemSmartContracts.StakedDataV2_0{ @@ -682,13 +688,13 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.NewList), peerAccount.GetList()) - stp.EpochConfirmed(arguments.StakingV4InitEpoch, 0) + enableEpochsHandler.IsStakingV4FlagEnabledField = true err = stp.updatePeerState(stakingData, blsPubKey, nonce) assert.NoError(t, err) assert.True(t, bytes.Equal(blsPubKey, peerAccount.GetBLSPublicKey())) assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) - stp.EpochConfirmed(0, 0) + enableEpochsHandler.IsStakingV4FlagEnabledField = false stakingData.UnStakedNonce = 11 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) @@ -708,11 +714,11 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.Equal(t, string(common.NewList), peerAccount.GetList()) - stp.EpochConfirmed(arguments.StakingV4InitEpoch, 0) + enableEpochsHandler.IsStakingV4FlagEnabledField = true err = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.NoError(t, err) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) - stp.EpochConfirmed(0, 0) + enableEpochsHandler.IsStakingV4FlagEnabledField = false stakingData.UnStakedNonce = 15 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) From 86516c826b2fb78d1845fdcc95bfd2462ceb0cc0 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 17 Jan 2023 11:57:38 +0200 Subject: [PATCH 371/958] FIX: bootstrap --- consensus/mock/peerProcessorStub.go | 0 factory/bootstrap/bootstrapComponents.go | 3 ++- factory/bootstrap/bootstrapComponents_test.go | 4 ++-- factory/bootstrapComponents_test.go | 0 factory/coreComponents_test.go | 0 factory/cryptoComponents_test.go | 0 factory/heartbeatComponents.go | 0 factory/processComponents_test.go | 0 integrationTests/mock/epochValidatorInfoCreatorStub.go | 0 integrationTests/testP2PNode.go | 0 .../testProcessorNodeWithStateCheckpointModulus.go | 0 11 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 consensus/mock/peerProcessorStub.go delete mode 100644 factory/bootstrapComponents_test.go delete mode 100644 factory/coreComponents_test.go delete mode 100644 factory/cryptoComponents_test.go delete mode 100644 factory/heartbeatComponents.go delete mode 100644 factory/processComponents_test.go delete mode 100644 integrationTests/mock/epochValidatorInfoCreatorStub.go delete mode 100644 integrationTests/testP2PNode.go delete mode 100644 integrationTests/testProcessorNodeWithStateCheckpointModulus.go diff --git a/consensus/mock/peerProcessorStub.go b/consensus/mock/peerProcessorStub.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/factory/bootstrap/bootstrapComponents.go b/factory/bootstrap/bootstrapComponents.go index 859f2f3c3a6..dd2f7cb059c 100644 --- a/factory/bootstrap/bootstrapComponents.go +++ b/factory/bootstrap/bootstrapComponents.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/process/headerCheck" "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/storage/directoryhandler" storageFactory "github.com/multiversx/mx-chain-go/storage/factory" @@ -182,7 +183,7 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory( bcf.coreComponents.InternalMarshalizer(), - bcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + bcf.coreComponents.EnableEpochsHandler().StakingV4EnableEpoch(), ) if err != nil { return nil, err diff --git a/factory/bootstrap/bootstrapComponents_test.go b/factory/bootstrap/bootstrapComponents_test.go index dcbb5a0c8c4..30bf26a3220 100644 --- a/factory/bootstrap/bootstrapComponents_test.go +++ b/factory/bootstrap/bootstrapComponents_test.go @@ -130,8 +130,8 @@ func TestBootstrapComponentsFactory_CreateEpochStartBootstrapCreationFail(t *tes coreComponents := componentsMock.GetDefaultCoreComponents() args.CoreComponents = coreComponents - bcf, _ := bootstrap.NewBootstrapComponentsFactory(args) - + bcf, err := bootstrap.NewBootstrapComponentsFactory(args) + _ = err coreComponents.RatingHandler = nil bc, err := bcf.Create() diff --git a/factory/bootstrapComponents_test.go b/factory/bootstrapComponents_test.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/factory/coreComponents_test.go b/factory/coreComponents_test.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/factory/cryptoComponents_test.go b/factory/cryptoComponents_test.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/factory/heartbeatComponents.go b/factory/heartbeatComponents.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/factory/processComponents_test.go b/factory/processComponents_test.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/integrationTests/mock/epochValidatorInfoCreatorStub.go b/integrationTests/mock/epochValidatorInfoCreatorStub.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/integrationTests/testP2PNode.go b/integrationTests/testP2PNode.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/integrationTests/testProcessorNodeWithStateCheckpointModulus.go b/integrationTests/testProcessorNodeWithStateCheckpointModulus.go deleted file mode 100644 index e69de29bb2d..00000000000 From 09dea8f03f3bf674d2579f7e3bc927750fa98fd9 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 17 Jan 2023 12:02:00 +0200 Subject: [PATCH 372/958] FIX: Lots of broken build packages --- common/enablers/enableEpochsHandler.go | 5 + common/interface.go | 1 + config/config.go | 1 + epochStart/bootstrap/baseStorageHandler.go | 4 +- epochStart/bootstrap/metaStorageHandler.go | 25 +- .../bootstrap/metaStorageHandler_test.go | 13 +- epochStart/bootstrap/process.go | 33 +- epochStart/bootstrap/process_test.go | 11 +- epochStart/bootstrap/shardStorageHandler.go | 26 +- .../bootstrap/shardStorageHandler_test.go | 13 +- epochStart/bootstrap/storageProcess.go | 27 +- epochStart/bootstrap/syncValidatorStatus.go | 40 ++- .../vm/staking/baseTestMetaProcessor.go | 9 +- .../vm/staking/nodesCoordiantorCreator.go | 2 +- process/block/metrics.go | 2 +- process/scToProtocol/stakingToPeer.go | 1 - sharding/mock/enableEpochsHandlerMock.go | 5 + .../indexHashedNodesCoordinator_test.go | 283 +++++++++--------- testscommon/components/default.go | 26 +- testscommon/enableEpochsHandlerStub.go | 9 + 20 files changed, 265 insertions(+), 271 deletions(-) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 163d9aa5709..c15381ef396 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -221,6 +221,11 @@ func (handler *enableEpochsHandler) RefactorPeersMiniBlocksEnableEpoch() uint32 return handler.enableEpochsConfig.RefactorPeersMiniBlocksEnableEpoch } +// StakingV4EnableEpoch returns the epoch when stakingV4 becomes active +func (handler *enableEpochsHandler) StakingV4EnableEpoch() uint32 { + return handler.enableEpochsConfig.StakingV4EnableEpoch +} + // IsInterfaceNil returns true if there is no value under the interface func (handler *enableEpochsHandler) IsInterfaceNil() bool { return handler == nil diff --git a/common/interface.go b/common/interface.go index 26a0402b356..3549216c37a 100644 --- a/common/interface.go +++ b/common/interface.go @@ -243,6 +243,7 @@ type EnableEpochsHandler interface { StorageAPICostOptimizationEnableEpoch() uint32 MiniBlockPartialExecutionEnableEpoch() uint32 RefactorPeersMiniBlocksEnableEpoch() uint32 + StakingV4EnableEpoch() uint32 IsSCDeployFlagEnabled() bool IsBuiltInFunctionsFlagEnabled() bool IsRelayedTransactionsFlagEnabled() bool diff --git a/config/config.go b/config/config.go index 34e1f377c8c..1d4cf43d604 100644 --- a/config/config.go +++ b/config/config.go @@ -215,6 +215,7 @@ type Config struct { PeersRatingConfig PeersRatingConfig PoolsCleanersConfig PoolsCleanersConfig + SoftAuctionConfig SoftAuctionConfig } diff --git a/epochStart/bootstrap/baseStorageHandler.go b/epochStart/bootstrap/baseStorageHandler.go index 1fe3eeedbfc..b2f6ee01b5a 100644 --- a/epochStart/bootstrap/baseStorageHandler.go +++ b/epochStart/bootstrap/baseStorageHandler.go @@ -2,20 +2,22 @@ package bootstrap import ( "encoding/hex" - "encoding/json" "strings" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/typeConverters" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/storage" ) // StorageHandlerArgs is a struct placeholder for all arguments required to create either a shard or a meta storage handler diff --git a/epochStart/bootstrap/metaStorageHandler.go b/epochStart/bootstrap/metaStorageHandler.go index b0c516ae0b3..b0263f21cab 100644 --- a/epochStart/bootstrap/metaStorageHandler.go +++ b/epochStart/bootstrap/metaStorageHandler.go @@ -7,17 +7,11 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-core-go/data/typeConverters" - "github.com/multiversx/mx-chain-core-go/hashing" - "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/bootstrap/disabled" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" - "github.com/multiversx/mx-chain-go/sharding" - "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/storage/factory" ) @@ -34,14 +28,17 @@ func NewMetaStorageHandler(args StorageHandlerArgs) (*metaStorageHandler, error) epochStartNotifier := &disabled.EpochStartNotifier{} storageFactory, err := factory.NewStorageServiceFactory( - &args.GeneralConfig, - &args.PreferencesConfig, - args.ShardCoordinator, - args.PathManagerHandler, - epochStartNotifier, - args.NodeTypeProvider, - args.CurrentEpoch, - false, + factory.StorageServiceFactoryArgs{ + Config: args.GeneralConfig, + PrefsConfig: args.PreferencesConfig, + ShardCoordinator: args.ShardCoordinator, + PathManager: args.PathManagerHandler, + EpochStartNotifier: epochStartNotifier, + NodeTypeProvider: args.NodeTypeProvider, + CurrentEpoch: args.CurrentEpoch, + StorageType: factory.BootstrapStorageService, + CreateTrieEpochRootHashStorer: false, + }, ) if err != nil { return nil, err diff --git a/epochStart/bootstrap/metaStorageHandler_test.go b/epochStart/bootstrap/metaStorageHandler_test.go index bebb630d7d6..4f2ca6ba65a 100644 --- a/epochStart/bootstrap/metaStorageHandler_test.go +++ b/epochStart/bootstrap/metaStorageHandler_test.go @@ -18,6 +18,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -159,16 +160,8 @@ func testMetaWithMissingStorer(missingUnit dataRetriever.UnitType, atCallNumber _ = os.RemoveAll("./Epoch_0") }() - gCfg := testscommon.GetGeneralConfig() - prefsConfig := config.PreferencesConfig{} - coordinator := &mock.ShardCoordinatorStub{} - pathManager := &testscommon.PathManagerStub{} - marshalizer := &mock.MarshalizerMock{} - hasher := &hashingMocks.HasherMock{} - uit64Cvt := &mock.Uint64ByteSliceConverterMock{} - nodeTypeProvider := &nodeTypeProviderMock.NodeTypeProviderStub{} - - mtStrHandler, _ := NewMetaStorageHandler(gCfg, prefsConfig, coordinator, pathManager, marshalizer, hasher, 1, uit64Cvt, nodeTypeProvider) + args := createStorageHandlerArgs() + mtStrHandler, _ := NewMetaStorageHandler(args) counter := 0 mtStrHandler.storageService = &storageStubs.ChainStorerStub{ GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index ec46cc0e6c4..ab8fccdcffb 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -733,7 +733,6 @@ func (e *epochStartBootstrap) processNodesConfig(pubKey []byte) ([]*block.MiniBl IsFullArchive: e.prefsConfig.FullArchive, EnableEpochsHandler: e.coreComponentsHolder.EnableEpochsHandler(), NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: e.enableEpochs.StakingV4EnableEpoch, } e.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) @@ -1175,22 +1174,22 @@ func (e *epochStartBootstrap) createRequestHandler() error { // this one should only be used before determining the correct shard where the node should reside log.Debug("epochStartBootstrap.createRequestHandler", "shard", e.shardCoordinator.SelfId()) resolversContainerArgs := resolverscontainer.FactoryArgs{ - ShardCoordinator: e.shardCoordinator, - Messenger: e.messenger, - Store: storageService, - Marshalizer: e.coreComponentsHolder.InternalMarshalizer(), - DataPools: e.dataPool, - Uint64ByteSliceConverter: uint64ByteSlice.NewBigEndianConverter(), - NumConcurrentResolvingJobs: 10, - DataPacker: dataPacker, - TriesContainer: e.trieContainer, - SizeCheckDelta: 0, - InputAntifloodHandler: disabled.NewAntiFloodHandler(), - OutputAntifloodHandler: disabled.NewAntiFloodHandler(), - CurrentNetworkEpochProvider: disabled.NewCurrentNetworkEpochProviderHandler(), - PreferredPeersHolder: disabled.NewPreferredPeersHolder(), - ResolverConfig: e.generalConfig.Resolvers, - PeersRatingHandler: disabled.NewDisabledPeersRatingHandler(), + ShardCoordinator: e.shardCoordinator, + Messenger: e.messenger, + Store: storageService, + Marshalizer: e.coreComponentsHolder.InternalMarshalizer(), + DataPools: e.dataPool, + Uint64ByteSliceConverter: uint64ByteSlice.NewBigEndianConverter(), + NumConcurrentResolvingJobs: 10, + DataPacker: dataPacker, + TriesContainer: e.trieContainer, + SizeCheckDelta: 0, + InputAntifloodHandler: disabled.NewAntiFloodHandler(), + OutputAntifloodHandler: disabled.NewAntiFloodHandler(), + CurrentNetworkEpochProvider: disabled.NewCurrentNetworkEpochProviderHandler(), + PreferredPeersHolder: disabled.NewPreferredPeersHolder(), + ResolverConfig: e.generalConfig.Resolvers, + PeersRatingHandler: disabled.NewDisabledPeersRatingHandler(), PayloadValidator: payloadValidator, } resolverFactory, err := resolverscontainer.NewMetaResolversContainerFactory(resolversContainerArgs) diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index fb8e2a32bc5..c5717c54096 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -96,13 +96,13 @@ func createMockEpochStartBootstrapArgs( ) ArgsEpochStartBootstrap { generalCfg := testscommon.GetGeneralConfig() return ArgsEpochStartBootstrap{ - ScheduledSCRsStorer: genericMocks.NewStorerMock(), - CoreComponentsHolder: coreMock, - CryptoComponentsHolder: cryptoMock, - Messenger: &p2pmocks.MessengerStub{ + ScheduledSCRsStorer: genericMocks.NewStorerMock(), + CoreComponentsHolder: coreMock, + CryptoComponentsHolder: cryptoMock, + Messenger: &p2pmocks.MessengerStub{ ConnectedPeersCalled: func() []core.PeerID { return []core.PeerID{"peer0", "peer1", "peer2", "peer3", "peer4", "peer5"} - },}, + }}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, GeneralConfig: config.Config{ MiniBlocksStorage: generalCfg.MiniBlocksStorage, @@ -198,7 +198,6 @@ func createMockEpochStartBootstrapArgs( return 1 }, }, - EnableEpochs: config.EnableEpochs{StakingV4EnableEpoch: 444}, GenesisNodesConfig: &mock.NodesSetupStub{}, GenesisShardCoordinator: mock.NewMultipleShardsCoordinatorMock(), Rater: &mock.RaterStub{}, diff --git a/epochStart/bootstrap/shardStorageHandler.go b/epochStart/bootstrap/shardStorageHandler.go index 394b7c187c5..be64367fece 100644 --- a/epochStart/bootstrap/shardStorageHandler.go +++ b/epochStart/bootstrap/shardStorageHandler.go @@ -10,17 +10,11 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-core-go/data/typeConverters" - "github.com/multiversx/mx-chain-core-go/hashing" - "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/bootstrap/disabled" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" - "github.com/multiversx/mx-chain-go/sharding" - "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/storage/factory" logger "github.com/multiversx/mx-chain-logger-go" ) @@ -38,15 +32,17 @@ func NewShardStorageHandler(args StorageHandlerArgs) (*shardStorageHandler, erro epochStartNotifier := &disabled.EpochStartNotifier{} storageFactory, err := factory.NewStorageServiceFactory( - &args.GeneralConfig, - &args.PreferencesConfig, - args.ShardCoordinator, - args.PathManagerHandler, - epochStartNotifier, - args.NodeTypeProvider, - args.CurrentEpoch, - factory.BootstrapStorageService, - false, + factory.StorageServiceFactoryArgs{ + Config: args.GeneralConfig, + PrefsConfig: args.PreferencesConfig, + ShardCoordinator: args.ShardCoordinator, + PathManager: args.PathManagerHandler, + EpochStartNotifier: epochStartNotifier, + NodeTypeProvider: args.NodeTypeProvider, + CurrentEpoch: args.CurrentEpoch, + StorageType: factory.BootstrapStorageService, + CreateTrieEpochRootHashStorer: false, + }, ) if err != nil { return nil, err diff --git a/epochStart/bootstrap/shardStorageHandler_test.go b/epochStart/bootstrap/shardStorageHandler_test.go index 9c4aedd779d..903a5603f33 100644 --- a/epochStart/bootstrap/shardStorageHandler_test.go +++ b/epochStart/bootstrap/shardStorageHandler_test.go @@ -13,21 +13,13 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-core-go/data/typeConverters" - "github.com/multiversx/mx-chain-core-go/hashing" - "github.com/multiversx/mx-chain-core-go/marshal" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" - "github.com/multiversx/mx-chain-go/epochStart/mock" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" - "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/testscommon" epochStartMocks "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks/epochStart" - "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" - "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -109,8 +101,8 @@ func testShardWithMissingStorer(missingUnit dataRetriever.UnitType, atCallNumber }() counter := 0 - args := createDefaultShardStorageArgs() - shardStorage, _ := NewShardStorageHandler(args.generalConfig, args.prefsConfig, args.shardCoordinator, args.pathManagerHandler, args.marshalizer, args.hasher, 1, args.uint64Converter, args.nodeTypeProvider) + args := createStorageHandlerArgs() + shardStorage, _ := NewShardStorageHandler(args) shardStorage.storageService = &storageStubs.ChainStorerStub{ GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { counter++ @@ -1118,7 +1110,6 @@ func createPendingAndProcessedMiniBlocksScenario() scenarioData { expectedPendingMbsWithScheduled := []bootstrapStorage.PendingMiniBlocksInfo{ {ShardID: 0, MiniBlocksHashes: [][]byte{crossMbHeaders[1].Hash, crossMbHeaders[2].Hash, crossMbHeaders[3].Hash, crossMbHeaders[4].Hash, crossMbHeaders[0].Hash}}, } - expectedProcessedMbsWithScheduled := make([]bootstrapStorage.MiniBlocksInMeta, 0) headers := map[string]data.HeaderHandler{ lastFinishedMetaBlockHash: &block.MetaBlock{ diff --git a/epochStart/bootstrap/storageProcess.go b/epochStart/bootstrap/storageProcess.go index 4231c78efc4..8aa61ddfa98 100644 --- a/epochStart/bootstrap/storageProcess.go +++ b/epochStart/bootstrap/storageProcess.go @@ -400,21 +400,20 @@ func (sesb *storageEpochStartBootstrap) processNodesConfig(pubKey []byte) error shardId = sesb.genesisShardCoordinator.SelfId() } argsNewValidatorStatusSyncers := ArgsNewSyncValidatorStatus{ - DataPool: sesb.dataPool, - Marshalizer: sesb.coreComponentsHolder.InternalMarshalizer(), - RequestHandler: sesb.requestHandler, - ChanceComputer: sesb.rater, - GenesisNodesConfig: sesb.genesisNodesConfig, - NodeShuffler: sesb.nodeShuffler, - Hasher: sesb.coreComponentsHolder.Hasher(), - PubKey: pubKey, - ShardIdAsObserver: shardId, - ChanNodeStop: sesb.coreComponentsHolder.ChanStopNodeProcess(), - NodeTypeProvider: sesb.coreComponentsHolder.NodeTypeProvider(), - IsFullArchive: sesb.prefsConfig.FullArchive, - EnableEpochsHandler: sesb.coreComponentsHolder.EnableEpochsHandler(), + DataPool: sesb.dataPool, + Marshalizer: sesb.coreComponentsHolder.InternalMarshalizer(), + RequestHandler: sesb.requestHandler, + ChanceComputer: sesb.rater, + GenesisNodesConfig: sesb.genesisNodesConfig, + NodeShuffler: sesb.nodeShuffler, + Hasher: sesb.coreComponentsHolder.Hasher(), + PubKey: pubKey, + ShardIdAsObserver: shardId, + ChanNodeStop: sesb.coreComponentsHolder.ChanStopNodeProcess(), + NodeTypeProvider: sesb.coreComponentsHolder.NodeTypeProvider(), + IsFullArchive: sesb.prefsConfig.FullArchive, + EnableEpochsHandler: sesb.coreComponentsHolder.EnableEpochsHandler(), NodesCoordinatorRegistryFactory: sesb.nodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: sesb.enableEpochs.StakingV4EnableEpoch, } sesb.nodesConfigHandler, err = NewSyncValidatorStatus(argsNewValidatorStatusSyncers) if err != nil { diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index 6499202099b..2acef8ac709 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -51,7 +51,6 @@ type ArgsNewSyncValidatorStatus struct { NodeTypeProvider NodeTypeProviderHandler IsFullArchive bool EnableEpochsHandler common.EnableEpochsHandler - StakingV4EnableEpoch uint32 NodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } @@ -113,27 +112,26 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat s.memDB = disabled.CreateMemUnit() argsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), - MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), - Marshalizer: args.Marshalizer, - Hasher: args.Hasher, - Shuffler: args.NodeShuffler, - EpochStartNotifier: &disabled.EpochStartNotifier{}, - BootStorer: s.memDB, - ShardIDAsObserver: args.ShardIdAsObserver, - NbShards: args.GenesisNodesConfig.NumberOfShards(), - EligibleNodes: eligibleValidators, - WaitingNodes: waitingValidators, - SelfPublicKey: args.PubKey, - ConsensusGroupCache: consensusGroupCache, - ShuffledOutHandler: disabled.NewShuffledOutHandler(), - ChanStopNode: args.ChanNodeStop, - NodeTypeProvider: args.NodeTypeProvider, - IsFullArchive: args.IsFullArchive, - EnableEpochsHandler: args.EnableEpochsHandler, - ValidatorInfoCacher: s.dataPool.CurrentEpochValidatorInfo(), + ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), + MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), + Marshalizer: args.Marshalizer, + Hasher: args.Hasher, + Shuffler: args.NodeShuffler, + EpochStartNotifier: &disabled.EpochStartNotifier{}, + BootStorer: s.memDB, + ShardIDAsObserver: args.ShardIdAsObserver, + NbShards: args.GenesisNodesConfig.NumberOfShards(), + EligibleNodes: eligibleValidators, + WaitingNodes: waitingValidators, + SelfPublicKey: args.PubKey, + ConsensusGroupCache: consensusGroupCache, + ShuffledOutHandler: disabled.NewShuffledOutHandler(), + ChanStopNode: args.ChanNodeStop, + NodeTypeProvider: args.NodeTypeProvider, + IsFullArchive: args.IsFullArchive, + EnableEpochsHandler: args.EnableEpochsHandler, + ValidatorInfoCacher: s.dataPool.CurrentEpochValidatorInfo(), NodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: args.StakingV4EnableEpoch, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 20a79032590..8f71e024094 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -22,10 +22,11 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/process" vmFactory "github.com/multiversx/mx-chain-go/process/factory" - "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts/defaults" vmcommon "github.com/multiversx/mx-chain-vm-common-go" arwenConfig "github.com/multiversx/mx-chain-vm-v1_4-go/config" @@ -137,7 +138,7 @@ func newTestMetaProcessor( stakingDataProvider, ) - txCoordinator := &mock.TransactionCoordinatorMock{} + txCoordinator := &testscommon.TransactionCoordinatorMock{} epochStartTrigger := createEpochStartTrigger(coreComponents, dataComponents.StorageService()) eligible, _ := nc.GetAllEligibleValidatorsPublicKeys(0) @@ -209,7 +210,7 @@ func saveNodesConfig( func createGasScheduleNotifier() core.GasScheduleNotifier { gasSchedule := arwenConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) - return mock.NewGasScheduleNotifierMock(gasSchedule) + return testscommon.NewGasScheduleNotifierMock(gasSchedule) } func createEpochStartTrigger( @@ -226,7 +227,7 @@ func createEpochStartTrigger( Storage: storageService, Marshalizer: coreComponents.InternalMarshalizer(), Hasher: coreComponents.Hasher(), - AppStatusHandler: coreComponents.StatusHandler(), + AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, } epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index cb2b20746f4..b958af08085 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -5,6 +5,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-core-go/storage/lrucache" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/factory" @@ -12,7 +13,6 @@ import ( "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/storage" - "github.com/multiversx/mx-chain-go/storage/lrucache" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" ) diff --git a/process/block/metrics.go b/process/block/metrics.go index e23f867ae61..31fe4b07066 100644 --- a/process/block/metrics.go +++ b/process/block/metrics.go @@ -270,7 +270,7 @@ func indexValidatorsRating( shardValidatorsRating := make(map[string][]*outportcore.ValidatorRatingInfo) for shardID, validatorInfosInShard := range validators.GetShardValidatorsInfoMap() { - validatorsInfos := make([]*indexer.ValidatorRatingInfo, 0) + validatorsInfos := make([]*outportcore.ValidatorRatingInfo, 0) for _, validatorInfo := range validatorInfosInShard { validatorsInfos = append(validatorsInfos, &outportcore.ValidatorRatingInfo{ PublicKey: hex.EncodeToString(validatorInfo.GetPublicKey()), diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index cdb68eeb582..dbfa78924fa 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -36,7 +36,6 @@ type ArgStakingToPeer struct { CurrTxs dataRetriever.TransactionCacher RatingsData process.RatingsInfoHandler EnableEpochsHandler common.EnableEpochsHandler - StakingV4InitEpoch uint32 } // stakingToPeer defines the component which will translate changes from staking SC state diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 0309a1822dd..5660224f2c6 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -92,6 +92,11 @@ func (mock *EnableEpochsHandlerMock) MiniBlockPartialExecutionEnableEpoch() uint return 0 } +// StakingV4EnableEpoch - +func (mock *EnableEpochsHandlerMock) StakingV4EnableEpoch() uint32 { + return 0 +} + // RefactorPeersMiniBlocksEnableEpoch returns 0 func (mock *EnableEpochsHandlerMock) RefactorPeersMiniBlocksEnableEpoch() uint32 { return mock.RefactorPeersMiniBlocksEnableEpochField diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index d3f6a4ba779..a677fdb6777 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -101,9 +101,6 @@ func createArguments() ArgNodesCoordinator { Hysteresis: hysteresis, Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, - EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: stakingV4Epoch, - }, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } nodeShuffler, _ := NewHashValidatorsShuffler(shufflerArgs) @@ -131,7 +128,7 @@ func createArguments() ArgNodesCoordinator { EnableEpochsHandler: &mock.EnableEpochsHandlerMock{ IsRefactorPeersMiniBlocksFlagEnabledField: true, }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, StakingV4EnableEpoch: stakingV4Epoch, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } @@ -276,23 +273,23 @@ func TestIndexHashedNodesCoordinator_OkValShouldWork(t *testing.T) { bootStorer := genericMocks.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 2, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: 2, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } @@ -337,23 +334,23 @@ func TestIndexHashedNodesCoordinator_NewCoordinatorTooFewNodesShouldErr(t *testi bootStorer := genericMocks.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 10, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: 10, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, err := NewIndexHashedNodesCoordinator(arguments) @@ -412,23 +409,23 @@ func TestIndexHashedNodesCoordinator_ComputeValidatorsGroup1ValidatorShouldRetur bootStorer := genericMocks.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: nodesMap, - WaitingNodes: make(map[uint32][]Validator), - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: nodesMap, + WaitingNodes: make(map[uint32][]Validator), + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -473,23 +470,23 @@ func TestIndexHashedNodesCoordinator_ComputeValidatorsGroup400of400For10locksNoM } arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusGroupSize, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: lruCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: consensusGroupSize, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: lruCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } @@ -562,23 +559,23 @@ func TestIndexHashedNodesCoordinator_ComputeValidatorsGroup400of400For10BlocksMe } arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusGroupSize, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 1, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: lruCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: consensusGroupSize, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 1, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: lruCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } @@ -961,23 +958,23 @@ func TestIndexHashedNodesCoordinator_GetValidatorWithPublicKeyShouldWork(t *test bootStorer := genericMocks.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: make(map[uint32][]Validator), - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: make(map[uint32][]Validator), + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -1045,24 +1042,24 @@ func TestIndexHashedGroupSelector_GetAllEligibleValidatorsPublicKeys(t *testing. bootStorer := genericMocks.NewStorerMock() arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardZeroId, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: make(map[uint32][]Validator), - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardZeroId, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: make(map[uint32][]Validator), + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } @@ -1125,24 +1122,24 @@ func TestIndexHashedGroupSelector_GetAllWaitingValidatorsPublicKeys(t *testing.T eligibleMap[shardZeroId] = []Validator{&validator{}} arguments := ArgNodesCoordinator{ - ShardConsensusGroupSize: 1, - MetaConsensusGroupSize: 1, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardZeroId, - NbShards: 2, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: []byte("key"), - ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: make(chan endProcess.ArgEndProcess), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: 1, + MetaConsensusGroupSize: 1, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardZeroId, + NbShards: 2, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: []byte("key"), + ConsensusGroupCache: &mock.NodesCoordinatorCacheMock{}, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: make(chan endProcess.ArgEndProcess), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } @@ -1534,7 +1531,7 @@ func TestIndexHashedNodesCoordinator_EpochStart_EligibleSortedAscendingByIndex(t EnableEpochsHandler: &mock.EnableEpochsHandlerMock{ IsRefactorPeersMiniBlocksFlagEnabledField: true, }, - ValidatorInfoCacher: dataPool.NewCurrentEpochValidatorInfoPool(), + ValidatorInfoCacher: dataPool.NewCurrentEpochValidatorInfoPool(), NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } diff --git a/testscommon/components/default.go b/testscommon/components/default.go index 9a302c0a7eb..bf6e54c95c5 100644 --- a/testscommon/components/default.go +++ b/testscommon/components/default.go @@ -14,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" 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" @@ -37,16 +38,17 @@ func GetDefaultCoreComponents() *mock.CoreComponentsMock { MinTransactionVersionCalled: func() uint32 { return 1 }, - WatchdogTimer: &testscommon.WatchdogMock{}, - AlarmSch: &testscommon.AlarmSchedulerStub{}, - NtpSyncTimer: &testscommon.SyncTimerStub{}, - RoundHandlerField: &testscommon.RoundHandlerMock{}, - EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - RatingsConfig: &testscommon.RatingsInfoMock{}, - RatingHandler: &testscommon.RaterMock{}, - NodesConfig: &testscommon.NodesSetupStub{}, - StartTime: time.Time{}, - NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, + WatchdogTimer: &testscommon.WatchdogMock{}, + AlarmSch: &testscommon.AlarmSchedulerStub{}, + NtpSyncTimer: &testscommon.SyncTimerStub{}, + RoundHandlerField: &testscommon.RoundHandlerMock{}, + EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, + RatingsConfig: &testscommon.RatingsInfoMock{}, + RatingHandler: &testscommon.RaterMock{}, + NodesConfig: &testscommon.NodesSetupStub{}, + StartTime: time.Time{}, + NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EnableEpochsHandlerField: &testscommon.EnableEpochsHandlerStub{}, } } @@ -122,8 +124,8 @@ func GetDefaultProcessComponents(shardCoordinator sharding.Coordinator) *mock.Pr BootSore: &mock.BootstrapStorerMock{}, HeaderSigVerif: &mock.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, - ValidatorStatistics: &mock.ValidatorStatisticsProcessorStub{}, - ValidatorProvider: &mock.ValidatorsProviderStub{}, + ValidatorStatistics: &testscommon.ValidatorStatisticsProcessorStub{}, + ValidatorProvider: &stakingcommon.ValidatorsProviderStub{}, BlockTrack: &mock.BlockTrackerStub{}, PendingMiniBlocksHdl: &mock.PendingMiniBlocksHandlerStub{}, ReqHandler: &testscommon.RequestHandlerStub{}, diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 4c60e1f8558..c94b4f53b18 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -26,6 +26,7 @@ type EnableEpochsHandlerStub struct { StorageAPICostOptimizationEnableEpochField uint32 MiniBlockPartialExecutionEnableEpochField uint32 RefactorPeersMiniBlocksEnableEpochField uint32 + StakingV4EnableEpochField uint32 IsSCDeployFlagEnabledField bool IsBuiltInFunctionsFlagEnabledField bool IsRelayedTransactionsFlagEnabledField bool @@ -1070,6 +1071,14 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Started() bool { return stub.IsStakingV4StartedField } +// StakingV4EnableEpoch - +func (stub *EnableEpochsHandlerStub) StakingV4EnableEpoch() uint32 { + stub.RLock() + defer stub.RUnlock() + + return stub.StakingV4EnableEpochField +} + // IsInterfaceNil - func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { return stub == nil From caf8c21fa555a31a549c570c18a2b5bf7c7eaeeb Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 17 Jan 2023 16:37:41 +0200 Subject: [PATCH 373/958] FIX: Build dependencies for stakingV4 tests --- factory/bootstrap/shardingFactory.go | 42 +++---- factory/processing/blockProcessorCreator.go | 18 +-- factory/processing/processComponents.go | 25 +--- .../mock/epochRewardsCreatorStub.go | 110 ------------------ integrationTests/testInitializer.go | 16 +-- integrationTests/testProcessorNode.go | 58 +++------ .../vm/staking/baseTestMetaProcessor.go | 2 + .../vm/staking/componentsHolderCreator.go | 53 ++++++++- .../vm/staking/metaBlockProcessorCreator.go | 81 +++++++------ .../vm/staking/nodesCoordiantorCreator.go | 6 +- .../vm/staking/systemSCCreator.go | 82 +++++++------ .../vm/staking/testMetaProcessor.go | 3 +- .../testMetaProcessorWithCustomNodesConfig.go | 3 +- process/block/metablock_test.go | 8 +- process/mock/epochRewardsCreatorStub.go | 109 ----------------- update/genesis/export.go | 2 +- 16 files changed, 195 insertions(+), 423 deletions(-) delete mode 100644 integrationTests/mock/epochRewardsCreatorStub.go delete mode 100644 process/mock/epochRewardsCreatorStub.go diff --git a/factory/bootstrap/shardingFactory.go b/factory/bootstrap/shardingFactory.go index 95b8dfe6275..518ce1cb697 100644 --- a/factory/bootstrap/shardingFactory.go +++ b/factory/bootstrap/shardingFactory.go @@ -178,27 +178,27 @@ func CreateNodesCoordinator( } argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: marshalizer, - Hasher: hasher, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartNotifier, - BootStorer: bootStorer, - ShardIDAsObserver: shardIDAsObserver, - NbShards: nbShards, - EligibleNodes: eligibleValidators, - WaitingNodes: waitingValidators, - SelfPublicKey: pubKeyBytes, - ConsensusGroupCache: consensusGroupCache, - ShuffledOutHandler: shuffledOutHandler, - Epoch: currentEpoch, - StartEpoch: startEpoch, - ChanStopNode: chanNodeStop, - NodeTypeProvider: nodeTypeProvider, - IsFullArchive: prefsConfig.FullArchive, - EnableEpochsHandler: enableEpochsHandler, - ValidatorInfoCacher: validatorInfoCacher, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: marshalizer, + Hasher: hasher, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartNotifier, + BootStorer: bootStorer, + ShardIDAsObserver: shardIDAsObserver, + NbShards: nbShards, + EligibleNodes: eligibleValidators, + WaitingNodes: waitingValidators, + SelfPublicKey: pubKeyBytes, + ConsensusGroupCache: consensusGroupCache, + ShuffledOutHandler: shuffledOutHandler, + Epoch: currentEpoch, + StartEpoch: startEpoch, + ChanStopNode: chanNodeStop, + NodeTypeProvider: nodeTypeProvider, + IsFullArchive: prefsConfig.FullArchive, + EnableEpochsHandler: enableEpochsHandler, + ValidatorInfoCacher: validatorInfoCacher, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, StakingV4EnableEpoch: stakingV4EnableEpoch, } diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index e4668552b8d..cb65af914c5 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -13,7 +13,9 @@ import ( "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/bootstrap/disabled" metachainEpochStart "github.com/multiversx/mx-chain-go/epochStart/metachain" + "github.com/multiversx/mx-chain-go/epochStart/notifier" mainFactory "github.com/multiversx/mx-chain-go/factory" + factoryDisabled "github.com/multiversx/mx-chain-go/factory/disabled" "github.com/multiversx/mx-chain-go/genesis" processDisabled "github.com/multiversx/mx-chain-go/genesis/process/disabled" "github.com/multiversx/mx-chain-go/outport" @@ -217,12 +219,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( return nil, err } - txFeeHandler, err := postprocess.NewFeeAccumulator() - if err != nil { - return nil, err - } - enableEpochs := pcf.epochConfig.EnableEpochs - + txFeeHandler := postprocess.NewFeeAccumulator() argsNewScProcessor := smartContract.ArgsNewSmartContractProcessor{ VmContainer: vmContainer, ArgsParser: argsParser, @@ -539,10 +536,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } - txFeeHandler, err := postprocess.NewFeeAccumulator() - if err != nil { - return nil, err - } + txFeeHandler := postprocess.NewFeeAccumulator() enableEpochs := pcf.epochConfig.EnableEpochs argsNewScProcessor := smartContract.ArgsNewSmartContractProcessor{ VmContainer: vmContainer, @@ -693,8 +687,6 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( CurrTxs: pcf.data.Datapool().CurrentBlockTxs(), RatingsData: pcf.coreData.RatingsData(), EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), - StakeEnableEpoch: pcf.epochConfig.EnableEpochs.StakeEnableEpoch, - StakingV4InitEpoch: pcf.epochConfig.EnableEpochs.StakingV4InitEnableEpoch, } smartContractToProtocol, err := scToProtocol.NewStakingToPeer(argsStaking) if err != nil { @@ -907,14 +899,12 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( ChanceComputer: pcf.coreData.Rater(), EpochNotifier: pcf.coreData.EpochNotifier(), GenesisNodesConfig: pcf.coreData.GenesisNodesSetup(), - MaxNodesEnableConfig: enableEpochs.MaxNodesChangeEnableEpoch, StakingDataProvider: stakingDataProvider, NodesConfigProvider: pcf.nodesCoordinator, ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), ESDTOwnerAddressBytes: esdtOwnerAddress, EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, - EpochConfig: pcf.epochConfig, AuctionListSelector: auctionListSelector, } diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 260096c7d3b..2759f55b6a7 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -374,7 +374,9 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { CacheRefreshIntervalDurationInSec: cacheRefreshDuration, ValidatorStatistics: validatorStatisticsProcessor, MaxRating: pcf.maxRating, - PubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), + AuctionListSelector: pcf.auctionListSelectorAPI, } validatorsProvider, err := peer.NewValidatorsProvider(argVSP) @@ -600,25 +602,6 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { return nil, err } - cacheRefreshDuration := time.Duration(pcf.config.ValidatorStatistics.CacheRefreshIntervalInSec) * time.Second - argVSP := peer.ArgValidatorsProvider{ - NodesCoordinator: pcf.nodesCoordinator, - StartEpoch: startEpochNum, - EpochStartEventNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), - CacheRefreshIntervalDurationInSec: cacheRefreshDuration, - ValidatorStatistics: validatorStatisticsProcessor, - StakingDataProvider: pcf.stakingDataProviderAPI, - MaxRating: pcf.maxRating, - ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), - AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), - AuctionListSelector: pcf.auctionListSelectorAPI, - } - - validatorsProvider, err := peer.NewValidatorsProvider(argVSP) - if err != nil { - return nil, err - } - conversionBase := 10 genesisNodePrice, ok := big.NewInt(0).SetString(pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, conversionBase) if !ok { @@ -755,7 +738,7 @@ func (pcf *processComponentsFactory) newValidatorStatisticsProcessor() (process. RatingEnableEpoch: ratingEnabledEpoch, GenesisNonce: pcf.data.Blockchain().GetGenesisHeader().GetNonce(), EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), - StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, } validatorStatisticsProcessor, err := peer.NewValidatorStatisticsProcessor(arguments) diff --git a/integrationTests/mock/epochRewardsCreatorStub.go b/integrationTests/mock/epochRewardsCreatorStub.go deleted file mode 100644 index b2c309bee20..00000000000 --- a/integrationTests/mock/epochRewardsCreatorStub.go +++ /dev/null @@ -1,110 +0,0 @@ - -package mock - -import ( - "math/big" - - "github.com/multiversx/mx-chain-core-go/data" - "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-go/epochStart" - "github.com/multiversx/mx-chain-go/state" -) - -// EpochRewardsCreatorStub - -type EpochRewardsCreatorStub struct { - CreateRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) (block.MiniBlockSlice, error) - VerifyRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) error - CreateMarshalledDataCalled func(body *block.Body) map[string][][]byte - SaveBlockDataToStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - DeleteBlockDataFromStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - RemoveBlockDataFromPoolsCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - GetRewardsTxsCalled func(body *block.Body) map[string]data.TransactionHandler - GetProtocolSustainCalled func() *big.Int - GetLocalTxCacheCalled func() epochStart.TransactionCacher -} - -// GetProtocolSustainabilityRewards - -func (e *EpochRewardsCreatorStub) GetProtocolSustainabilityRewards() *big.Int { - if e.GetProtocolSustainCalled != nil { - return e.GetProtocolSustainCalled() - } - return big.NewInt(0) -} - -// GetLocalTxCache - -func (e *EpochRewardsCreatorStub) GetLocalTxCache() epochStart.TransactionCacher { - if e.GetLocalTxCacheCalled != nil { - return e.GetLocalTxCacheCalled() - } - return &TxForCurrentBlockStub{} -} - -// CreateRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) CreateRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) (block.MiniBlockSlice, error) { - if e.CreateRewardsMiniBlocksCalled != nil { - return e.CreateRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil, nil -} - -// GetRewardsTxs - -func (e *EpochRewardsCreatorStub) GetRewardsTxs(body *block.Body) map[string]data.TransactionHandler { - if e.GetRewardsTxsCalled != nil { - return e.GetRewardsTxsCalled(body) - } - return nil -} - -// VerifyRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) VerifyRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) error { - if e.VerifyRewardsMiniBlocksCalled != nil { - return e.VerifyRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil -} - -// CreateMarshalledData - -func (e *EpochRewardsCreatorStub) CreateMarshalledData(body *block.Body) map[string][][]byte { - if e.CreateMarshalledDataCalled != nil { - return e.CreateMarshalledDataCalled(body) - } - return nil -} - -// SaveBlockDataToStorage - -func (e *EpochRewardsCreatorStub) SaveBlockDataToStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.SaveBlockDataToStorageCalled != nil { - e.SaveBlockDataToStorageCalled(metaBlock, body) - } -} - -// DeleteBlockDataFromStorage - -func (e *EpochRewardsCreatorStub) DeleteBlockDataFromStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.DeleteBlockDataFromStorageCalled != nil { - e.DeleteBlockDataFromStorageCalled(metaBlock, body) - } -} - -// IsInterfaceNil - -func (e *EpochRewardsCreatorStub) IsInterfaceNil() bool { - return e == nil -} - -// RemoveBlockDataFromPools - -func (e *EpochRewardsCreatorStub) RemoveBlockDataFromPools(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.RemoveBlockDataFromPoolsCalled != nil { - e.RemoveBlockDataFromPoolsCalled(metaBlock, body) - } -} \ No newline at end of file diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 2e6f9614787..6ad08fa4435 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -56,9 +56,9 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" testStorage "github.com/multiversx/mx-chain-go/testscommon/state" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" - "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/trie" "github.com/multiversx/mx-chain-go/trie/hashesHolder" @@ -705,13 +705,6 @@ func CreateFullGenesisBlocks( return false }, }, - EpochConfig: &config.EpochConfig{ - EnableEpochs: enableEpochsConfig, - StakeLimitsEnableEpoch: 10, - StakingV2EnableEpoch: StakingV2Epoch, - StakingV4EnableEpoch: StakingV4Epoch, - StakingV4InitEnableEpoch: StakingV4Epoch - 1, - }, } genesisProcessor, _ := genesisProcess.NewGenesisBlockCreator(argsGenesis) @@ -812,13 +805,6 @@ func CreateGenesisMetaBlock( BlockSignKeyGen: &mock.KeyGenMock{}, ImportStartHandler: &mock.ImportStartHandlerStub{}, GenesisNodePrice: big.NewInt(1000), - EpochConfig: &config.EpochConfig{ - EnableEpochs: enableEpochsConfig, - StakeLimitsEnableEpoch: 10, - StakingV2EnableEpoch: StakingV2Epoch, - StakingV4InitEnableEpoch: StakingV4Epoch - 1, - StakingV4EnableEpoch: StakingV4Epoch, - }, } if shardCoordinator.SelfId() != core.MetachainShardId { diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index e437b14f719..bf50c4b9d7c 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -108,6 +108,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/outport" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" @@ -460,11 +461,6 @@ func newBaseTestProcessorNode(args ArgTestProcessorNode) *TestProcessorNode { BootstrapStorer: &mock.BoostrapStorerMock{}, RatingsData: args.RatingsData, EpochStartNotifier: args.EpochStartSubscriber, - EnableEpochs: config.EnableEpochs{ - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4EnableEpoch: StakingV4Epoch, - StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, - }, } tpn.NodeKeys = args.NodeKeys @@ -853,14 +849,7 @@ func (tpn *TestProcessorNode) createFullSCQueryService(gasMap map[string]map[str ChanceComputer: tpn.NodesCoordinator, ShardCoordinator: tpn.ShardCoordinator, EnableEpochsHandler: tpn.EnableEpochsHandler, - EpochConfig: &config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: StakingV4Epoch, - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, - }, - }, - NodesCoordinator: tpn.NodesCoordinator, + NodesCoordinator: tpn.NodesCoordinator, } tpn.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: tpn.EnableEpochs.DelegationSmartContractEnableEpoch, @@ -1717,7 +1706,6 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors(gasMap map[string]map[stri EnableEpochsHandler: tpn.EnableEpochsHandler, NodesCoordinator: tpn.NodesCoordinator, } - argsVMContainerFactory.EpochConfig.EnableEpochs.StakingV4EnableEpoch = StakingV4Epoch vmFactory, _ := metaProcess.NewVMContainerFactory(argsVMContainerFactory) tpn.VMContainer, _ = vmFactory.Create() @@ -2086,7 +2074,6 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { CurrTxs: tpn.DataPool.CurrentBlockTxs(), RatingsData: tpn.RatingsData, EnableEpochsHandler: tpn.EnableEpochsHandler, - StakingV4InitEpoch: StakingV4InitEpoch, } scToProtocolInstance, _ := scToProtocol.NewStakingToPeer(argsStakingToPeer) @@ -2185,33 +2172,24 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) argsEpochSystemSC := metachain.ArgsNewEpochStartSystemSCProcessing{ - SystemVM: systemVM, - UserAccountsDB: tpn.AccntState, - PeerAccountsDB: tpn.PeerState, - Marshalizer: TestMarshalizer, - StartRating: tpn.RatingsData.StartRating(), - ValidatorInfoCreator: tpn.ValidatorStatisticsProcessor, - EndOfEpochCallerAddress: vm.EndOfEpochAddress, - StakingSCAddress: vm.StakingSCAddress, - ChanceComputer: tpn.NodesCoordinator, - EpochNotifier: tpn.EpochNotifier, - GenesisNodesConfig: tpn.NodesSetup, - StakingDataProvider: stakingDataProvider, - NodesConfigProvider: tpn.NodesCoordinator, - ShardCoordinator: tpn.ShardCoordinator, - ESDTOwnerAddressBytes: vm.EndOfEpochAddress, - EnableEpochsHandler: tpn.EnableEpochsHandler, + SystemVM: systemVM, + UserAccountsDB: tpn.AccntState, + PeerAccountsDB: tpn.PeerState, + Marshalizer: TestMarshalizer, + StartRating: tpn.RatingsData.StartRating(), + ValidatorInfoCreator: tpn.ValidatorStatisticsProcessor, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ChanceComputer: tpn.NodesCoordinator, + EpochNotifier: tpn.EpochNotifier, + GenesisNodesConfig: tpn.NodesSetup, + StakingDataProvider: stakingDataProvider, + NodesConfigProvider: tpn.NodesCoordinator, + ShardCoordinator: tpn.ShardCoordinator, + ESDTOwnerAddressBytes: vm.EndOfEpochAddress, + EnableEpochsHandler: tpn.EnableEpochsHandler, AuctionListSelector: auctionListSelector, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, - EpochConfig: config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV2EnableEpoch: StakingV2Epoch, - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4EnableEpoch: StakingV4Epoch, - StakingV4DistributeAuctionToWaitingEpoch: StakingV4DistributeAuctionToWaiting, - ESDTEnableEpoch: 0, - }, - }, } epochStartSystemSCProcessor, _ := metachain.NewSystemSCProcessor(argsEpochSystemSC) tpn.EpochStartSystemSCProcessor = epochStartSystemSCProcessor diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 8f71e024094..9bec4e5ac4f 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -25,6 +25,7 @@ import ( "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" + dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts/defaults" @@ -228,6 +229,7 @@ func createEpochStartTrigger( Marshalizer: coreComponents.InternalMarshalizer(), Hasher: coreComponents.Hasher(), AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, + DataPool: dataRetrieverMock.NewPoolsHolderMock(), } epochStartTrigger, _ := metachain.NewEpochStartTrigger(argsEpochStart) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 4a03134498b..b4fac118a99 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -12,7 +12,9 @@ import ( "github.com/multiversx/mx-chain-core-go/hashing/sha256" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/enablers" "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" "github.com/multiversx/mx-chain-go/epochStart/notifier" @@ -31,11 +33,15 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" + "github.com/multiversx/mx-chain-go/testscommon/outport" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/trie" + "github.com/multiversx/mx-chain-go/trie/hashesHolder" ) +const hashSize = 32 + func createComponentHolders(numOfShards uint32) ( factory.CoreComponentsHolder, factory.DataComponentsHolder, @@ -53,6 +59,16 @@ func createComponentHolders(numOfShards uint32) ( } func createCoreComponents() factory.CoreComponentsHolder { + epochNotifier := forking.NewGenericEpochNotifier() + configEnableEpochs := config.EnableEpochs{ + StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4InitEnableEpoch: stakingV4InitEpoch, + StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, + RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + } + + enableEpochsHandler, _ := enablers.NewEnableEpochsHandler(configEnableEpochs, epochNotifier) + return &integrationMocks.CoreComponentsStub{ InternalMarshalizerField: &marshal.GogoProtoMarshalizer{}, HasherField: sha256.NewSha256(), @@ -60,13 +76,15 @@ func createCoreComponents() factory.CoreComponentsHolder { StatusHandlerField: statusHandler.NewStatusMetrics(), RoundHandlerField: &mock.RoundHandlerMock{RoundTimeDuration: time.Second}, EpochStartNotifierWithConfirmField: notifier.NewEpochStartSubscriptionHandler(), - EpochNotifierField: forking.NewGenericEpochNotifier(), + EpochNotifierField: epochNotifier, RaterField: &testscommon.RaterMock{Chance: 5}, AddressPubKeyConverterField: testscommon.NewPubkeyConverterMock(addressLength), EconomicsDataField: stakingcommon.CreateEconomicsData(), ChanStopNodeProcessField: endProcess.GetDummyEndProcessChannel(), NodeTypeProviderField: nodetype.NewNodeTypeProvider(core.NodeTypeValidator), ProcessStatusHandlerInternal: statusHandler.NewProcessStatusHandler(), + EnableEpochsHandlerField: enableEpochsHandler, + EnableRoundsHandlerField: &testscommon.EnableRoundsHandlerStub{}, } } @@ -75,7 +93,7 @@ func createDataComponents(coreComponents factory.CoreComponentsHolder, numOfShar genesisBlockHash, _ := coreComponents.InternalMarshalizer().Marshal(genesisBlock) genesisBlockHash = coreComponents.Hasher().Compute(string(genesisBlockHash)) - blockChain, _ := blockchain.NewMetaChain(coreComponents.StatusHandler()) + blockChain, _ := blockchain.NewMetaChain(&statusHandlerMock.AppStatusHandlerStub{}) _ = blockChain.SetGenesisHeader(createGenesisMetaBlock()) blockChain.SetGenesisHeaderHash(genesisBlockHash) @@ -122,31 +140,52 @@ func createBootstrapComponents( func createStatusComponents() factory.StatusComponentsHolder { return &integrationMocks.StatusComponentsStub{ - Outport: &testscommon.OutportStub{}, + Outport: &outport.OutportStub{}, AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, } } func createStateComponents(coreComponents factory.CoreComponentsHolder) factory.StateComponentsHandler { - trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(integrationTests.CreateMemUnit()) + tsmArgs := getNewTrieStorageManagerArgs(coreComponents) + tsm, _ := trie.NewTrieStorageManager(tsmArgs) + trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(tsm) userAccountsDB := createAccountsDB(coreComponents, stateFactory.NewAccountCreator(), trieFactoryManager) peerAccountsDB := createAccountsDB(coreComponents, stateFactory.NewPeerAccountCreator(), trieFactoryManager) + _ = userAccountsDB.SetSyncer(&mock.AccountsDBSyncerStub{}) + _ = peerAccountsDB.SetSyncer(&mock.AccountsDBSyncerStub{}) + return &testscommon.StateComponentsMock{ PeersAcc: peerAccountsDB, Accounts: userAccountsDB, } } +func getNewTrieStorageManagerArgs(coreComponents factory.CoreComponentsHolder) trie.NewTrieStorageManagerArgs { + return trie.NewTrieStorageManagerArgs{ + MainStorer: testscommon.CreateMemUnit(), + CheckpointsStorer: testscommon.CreateMemUnit(), + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + GeneralConfig: config.TrieStorageManagerConfig{SnapshotsGoroutineNum: 1}, + CheckpointHashesHolder: hashesHolder.NewCheckpointHashesHolder(10, hashSize), + IdleProvider: &testscommon.ProcessStatusHandlerStub{}, + } +} + func createAccountsDB( coreComponents factory.CoreComponentsHolder, accountFactory state.AccountFactory, trieStorageManager common.StorageManager, ) *state.AccountsDB { tr, _ := trie.NewTrie(trieStorageManager, coreComponents.InternalMarshalizer(), coreComponents.Hasher(), 5) - ewl, _ := evictionWaitingList.NewEvictionWaitingList(10, testscommon.NewMemDbMock(), coreComponents.InternalMarshalizer()) - spm, _ := storagePruningManager.NewStoragePruningManager(ewl, 10) + argsEvictionWaitingList := evictionWaitingList.MemoryEvictionWaitingListArgs{ + RootHashesSize: 10, + HashesSize: hashSize, + } + ewl, _ := evictionWaitingList.NewMemoryEvictionWaitingList(argsEvictionWaitingList) + spm, _ := storagePruningManager.NewStoragePruningManager(ewl, 10) argsAccountsDb := state.ArgsAccountsDB{ Trie: tr, Hasher: coreComponents.Hasher(), @@ -155,6 +194,8 @@ func createAccountsDB( StoragePruningManager: spm, ProcessingMode: common.Normal, ProcessStatusHandler: coreComponents.ProcessStatusHandler(), + AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, + AddressConverter: coreComponents.AddressPubKeyConverter(), } adb, _ := state.NewAccountsDB(argsAccountsDb) return adb diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 716d83a2f9c..2e8f0c486c8 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -24,6 +24,10 @@ import ( "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/dblookupext" + factory2 "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/integrationtests" + "github.com/multiversx/mx-chain-go/testscommon/outport" + statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" ) func createMetaBlockProcessor( @@ -57,9 +61,10 @@ func createMetaBlockProcessor( accountsDb[state.UserAccountsState] = stateComponents.AccountsAdapter() accountsDb[state.PeerAccountsState] = stateComponents.PeerAccounts() + bootStrapStorer, _ := dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit) bootStorer, _ := bootstrapStorage.NewBootstrapStorer( coreComponents.InternalMarshalizer(), - dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), + bootStrapStorer, ) headerValidator := createHeaderValidator(coreComponents) @@ -68,10 +73,13 @@ func createMetaBlockProcessor( args := blproc.ArgMetaProcessor{ ArgBaseProcessor: blproc.ArgBaseProcessor{ - CoreComponents: coreComponents, - DataComponents: dataComponents, - BootstrapComponents: bootstrapComponents, - StatusComponents: statusComponents, + CoreComponents: coreComponents, + DataComponents: dataComponents, + BootstrapComponents: bootstrapComponents, + StatusComponents: statusComponents, + StatusCoreComponents: &factory2.StatusCoreComponentsStub{ + AppStatusHandlerField: &statusHandlerMock.AppStatusHandlerStub{}, + }, AccountsDB: accountsDb, ForkDetector: &integrationMocks.ForkDetectorStub{}, NodesCoordinator: nc, @@ -81,18 +89,19 @@ func createMetaBlockProcessor( TxCoordinator: txCoordinator, EpochStartTrigger: epochStartHandler, HeaderValidator: headerValidator, - GasHandler: &mock.GasHandlerMock{}, BootStorer: bootStorer, BlockTracker: blockTracker, BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, - EpochNotifier: coreComponents.EpochNotifier(), - RoundNotifier: &mock.RoundNotifierStub{}, - ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, - ScheduledMiniBlocksEnableEpoch: 10000, + EnableRoundsHandler: coreComponents.EnableRoundsHandler(), VMContainersFactory: metaVMFactory, VmContainer: vmContainer, + GasHandler: &mock.GasHandlerMock{}, + ScheduledTxsExecutionHandler: &testscommon.ScheduledTxsExecutionStub{}, + ScheduledMiniBlocksEnableEpoch: 10000, ProcessedMiniBlocksTracker: processedMb.NewProcessedMiniBlocksTracker(), + OutportDataProvider: &outport.OutportDataProviderStub{}, + ReceiptsRepository: &testscommon.ReceiptsRepositoryStub{}, }, SCToProtocol: stakingToPeer, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, @@ -117,12 +126,16 @@ func createValidatorInfoCreator( dataComponents factory.DataComponentsHolder, shardCoordinator sharding.Coordinator, ) process.EpochStartValidatorInfoCreator { + mbStorer, _ := dataComponents.StorageService().GetStorer(dataRetriever.MiniBlockUnit) + args := metachain.ArgsNewValidatorInfoCreator{ - ShardCoordinator: shardCoordinator, - MiniBlockStorage: dataComponents.StorageService().GetStorer(dataRetriever.MiniBlockUnit), - Hasher: coreComponents.Hasher(), - Marshalizer: coreComponents.InternalMarshalizer(), - DataPool: dataComponents.Datapool(), + ShardCoordinator: shardCoordinator, + MiniBlockStorage: mbStorer, + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + DataPool: dataComponents.Datapool(), + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + ValidatorInfoStorage: integrationtests.CreateMemUnit(), } valInfoCreator, _ := metachain.NewValidatorInfoCreator(args) @@ -137,15 +150,16 @@ func createEpochStartDataCreator( blockTracker process.BlockTracker, ) process.EpochStartDataCreator { argsEpochStartDataCreator := metachain.ArgsNewEpochStartData{ - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - Store: dataComponents.StorageService(), - DataPool: dataComponents.Datapool(), - BlockTracker: blockTracker, - ShardCoordinator: shardCoordinator, - EpochStartTrigger: epochStartTrigger, - RequestHandler: &testscommon.RequestHandlerStub{}, - GenesisEpoch: 0, + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + Store: dataComponents.StorageService(), + DataPool: dataComponents.Datapool(), + BlockTracker: blockTracker, + ShardCoordinator: shardCoordinator, + EpochStartTrigger: epochStartTrigger, + RequestHandler: &testscommon.RequestHandlerStub{}, + GenesisEpoch: 0, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), } epochStartDataCreator, _ := metachain.NewEpochStartData(argsEpochStartDataCreator) return epochStartDataCreator @@ -214,16 +228,15 @@ func createSCToProtocol( txCacher dataRetriever.TransactionCacher, ) process.SmartContractToProtocolHandler { args := scToProtocol.ArgStakingToPeer{ - PubkeyConv: coreComponents.AddressPubKeyConverter(), - Hasher: coreComponents.Hasher(), - Marshalizer: coreComponents.InternalMarshalizer(), - PeerState: stateComponents.PeerAccounts(), - BaseState: stateComponents.AccountsAdapter(), - ArgParser: smartContract.NewArgumentParser(), - CurrTxs: txCacher, - RatingsData: &mock.RatingsInfoMock{}, - EpochNotifier: coreComponents.EpochNotifier(), - StakingV4InitEpoch: stakingV4InitEpoch, + PubkeyConv: coreComponents.AddressPubKeyConverter(), + Hasher: coreComponents.Hasher(), + Marshalizer: coreComponents.InternalMarshalizer(), + PeerState: stateComponents.PeerAccounts(), + BaseState: stateComponents.AccountsAdapter(), + ArgParser: smartContract.NewArgumentParser(), + CurrTxs: txCacher, + RatingsData: &mock.RatingsInfoMock{}, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), } stakingToPeer, _ := scToProtocol.NewStakingToPeer(args) return stakingToPeer diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index b958af08085..8fa998ccb82 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -8,6 +8,7 @@ import ( "github.com/multiversx/mx-chain-core-go/storage/lrucache" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever/dataPool" "github.com/multiversx/mx-chain-go/factory" integrationMocks "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" @@ -47,9 +48,9 @@ func createNodesCoordinator( StakingV4EnableEpoch: stakingV4EnableEpoch, StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, }, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) - cache, _ := lrucache.NewCache(10000) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: shardConsensusGroupSize, @@ -71,11 +72,12 @@ func createNodesCoordinator( StakingV4EnableEpoch: stakingV4EnableEpoch, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, NodeTypeProvider: coreComponents.NodeTypeProvider(), + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + ValidatorInfoCacher: dataPool.NewCurrentEpochValidatorInfoPool(), } baseNodesCoordinator, _ := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) nodesCoord, _ := nodesCoordinator.NewIndexHashedNodesCoordinatorWithRater(baseNodesCoordinator, coreComponents.Rater()) - return nodesCoord } diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 476f487cebf..c75457316b7 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -18,6 +18,7 @@ import ( "github.com/multiversx/mx-chain-go/process/peer" "github.com/multiversx/mx-chain-go/process/smartContract/builtInFunctions" "github.com/multiversx/mx-chain-go/process/smartContract/hooks" + "github.com/multiversx/mx-chain-go/process/smartContract/hooks/counters" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" @@ -55,28 +56,22 @@ func createSystemSCProcessor( auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) args := metachain.ArgsNewEpochStartSystemSCProcessing{ - SystemVM: systemVM, - UserAccountsDB: stateComponents.AccountsAdapter(), - PeerAccountsDB: stateComponents.PeerAccounts(), - Marshalizer: coreComponents.InternalMarshalizer(), - StartRating: initialRating, - ValidatorInfoCreator: validatorStatisticsProcessor, - EndOfEpochCallerAddress: vm.EndOfEpochAddress, - StakingSCAddress: vm.StakingSCAddress, - ChanceComputer: &epochStartMock.ChanceComputerStub{}, - EpochNotifier: coreComponents.EpochNotifier(), - GenesisNodesConfig: &mock.NodesSetupStub{}, - StakingDataProvider: stakingDataProvider, - NodesConfigProvider: nc, - ShardCoordinator: shardCoordinator, - ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), - EpochConfig: config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, - MaxNodesChangeEnableEpoch: maxNodesConfig, - }, - }, + SystemVM: systemVM, + UserAccountsDB: stateComponents.AccountsAdapter(), + PeerAccountsDB: stateComponents.PeerAccounts(), + Marshalizer: coreComponents.InternalMarshalizer(), + StartRating: initialRating, + ValidatorInfoCreator: validatorStatisticsProcessor, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ChanceComputer: &epochStartMock.ChanceComputerStub{}, + EpochNotifier: coreComponents.EpochNotifier(), + GenesisNodesConfig: &mock.NodesSetupStub{}, + StakingDataProvider: stakingDataProvider, + NodesConfigProvider: nc, + ShardCoordinator: shardCoordinator, + ESDTOwnerAddressBytes: bytes.Repeat([]byte{1}, 32), + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, AuctionListSelector: auctionListSelector, } @@ -121,8 +116,7 @@ func createValidatorStatisticsProcessor( NodesSetup: &mock.NodesSetupStub{}, MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, - EpochNotifier: coreComponents.EpochNotifier(), - StakingV2EnableEpoch: 0, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), StakingV4EnableEpoch: stakingV4EnableEpoch, } validatorStatisticsProcessor, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) @@ -137,14 +131,20 @@ func createBlockChainHook( gasScheduleNotifier core.GasScheduleNotifier, ) process.BlockChainHookHandler { argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: gasScheduleNotifier, - MapDNSAddresses: make(map[string]struct{}), - Marshalizer: coreComponents.InternalMarshalizer(), - Accounts: accountsAdapter, - ShardCoordinator: shardCoordinator, - EpochNotifier: coreComponents.EpochNotifier(), + GasSchedule: gasScheduleNotifier, + MapDNSAddresses: make(map[string]struct{}), + Marshalizer: coreComponents.InternalMarshalizer(), + Accounts: accountsAdapter, + ShardCoordinator: shardCoordinator, + EpochNotifier: coreComponents.EpochNotifier(), + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + AutomaticCrawlerAddresses: [][]byte{core.SystemAccountAddress}, + MaxNumNodesInTransferRole: 1, } - builtInFunctionsContainer, _, _, _ := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) + + builtInFunctionsContainer, _ := builtInFunctions.CreateBuiltInFunctionsFactory(argsBuiltIn) + _ = builtInFunctionsContainer.CreateBuiltInFunctionContainer() + builtInFunctionsContainer.BuiltInFunctionContainer() argsHook := hooks.ArgBlockChainHook{ Accounts: accountsAdapter, @@ -155,15 +155,19 @@ func createBlockChainHook( Marshalizer: coreComponents.InternalMarshalizer(), Uint64Converter: coreComponents.Uint64ByteSliceConverter(), NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, - BuiltInFunctions: builtInFunctionsContainer, + BuiltInFunctions: builtInFunctionsContainer.BuiltInFunctionContainer(), DataPool: dataComponents.Datapool(), CompiledSCPool: dataComponents.Datapool().SmartContracts(), EpochNotifier: coreComponents.EpochNotifier(), GlobalSettingsHandler: &vmcommonMock.GlobalSettingsHandlerStub{}, NilCompiledSCStore: true, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + GasSchedule: gasScheduleNotifier, + Counter: counters.NewDisabledCounter(), } - blockChainHook, _ := hooks.NewBlockChainHookImpl(argsHook) + blockChainHook, err := hooks.NewBlockChainHookImpl(argsHook) + _ = err return blockChainHook } @@ -229,15 +233,9 @@ func createVMContainerFactory( }, ValidatorAccountsDB: peerAccounts, ChanceComputer: coreComponents.Rater(), - EpochNotifier: coreComponents.EpochNotifier(), - EpochConfig: &config.EpochConfig{ - EnableEpochs: config.EnableEpochs{ - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, - }, - }, - ShardCoordinator: shardCoordinator, - NodesCoordinator: nc, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + ShardCoordinator: shardCoordinator, + NodesCoordinator: nc, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 480e898f967..7a70a152d65 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -42,6 +42,7 @@ func NewTestMetaProcessor( stateComponents, ) + bootStrapStorer, _ := dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit) nc := createNodesCoordinator( eligibleMap, waitingMap, @@ -51,7 +52,7 @@ func NewTestMetaProcessor( shardConsensusGroupSize, metaConsensusGroupSize, coreComponents, - dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), + bootStrapStorer, bootstrapComponents.NodesCoordinatorRegistryFactory(), maxNodesConfig, ) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 1739fd7a328..80d0238b17b 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -56,6 +56,7 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr stateComponents, ) + bootstrapStorer, _ := dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit) nc := createNodesCoordinator( eligibleMap, waitingMap, @@ -65,7 +66,7 @@ func NewTestMetaProcessorWithCustomNodes(config *InitialNodesConfig) *TestMetaPr config.ShardConsensusGroupSize, config.MetaConsensusGroupSize, coreComponents, - dataComponents.StorageService().GetStorer(dataRetriever.BootstrapUnit), + bootstrapStorer, bootstrapComponents.NodesCoordinatorRegistryFactory(), config.MaxNodesChangeConfig, ) diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 7886af3650f..99e85a3c0da 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -3181,7 +3181,6 @@ func TestMetaProcessor_ProcessEpochStartMetaBlock(t *testing.T) { StakingV2EnableEpochField: 10, } arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) - arguments.RewardsV2EnableEpoch = 10 arguments.ValidatorStatisticsProcessor = &testscommon.ValidatorStatisticsProcessorStub{} wasCalled := false @@ -3346,8 +3345,6 @@ func TestMetaProcessor_CreateEpochStartBodyShouldFail(t *testing.T) { func TestMetaProcessor_CreateEpochStartBodyShouldWork(t *testing.T) { t.Parallel() - coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() - expectedValidatorsInfo := state.NewShardValidatorsInfoMap() _ = expectedValidatorsInfo.Add( &state.ValidatorInfo{ @@ -3585,8 +3582,7 @@ func TestMetaProcessor_getAllMarshalledTxs(t *testing.T) { t.Parallel() arguments := createMockMetaArguments(createMockComponentHolders()) - - arguments.EpochRewardsCreator = &mock.EpochRewardsCreatorStub{ + arguments.EpochRewardsCreator = &testscommon.RewardsCreatorStub{ CreateMarshalledDataCalled: func(body *block.Body) map[string][][]byte { marshalledData := make(map[string][][]byte) for _, miniBlock := range body.MiniBlocks { @@ -3599,7 +3595,7 @@ func TestMetaProcessor_getAllMarshalledTxs(t *testing.T) { }, } - arguments.EpochValidatorInfoCreator = &mock.EpochValidatorInfoCreatorStub{ + arguments.EpochValidatorInfoCreator = &testscommon.EpochValidatorInfoCreatorStub{ CreateMarshalledDataCalled: func(body *block.Body) map[string][][]byte { marshalledData := make(map[string][][]byte) for _, miniBlock := range body.MiniBlocks { diff --git a/process/mock/epochRewardsCreatorStub.go b/process/mock/epochRewardsCreatorStub.go deleted file mode 100644 index ce17c1e636a..00000000000 --- a/process/mock/epochRewardsCreatorStub.go +++ /dev/null @@ -1,109 +0,0 @@ -package mock - -import ( - "math/big" - - "github.com/multiversx/mx-chain-core-go/data" - "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-go/epochStart" - "github.com/multiversx/mx-chain-go/state" -) - -// EpochRewardsCreatorStub - -type EpochRewardsCreatorStub struct { - CreateRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) (block.MiniBlockSlice, error) - VerifyRewardsMiniBlocksCalled func( - metaBlock data.MetaHeaderHandler, validatorsInfo map[uint32][]*state.ValidatorInfo, computedEconomics *block.Economics, - ) error - CreateMarshalledDataCalled func(body *block.Body) map[string][][]byte - SaveBlockDataToStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - DeleteBlockDataFromStorageCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - RemoveBlockDataFromPoolsCalled func(metaBlock data.MetaHeaderHandler, body *block.Body) - GetRewardsTxsCalled func(body *block.Body) map[string]data.TransactionHandler - GetProtocolSustainCalled func() *big.Int - GetLocalTxCacheCalled func() epochStart.TransactionCacher -} - -// GetProtocolSustainabilityRewards - -func (e *EpochRewardsCreatorStub) GetProtocolSustainabilityRewards() *big.Int { - if e.GetProtocolSustainCalled != nil { - return e.GetProtocolSustainCalled() - } - return big.NewInt(0) -} - -// GetLocalTxCache - -func (e *EpochRewardsCreatorStub) GetLocalTxCache() epochStart.TransactionCacher { - if e.GetLocalTxCacheCalled != nil { - return e.GetLocalTxCacheCalled() - } - return &TxForCurrentBlockStub{} -} - -// CreateRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) CreateRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) (block.MiniBlockSlice, error) { - if e.CreateRewardsMiniBlocksCalled != nil { - return e.CreateRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil, nil -} - -// VerifyRewardsMiniBlocks - -func (e *EpochRewardsCreatorStub) VerifyRewardsMiniBlocks( - metaBlock data.MetaHeaderHandler, - validatorsInfo map[uint32][]*state.ValidatorInfo, - computedEconomics *block.Economics, -) error { - if e.VerifyRewardsMiniBlocksCalled != nil { - return e.VerifyRewardsMiniBlocksCalled(metaBlock, validatorsInfo, computedEconomics) - } - return nil -} - -// CreateMarshalledData - -func (e *EpochRewardsCreatorStub) CreateMarshalledData(body *block.Body) map[string][][]byte { - if e.CreateMarshalledDataCalled != nil { - return e.CreateMarshalledDataCalled(body) - } - return nil -} - -// GetRewardsTxs - -func (e *EpochRewardsCreatorStub) GetRewardsTxs(body *block.Body) map[string]data.TransactionHandler { - if e.GetRewardsTxsCalled != nil { - return e.GetRewardsTxsCalled(body) - } - return nil -} - -// SaveBlockDataToStorage - -func (e *EpochRewardsCreatorStub) SaveBlockDataToStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.SaveBlockDataToStorageCalled != nil { - e.SaveBlockDataToStorageCalled(metaBlock, body) - } -} - -// DeleteBlockDataFromStorage - -func (e *EpochRewardsCreatorStub) DeleteBlockDataFromStorage(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.DeleteBlockDataFromStorageCalled != nil { - e.DeleteBlockDataFromStorageCalled(metaBlock, body) - } -} - -// IsInterfaceNil - -func (e *EpochRewardsCreatorStub) IsInterfaceNil() bool { - return e == nil -} - -// RemoveBlockDataFromPools - -func (e *EpochRewardsCreatorStub) RemoveBlockDataFromPools(metaBlock data.MetaHeaderHandler, body *block.Body) { - if e.RemoveBlockDataFromPoolsCalled != nil { - e.RemoveBlockDataFromPoolsCalled(metaBlock, body) - } -} diff --git a/update/genesis/export.go b/update/genesis/export.go index 45629ef2d73..7d5a09df1c5 100644 --- a/update/genesis/export.go +++ b/update/genesis/export.go @@ -303,7 +303,7 @@ func (se *stateExport) exportTrie(key string, trie common.Trie) error { } if accType == ValidatorAccount { - validatorData, err := getValidatorDataFromLeaves(leavesChannel, se.marshalizer) + validatorData, err := getValidatorDataFromLeaves(leavesChannels, se.marshalizer) if err != nil { return err } From 195bd7b8ba6e3d9e151a6ce3adba4b3a7bd0cad1 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 10:53:55 +0200 Subject: [PATCH 374/958] FIX: stakingDataProvider.go --- epochStart/metachain/stakingDataProvider.go | 41 +++++-------------- .../metachain/stakingDataProvider_test.go | 27 ++++++------ epochStart/metachain/systemSCs_test.go | 7 ++-- factory/processing/blockProcessorCreator.go | 8 ++-- integrationTests/testProcessorNode.go | 8 ++-- .../vm/staking/baseTestMetaProcessor.go | 2 +- .../vm/staking/systemSCCreator.go | 11 +++-- 7 files changed, 37 insertions(+), 67 deletions(-) diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 4f415cc2193..ab3c5871183 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -7,11 +7,9 @@ import ( "math/big" "sync" - "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/epochStart" - "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -47,19 +45,14 @@ type stakingDataProvider struct { totalEligibleTopUpStake *big.Int minNodePrice *big.Int numOfValidatorsInCurrEpoch uint32 - stakingV4EnableEpoch uint32 - flagStakingV4Enable atomic.Flag - stakingV4InitEpoch uint32 - flagStakingV4Initialized atomic.Flag + enableEpochsHandler common.EnableEpochsHandler } // StakingDataProviderArgs is a struct placeholder for all arguments required to create a NewStakingDataProvider type StakingDataProviderArgs struct { - EpochNotifier process.EpochNotifier - SystemVM vmcommon.VMExecutionHandler - MinNodePrice string - StakingV4InitEnableEpoch uint32 - StakingV4EnableEpoch uint32 + EnableEpochsHandler common.EnableEpochsHandler + SystemVM vmcommon.VMExecutionHandler + MinNodePrice string } // NewStakingDataProvider will create a new instance of a staking data provider able to aid in the final rewards @@ -68,8 +61,8 @@ func NewStakingDataProvider(args StakingDataProviderArgs) (*stakingDataProvider, if check.IfNil(args.SystemVM) { return nil, epochStart.ErrNilSystemVmInstance } - if check.IfNil(args.EpochNotifier) { - return nil, epochStart.ErrNilEpochStartNotifier + if check.IfNil(args.EnableEpochsHandler) { + return nil, epochStart.ErrNilEnableEpochsHandler } nodePrice, ok := big.NewInt(0).SetString(args.MinNodePrice, 10) @@ -83,13 +76,8 @@ func NewStakingDataProvider(args StakingDataProviderArgs) (*stakingDataProvider, minNodePrice: nodePrice, totalEligibleStake: big.NewInt(0), totalEligibleTopUpStake: big.NewInt(0), - stakingV4EnableEpoch: args.StakingV4EnableEpoch, - stakingV4InitEpoch: args.StakingV4InitEnableEpoch, + enableEpochsHandler: args.EnableEpochsHandler, } - log.Debug("stakingDataProvider: enable epoch for staking v4 init", "epoch", sdp.stakingV4InitEpoch) - log.Debug("stakingDataProvider: enable epoch for staking v4", "epoch", sdp.stakingV4EnableEpoch) - - args.EpochNotifier.RegisterNotifyHandler(sdp) return sdp, nil } @@ -363,7 +351,7 @@ func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( hex.EncodeToString(validator.GetPublicKey()), ) } - if !sdp.flagStakingV4Initialized.IsSet() { + if !sdp.enableEpochsHandler.IsStakingV4Started() { return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4, hex.EncodeToString(ownerPubKey), @@ -459,7 +447,7 @@ func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.Shard list := validator.GetList() pubKey := validator.GetPublicKey() - if sdp.flagStakingV4Enable.IsSet() && list == string(common.NewList) { + if sdp.enableEpochsHandler.IsStakingV4Enabled() && list == string(common.NewList) { return nil, fmt.Errorf("%w, bls key = %s", epochStart.ErrReceivedNewListNodeInStakingV4, hex.EncodeToString(pubKey), @@ -529,7 +517,7 @@ func (sdp *stakingDataProvider) arrangeBlsKeysByStatus(mapBlsKeyStatus map[strin func (sdp *stakingDataProvider) getNewNodesList() string { newNodesList := string(common.NewList) - if sdp.flagStakingV4Enable.IsSet() { + if sdp.enableEpochsHandler.IsStakingV4Enabled() { newNodesList = string(common.AuctionList) } @@ -544,15 +532,6 @@ func (sdp *stakingDataProvider) GetNumOfValidatorsInCurrentEpoch() uint32 { return sdp.numOfValidatorsInCurrEpoch } -// EpochConfirmed is called whenever a new epoch is confirmed -func (sdp *stakingDataProvider) EpochConfirmed(epoch uint32, _ uint64) { - sdp.flagStakingV4Enable.SetValue(epoch >= sdp.stakingV4EnableEpoch) - log.Debug("stakingDataProvider: staking v4 enable epoch", "enabled", sdp.flagStakingV4Enable.IsSet()) - - sdp.flagStakingV4Initialized.SetValue(epoch >= sdp.stakingV4InitEpoch) - log.Debug("stakingDataProvider: staking v4 initialized", "enabled", sdp.flagStakingV4Initialized.IsSet()) -} - // IsInterfaceNil return true if underlying object is nil func (sdp *stakingDataProvider) IsInterfaceNil() bool { return sdp == nil diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 1e97848e061..cf37607adf5 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -17,7 +17,6 @@ import ( "github.com/multiversx/mx-chain-go/epochStart/mock" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" - "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" @@ -29,11 +28,9 @@ const stakingV4EnableEpoch = 445 func createStakingDataProviderArgs() StakingDataProviderArgs { return StakingDataProviderArgs{ - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - SystemVM: &mock.VMExecutionHandlerStub{}, - MinNodePrice: "2500", - StakingV4InitEnableEpoch: stakingV4EInitEnableEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + SystemVM: &mock.VMExecutionHandlerStub{}, + MinNodePrice: "2500", } } @@ -50,10 +47,10 @@ func TestNewStakingDataProvider_NilInputPointersShouldErr(t *testing.T) { t.Run("nil epoch notifier", func(t *testing.T) { args := createStakingDataProviderArgs() - args.EpochNotifier = nil + args.EnableEpochsHandler = nil sdp, err := NewStakingDataProvider(args) assert.True(t, check.IfNil(sdp)) - assert.Equal(t, epochStart.ErrNilEpochStartNotifier, err) + assert.Equal(t, vm.ErrNilEnableEpochsHandler, err) }) t.Run("should work", func(t *testing.T) { @@ -274,7 +271,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4ReceivedNewList _ = valInfo.Add(v2) sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) require.Error(t, err) @@ -337,7 +334,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithS _ = valInfo.Add(v1) sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} sdp.cache[owner].blsKeys = append(sdp.cache[owner].blsKeys, []byte("newKey")) sdp.cache[owner].totalStaked = big.NewInt(2500) @@ -531,7 +528,7 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.EpochConfirmed(stakingV4EInitEnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4StartedField: true} owner := []byte("owner") ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3} @@ -554,7 +551,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -568,7 +565,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -584,7 +581,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -600,7 +597,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.EpochConfirmed(stakingV4EnableEpoch, 0) + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 7e9fac8bbc8..8035e85ddbd 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -862,10 +862,9 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp systemVM, _ := vmContainer.Get(vmFactory.SystemVirtualMachine) argsStakingDataProvider := StakingDataProviderArgs{ - EpochNotifier: en, - SystemVM: systemVM, - MinNodePrice: "1000", - StakingV4EnableEpoch: stakingV4EnableEpoch, + EnableEpochsHandler: enableEpochsHandler, + SystemVM: systemVM, + MinNodePrice: "1000", } stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index cb65af914c5..ba09d6b8ec4 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -736,11 +736,9 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( } argsStakingDataProvider := metachainEpochStart.StakingDataProviderArgs{ - EpochNotifier: pcf.coreData.EpochNotifier(), - SystemVM: systemVM, - MinNodePrice: pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, - StakingV4InitEnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4InitEnableEpoch, - StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, + EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), + SystemVM: systemVM, + MinNodePrice: pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, } // TODO: in case of changing the minimum node price, make sure to update the staking data provider diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index bf50c4b9d7c..2afd6868aec 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2110,11 +2110,9 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { } argsStakingDataProvider := metachain.StakingDataProviderArgs{ - EpochNotifier: coreComponents.EpochNotifier(), - SystemVM: systemVM, - MinNodePrice: "1000", - StakingV4InitEnableEpoch: StakingV4InitEpoch, - StakingV4EnableEpoch: StakingV4Epoch, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + SystemVM: systemVM, + MinNodePrice: "1000", } stakingDataProvider, errRsp := metachain.NewStakingDataProvider(argsStakingDataProvider) if errRsp != nil { diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 9bec4e5ac4f..c9ff341edcf 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -125,7 +125,7 @@ func newTestMetaProcessor( stateComponents.PeerAccounts(), ) stakingDataProvider := createStakingDataProvider( - coreComponents.EpochNotifier(), + coreComponents.EnableEpochsHandler(), systemVM, ) scp := createSystemSCProcessor( diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index c75457316b7..3c346d16858 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/metachain" @@ -81,15 +82,13 @@ func createSystemSCProcessor( } func createStakingDataProvider( - epochNotifier process.EpochNotifier, + enableEpochsHandler common.EnableEpochsHandler, systemVM vmcommon.VMExecutionHandler, ) epochStart.StakingDataProvider { argsStakingDataProvider := metachain.StakingDataProviderArgs{ - EpochNotifier: epochNotifier, - SystemVM: systemVM, - MinNodePrice: strconv.Itoa(nodePrice), - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + EnableEpochsHandler: enableEpochsHandler, + SystemVM: systemVM, + MinNodePrice: strconv.Itoa(nodePrice), } stakingSCProvider, _ := metachain.NewStakingDataProvider(argsStakingDataProvider) From b71b6f5715f4d929d7cd702b6d00973ec307d8f8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 11:11:06 +0200 Subject: [PATCH 375/958] FIX: One stakingV4 integration test --- factory/processing/processComponents.go | 1 - integrationTests/testProcessorNode.go | 1 - .../vm/staking/systemSCCreator.go | 1 - process/peer/process.go | 13 +------------ process/peer/process_test.go | 19 +++++++++++++++++-- testscommon/enableEpochsHandlerStub.go | 5 +++++ 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 2759f55b6a7..8762d6fe86d 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -738,7 +738,6 @@ func (pcf *processComponentsFactory) newValidatorStatisticsProcessor() (process. RatingEnableEpoch: ratingEnabledEpoch, GenesisNonce: pcf.data.Blockchain().GetGenesisHeader().GetNonce(), EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), - StakingV4EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV4EnableEpoch, } validatorStatisticsProcessor, err := peer.NewValidatorStatisticsProcessor(arguments) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 2afd6868aec..ee9f8b893d7 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -593,7 +593,6 @@ func (tpn *TestProcessorNode) initValidatorStatistics() { NodesSetup: tpn.NodesSetup, GenesisNonce: tpn.BlockChain.GetGenesisHeader().GetNonce(), EnableEpochsHandler: tpn.EnableEpochsHandler, - StakingV4EnableEpoch: StakingV4Epoch, } tpn.ValidatorStatisticsProcessor, _ = peer.NewValidatorStatisticsProcessor(arguments) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 3c346d16858..0e3d1920b7e 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -116,7 +116,6 @@ func createValidatorStatisticsProcessor( MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, EnableEpochsHandler: coreComponents.EnableEpochsHandler(), - StakingV4EnableEpoch: stakingV4EnableEpoch, } validatorStatisticsProcessor, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) return validatorStatisticsProcessor diff --git a/process/peer/process.go b/process/peer/process.go index 9c4ad438a00..63317ca5397 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -9,7 +9,6 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" @@ -55,7 +54,6 @@ type ArgValidatorStatisticsProcessor struct { GenesisNonce uint64 RatingEnableEpoch uint32 EnableEpochsHandler common.EnableEpochsHandler - StakingV4EnableEpoch uint32 } type validatorStatistics struct { @@ -76,8 +74,6 @@ type validatorStatistics struct { ratingEnableEpoch uint32 lastFinalizedRootHash []byte enableEpochsHandler common.EnableEpochsHandler - flagStakingV4 atomic.Flag - stakingV4EnableEpoch uint32 } // NewValidatorStatisticsProcessor instantiates a new validatorStatistics structure responsible for keeping account of @@ -138,7 +134,6 @@ func NewValidatorStatisticsProcessor(arguments ArgValidatorStatisticsProcessor) maxConsecutiveRoundsOfRatingDecrease: arguments.MaxConsecutiveRoundsOfRatingDecrease, genesisNonce: arguments.GenesisNonce, enableEpochsHandler: arguments.EnableEpochsHandler, - stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, } err := vs.saveInitialState(arguments.NodesSetup) @@ -188,7 +183,7 @@ func (vs *validatorStatistics) saveNodesCoordinatorUpdates(epoch uint32) (bool, } nodeForcedToRemain = nodeForcedToRemain || tmpNodeForcedToRemain - if vs.flagStakingV4.IsSet() { + if vs.enableEpochsHandler.IsStakingV4Enabled() { nodesMap, err = vs.nodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) if err != nil { return false, err @@ -1244,9 +1239,3 @@ func (vs *validatorStatistics) LastFinalizedRootHash() []byte { defer vs.mutValidatorStatistics.RUnlock() return vs.lastFinalizedRootHash } - -// EpochConfirmed is called whenever a new epoch is confirmed -func (vs *validatorStatistics) EpochConfirmed(epoch uint32, _ uint64) { - vs.flagStakingV4.SetValue(epoch >= vs.stakingV4EnableEpoch) - log.Debug("validatorStatistics: staking v4", "enabled", vs.flagStakingV4.IsSet()) -} diff --git a/process/peer/process_test.go b/process/peer/process_test.go index a5ef0e75322..a6cdf86b48e 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -123,7 +123,6 @@ func createMockArguments() peer.ArgValidatorStatisticsProcessor { IsSwitchJailWaitingFlagEnabledField: true, IsBelowSignedThresholdFlagEnabledField: true, }, - StakingV4EnableEpoch: 444, } return arguments } @@ -2698,6 +2697,22 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t return mapNodes, nil }, } + stakingV4EnableEpochCalledCt := 0 + arguments.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ + IsStakingV4EnabledCalled: func() bool { + stakingV4EnableEpochCalledCt++ + switch stakingV4EnableEpochCalledCt { + case 1: + return false + case 2: + return true + default: + require.Fail(t, "should only call this twice") + } + + return false + }, + } validatorStatistics, _ := peer.NewValidatorStatisticsProcessor(arguments) nodeForcedToRemain, err := validatorStatistics.SaveNodesCoordinatorUpdates(0) @@ -2708,7 +2723,7 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t ctSaveAccount.Reset() ctLoadAccount.Reset() - validatorStatistics.EpochConfirmed(arguments.StakingV4EnableEpoch, 0) + nodeForcedToRemain, err = validatorStatistics.SaveNodesCoordinatorUpdates(0) require.Nil(t, err) require.False(t, nodeForcedToRemain) diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index c94b4f53b18..6a7bd365300 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -126,6 +126,7 @@ type EnableEpochsHandlerStub struct { IsStakingQueueEnabledField bool IsLiquidStakingEnabledField bool IsStakingV4StartedField bool + IsStakingV4EnabledCalled func() bool } // ResetPenalizedTooMuchGasFlag - @@ -1028,6 +1029,10 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Enabled() bool { stub.RLock() defer stub.RUnlock() + if stub.IsStakingV4EnabledCalled != nil { + return stub.IsStakingV4EnabledCalled() + } + return stub.IsStakingV4FlagEnabledField } From fd32e9bc12696c74d6e12f84e50d32327396162a Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 12:29:55 +0200 Subject: [PATCH 376/958] FIX: StakingV4 integration tests --- epochStart/metachain/systemSCs_test.go | 1 - integrationTests/vm/txsFee/validatorSC_test.go | 3 +-- process/scToProtocol/stakingToPeer.go | 2 +- testscommon/transactionCoordinatorMock.go | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 8035e85ddbd..4e40e84957c 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -764,7 +764,6 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, EnableEpochsHandler: enableEpochsHandler, - StakingV4EnableEpoch: 444, } vCreator, _ := peer.NewValidatorStatisticsProcessor(argsValidatorsProcessor) diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index 4d7e0b495a5..dee87416715 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -10,16 +10,15 @@ import ( "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" "github.com/multiversx/mx-chain-core-go/data/transaction" - "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/process/smartContract/hooks" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" vmAddr "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" vmcommon "github.com/multiversx/mx-chain-vm-common-go" - "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/stretchr/testify/require" ) diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index dbfa78924fa..4cff2ab4794 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -323,7 +323,7 @@ func (stp *stakingToPeer) updatePeerState( } newNodesList := common.NewList - if stp.enableEpochsHandler.IsStakingV4Enabled() { + if stp.enableEpochsHandler.IsStakingV4Started() { newNodesList = common.AuctionList } diff --git a/testscommon/transactionCoordinatorMock.go b/testscommon/transactionCoordinatorMock.go index 26e79df8907..d6b4db9b64b 100644 --- a/testscommon/transactionCoordinatorMock.go +++ b/testscommon/transactionCoordinatorMock.go @@ -235,7 +235,7 @@ func (tcm *TransactionCoordinatorMock) GetAllIntermediateTxs() map[block.Type]ma // AddTxsFromMiniBlocks - func (tcm *TransactionCoordinatorMock) AddTxsFromMiniBlocks(miniBlocks block.MiniBlockSlice) { if tcm.AddTxsFromMiniBlocksCalled == nil { - tcm.miniBlocks = miniBlocks + tcm.miniBlocks = append(tcm.miniBlocks, miniBlocks...) return } From 5dd2f1e9e3cf0ba46a261322a16885433274c89b Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 13:48:44 +0200 Subject: [PATCH 377/958] FIX: Bootstrap factory package --- .../config/gasSchedules/gasScheduleV7.toml | 1 + factory/processing/processComponents.go | 53 ++++++++++--------- integrationTests/consensus/testInitializer.go | 0 testscommon/components/components.go | 9 ++-- 4 files changed, 34 insertions(+), 29 deletions(-) delete mode 100644 integrationTests/consensus/testInitializer.go diff --git a/cmd/node/config/gasSchedules/gasScheduleV7.toml b/cmd/node/config/gasSchedules/gasScheduleV7.toml index 938e2f50f7a..7da5320e5b3 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV7.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV7.toml @@ -40,6 +40,7 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 + LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 8762d6fe86d..08bb83cf453 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -358,32 +358,6 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { return nil, err } - startEpochNum := pcf.bootstrapComponents.EpochBootstrapParams().Epoch() - if startEpochNum == 0 { - err = pcf.indexGenesisBlocks(genesisBlocks, initialTxs, genesisAccounts) - if err != nil { - return nil, err - } - } - - cacheRefreshDuration := time.Duration(pcf.config.ValidatorStatistics.CacheRefreshIntervalInSec) * time.Second - argVSP := peer.ArgValidatorsProvider{ - NodesCoordinator: pcf.nodesCoordinator, - StartEpoch: startEpochNum, - EpochStartEventNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), - CacheRefreshIntervalDurationInSec: cacheRefreshDuration, - ValidatorStatistics: validatorStatisticsProcessor, - MaxRating: pcf.maxRating, - ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), - AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), - AuctionListSelector: pcf.auctionListSelectorAPI, - } - - validatorsProvider, err := peer.NewValidatorsProvider(argVSP) - if err != nil { - return nil, err - } - epochStartTrigger, err := pcf.newEpochStartTrigger(requestHandler) if err != nil { return nil, err @@ -602,6 +576,33 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { return nil, err } + startEpochNum := pcf.bootstrapComponents.EpochBootstrapParams().Epoch() + if startEpochNum == 0 { + err = pcf.indexGenesisBlocks(genesisBlocks, initialTxs, genesisAccounts) + if err != nil { + return nil, err + } + } + + cacheRefreshDuration := time.Duration(pcf.config.ValidatorStatistics.CacheRefreshIntervalInSec) * time.Second + argVSP := peer.ArgValidatorsProvider{ + NodesCoordinator: pcf.nodesCoordinator, + StartEpoch: startEpochNum, + EpochStartEventNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), + CacheRefreshIntervalDurationInSec: cacheRefreshDuration, + ValidatorStatistics: validatorStatisticsProcessor, + MaxRating: pcf.maxRating, + ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), + AuctionListSelector: pcf.auctionListSelectorAPI, + StakingDataProvider: pcf.stakingDataProviderAPI, + } + + validatorsProvider, err := peer.NewValidatorsProvider(argVSP) + if err != nil { + return nil, err + } + conversionBase := 10 genesisNodePrice, ok := big.NewInt(0).SetString(pcf.systemSCConfig.StakingSystemSCConfig.GenesisNodePrice, conversionBase) if !ok { diff --git a/integrationTests/consensus/testInitializer.go b/integrationTests/consensus/testInitializer.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/testscommon/components/components.go b/testscommon/components/components.go index 1afe538b5b6..cb5dcc51e4b 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -522,8 +522,9 @@ func GetProcessArgs( ImportStartHandler: &testscommon.ImportStartHandlerStub{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ @@ -553,6 +554,8 @@ func GetProcessArgs( MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + StakeLimitPercentage: 100, + NodeLimitPercentage: 100, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -810,7 +813,7 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value gasMap["FixWaitingListSize"] = value - + gasMap["LiquidStakingOps"] = value return gasMap } From 2de1184b53dfc29e6749011dd6eb377cd0d0c519 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 15:18:14 +0200 Subject: [PATCH 378/958] FIX: bootStrap tests --- api/mock/facadeStub.go | 10 +++++----- epochStart/bootstrap/process_test.go | 4 +++- epochStart/bootstrap/syncValidatorStatus.go | 1 + epochStart/metachain/auctionListSelector_test.go | 2 +- node/mock/peerProcessorMock.go | 0 5 files changed, 10 insertions(+), 7 deletions(-) delete mode 100644 node/mock/peerProcessorMock.go diff --git a/api/mock/facadeStub.go b/api/mock/facadeStub.go index 4538a7a7e83..4a05179666e 100644 --- a/api/mock/facadeStub.go +++ b/api/mock/facadeStub.go @@ -187,7 +187,7 @@ func (f *FacadeStub) GetBalance(address string, options api.AccountQueryOptions) return f.GetBalanceCalled(address, options) } - return nil, nil + return nil, api.BlockInfo{}, nil } // GetValueForKey is the mock implementation of a handler's GetValueForKey method @@ -263,12 +263,12 @@ func (f *FacadeStub) GetAllIssuedESDTs(tokenType string) ([]string, error) { } // GetAccount - -func (f *FacadeStub) GetAccount(address string) (api.AccountResponse, error) { - if f.GetAccountHandler != nil { - return f.GetAccountHandler(address) +func (f *FacadeStub) GetAccount(address string, options api.AccountQueryOptions) (api.AccountResponse, api.BlockInfo, error) { + if f.GetAccountCalled != nil { + return f.GetAccountCalled(address, options) } - return api.AccountResponse{}, nil + return api.AccountResponse{}, api.BlockInfo{}, nil } // GetAccounts - diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index c5717c54096..61f074515c5 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -77,7 +77,9 @@ func createComponentsForEpochStart() (*mock.CoreComponentsMock, *mock.CryptoComp NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, ProcessStatusHandlerInstance: &testscommon.ProcessStatusHandlerStub{}, HardforkTriggerPubKeyField: []byte("provided hardfork pub key"), - EnableEpochsHandlerField: &testscommon.EnableEpochsHandlerStub{}, + EnableEpochsHandlerField: &testscommon.EnableEpochsHandlerStub{ + StakingV4EnableEpochField: 99999, + }, }, &mock.CryptoComponentsMock{ PubKey: &cryptoMocks.PublicKeyStub{}, diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index 2acef8ac709..8a0c307b901 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -132,6 +132,7 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat EnableEpochsHandler: args.EnableEpochsHandler, ValidatorInfoCacher: s.dataPool.CurrentEpochValidatorInfo(), NodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, + StakingV4EnableEpoch: args.EnableEpochsHandler.StakingV4EnableEpoch(), } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 23ac04ee6db..d5b8dc55435 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -48,7 +48,7 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) - epochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ + argsSystemSC.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: stakingV4EnableEpoch, }) argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider diff --git a/node/mock/peerProcessorMock.go b/node/mock/peerProcessorMock.go deleted file mode 100644 index e69de29bb2d..00000000000 From b307c0d4240b6d11b532fc03b5785f85088872bb Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 15:20:37 +0200 Subject: [PATCH 379/958] FIX: Node --- node/mock/validatorsProviderStub.go | 0 node/node_test.go | 1 + 2 files changed, 1 insertion(+) delete mode 100644 node/mock/validatorsProviderStub.go diff --git a/node/mock/validatorsProviderStub.go b/node/mock/validatorsProviderStub.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/node/node_test.go b/node/node_test.go index 4cd7b963c43..b918e2b49e0 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -51,6 +51,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/testscommon/storage" From b327be2f89e34d1b1afe4de73939955a97d9373e Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 18 Jan 2023 15:51:49 +0200 Subject: [PATCH 380/958] FIX: heartbeatComponents_test.go --- factory/bootstrap/bootstrapComponents_test.go | 2 +- .../factory/heartbeatComponents/heartbeatComponents_test.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/factory/bootstrap/bootstrapComponents_test.go b/factory/bootstrap/bootstrapComponents_test.go index 30bf26a3220..ba72b7b4feb 100644 --- a/factory/bootstrap/bootstrapComponents_test.go +++ b/factory/bootstrap/bootstrapComponents_test.go @@ -131,7 +131,7 @@ func TestBootstrapComponentsFactory_CreateEpochStartBootstrapCreationFail(t *tes args.CoreComponents = coreComponents bcf, err := bootstrap.NewBootstrapComponentsFactory(args) - _ = err + require.Nil(t, err) coreComponents.RatingHandler = nil bc, err := bcf.Create() diff --git a/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go b/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go index 734387245b5..26c457375d4 100644 --- a/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go +++ b/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go @@ -68,6 +68,8 @@ func TestHeartbeatComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.NodeTypeProvider(), managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), + managedBootstrapComponents.NodesCoordinatorRegistryFactory(), + configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( From fed325e718687a4faa14c8d49ce6e42113246ca4 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 19 Jan 2023 10:49:53 +0200 Subject: [PATCH 381/958] FIX: Tests --- facade/mock/nodeStub.go | 8 ++++---- process/scToProtocol/stakingToPeer_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/facade/mock/nodeStub.go b/facade/mock/nodeStub.go index 3208efb010e..ae05956aff9 100644 --- a/facade/mock/nodeStub.go +++ b/facade/mock/nodeStub.go @@ -128,11 +128,11 @@ func (ns *NodeStub) DecodeAddressPubkey(pk string) ([]byte, error) { // GetBalance - func (ns *NodeStub) GetBalance(address string, options api.AccountQueryOptions) (*big.Int, api.BlockInfo, error) { - if ns.GetBalanceHandler != nil { + if ns.GetBalanceCalled != nil { return ns.GetBalanceCalled(address, options) } - return nil, nil + return nil, api.BlockInfo{}, nil } // CreateTransaction - @@ -171,11 +171,11 @@ func (ns *NodeStub) SendBulkTransactions(txs []*transaction.Transaction) (uint64 // GetAccount - func (ns *NodeStub) GetAccount(address string, options api.AccountQueryOptions) (api.AccountResponse, api.BlockInfo, error) { - if ns.GetAccountHandler != nil { + if ns.GetAccountCalled != nil { return ns.GetAccountCalled(address, options) } - return api.AccountResponse{}, nil + return api.AccountResponse{}, api.BlockInfo{}, nil } // GetCode - diff --git a/process/scToProtocol/stakingToPeer_test.go b/process/scToProtocol/stakingToPeer_test.go index 44b3d5efdc6..7355788289d 100644 --- a/process/scToProtocol/stakingToPeer_test.go +++ b/process/scToProtocol/stakingToPeer_test.go @@ -688,13 +688,13 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.NewList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4FlagEnabledField = true + enableEpochsHandler.IsStakingV4StartedField = true err = stp.updatePeerState(stakingData, blsPubKey, nonce) assert.NoError(t, err) assert.True(t, bytes.Equal(blsPubKey, peerAccount.GetBLSPublicKey())) assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4FlagEnabledField = false + enableEpochsHandler.IsStakingV4StartedField = false stakingData.UnStakedNonce = 11 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) @@ -714,11 +714,11 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.Equal(t, string(common.NewList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4FlagEnabledField = true + enableEpochsHandler.IsStakingV4StartedField = true err = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.NoError(t, err) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4FlagEnabledField = false + enableEpochsHandler.IsStakingV4StartedField = false stakingData.UnStakedNonce = 15 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) From 8472d0b44a7df6bef4a0046c17889d7d20c7f4d8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 19 Jan 2023 11:54:06 +0200 Subject: [PATCH 382/958] FIX: Tests --- api/groups/validatorGroup.go | 2 +- common/statistics/resourceMonitor_test.go | 2 +- .../bootstrap/syncValidatorStatus_test.go | 14 +++---- integrationTests/nodesCoordinatorFactory.go | 4 +- .../testProcessorNodeWithMultisigner.go | 38 ++++++++--------- .../vm/staking/componentsHolderCreator.go | 2 +- process/peer/validatorsProvider.go | 2 +- .../hashValidatorShuffler_test.go | 4 +- sharding/nodesCoordinator/shardingArgs.go | 42 +++++++++---------- .../memoryEvictionWaitingList.go | 2 +- .../shardingMocks/nodesCoordinatorMock.go | 30 ++++++------- vm/factory/systemSCFactory_test.go | 2 +- 12 files changed, 72 insertions(+), 72 deletions(-) diff --git a/api/groups/validatorGroup.go b/api/groups/validatorGroup.go index 5d588a7e08a..1a608d319eb 100644 --- a/api/groups/validatorGroup.go +++ b/api/groups/validatorGroup.go @@ -9,8 +9,8 @@ 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/common" + "github.com/multiversx/mx-chain-go/state" ) const ( diff --git a/common/statistics/resourceMonitor_test.go b/common/statistics/resourceMonitor_test.go index c9614d5dca4..738a53275d6 100644 --- a/common/statistics/resourceMonitor_test.go +++ b/common/statistics/resourceMonitor_test.go @@ -5,10 +5,10 @@ import ( "fmt" "testing" - logger "github.com/multiversx/mx-chain-logger-go" stats "github.com/multiversx/mx-chain-go/common/statistics" "github.com/multiversx/mx-chain-go/common/statistics/disabled" "github.com/multiversx/mx-chain-go/config" + logger "github.com/multiversx/mx-chain-logger-go" "github.com/stretchr/testify/assert" ) diff --git a/epochStart/bootstrap/syncValidatorStatus_test.go b/epochStart/bootstrap/syncValidatorStatus_test.go index e0f94704cc7..488dbe84aeb 100644 --- a/epochStart/bootstrap/syncValidatorStatus_test.go +++ b/epochStart/bootstrap/syncValidatorStatus_test.go @@ -305,13 +305,13 @@ func getSyncValidatorStatusArgs() ArgsNewSyncValidatorStatus { return 2 }, }, - NodeShuffler: &shardingMocks.NodeShufflerMock{}, - PubKey: []byte("public key"), - ShardIdAsObserver: 0, - ChanNodeStop: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + NodeShuffler: &shardingMocks.NodeShufflerMock{}, + PubKey: []byte("public key"), + ShardIdAsObserver: 0, + ChanNodeStop: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } } diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 8244e26a03f..e56159cf600 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -78,7 +78,7 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ RefactorPeersMiniBlocksEnableEpochField: UnreachableEpoch, }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, StakingV4EnableEpoch: StakingV4Epoch, } @@ -143,7 +143,7 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato IsWaitingListFixFlagEnabledField: true, RefactorPeersMiniBlocksEnableEpochField: UnreachableEpoch, }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index e83884f24d8..fd5b6283eb6 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -537,25 +537,25 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( bootStorer := CreateMemUnit() lruCache, _ := cache.NewLRUCache(10000) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardId, - NbShards: uint32(nbShards), - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: waitingMapForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: lruCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardId, + NbShards: uint32(nbShards), + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: waitingMapForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: lruCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, StakingV4EnableEpoch: StakingV4Epoch, } diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index b4fac118a99..ed20496a8fb 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -147,7 +147,7 @@ func createStatusComponents() factory.StatusComponentsHolder { func createStateComponents(coreComponents factory.CoreComponentsHolder) factory.StateComponentsHandler { tsmArgs := getNewTrieStorageManagerArgs(coreComponents) - tsm, _ := trie.NewTrieStorageManager(tsmArgs) + tsm, _ := trie.CreateTrieStorageManager(tsmArgs, trie.StorageManagerOptions{}) trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(tsm) userAccountsDB := createAccountsDB(coreComponents, stateFactory.NewAccountCreator(), trieFactoryManager) peerAccountsDB := createAccountsDB(coreComponents, stateFactory.NewPeerAccountCreator(), trieFactoryManager) diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index c23b5bee275..6cca21a7b68 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -10,11 +10,11 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/notifier" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" - "github.com/multiversx/mx-chain-go/epochStart" ) var _ process.ValidatorsProvider = (*validatorsProvider)(nil) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index b10b22cbd89..a72e1f2ddd1 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -2406,7 +2406,7 @@ func TestRandHashShuffler_UpdateNodeLists_All(t *testing.T) { StakingV4EnableEpoch: 443, StakingV4DistributeAuctionToWaitingEpoch: 444, }, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) @@ -2759,7 +2759,7 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t StakingV4EnableEpoch: 443, StakingV4DistributeAuctionToWaitingEpoch: 444, }, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) diff --git a/sharding/nodesCoordinator/shardingArgs.go b/sharding/nodesCoordinator/shardingArgs.go index a94444bb57a..fe235aea7f9 100644 --- a/sharding/nodesCoordinator/shardingArgs.go +++ b/sharding/nodesCoordinator/shardingArgs.go @@ -11,27 +11,27 @@ import ( // ArgNodesCoordinator holds all dependencies required by the nodes coordinator in order to create new instances type ArgNodesCoordinator struct { - ShardConsensusGroupSize int - MetaConsensusGroupSize int - Marshalizer marshal.Marshalizer - Hasher hashing.Hasher - Shuffler NodesShuffler - EpochStartNotifier EpochStartEventNotifier - BootStorer storage.Storer - ShardIDAsObserver uint32 - NbShards uint32 - EligibleNodes map[uint32][]Validator - WaitingNodes map[uint32][]Validator - SelfPublicKey []byte - Epoch uint32 - StartEpoch uint32 - ConsensusGroupCache Cacher - ShuffledOutHandler ShuffledOutHandler - ChanStopNode chan endProcess.ArgEndProcess - NodeTypeProvider NodeTypeProviderHandler - IsFullArchive bool - EnableEpochsHandler common.EnableEpochsHandler - ValidatorInfoCacher epochStart.ValidatorInfoCacher + ShardConsensusGroupSize int + MetaConsensusGroupSize int + Marshalizer marshal.Marshalizer + Hasher hashing.Hasher + Shuffler NodesShuffler + EpochStartNotifier EpochStartEventNotifier + BootStorer storage.Storer + ShardIDAsObserver uint32 + NbShards uint32 + EligibleNodes map[uint32][]Validator + WaitingNodes map[uint32][]Validator + SelfPublicKey []byte + Epoch uint32 + StartEpoch uint32 + ConsensusGroupCache Cacher + ShuffledOutHandler ShuffledOutHandler + ChanStopNode chan endProcess.ArgEndProcess + NodeTypeProvider NodeTypeProviderHandler + IsFullArchive bool + EnableEpochsHandler common.EnableEpochsHandler + ValidatorInfoCacher epochStart.ValidatorInfoCacher StakingV4EnableEpoch uint32 NodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory } diff --git a/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go b/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go index ae67f262ce8..c1515eabb56 100644 --- a/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go +++ b/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go @@ -6,9 +6,9 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/data" - logger "github.com/multiversx/mx-chain-logger-go" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/state" + logger "github.com/multiversx/mx-chain-logger-go" ) var log = logger.GetOrCreate("state/evictionWaitingList") diff --git a/testscommon/shardingMocks/nodesCoordinatorMock.go b/testscommon/shardingMocks/nodesCoordinatorMock.go index 4238e881244..5c2811fe61a 100644 --- a/testscommon/shardingMocks/nodesCoordinatorMock.go +++ b/testscommon/shardingMocks/nodesCoordinatorMock.go @@ -11,21 +11,21 @@ import ( // NodesCoordinatorMock defines the behaviour of a struct able to do validator group selection type NodesCoordinatorMock struct { - Validators map[uint32][]nodesCoordinator.Validator - ShardConsensusSize uint32 - MetaConsensusSize uint32 - ShardId uint32 - NbShards uint32 - GetSelectedPublicKeysCalled func(selection []byte, shardId uint32, epoch uint32) (publicKeys []string, err error) - GetValidatorsPublicKeysCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) - GetValidatorsRewardsAddressesCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) - SetNodesPerShardsCalled func(nodes map[uint32][]nodesCoordinator.Validator, epoch uint32) error - ComputeValidatorsGroupCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) - GetValidatorWithPublicKeyCalled func(publicKey []byte) (validator nodesCoordinator.Validator, shardId uint32, err error) - GetAllEligibleValidatorsPublicKeysCalled func(epoch uint32) (map[uint32][][]byte, error) - GetAllWaitingValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) - ConsensusGroupSizeCalled func(uint32) int - GetValidatorsIndexesCalled func(publicKeys []string, epoch uint32) ([]uint64, error) + Validators map[uint32][]nodesCoordinator.Validator + ShardConsensusSize uint32 + MetaConsensusSize uint32 + ShardId uint32 + NbShards uint32 + GetSelectedPublicKeysCalled func(selection []byte, shardId uint32, epoch uint32) (publicKeys []string, err error) + GetValidatorsPublicKeysCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) + GetValidatorsRewardsAddressesCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) + SetNodesPerShardsCalled func(nodes map[uint32][]nodesCoordinator.Validator, epoch uint32) error + ComputeValidatorsGroupCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) + GetValidatorWithPublicKeyCalled func(publicKey []byte) (validator nodesCoordinator.Validator, shardId uint32, err error) + GetAllEligibleValidatorsPublicKeysCalled func(epoch uint32) (map[uint32][][]byte, error) + GetAllWaitingValidatorsPublicKeysCalled func() (map[uint32][][]byte, error) + ConsensusGroupSizeCalled func(uint32) int + GetValidatorsIndexesCalled func(publicKeys []string, epoch uint32) ([]uint64, error) GetAllShuffledOutValidatorsPublicKeysCalled func(epoch uint32) (map[uint32][][]byte, error) GetNumTotalEligibleCalled func() uint64 } diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index d2f0751bd0e..b302735ca2c 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -73,7 +73,7 @@ func createMockNewSystemScFactoryArgs() ArgsNewSystemSCFactory { AddressPubKeyConverter: &mock.PubkeyConverterMock{}, ShardCoordinator: &mock.ShardCoordinatorStub{}, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, - NodesCoordinator: &mock.NodesCoordinatorStub{}, + NodesCoordinator: &mock.NodesCoordinatorStub{}, } } From 34ce38228a2ebdf902f45e87e453f6f98c907d90 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 19 Jan 2023 12:13:38 +0200 Subject: [PATCH 383/958] FIX: Linter --- node/node.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/node.go b/node/node.go index 90f565539f0..02e3a9c9444 100644 --- a/node/node.go +++ b/node/node.go @@ -344,7 +344,7 @@ func (n *Node) GetValueForKey(address string, key string, options api.AccountQue // GetESDTData returns the esdt balance and properties from a given account func (n *Node) GetESDTData(address, tokenID string, nonce uint64, options api.AccountQueryOptions) (*esdt.ESDigitalToken, api.BlockInfo, error) { - userAccount, blockInfo, err := n.loadUserAccountHandlerByAddress(address, options) + userAccount, _, err := n.loadUserAccountHandlerByAddress(address, options) if err != nil { return nil, api.BlockInfo{}, err } @@ -508,7 +508,7 @@ func bigToString(bigValue *big.Int) string { // GetAllESDTTokens returns all the ESDTs that the given address interacted with func (n *Node) GetAllESDTTokens(address string, options api.AccountQueryOptions, ctx context.Context) (map[string]*esdt.ESDigitalToken, api.BlockInfo, error) { - userAccount, blockInfo, err := n.loadUserAccountHandlerByAddress(address, options) + userAccount, _, err := n.loadUserAccountHandlerByAddress(address, options) if err != nil { return nil, api.BlockInfo{}, err } From 1170da4e6247f973bccf135c7ea9ab33b3312678 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 19 Jan 2023 15:02:04 +0200 Subject: [PATCH 384/958] FIX: Check for nil input values --- epochStart/metachain/errors.go | 5 +++++ epochStart/metachain/systemSCs.go | 19 +++++++++++++++++- epochStart/metachain/systemSCs_test.go | 27 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 epochStart/metachain/errors.go diff --git a/epochStart/metachain/errors.go b/epochStart/metachain/errors.go new file mode 100644 index 00000000000..e55f55ba9a3 --- /dev/null +++ b/epochStart/metachain/errors.go @@ -0,0 +1,5 @@ +package metachain + +import "errors" + +var errNilValidatorsInfoMap = errors.New("received nil shard validators info map") diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 27409981fd9..5b706ec85e3 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -85,13 +85,30 @@ func (s *systemSCProcessor) ProcessSystemSmartContract( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - err := s.processLegacy(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) + err := checkNilInputValues(validatorsInfoMap, header) + if err != nil { + return err + } + + err = s.processLegacy(validatorsInfoMap, header.GetNonce(), header.GetEpoch()) if err != nil { return err } return s.processWithNewFlags(validatorsInfoMap, header) } +func checkNilInputValues(validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler) error { + if check.IfNil(header) { + return process.ErrNilHeaderHandler + } + if validatorsInfoMap == nil { + return fmt.Errorf("systemSCProcessor.ProcessSystemSmartContract : %w, header nonce: %d ", + errNilValidatorsInfoMap, header.GetNonce()) + } + + return nil +} + func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 4e40e84957c..df8e3d68316 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -8,6 +8,7 @@ import ( "math" "math/big" "os" + "strings" "testing" "github.com/multiversx/mx-chain-core-go/core" @@ -28,6 +29,7 @@ import ( "github.com/multiversx/mx-chain-go/epochStart/mock" "github.com/multiversx/mx-chain-go/epochStart/notifier" "github.com/multiversx/mx-chain-go/genesis/process/disabled" + "github.com/multiversx/mx-chain-go/process" vmFactory "github.com/multiversx/mx-chain-go/process/factory" metaProcess "github.com/multiversx/mx-chain-go/process/factory/metachain" "github.com/multiversx/mx-chain-go/process/peer" @@ -2076,6 +2078,31 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar require.Equal(t, nodesConfigEpoch6.MaxNumNodes, s.maxNodes) } +func TestSystemSCProcessor_ProcessSystemSmartContractNilInputValues(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + s, _ := NewSystemSCProcessor(args) + + t.Run("nil validators info map, expect error", func(t *testing.T) { + t.Parallel() + + blockHeader := &block.Header{Nonce: 4} + err := s.ProcessSystemSmartContract(nil, blockHeader) + require.True(t, strings.Contains(err.Error(), errNilValidatorsInfoMap.Error())) + require.True(t, strings.Contains(err.Error(), fmt.Sprintf("%d", blockHeader.GetNonce()))) + }) + + t.Run("nil header, expect error", func(t *testing.T) { + t.Parallel() + + validatorsInfoMap := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfoMap, nil) + require.Equal(t, process.ErrNilHeaderHandler, err) + }) + +} + func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { for _, pubKey := range stakedPubKeys { owner, err := s.GetBlsKeyOwner(pubKey) From 31e965f056c546d187b66ea584c6ac74feb12f91 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 20 Jan 2023 16:44:13 +0200 Subject: [PATCH 385/958] FIX: Long tests --- ...nuousTransactionsInMultiShardedEnvironment_test.go | 9 ++++++--- ...ithoutTransactionInMultiShardedEnvironment_test.go | 9 ++++++--- .../endOfEpoch/startInEpoch/startInEpoch_test.go | 11 +++++++---- integrationTests/testConsensusNode.go | 4 +++- integrationTests/testInitializer.go | 9 +++++++++ integrationTests/testProcessorNode.go | 3 +++ integrationTests/testProcessorNodeWithMultisigner.go | 11 +++++++---- integrationTests/vm/delegation/liquidStaking_test.go | 3 +++ integrationTests/vm/systemVM/stakingSC_test.go | 9 ++++++--- 9 files changed, 50 insertions(+), 18 deletions(-) diff --git a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go index d89abd3aae5..b0b598e2f98 100644 --- a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go +++ b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go @@ -20,9 +20,12 @@ func TestEpochStartChangeWithContinuousTransactionsInMultiShardedEnvironment(t * numMetachainNodes := 3 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go index b7b658e4ca2..a42a8ff246a 100644 --- a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go +++ b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go @@ -19,9 +19,12 @@ func TestEpochStartChangeWithoutTransactionInMultiShardedEnvironment(t *testing. numMetachainNodes := 2 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index 9fe30f7e9ef..a8732873ab5 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -60,10 +60,13 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui numMetachainNodes := 3 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, - RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 49b71bc390b..990af73241c 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -303,7 +303,9 @@ func (tcn *TestConsensusNode) initNodesCoordinator( EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ IsWaitingListFixFlagEnabledField: true, }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, + StakingV4EnableEpoch: StakingV4Epoch, } tcn.NodesCoordinator, _ = nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 6ad08fa4435..34f47443ff2 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -705,6 +705,9 @@ func CreateFullGenesisBlocks( return false }, }, + EpochConfig: &config.EpochConfig{ + EnableEpochs: enableEpochsConfig, + }, } genesisProcessor, _ := genesisProcess.NewGenesisBlockCreator(argsGenesis) @@ -1454,6 +1457,9 @@ func CreateNodesWithFullGenesis( enableEpochsConfig := GetDefaultEnableEpochsConfig() enableEpochsConfig.StakingV2EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4InitEnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch = UnreachableEpoch economicsConfig := createDefaultEconomicsConfig() economicsConfig.GlobalSettings.YearSettings = append( @@ -1522,6 +1528,9 @@ func CreateNodesWithCustomStateCheckpointModulus( enableEpochsConfig := GetDefaultEnableEpochsConfig() enableEpochsConfig.StakingV2EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4InitEnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch = UnreachableEpoch scm := &IntWrapper{ Value: stateCheckpointModulus, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index ee9f8b893d7..f359d40ce11 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -3326,5 +3326,8 @@ func GetDefaultEnableEpochsConfig() *config.EnableEpochs { ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, FailExecutionOnEveryAPIErrorEnableEpoch: UnreachableEpoch, + StakingV4InitEnableEpoch: UnreachableEpoch, + StakingV4EnableEpoch: UnreachableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: UnreachableEpoch, } } diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index fd5b6283eb6..8c03ff31ce3 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -230,10 +230,13 @@ func CreateNodesWithNodesCoordinatorFactory( } epochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, - RefactorPeersMiniBlocksEnableEpoch: UnreachableEpoch, + StakingV2EnableEpoch: UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, + RefactorPeersMiniBlocksEnableEpoch: UnreachableEpoch, + StakingV4EnableEpoch: UnreachableEpoch, + StakingV4InitEnableEpoch: UnreachableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: UnreachableEpoch, } nodesMap := make(map[uint32][]*TestProcessorNode) diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go index 87be301b03b..f0e867289c2 100644 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ b/integrationTests/vm/delegation/liquidStaking_test.go @@ -22,6 +22,9 @@ import ( var log = logger.GetOrCreate("liquidStaking") func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { + t.Skip("this test seems to be incompatible with later flags;" + + "since liquid staking will be most likely used on RUST SC and not on protocol level, we will be disable this test") + if testing.Short() { t.Skip("this is not a short test") } diff --git a/integrationTests/vm/systemVM/stakingSC_test.go b/integrationTests/vm/systemVM/stakingSC_test.go index 2616f20e80e..cd18133ceb8 100644 --- a/integrationTests/vm/systemVM/stakingSC_test.go +++ b/integrationTests/vm/systemVM/stakingSC_test.go @@ -31,9 +31,12 @@ func TestStakingUnstakingAndUnbondingOnMultiShardEnvironment(t *testing.T) { numMetachainNodes := 2 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( From 165d924ff63e93fcad63fb369a59ad682f0cea80 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 26 Jan 2023 13:13:27 +0200 Subject: [PATCH 386/958] FIX: After review --- common/enablers/epochFlags.go | 4 ++-- common/interface.go | 2 +- epochStart/metachain/stakingDataProvider_test.go | 2 +- epochStart/metachain/systemSCs_test.go | 2 +- sharding/mock/enableEpochsHandlerMock.go | 4 ++-- testscommon/enableEpochsHandlerStub.go | 4 ++-- vm/systemSmartContracts/validator.go | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index f2ffa4d3183..7393d8fee43 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -662,8 +662,8 @@ func (holder *epochFlagsHolder) IsWipeSingleNFTLiquidityDecreaseEnabled() bool { return holder.wipeSingleNFTLiquidityDecreaseFlag.IsSet() } -// IsStakeLimitsEnabled returns true if stakeLimitsFlag is enabled -func (holder *epochFlagsHolder) IsStakeLimitsEnabled() bool { +// IsStakeLimitsFlagEnabled returns true if stakeLimitsFlag is enabled +func (holder *epochFlagsHolder) IsStakeLimitsFlagEnabled() bool { return holder.stakeLimitsFlag.IsSet() } diff --git a/common/interface.go b/common/interface.go index 3549216c37a..14d528ba978 100644 --- a/common/interface.go +++ b/common/interface.go @@ -336,7 +336,7 @@ type EnableEpochsHandler interface { IsRuntimeMemStoreLimitEnabled() bool IsMaxBlockchainHookCountersFlagEnabled() bool IsWipeSingleNFTLiquidityDecreaseEnabled() bool - IsStakeLimitsEnabled() bool + IsStakeLimitsFlagEnabled() bool IsStakingV4InitEnabled() bool IsStakingV4Enabled() bool IsStakingV4DistributeAuctionToWaitingEnabled() bool diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index cf37607adf5..abd134fcc2c 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -23,7 +23,7 @@ import ( "github.com/stretchr/testify/require" ) -const stakingV4EInitEnableEpoch = 444 +const stakingV4InitEnableEpoch = 444 const stakingV4EnableEpoch = 445 func createStakingDataProviderArgs() StakingDataProviderArgs { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index df8e3d68316..f0fea647964 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1773,7 +1773,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) - args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4EInitEnableEpoch}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4InitEnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 5660224f2c6..e6dd5e6b2db 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -561,8 +561,8 @@ func (mock *EnableEpochsHandlerMock) IsWipeSingleNFTLiquidityDecreaseEnabled() b return false } -// IsStakeLimitsEnabled - -func (mock *EnableEpochsHandlerMock) IsStakeLimitsEnabled() bool { +// IsStakeLimitsFlagEnabled - +func (mock *EnableEpochsHandlerMock) IsStakeLimitsFlagEnabled() bool { return false } diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 6a7bd365300..065e2364250 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -1008,8 +1008,8 @@ func (stub *EnableEpochsHandlerStub) IsWipeSingleNFTLiquidityDecreaseEnabled() b return stub.IsWipeSingleNFTLiquidityDecreaseEnabledField } -// IsStakeLimitsEnabled - -func (stub *EnableEpochsHandlerStub) IsStakeLimitsEnabled() bool { +// IsStakeLimitsFlagEnabled - +func (stub *EnableEpochsHandlerStub) IsStakeLimitsFlagEnabled() bool { stub.RLock() defer stub.RUnlock() diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index d6f267bf220..f03383ea526 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -911,7 +911,7 @@ func (v *validatorSC) checkAllGivenKeysAreUnStaked(registrationData *ValidatorDa } func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { - if !v.enableEpochsHandler.IsStakeLimitsEnabled() { + if !v.enableEpochsHandler.IsStakeLimitsFlagEnabled() { return false } @@ -919,7 +919,7 @@ func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { } func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) bool { - if !v.enableEpochsHandler.IsStakeLimitsEnabled() { + if !v.enableEpochsHandler.IsStakeLimitsFlagEnabled() { return false } From ddb2f64f27661b899ed5cd74bf206166c4cf0bfd Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 26 Jan 2023 13:26:15 +0200 Subject: [PATCH 387/958] FIX: After merge --- common/enablers/enableEpochsHandler_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index f7d249624ae..9869902e9e0 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -215,7 +215,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsRuntimeMemStoreLimitEnabled()) assert.True(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.True(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) - assert.True(t, handler.IsStakeLimitsEnabled()) + assert.True(t, handler.IsStakeLimitsFlagEnabled()) assert.False(t, handler.IsStakingV4InitEnabled()) // epoch == limit assert.True(t, handler.IsStakingV4Enabled()) assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) @@ -324,7 +324,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.True(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) assert.True(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) - assert.True(t, handler.IsStakeLimitsEnabled()) + assert.True(t, handler.IsStakeLimitsFlagEnabled()) assert.True(t, handler.IsStakingV4InitEnabled()) assert.True(t, handler.IsStakingV4Enabled()) assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) @@ -426,7 +426,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.False(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) assert.False(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) - assert.False(t, handler.IsStakeLimitsEnabled()) + assert.False(t, handler.IsStakeLimitsFlagEnabled()) assert.False(t, handler.IsStakingV4InitEnabled()) assert.False(t, handler.IsStakingV4Enabled()) assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) From daf5f9857b2011f1df8aa1c1d4faf3b47cc53dfa Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 31 Jan 2023 12:23:55 +0200 Subject: [PATCH 388/958] FEAT: Remove LS files --- .../vm/delegation/liquidStaking_test.go | 193 ------ vm/systemSmartContracts/liquidStaking.go | 578 ------------------ vm/systemSmartContracts/liquidStaking.pb.go | 424 ------------- vm/systemSmartContracts/liquidStaking.proto | 13 - vm/systemSmartContracts/liquidStaking_test.go | 553 ----------------- 5 files changed, 1761 deletions(-) delete mode 100644 integrationTests/vm/delegation/liquidStaking_test.go delete mode 100644 vm/systemSmartContracts/liquidStaking.go delete mode 100644 vm/systemSmartContracts/liquidStaking.pb.go delete mode 100644 vm/systemSmartContracts/liquidStaking.proto delete mode 100644 vm/systemSmartContracts/liquidStaking_test.go diff --git a/integrationTests/vm/delegation/liquidStaking_test.go b/integrationTests/vm/delegation/liquidStaking_test.go deleted file mode 100644 index f0e867289c2..00000000000 --- a/integrationTests/vm/delegation/liquidStaking_test.go +++ /dev/null @@ -1,193 +0,0 @@ -//go:build !race -// +build !race - -package delegation - -import ( - "bytes" - "math/big" - "testing" - "time" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-go/integrationTests" - "github.com/multiversx/mx-chain-go/integrationTests/vm/esdt" - "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" - "github.com/multiversx/mx-chain-go/vm" - logger "github.com/multiversx/mx-chain-logger-go" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" - "github.com/stretchr/testify/require" -) - -var log = logger.GetOrCreate("liquidStaking") - -func TestDelegationSystemSCWithLiquidStaking(t *testing.T) { - t.Skip("this test seems to be incompatible with later flags;" + - "since liquid staking will be most likely used on RUST SC and not on protocol level, we will be disable this test") - - if testing.Short() { - t.Skip("this is not a short test") - } - - nodes, idxProposers, delegationAddress, tokenID, nonce, round := setupNodesDelegationContractInitLiquidStaking(t) - defer func() { - for _, n := range nodes { - _ = n.Messenger.Close() - } - }() - - txData := txDataBuilder.NewBuilder().Clear(). - Func("claimDelegatedPosition"). - Bytes(big.NewInt(1).Bytes()). - Bytes(delegationAddress). - Bytes(big.NewInt(5000).Bytes()). - ToString() - for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txData, core.MinMetaTxExtraGasCost) - } - - nrRoundsToPropagateMultiShard := 12 - time.Sleep(time.Second) - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(time.Second) - - // claim again - for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), vm.LiquidStakingSCAddress, txData, core.MinMetaTxExtraGasCost) - } - - time.Sleep(time.Second) - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(time.Second) - - for i := 1; i < len(nodes); i++ { - checkLPPosition(t, nodes[i].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(10000)) - } - // owner is not allowed to get LP position - checkLPPosition(t, nodes[0].OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) - metaNode := getNodeWithShardID(nodes, core.MetachainShardId) - allDelegatorAddresses := make([][]byte, 0) - for i := 1; i < len(nodes); i++ { - allDelegatorAddresses = append(allDelegatorAddresses, nodes[i].OwnAccount.Address) - } - verifyDelegatorIsDeleted(t, metaNode, allDelegatorAddresses, delegationAddress) - - oneTransfer := &vmcommon.ESDTTransfer{ - ESDTValue: big.NewInt(1000), - ESDTTokenName: tokenID, - ESDTTokenType: uint32(core.NonFungible), - ESDTTokenNonce: 1, - } - esdtTransfers := []*vmcommon.ESDTTransfer{oneTransfer, oneTransfer, oneTransfer, oneTransfer, oneTransfer} - txBuilder := txDataBuilder.NewBuilder().MultiTransferESDTNFT(vm.LiquidStakingSCAddress, esdtTransfers) - txBuilder.Bytes([]byte("unDelegatePosition")) - for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), node.OwnAccount.Address, txBuilder.ToString(), core.MinMetaTxExtraGasCost) - } - - txBuilder = txDataBuilder.NewBuilder().MultiTransferESDTNFT(vm.LiquidStakingSCAddress, esdtTransfers) - txBuilder.Bytes([]byte("returnPosition")) - for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(0), node.OwnAccount.Address, txBuilder.ToString(), core.MinMetaTxExtraGasCost) - } - time.Sleep(time.Second) - finalWait := 20 - _, _ = integrationTests.WaitOperationToBeDone(t, nodes, finalWait, nonce, round, idxProposers) - time.Sleep(time.Second) - - for _, node := range nodes { - checkLPPosition(t, node.OwnAccount.Address, nodes, tokenID, uint64(1), big.NewInt(0)) - } - - verifyDelegatorsStake(t, metaNode, "getUserActiveStake", allDelegatorAddresses, delegationAddress, big.NewInt(5000)) - verifyDelegatorsStake(t, metaNode, "getUserUnStakedValue", allDelegatorAddresses, delegationAddress, big.NewInt(5000)) -} - -func setupNodesDelegationContractInitLiquidStaking( - t *testing.T, -) ([]*integrationTests.TestProcessorNode, []int, []byte, []byte, uint64, uint64) { - numOfShards := 2 - nodesPerShard := 2 - numMetachainNodes := 2 - - nodes := integrationTests.CreateNodes( - numOfShards, - nodesPerShard, - numMetachainNodes, - ) - - integrationTests.DisplayAndStartNodes(nodes) - - idxProposers := make([]int, numOfShards+1) - for i := 0; i < numOfShards; i++ { - idxProposers[i] = i * nodesPerShard - } - idxProposers[numOfShards] = numOfShards * nodesPerShard - - tokenID := initDelegationManagementAndLiquidStaking(nodes) - - initialVal := big.NewInt(10000000000) - initialVal.Mul(initialVal, initialVal) - integrationTests.MintAllNodes(nodes, initialVal) - - delegationAddress := createNewDelegationSystemSC(nodes[0], nodes) - - round := uint64(0) - nonce := uint64(0) - round = integrationTests.IncrementAndPrintRound(round) - nonce++ - - time.Sleep(time.Second) - nrRoundsToPropagateMultiShard := 6 - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(time.Second) - - txData := "delegate" - for _, node := range nodes { - integrationTests.CreateAndSendTransaction(node, nodes, big.NewInt(10000), delegationAddress, txData, core.MinMetaTxExtraGasCost) - } - - time.Sleep(time.Second) - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) - time.Sleep(time.Second) - - return nodes, idxProposers, delegationAddress, tokenID, nonce, round -} - -func initDelegationManagementAndLiquidStaking(nodes []*integrationTests.TestProcessorNode) []byte { - var tokenID []byte - for _, node := range nodes { - node.InitDelegationManager() - tmpTokenID := node.InitLiquidStaking() - if len(tmpTokenID) != 0 { - if len(tokenID) == 0 { - tokenID = tmpTokenID - } - - if !bytes.Equal(tokenID, tmpTokenID) { - log.Error("tokenID missmatch", "current", tmpTokenID, "old", tokenID) - } - } - } - return tokenID -} - -func checkLPPosition( - t *testing.T, - address []byte, - nodes []*integrationTests.TestProcessorNode, - tokenID []byte, - nonce uint64, - value *big.Int, -) { - esdtData := esdt.GetESDTTokenData(t, address, nodes, tokenID, nonce) - - if value.Cmp(big.NewInt(0)) == 0 { - require.Nil(t, esdtData.TokenMetaData) - return - } - - require.NotNil(t, esdtData.TokenMetaData) - require.Equal(t, vm.LiquidStakingSCAddress, esdtData.TokenMetaData.Creator) - require.Equal(t, value.Bytes(), esdtData.Value.Bytes()) -} diff --git a/vm/systemSmartContracts/liquidStaking.go b/vm/systemSmartContracts/liquidStaking.go deleted file mode 100644 index 0549d48fe25..00000000000 --- a/vm/systemSmartContracts/liquidStaking.go +++ /dev/null @@ -1,578 +0,0 @@ -//go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. liquidStaking.proto -package systemSmartContracts - -import ( - "bytes" - "encoding/hex" - "fmt" - "math/big" - "sync" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-core-go/hashing" - "github.com/multiversx/mx-chain-core-go/marshal" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/config" - "github.com/multiversx/mx-chain-go/vm" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" -) - -const tokenIDKey = "tokenID" -const nonceAttributesPrefix = "n" -const attributesNoncePrefix = "a" - -type liquidStaking struct { - eei vm.SystemEI - liquidStakingSCAddress []byte - gasCost vm.GasCost - marshalizer marshal.Marshalizer - hasher hashing.Hasher - mutExecution sync.RWMutex - enableEpochsHandler common.EnableEpochsHandler -} - -// ArgsNewLiquidStaking defines the arguments to create the liquid staking smart contract -type ArgsNewLiquidStaking struct { - EpochConfig config.EpochConfig - Eei vm.SystemEI - LiquidStakingSCAddress []byte - GasCost vm.GasCost - Marshalizer marshal.Marshalizer - Hasher hashing.Hasher - EnableEpochsHandler common.EnableEpochsHandler -} - -// TODO: resolve errors if multi transfer from metachain fails. should it return - restore position or should remain at destination -// better to remain at destination - -// NewLiquidStakingSystemSC creates a new liquid staking system SC -func NewLiquidStakingSystemSC(args ArgsNewLiquidStaking) (*liquidStaking, error) { - if check.IfNil(args.Eei) { - return nil, vm.ErrNilSystemEnvironmentInterface - } - if len(args.LiquidStakingSCAddress) < 1 { - return nil, fmt.Errorf("%w for liquid staking sc address", vm.ErrInvalidAddress) - } - if check.IfNil(args.Marshalizer) { - return nil, vm.ErrNilMarshalizer - } - if check.IfNil(args.Hasher) { - return nil, vm.ErrNilHasher - } - if check.IfNil(args.EnableEpochsHandler) { - return nil, vm.ErrNilEnableEpochsHandler - } - - l := &liquidStaking{ - eei: args.Eei, - liquidStakingSCAddress: args.LiquidStakingSCAddress, - gasCost: args.GasCost, - marshalizer: args.Marshalizer, - hasher: args.Hasher, - enableEpochsHandler: args.EnableEpochsHandler, - } - - return l, nil -} - -// Execute calls one of the functions from the delegation contract and runs the code according to the input -func (l *liquidStaking) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - l.mutExecution.RLock() - defer l.mutExecution.RUnlock() - - err := CheckIfNil(args) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - if !l.enableEpochsHandler.IsLiquidStakingEnabled() { - l.eei.AddReturnMessage("liquid staking contract is not enabled") - return vmcommon.UserError - } - - switch args.Function { - case core.SCDeployInitFunctionName: - return l.init(args) - case "claimDelegatedPosition": - return l.claimDelegatedPosition(args) - case "claimRewardsFromPosition": - return l.claimRewardsFromDelegatedPosition(args) - case "reDelegateRewardsFromPosition": - return l.reDelegateRewardsFromPosition(args) - case "unDelegatePosition": - return l.returnLiquidStaking(args, "unDelegateViaLiquidStaking") - case "returnPosition": - return l.returnLiquidStaking(args, "returnViaLiquidStaking") - case "readTokenID": - return l.readTokenID(args) - } - - l.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError -} - -func (l *liquidStaking) init(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !bytes.Equal(args.CallerAddr, l.liquidStakingSCAddress) { - l.eei.AddReturnMessage("invalid caller") - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - l.eei.AddReturnMessage("function is not payable in eGLD") - return vmcommon.UserError - } - if len(args.Arguments) != 1 { - l.eei.AddReturnMessage("invalid number of arguments") - return vmcommon.UserError - } - tokenID := args.Arguments[0] - l.eei.SetStorage([]byte(tokenIDKey), tokenID) - - return vmcommon.Ok -} - -func (l *liquidStaking) getTokenID() []byte { - return l.eei.GetStorage([]byte(tokenIDKey)) -} - -func (l *liquidStaking) readTokenID(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if len(args.ESDTTransfers) != 0 || args.CallValue.Cmp(zero) != 0 { - l.eei.AddReturnMessage("function is not payable") - return vmcommon.UserError - } - if len(args.Arguments) > 0 { - l.eei.AddReturnMessage("function does not accept arguments") - return vmcommon.UserError - } - err := l.eei.UseGas(l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.OutOfGas - } - - l.eei.Finish(l.getTokenID()) - return vmcommon.Ok -} - -func (l *liquidStaking) checkArgumentsWhenPositionIsInput(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if len(args.ESDTTransfers) < 1 { - l.eei.AddReturnMessage("function requires liquid staking input") - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - l.eei.AddReturnMessage("function is not payable in eGLD") - return vmcommon.UserError - } - definedTokenID := l.getTokenID() - for _, esdtTransfer := range args.ESDTTransfers { - if !bytes.Equal(esdtTransfer.ESDTTokenName, definedTokenID) { - l.eei.AddReturnMessage("wrong tokenID input") - return vmcommon.UserError - } - } - err := l.eei.UseGas(uint64(len(args.ESDTTransfers)) * l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.OutOfGas - } - - return vmcommon.Ok -} - -func (l *liquidStaking) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if args.CallValue.Cmp(zero) != 0 { - l.eei.AddReturnMessage("function is not payable in eGLD") - return vmcommon.UserError - } - if len(args.Arguments) < 3 { - l.eei.AddReturnMessage("not enough arguments") - return vmcommon.UserError - } - if len(args.ESDTTransfers) > 0 { - l.eei.AddReturnMessage("function is not payable in ESDT") - return vmcommon.UserError - } - - numOfCalls := big.NewInt(0).SetBytes(args.Arguments[0]).Int64() - minNumArguments := numOfCalls*2 + 1 - if int64(len(args.Arguments)) < minNumArguments { - l.eei.AddReturnMessage("not enough arguments") - return vmcommon.UserError - } - err := l.eei.UseGas(uint64(numOfCalls) * l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.OutOfGas - } - - listNonces := make([]uint64, 0) - listValues := make([]*big.Int, 0) - startIndex := int64(1) - for i := int64(0); i < numOfCalls; i++ { - callStartIndex := startIndex + i*2 - nonce, valueToClaim, returnCode := l.claimOneDelegatedPosition(args.CallerAddr, args.Arguments[callStartIndex], args.Arguments[callStartIndex+1]) - if returnCode != vmcommon.Ok { - return returnCode - } - - listNonces = append(listNonces, nonce) - listValues = append(listValues, valueToClaim) - } - - var additionalArgs [][]byte - if int64(len(args.Arguments)) > minNumArguments { - additionalArgs = args.Arguments[minNumArguments:] - } - err = l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, additionalArgs) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (l *liquidStaking) claimOneDelegatedPosition( - callerAddr []byte, - destSCAddress []byte, - valueAsBytes []byte, -) (uint64, *big.Int, vmcommon.ReturnCode) { - if len(destSCAddress) != len(l.liquidStakingSCAddress) || bytes.Equal(destSCAddress, l.liquidStakingSCAddress) { - l.eei.AddReturnMessage("invalid destination SC address") - return 0, nil, vmcommon.UserError - } - - valueToClaim := big.NewInt(0).SetBytes(valueAsBytes) - _, returnCode := l.executeOnDestinationSC( - destSCAddress, - "claimDelegatedPosition", - callerAddr, - valueToClaim, - 0, - ) - if returnCode != vmcommon.Ok { - return 0, nil, returnCode - } - - newCheckpoint := l.eei.BlockChainHook().CurrentEpoch() + 1 - nonce, err := l.createOrAddNFT(destSCAddress, newCheckpoint, valueToClaim) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return 0, nil, vmcommon.UserError - } - - return nonce, valueToClaim, vmcommon.Ok -} - -func (l *liquidStaking) claimRewardsFromDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - listNonces := make([]uint64, 0) - listValues := make([]*big.Int, 0) - for _, esdtTransfer := range args.ESDTTransfers { - attributes, _, execCode := l.burnAndExecuteFromESDTTransfer( - args.CallerAddr, - esdtTransfer, - "claimRewardsViaLiquidStaking", - ) - if execCode != vmcommon.Ok { - return execCode - } - - newCheckpoint := l.eei.BlockChainHook().CurrentEpoch() + 1 - nonce, err := l.createOrAddNFT(attributes.ContractAddress, newCheckpoint, esdtTransfer.ESDTValue) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - listNonces = append(listNonces, nonce) - listValues = append(listValues, esdtTransfer.ESDTValue) - } - - err := l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, args.Arguments) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (l *liquidStaking) reDelegateRewardsFromPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - listNonces := make([]uint64, 0) - listValues := make([]*big.Int, 0) - for _, esdtTransfer := range args.ESDTTransfers { - attributes, returnData, execCode := l.burnAndExecuteFromESDTTransfer( - args.CallerAddr, - esdtTransfer, - "reDelegateRewardsViaLiquidStaking", - ) - if execCode != vmcommon.Ok { - return execCode - } - if len(returnData) != 1 { - l.eei.AddReturnMessage("invalid return data") - return vmcommon.UserError - } - - earnedRewards := big.NewInt(0).SetBytes(returnData[0]) - totalToCreate := big.NewInt(0).Add(esdtTransfer.ESDTValue, earnedRewards) - newCheckpoint := l.eei.BlockChainHook().CurrentEpoch() + 1 - - nonce, err := l.createOrAddNFT(attributes.ContractAddress, newCheckpoint, totalToCreate) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - listNonces = append(listNonces, nonce) - listValues = append(listValues, totalToCreate) - } - - err := l.sendNFTMultiTransfer(args.CallerAddr, listNonces, listValues, args.Arguments) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (l *liquidStaking) returnLiquidStaking( - args *vmcommon.ContractCallInput, - functionToCall string, -) vmcommon.ReturnCode { - returnCode := l.checkArgumentsWhenPositionIsInput(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - for _, esdtTransfer := range args.ESDTTransfers { - _, _, returnCode = l.burnAndExecuteFromESDTTransfer( - args.CallerAddr, - esdtTransfer, - functionToCall, - ) - if returnCode != vmcommon.Ok { - return returnCode - } - } - - return vmcommon.Ok -} - -func (l *liquidStaking) burnAndExecuteFromESDTTransfer( - callerAddr []byte, - esdtTransfer *vmcommon.ESDTTransfer, - functionToCall string, -) (*LiquidStakingAttributes, [][]byte, vmcommon.ReturnCode) { - attributes, err := l.getAttributesForNonce(esdtTransfer.ESDTTokenNonce) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return nil, nil, vmcommon.UserError - } - - err = l.burnSFT(esdtTransfer.ESDTTokenNonce, esdtTransfer.ESDTValue) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return nil, nil, vmcommon.UserError - } - - returnData, returnCode := l.executeOnDestinationSC( - attributes.ContractAddress, - functionToCall, - callerAddr, - esdtTransfer.ESDTValue, - attributes.RewardsCheckpoint, - ) - if returnCode != vmcommon.Ok { - return nil, nil, returnCode - } - - return attributes, returnData, vmcommon.Ok -} - -func (l *liquidStaking) executeOnDestinationSC( - dstSCAddress []byte, - functionToCall string, - userAddress []byte, - valueToSend *big.Int, - rewardsCheckPoint uint32, -) ([][]byte, vmcommon.ReturnCode) { - txData := functionToCall + "@" + hex.EncodeToString(userAddress) + "@" + hex.EncodeToString(valueToSend.Bytes()) - if rewardsCheckPoint > 0 { - txData += "@" + hex.EncodeToString(big.NewInt(int64(rewardsCheckPoint)).Bytes()) - } - vmOutput, err := l.eei.ExecuteOnDestContext(dstSCAddress, l.liquidStakingSCAddress, big.NewInt(0), []byte(txData)) - if err != nil { - l.eei.AddReturnMessage(err.Error()) - return nil, vmcommon.UserError - } - - if vmOutput.ReturnCode != vmcommon.Ok { - return nil, vmOutput.ReturnCode - } - - return vmOutput.ReturnData, vmcommon.Ok -} - -func (l *liquidStaking) createOrAddNFT( - delegationSCAddress []byte, - rewardsCheckpoint uint32, - value *big.Int, -) (uint64, error) { - attributes := &LiquidStakingAttributes{ - ContractAddress: delegationSCAddress, - RewardsCheckpoint: rewardsCheckpoint, - } - - marshaledData, err := l.marshalizer.Marshal(attributes) - if err != nil { - return 0, err - } - - hash := l.hasher.Compute(string(marshaledData)) - attrNonceKey := append([]byte(attributesNoncePrefix), hash...) - storageData := l.eei.GetStorage(attrNonceKey) - if len(storageData) > 0 { - nonce := big.NewInt(0).SetBytes(storageData).Uint64() - err = l.addQuantityToSFT(nonce, value) - if err != nil { - return 0, err - } - - return nonce, nil - } - - nonce, err := l.createNewSFT(value) - if err != nil { - return 0, err - } - - nonceBytes := big.NewInt(0).SetUint64(nonce).Bytes() - l.eei.SetStorage(attrNonceKey, nonceBytes) - - nonceKey := append([]byte(nonceAttributesPrefix), nonceBytes...) - l.eei.SetStorage(nonceKey, marshaledData) - - return nonce, nil -} - -func (l *liquidStaking) createNewSFT(value *big.Int) (uint64, error) { - valuePlusOne := big.NewInt(0).Add(value, big.NewInt(1)) - - args := make([][]byte, 7) - args[0] = l.getTokenID() - args[1] = valuePlusOne.Bytes() - - vmOutput, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionESDTNFTCreate, args) - if err != nil { - return 0, err - } - if len(vmOutput.ReturnData) != 1 { - return 0, vm.ErrInvalidReturnData - } - - return big.NewInt(0).SetBytes(vmOutput.ReturnData[0]).Uint64(), nil -} - -func (l *liquidStaking) addQuantityToSFT(nonce uint64, value *big.Int) error { - args := make([][]byte, 3) - args[0] = l.getTokenID() - args[1] = big.NewInt(0).SetUint64(nonce).Bytes() - args[2] = value.Bytes() - - _, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionESDTNFTAddQuantity, args) - if err != nil { - return err - } - - return nil -} - -func (l *liquidStaking) burnSFT(nonce uint64, value *big.Int) error { - args := make([][]byte, 3) - args[0] = l.getTokenID() - args[1] = big.NewInt(0).SetUint64(nonce).Bytes() - args[2] = value.Bytes() - - _, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionESDTNFTBurn, args) - if err != nil { - return err - } - - return nil -} - -func (l *liquidStaking) getAttributesForNonce(nonce uint64) (*LiquidStakingAttributes, error) { - nonceKey := append([]byte(nonceAttributesPrefix), big.NewInt(0).SetUint64(nonce).Bytes()...) - marshaledData := l.eei.GetStorage(nonceKey) - if len(marshaledData) == 0 { - return nil, vm.ErrEmptyStorage - } - - lAttr := &LiquidStakingAttributes{} - err := l.marshalizer.Unmarshal(lAttr, marshaledData) - if err != nil { - return nil, err - } - - return lAttr, nil -} - -func (l *liquidStaking) sendNFTMultiTransfer( - destinationAddress []byte, - listNonces []uint64, - listValue []*big.Int, - additionalArgs [][]byte, -) error { - - numOfTransfer := int64(len(listNonces)) - args := make([][]byte, 0) - args = append(args, destinationAddress) - args = append(args, big.NewInt(numOfTransfer).Bytes()) - - tokenID := l.getTokenID() - for i := 0; i < len(listNonces); i++ { - args = append(args, tokenID) - args = append(args, big.NewInt(0).SetUint64(listNonces[i]).Bytes()) - args = append(args, listValue[i].Bytes()) - } - - if len(additionalArgs) > 0 { - args = append(args, additionalArgs...) - } - - _, err := l.eei.ProcessBuiltInFunction(l.liquidStakingSCAddress, l.liquidStakingSCAddress, core.BuiltInFunctionMultiESDTNFTTransfer, args) - if err != nil { - return err - } - - return nil -} - -// SetNewGasCost is called whenever a gas cost was changed -func (l *liquidStaking) SetNewGasCost(gasCost vm.GasCost) { - l.mutExecution.Lock() - l.gasCost = gasCost - l.mutExecution.Unlock() -} - -// CanUseContract returns true if contract can be used -func (l *liquidStaking) CanUseContract() bool { - return l.enableEpochsHandler.IsLiquidStakingEnabled() -} - -// IsInterfaceNil returns true if underlying object is nil -func (l *liquidStaking) IsInterfaceNil() bool { - return l == nil -} diff --git a/vm/systemSmartContracts/liquidStaking.pb.go b/vm/systemSmartContracts/liquidStaking.pb.go deleted file mode 100644 index 4f0068f3ccd..00000000000 --- a/vm/systemSmartContracts/liquidStaking.pb.go +++ /dev/null @@ -1,424 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: liquidStaking.proto - -package systemSmartContracts - -import ( - bytes "bytes" - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" - reflect "reflect" - strings "strings" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type LiquidStakingAttributes struct { - ContractAddress []byte `protobuf:"bytes,1,opt,name=ContractAddress,proto3" json:"ContractAddress"` - RewardsCheckpoint uint32 `protobuf:"varint,2,opt,name=RewardsCheckpoint,proto3" json:"RewardsCheckpoint"` -} - -func (m *LiquidStakingAttributes) Reset() { *m = LiquidStakingAttributes{} } -func (*LiquidStakingAttributes) ProtoMessage() {} -func (*LiquidStakingAttributes) Descriptor() ([]byte, []int) { - return fileDescriptor_ba9d71ac181fc9d8, []int{0} -} -func (m *LiquidStakingAttributes) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *LiquidStakingAttributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *LiquidStakingAttributes) XXX_Merge(src proto.Message) { - xxx_messageInfo_LiquidStakingAttributes.Merge(m, src) -} -func (m *LiquidStakingAttributes) XXX_Size() int { - return m.Size() -} -func (m *LiquidStakingAttributes) XXX_DiscardUnknown() { - xxx_messageInfo_LiquidStakingAttributes.DiscardUnknown(m) -} - -var xxx_messageInfo_LiquidStakingAttributes proto.InternalMessageInfo - -func (m *LiquidStakingAttributes) GetContractAddress() []byte { - if m != nil { - return m.ContractAddress - } - return nil -} - -func (m *LiquidStakingAttributes) GetRewardsCheckpoint() uint32 { - if m != nil { - return m.RewardsCheckpoint - } - return 0 -} - -func init() { - proto.RegisterType((*LiquidStakingAttributes)(nil), "proto.LiquidStakingAttributes") -} - -func init() { proto.RegisterFile("liquidStaking.proto", fileDescriptor_ba9d71ac181fc9d8) } - -var fileDescriptor_ba9d71ac181fc9d8 = []byte{ - // 253 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xce, 0xc9, 0x2c, 0x2c, - 0xcd, 0x4c, 0x09, 0x2e, 0x49, 0xcc, 0xce, 0xcc, 0x4b, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0x62, 0x05, 0x53, 0x52, 0xba, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, - 0xe9, 0xf9, 0xe9, 0xf9, 0xfa, 0x60, 0xe1, 0xa4, 0xd2, 0x34, 0x30, 0x0f, 0xcc, 0x01, 0xb3, 0x20, - 0xba, 0x94, 0xe6, 0x32, 0x72, 0x89, 0xfb, 0x20, 0x9b, 0xe6, 0x58, 0x52, 0x52, 0x94, 0x99, 0x54, - 0x5a, 0x92, 0x5a, 0x2c, 0x64, 0xcb, 0xc5, 0xef, 0x9c, 0x9f, 0x57, 0x52, 0x94, 0x98, 0x5c, 0xe2, - 0x98, 0x92, 0x52, 0x94, 0x5a, 0x5c, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe3, 0x24, 0xfc, 0xea, - 0x9e, 0x3c, 0xba, 0x54, 0x10, 0xba, 0x80, 0x90, 0x33, 0x97, 0x60, 0x50, 0x6a, 0x79, 0x62, 0x51, - 0x4a, 0xb1, 0x73, 0x46, 0x6a, 0x72, 0x76, 0x41, 0x7e, 0x66, 0x5e, 0x89, 0x04, 0x93, 0x02, 0xa3, - 0x06, 0xaf, 0x93, 0xe8, 0xab, 0x7b, 0xf2, 0x98, 0x92, 0x41, 0x98, 0x42, 0x4e, 0x7e, 0x17, 0x1e, - 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xf0, 0xe1, 0xa1, 0x1c, 0x63, 0xc3, 0x23, 0x39, 0xc6, 0x15, - 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc6, 0x23, 0x39, 0xc6, - 0x07, 0x8f, 0xe4, 0x18, 0x5f, 0x3c, 0x92, 0x63, 0xf8, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, - 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x12, 0x29, 0xae, 0x2c, 0x2e, 0x49, - 0xcd, 0x0d, 0xce, 0x4d, 0x2c, 0x2a, 0x81, 0x39, 0xad, 0x38, 0x89, 0x0d, 0xec, 0x6d, 0x63, 0x40, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x17, 0xf9, 0x32, 0x43, 0x01, 0x00, 0x00, -} - -func (this *LiquidStakingAttributes) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*LiquidStakingAttributes) - if !ok { - that2, ok := that.(LiquidStakingAttributes) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if !bytes.Equal(this.ContractAddress, that1.ContractAddress) { - return false - } - if this.RewardsCheckpoint != that1.RewardsCheckpoint { - return false - } - return true -} -func (this *LiquidStakingAttributes) GoString() string { - if this == nil { - return "nil" - } - s := make([]string, 0, 6) - s = append(s, "&systemSmartContracts.LiquidStakingAttributes{") - s = append(s, "ContractAddress: "+fmt.Sprintf("%#v", this.ContractAddress)+",\n") - s = append(s, "RewardsCheckpoint: "+fmt.Sprintf("%#v", this.RewardsCheckpoint)+",\n") - s = append(s, "}") - return strings.Join(s, "") -} -func valueToGoStringLiquidStaking(v interface{}, typ string) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) -} -func (m *LiquidStakingAttributes) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *LiquidStakingAttributes) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *LiquidStakingAttributes) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.RewardsCheckpoint != 0 { - i = encodeVarintLiquidStaking(dAtA, i, uint64(m.RewardsCheckpoint)) - i-- - dAtA[i] = 0x10 - } - if len(m.ContractAddress) > 0 { - i -= len(m.ContractAddress) - copy(dAtA[i:], m.ContractAddress) - i = encodeVarintLiquidStaking(dAtA, i, uint64(len(m.ContractAddress))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintLiquidStaking(dAtA []byte, offset int, v uint64) int { - offset -= sovLiquidStaking(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *LiquidStakingAttributes) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ContractAddress) - if l > 0 { - n += 1 + l + sovLiquidStaking(uint64(l)) - } - if m.RewardsCheckpoint != 0 { - n += 1 + sovLiquidStaking(uint64(m.RewardsCheckpoint)) - } - return n -} - -func sovLiquidStaking(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozLiquidStaking(x uint64) (n int) { - return sovLiquidStaking(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *LiquidStakingAttributes) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&LiquidStakingAttributes{`, - `ContractAddress:` + fmt.Sprintf("%v", this.ContractAddress) + `,`, - `RewardsCheckpoint:` + fmt.Sprintf("%v", this.RewardsCheckpoint) + `,`, - `}`, - }, "") - return s -} -func valueToStringLiquidStaking(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *LiquidStakingAttributes) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowLiquidStaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: LiquidStakingAttributes: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: LiquidStakingAttributes: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowLiquidStaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthLiquidStaking - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthLiquidStaking - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContractAddress = append(m.ContractAddress[:0], dAtA[iNdEx:postIndex]...) - if m.ContractAddress == nil { - m.ContractAddress = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RewardsCheckpoint", wireType) - } - m.RewardsCheckpoint = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowLiquidStaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RewardsCheckpoint |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipLiquidStaking(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthLiquidStaking - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthLiquidStaking - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipLiquidStaking(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowLiquidStaking - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowLiquidStaking - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowLiquidStaking - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthLiquidStaking - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupLiquidStaking - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthLiquidStaking - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthLiquidStaking = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowLiquidStaking = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupLiquidStaking = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vm/systemSmartContracts/liquidStaking.proto b/vm/systemSmartContracts/liquidStaking.proto deleted file mode 100644 index b9e46450c9d..00000000000 --- a/vm/systemSmartContracts/liquidStaking.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package proto; - -option go_package = "systemSmartContracts"; -option (gogoproto.stable_marshaler_all) = true; - -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; - -message LiquidStakingAttributes { - bytes ContractAddress = 1 [(gogoproto.jsontag) = "ContractAddress"]; - uint32 RewardsCheckpoint = 2 [(gogoproto.jsontag) = "RewardsCheckpoint"]; -} diff --git a/vm/systemSmartContracts/liquidStaking_test.go b/vm/systemSmartContracts/liquidStaking_test.go deleted file mode 100644 index 9491c428adc..00000000000 --- a/vm/systemSmartContracts/liquidStaking_test.go +++ /dev/null @@ -1,553 +0,0 @@ -package systemSmartContracts - -import ( - "bytes" - "errors" - "math/big" - "testing" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-go/config" - "github.com/multiversx/mx-chain-go/testscommon" - "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" - "github.com/multiversx/mx-chain-go/vm" - "github.com/multiversx/mx-chain-go/vm/mock" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" - "github.com/stretchr/testify/assert" -) - -func createMockArgumentsForLiquidStaking() ArgsNewLiquidStaking { - return ArgsNewLiquidStaking{ - EpochConfig: config.EpochConfig{}, - Eei: &mock.SystemEIStub{}, - LiquidStakingSCAddress: vm.LiquidStakingSCAddress, - GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{LiquidStakingOps: 10}}, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: true}, - } -} - -func createLiquidStakingContractAndEEI() (*liquidStaking, *vmContext) { - args := createMockArgumentsForLiquidStaking() - argsVMContext := createArgsVMContext() - argsVMContext.EnableEpochsHandler = args.EnableEpochsHandler - eei, _ := NewVMContext(argsVMContext) - systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - - _ = eei.SetSystemSCContainer(systemSCContainerStub) - - args.Eei = eei - l, _ := NewLiquidStakingSystemSC(args) - l.eei.SetStorage([]byte(tokenIDKey), []byte("TKN")) - return l, eei -} - -func TestLiquidStaking_NilEEI(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - args.Eei = nil - _, err := NewLiquidStakingSystemSC(args) - assert.Equal(t, err, vm.ErrNilSystemEnvironmentInterface) -} - -func TestLiquidStaking_NilAddress(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - args.LiquidStakingSCAddress = nil - _, err := NewLiquidStakingSystemSC(args) - assert.True(t, errors.Is(err, vm.ErrInvalidAddress)) -} - -func TestLiquidStaking_NilMarshalizer(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - args.Marshalizer = nil - _, err := NewLiquidStakingSystemSC(args) - assert.True(t, errors.Is(err, vm.ErrNilMarshalizer)) -} - -func TestLiquidStaking_NilHasher(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - args.Hasher = nil - _, err := NewLiquidStakingSystemSC(args) - assert.True(t, errors.Is(err, vm.ErrNilHasher)) -} - -func TestLiquidStaking_NilEpochNotifier(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - args.EnableEpochsHandler = nil - l, err := NewLiquidStakingSystemSC(args) - assert.True(t, errors.Is(err, vm.ErrNilEnableEpochsHandler)) - assert.True(t, l.IsInterfaceNil()) -} - -func TestLiquidStaking_New(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - l, err := NewLiquidStakingSystemSC(args) - assert.Nil(t, err) - assert.NotNil(t, l) - assert.False(t, l.IsInterfaceNil()) -} - -func TestLiquidStaking_CanUseContract(t *testing.T) { - t.Parallel() - - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: false} - - args := createMockArgumentsForLiquidStaking() - args.EnableEpochsHandler = enableEpochsHandler - l, _ := NewLiquidStakingSystemSC(args) - assert.False(t, l.CanUseContract()) - - enableEpochsHandler.IsLiquidStakingEnabledField = true - args.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch = 0 - l, _ = NewLiquidStakingSystemSC(args) - assert.True(t, l.CanUseContract()) -} - -func TestLiquidStaking_SetNewGasConfig(t *testing.T) { - t.Parallel() - - args := createMockArgumentsForLiquidStaking() - l, _ := NewLiquidStakingSystemSC(args) - - assert.Equal(t, l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps, uint64(10)) - gasCost := vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{LiquidStakingOps: 100}} - l.SetNewGasCost(gasCost) - assert.Equal(t, l.gasCost.MetaChainSystemSCsCost.LiquidStakingOps, uint64(100)) -} - -func TestLiquidStaking_NotActiveWrongCalls(t *testing.T) { - t.Parallel() - - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: false} - l, eei := createLiquidStakingContractAndEEI() - l.enableEpochsHandler = enableEpochsHandler - - returnCode := l.Execute(nil) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, vm.ErrInputArgsIsNil.Error()) - - eei.returnMessage = "" - vmInput := getDefaultVmInputForFunc("returnViaLiquidStaking", make([][]byte, 0)) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "liquid staking contract is not enabled") - - enableEpochsHandler.IsLiquidStakingEnabledField = true - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, vmInput.Function+" is an unknown function") -} - -func TestLiquidStaking_init(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc(core.SCDeployInitFunctionName, make([][]byte, 0)) - - eei.returnMessage = "" - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "invalid caller") - - eei.returnMessage = "" - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.CallValue = big.NewInt(10) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function is not payable in eGLD") - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(0) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "invalid number of arguments") - - vmInput.Arguments = append(vmInput.Arguments, []byte("tokenID")) - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) - assert.Equal(t, l.getTokenID(), []byte("tokenID")) -} - -func TestLiquidStaking_checkArgumentsWhenPosition(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc("claimRewardsFromPosition", make([][]byte, 0)) - - eei.returnMessage = "" - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function requires liquid staking input") - - eei.returnMessage = "" - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10)}} - vmInput.CallValue = big.NewInt(10) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function is not payable in eGLD") - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(0) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "wrong tokenID input") - - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID()}} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.OutOfGas) -} - -func TestLiquidStaking_ClaimDelegatedPosition(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(10) - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function is not payable in eGLD") - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(0) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "not enough arguments") - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{{3}, {2}, {3}} - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID()}} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function is not payable in ESDT") - - eei.returnMessage = "" - vmInput.ESDTTransfers = nil - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "not enough arguments") - - vmInput.Arguments[0] = []byte{1} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.OutOfGas) - - eei.returnMessage = "" - eei.gasRemaining = 1000 - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "invalid destination SC address") - - localErr := errors.New("local err") - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return nil, localErr - }} - - vmInput.Arguments[1] = bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{} - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return nil, localErr - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - if input.Function == core.BuiltInFunctionMultiESDTNFTTransfer { - return nil, localErr - } - return &vmcommon.VMOutput{ - ReturnData: [][]byte{{1}}, - }, nil - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.returnMessage = "" - vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) - eei.blockChainHook = &mock.BlockChainHookStub{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) -} - -func TestLiquidStaking_ClaimRewardsFromDelegatedPosition(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc("claimRewardsFromPosition", make([][]byte, 0)) - vmInput.Arguments = [][]byte{{3}, {2}, {3}} - - eei.returnMessage = "" - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function requires liquid staking input") - - eei.gasRemaining = 1000 - eei.returnMessage = "" - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID(), ESDTTokenNonce: 1}} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, vm.ErrEmptyStorage.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return &vmcommon.VMOutput{ - ReturnData: [][]byte{{1}}, - }, nil - }} - _, _ = l.createOrAddNFT(vm.FirstDelegationSCAddress, 10, big.NewInt(10)) - localErr := errors.New("local err") - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return nil, localErr - }} - - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{} - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return nil, localErr - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - if input.Function == core.BuiltInFunctionMultiESDTNFTTransfer { - return nil, localErr - } - return &vmcommon.VMOutput{ - ReturnData: [][]byte{{1}}, - }, nil - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.returnMessage = "" - vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) - eei.blockChainHook = &mock.BlockChainHookStub{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) -} - -func TestLiquidStaking_ReDelegateRewardsFromPosition(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc("reDelegateRewardsFromPosition", make([][]byte, 0)) - vmInput.Arguments = [][]byte{{3}, {2}, {3}} - - eei.returnMessage = "" - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function requires liquid staking input") - - eei.gasRemaining = 1000 - eei.returnMessage = "" - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID(), ESDTTokenNonce: 1}} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, vm.ErrEmptyStorage.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return &vmcommon.VMOutput{ - ReturnData: [][]byte{{1}}, - }, nil - }} - _, _ = l.createOrAddNFT(vm.FirstDelegationSCAddress, 10, big.NewInt(10)) - localErr := errors.New("local err") - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return nil, localErr - }} - - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{} - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return nil, localErr - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - if input.Function == core.BuiltInFunctionMultiESDTNFTTransfer { - return nil, localErr - } - return &vmcommon.VMOutput{ - ReturnData: [][]byte{{1}}, - }, nil - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "invalid return data") - - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - eei.Finish(big.NewInt(10).Bytes()) - return vmcommon.Ok - }}, nil - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.returnMessage = "" - vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) - eei.blockChainHook = &mock.BlockChainHookStub{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) -} - -func TestLiquidStaking_ReturnLiquidStaking(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc("unDelegatePosition", make([][]byte, 0)) - vmInput.Arguments = [][]byte{{3}, {2}, {3}} - - eei.returnMessage = "" - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function requires liquid staking input") - - eei.gasRemaining = 1000 - eei.returnMessage = "" - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID(), ESDTTokenNonce: 1}} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, vm.ErrEmptyStorage.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return &vmcommon.VMOutput{ - ReturnData: [][]byte{{1}}, - }, nil - }} - _, _ = l.createOrAddNFT(vm.FirstDelegationSCAddress, 10, big.NewInt(10)) - localErr := errors.New("local err") - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return nil, localErr - }} - - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{} - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return nil, localErr - }} - eei.returnMessage = "" - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.systemContracts = &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - return vmcommon.Ok - }}, nil - }} - eei.returnMessage = "" - vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) - eei.blockChainHook = &mock.BlockChainHookStub{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) - - vmInput.Function = "returnPosition" - eei.returnMessage = "" - vmInput.Arguments = append(vmInput.Arguments, [][]byte{{1}, {2}}...) - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) -} - -func TestLiquidStaking_ReadTokenID(t *testing.T) { - t.Parallel() - - l, eei := createLiquidStakingContractAndEEI() - vmInput := getDefaultVmInputForFunc("readTokenID", make([][]byte, 0)) - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(10) - returnCode := l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function is not payable") - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(0) - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10), ESDTTokenName: l.getTokenID()}} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function is not payable") - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{{3}, {2}, {3}} - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.UserError) - assert.Equal(t, eei.returnMessage, "function does not accept arguments") - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.OutOfGas) - - eei.gasRemaining = 100000 - eei.returnMessage = "" - vmInput.Arguments = [][]byte{} - returnCode = l.Execute(vmInput) - assert.Equal(t, returnCode, vmcommon.Ok) - assert.Equal(t, eei.output[0], l.getTokenID()) -} From 70d812b41bb3d467e1bd6ebb7b0a9044dbc094ac Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 31 Jan 2023 12:37:52 +0200 Subject: [PATCH 389/958] FEAT: Remove LS files --- .../config/gasSchedules/gasScheduleV1.toml | 1 - .../config/gasSchedules/gasScheduleV2.toml | 1 - .../config/gasSchedules/gasScheduleV3.toml | 1 - .../config/gasSchedules/gasScheduleV4.toml | 1 - .../config/gasSchedules/gasScheduleV5.toml | 1 - .../config/gasSchedules/gasScheduleV6.toml | 1 - .../config/gasSchedules/gasScheduleV7.toml | 1 - common/enablers/enableEpochsHandler.go | 2 - common/enablers/enableEpochsHandler_test.go | 6 - common/enablers/epochFlags.go | 16 +- common/interface.go | 2 - examples/address_test.go | 3 - .../metachain/vmContainerFactory_test.go | 1 - sharding/mock/enableEpochsHandlerMock.go | 10 - testscommon/enableEpochsHandlerStub.go | 18 - vm/address.go | 3 - vm/gasCost.go | 1 - vm/systemSmartContracts/defaults/gasMap.go | 1 - vm/systemSmartContracts/delegation_test.go | 372 ------------------ vm/systemSmartContracts/eei_test.go | 40 -- 20 files changed, 1 insertion(+), 481 deletions(-) diff --git a/cmd/node/config/gasSchedules/gasScheduleV1.toml b/cmd/node/config/gasSchedules/gasScheduleV1.toml index 40d4046f161..6553ceb9269 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV1.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV1.toml @@ -39,7 +39,6 @@ ValidatorToDelegation = 500000000 GetAllNodeStates = 100000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV2.toml b/cmd/node/config/gasSchedules/gasScheduleV2.toml index 94497e3210a..4f9da0c70ce 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV2.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV2.toml @@ -39,7 +39,6 @@ ValidatorToDelegation = 500000000 GetAllNodeStates = 100000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV3.toml b/cmd/node/config/gasSchedules/gasScheduleV3.toml index 4e1668021cd..9571bddb584 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV3.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV3.toml @@ -39,7 +39,6 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 50000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV4.toml b/cmd/node/config/gasSchedules/gasScheduleV4.toml index 5a1be21a73e..dadcd264502 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV4.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV4.toml @@ -39,7 +39,6 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV5.toml b/cmd/node/config/gasSchedules/gasScheduleV5.toml index 4138b4a5adc..6ba7ed70af0 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV5.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV5.toml @@ -39,7 +39,6 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV6.toml b/cmd/node/config/gasSchedules/gasScheduleV6.toml index 96ab059b524..cc69a1bc1e9 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV6.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV6.toml @@ -39,7 +39,6 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/cmd/node/config/gasSchedules/gasScheduleV7.toml b/cmd/node/config/gasSchedules/gasScheduleV7.toml index a5cb7f5be0a..9f395424c19 100644 --- a/cmd/node/config/gasSchedules/gasScheduleV7.toml +++ b/cmd/node/config/gasSchedules/gasScheduleV7.toml @@ -40,7 +40,6 @@ UnstakeTokens = 5000000 UnbondTokens = 5000000 FixWaitingListSize = 500000000 - LiquidStakingOps = 10000000 [BaseOperationCost] StorePerByte = 10000 diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 7e7198f3e23..1407ec06a11 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -121,9 +121,7 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4InitFlag, "stakingV4InitFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4EnableEpoch, handler.stakingV4Flag, "stakingV4Flag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") - handler.setFlagValue(epoch == handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, handler.initLiquidStakingFlag, "initLiquidStakingFlag") handler.setFlagValue(epoch < handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingQueueEnabledFlag, "stakingQueueEnabledFlag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, handler.liquidStakingFlag, "liquidStakingFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4StartedFlag, "stakingV4StartedFlag") } diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 9869902e9e0..bf81ab8ea47 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -220,8 +220,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsStakingV4Enabled()) assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) assert.False(t, handler.IsStakingQueueEnabled()) - assert.False(t, handler.IsInitLiquidStakingEnabled()) - assert.True(t, handler.IsLiquidStakingEnabled()) assert.True(t, handler.IsStakingV4Started()) }) t.Run("flags with == condition should be set, along with all >=", func(t *testing.T) { @@ -329,8 +327,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsStakingV4Enabled()) assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) assert.False(t, handler.IsStakingQueueEnabled()) - assert.True(t, handler.IsInitLiquidStakingEnabled()) - assert.True(t, handler.IsLiquidStakingEnabled()) assert.True(t, handler.IsStakingV4Started()) }) t.Run("flags with < should be set", func(t *testing.T) { @@ -431,8 +427,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsStakingV4Enabled()) assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) assert.True(t, handler.IsStakingQueueEnabled()) - assert.False(t, handler.IsInitLiquidStakingEnabled()) - assert.False(t, handler.IsLiquidStakingEnabled()) assert.False(t, handler.IsStakingV4Started()) }) } diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index 97bb30818fd..6a2e79019f6 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -94,8 +94,6 @@ type epochFlagsHolder struct { stakingV4Flag *atomic.Flag stakingV4DistributeAuctionToWaitingFlag *atomic.Flag stakingQueueEnabledFlag *atomic.Flag - initLiquidStakingFlag *atomic.Flag - liquidStakingFlag *atomic.Flag stakingV4StartedFlag *atomic.Flag } @@ -190,8 +188,6 @@ func newEpochFlagsHolder() *epochFlagsHolder { stakingV4Flag: &atomic.Flag{}, stakingV4DistributeAuctionToWaitingFlag: &atomic.Flag{}, stakingQueueEnabledFlag: &atomic.Flag{}, - initLiquidStakingFlag: &atomic.Flag{}, - liquidStakingFlag: &atomic.Flag{}, stakingV4StartedFlag: &atomic.Flag{}, } } @@ -689,22 +685,12 @@ func (holder *epochFlagsHolder) IsStakingV4DistributeAuctionToWaitingEnabled() b return holder.stakingV4DistributeAuctionToWaitingFlag.IsSet() } -// IsInitLiquidStakingEnabled returns true if initLiquidStakingFlag is enabled -func (holder *epochFlagsHolder) IsInitLiquidStakingEnabled() bool { - return holder.initLiquidStakingFlag.IsSet() -} - // IsStakingQueueEnabled returns true if stakingQueueEnabledFlag is enabled func (holder *epochFlagsHolder) IsStakingQueueEnabled() bool { return holder.stakingQueueEnabledFlag.IsSet() } -// IsLiquidStakingEnabled returns true if liquidStakingFlag is enabled -func (holder *epochFlagsHolder) IsLiquidStakingEnabled() bool { - return holder.liquidStakingFlag.IsSet() -} - -// IsStakingV4Started returns true if liquidStakingFlag is enabled +// IsStakingV4Started returns true if stakingV4StartedFlag is enabled func (holder *epochFlagsHolder) IsStakingV4Started() bool { return holder.stakingV4StartedFlag.IsSet() } diff --git a/common/interface.go b/common/interface.go index 3273e866237..4d019c3b2c7 100644 --- a/common/interface.go +++ b/common/interface.go @@ -341,9 +341,7 @@ type EnableEpochsHandler interface { IsStakingV4InitEnabled() bool IsStakingV4Enabled() bool IsStakingV4DistributeAuctionToWaitingEnabled() bool - IsInitLiquidStakingEnabled() bool IsStakingQueueEnabled() bool - IsLiquidStakingEnabled() bool IsStakingV4Started() bool IsInterfaceNil() bool diff --git a/examples/address_test.go b/examples/address_test.go index 6847ed3f56a..fb7539e738d 100644 --- a/examples/address_test.go +++ b/examples/address_test.go @@ -70,7 +70,6 @@ func TestSystemSCsAddressesAndSpecialAddresses(t *testing.T) { endOfEpochAddress := addressEncoder.Encode(vm.EndOfEpochAddress) delegationManagerScAddress := addressEncoder.Encode(vm.DelegationManagerSCAddress) firstDelegationScAddress := addressEncoder.Encode(vm.FirstDelegationSCAddress) - liquidStakingSCAddress := addressEncoder.Encode(vm.LiquidStakingSCAddress) genesisMintingAddressBytes, err := hex.DecodeString("f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0") require.NoError(t, err) @@ -92,7 +91,6 @@ func TestSystemSCsAddressesAndSpecialAddresses(t *testing.T) { display.NewLineData(false, []string{"First delegation", firstDelegationScAddress}), display.NewLineData(false, []string{"Genesis Minting Address", genesisMintingAddress}), display.NewLineData(false, []string{"System Account Address", systemAccountAddress}), - display.NewLineData(false, []string{"Liquid staking", liquidStakingSCAddress}), display.NewLineData(false, []string{"ESDT Global Settings Shard 0", esdtGlobalSettingsAddresses[0]}), display.NewLineData(false, []string{"ESDT Global Settings Shard 1", esdtGlobalSettingsAddresses[1]}), display.NewLineData(false, []string{"ESDT Global Settings Shard 2", esdtGlobalSettingsAddresses[2]}), @@ -112,7 +110,6 @@ func TestSystemSCsAddressesAndSpecialAddresses(t *testing.T) { assert.Equal(t, "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", contractDeployScAdress) assert.Equal(t, "erd17rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rcqqkhty3", genesisMintingAddress) assert.Equal(t, "erd1lllllllllllllllllllllllllllllllllllllllllllllllllllsckry7t", systemAccountAddress) - assert.Equal(t, "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq9lllsm6xupm", liquidStakingSCAddress) assert.Equal(t, "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqq2m3f0f", esdtGlobalSettingsAddresses[0]) assert.Equal(t, "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", esdtGlobalSettingsAddresses[1]) assert.Equal(t, "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", esdtGlobalSettingsAddresses[2]) diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 69412ef1c09..546a0410057 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -431,7 +431,6 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value gasMap["FixWaitingListSize"] = value - gasMap["LiquidStakingOps"] = value return gasMap } diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index e770ec03c81..ab82535cd14 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -581,21 +581,11 @@ func (mock *EnableEpochsHandlerMock) IsStakingV4DistributeAuctionToWaitingEnable return false } -// IsInitLiquidStakingEnabled - -func (mock *EnableEpochsHandlerMock) IsInitLiquidStakingEnabled() bool { - return false -} - // IsStakingQueueEnabled - func (mock *EnableEpochsHandlerMock) IsStakingQueueEnabled() bool { return false } -// IsLiquidStakingEnabled - -func (mock *EnableEpochsHandlerMock) IsLiquidStakingEnabled() bool { - return false -} - // IsStakingV4Started - func (mock *EnableEpochsHandlerMock) IsStakingV4Started() bool { return false diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 66f94bfd7eb..7982d15a3e5 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -123,9 +123,7 @@ type EnableEpochsHandlerStub struct { IsStakingV4InitFlagEnabledField bool IsStakingV4FlagEnabledField bool IsStakingV4DistributeAuctionToWaitingEnabledField bool - IsInitLiquidStakingEnabledField bool IsStakingQueueEnabledField bool - IsLiquidStakingEnabledField bool IsStakingV4StartedField bool IsStakingV4EnabledCalled func() bool } @@ -1053,14 +1051,6 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4DistributeAuctionToWaitingEnable return stub.IsStakingV4DistributeAuctionToWaitingEnabledField } -// IsInitLiquidStakingEnabled - -func (stub *EnableEpochsHandlerStub) IsInitLiquidStakingEnabled() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsInitLiquidStakingEnabledField -} - // IsStakingQueueEnabled - func (stub *EnableEpochsHandlerStub) IsStakingQueueEnabled() bool { stub.RLock() @@ -1069,14 +1059,6 @@ func (stub *EnableEpochsHandlerStub) IsStakingQueueEnabled() bool { return stub.IsStakingQueueEnabledField } -// IsLiquidStakingEnabled - -func (stub *EnableEpochsHandlerStub) IsLiquidStakingEnabled() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsLiquidStakingEnabledField -} - // IsStakingV4Started - func (stub *EnableEpochsHandlerStub) IsStakingV4Started() bool { stub.RLock() diff --git a/vm/address.go b/vm/address.go index 736cb632248..89ffe44d44f 100644 --- a/vm/address.go +++ b/vm/address.go @@ -21,8 +21,5 @@ var EndOfEpochAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 255, // DelegationManagerSCAddress is the hard-coded address for the delegation manager smart contract var DelegationManagerSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 255, 255} -// LiquidStakingSCAddress is the hard-coded address for the delegation token smart contract -var LiquidStakingSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 255, 255} - // FirstDelegationSCAddress is the hard-coded address for the first delegation contract, the other will follow var FirstDelegationSCAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255} diff --git a/vm/gasCost.go b/vm/gasCost.go index 286e0747820..57762655960 100644 --- a/vm/gasCost.go +++ b/vm/gasCost.go @@ -35,7 +35,6 @@ type MetaChainSystemSCsCost struct { ValidatorToDelegation uint64 GetAllNodeStates uint64 FixWaitingListSize uint64 - LiquidStakingOps uint64 } // BuiltInCost defines cost for built-in methods diff --git a/vm/systemSmartContracts/defaults/gasMap.go b/vm/systemSmartContracts/defaults/gasMap.go index 96c30bdf632..9137f03cc35 100644 --- a/vm/systemSmartContracts/defaults/gasMap.go +++ b/vm/systemSmartContracts/defaults/gasMap.go @@ -76,7 +76,6 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value gasMap["FixWaitingListSize"] = value - gasMap["LiquidStakingOps"] = value return gasMap } diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 31f44e0d1f5..55a1881055a 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -4920,375 +4920,3 @@ func TestDelegation_FailsIfESDTTransfers(t *testing.T) { assert.Equal(t, vmcommon.UserError, returnCode) assert.Equal(t, eei.returnMessage, "cannot transfer ESDT to system SCs") } - -func TestDelegation_BasicCheckForLiquidStaking(t *testing.T) { - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsLiquidStakingEnabledField: false, IsDelegationSmartContractFlagEnabledField: true} - d, eei := createDelegationContractAndEEI() - d.enableEpochsHandler = enableEpochsHandler - - vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, vmInput.Function+" is an unknown function") - - eei.returnMessage = "" - enableEpochsHandler.IsLiquidStakingEnabledField = true - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") - - eei.returnMessage = "" - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.CallValue = big.NewInt(10) - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "call value must be 0") - - eei.returnMessage = "" - vmInput.CallValue = big.NewInt(0) - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "not enough arguments") - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{{1}, {2}} - eei.gasRemaining = 0 - d.gasCost.MetaChainSystemSCsCost.DelegationOps = 1 - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.OutOfGas, returnCode) - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{{1}, {0}} - eei.gasRemaining = 10000 - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid argument for value as bigInt") - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{{1}, {1}} - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid address as input") - - eei.returnMessage = "" - vmInput.Arguments = [][]byte{vm.LiquidStakingSCAddress, {1}} - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "call value below minimum to operate") - - eei.SetStorageForAddress(d.delegationMgrSCAddress, []byte(delegationManagementKey), nil) - eei.returnMessage = "" - vmInput.Arguments = [][]byte{vm.LiquidStakingSCAddress, {1}} - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key getDelegationManagementData") - - eei.returnMessage = "" - d.eei.SetStorage([]byte(ownerKey), vm.LiquidStakingSCAddress) - vmInput.Arguments = [][]byte{vm.LiquidStakingSCAddress, {1}} - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "owner of delegation cannot call liquid staking operations") -} - -func TestDelegation_ClaimDelegatedPosition(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") - - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "caller is not a delegator") - - delegator := &DelegatorData{ - RewardsCheckpoint: 10, - UnClaimedRewards: big.NewInt(0), - } - _ = d.saveDelegatorData(userAddress, delegator) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key getFund ") - - _ = d.addToActiveFund(userAddress, delegator, big.NewInt(5), &DelegationContractStatus{}, true) - _ = d.saveDelegatorData(userAddress, delegator) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "not enough funds to claim position") - - _ = d.addToActiveFund(userAddress, delegator, big.NewInt(5), &DelegationContractStatus{}, true) - _ = d.saveDelegatorData(userAddress, delegator) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key delegation status") - - _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) - delegator.ActiveFund = nil - _ = d.addToActiveFund(userAddress, delegator, big.NewInt(11), &DelegationContractStatus{}, true) - _ = d.saveDelegatorData(userAddress, delegator) - - eei.returnMessage = "" - vmInput.Arguments[1] = big.NewInt(10).Bytes() - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, vm.ErrNotEnoughRemainingFunds.Error()) - - eei.returnMessage = "" - vmInput.Arguments[1] = big.NewInt(11).Bytes() - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - - isNew, _, _ := d.getOrCreateDelegatorData(userAddress) - assert.True(t, isNew) -} - -func TestDelegation_ClaimDelegatedPositionUserRemainsRewardsComputed(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} - vmInput.CallerAddr = vm.LiquidStakingSCAddress - - delegator := &DelegatorData{ - RewardsCheckpoint: 0, - UnClaimedRewards: big.NewInt(0), - } - - _ = d.addToActiveFund(userAddress, delegator, big.NewInt(25), &DelegationContractStatus{}, true) - _ = d.saveDelegatorData(userAddress, delegator) - _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) - - _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(25)}) - _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(25)}) - - eei.returnMessage = "" - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - assert.Equal(t, eei.returnMessage, "") - - isNew, delegator, _ := d.getOrCreateDelegatorData(userAddress) - assert.False(t, isNew) - fund, _ := d.getFund(delegator.ActiveFund) - assert.Equal(t, fund.Value, big.NewInt(15)) - assert.Equal(t, delegator.RewardsCheckpoint, uint32(3)) - assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(20)) - - vmInput.Arguments[1] = fund.Value.Bytes() - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - assert.Equal(t, eei.returnMessage, "") - - _, delegator, _ = d.getOrCreateDelegatorData(userAddress) - assert.Equal(t, len(delegator.ActiveFund), 0) - assert.Equal(t, delegator.RewardsCheckpoint, uint32(3)) - assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(20)) -} - -func TestDelegation_ClaimRewardsViaLiquidStaking(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - vmInput := getDefaultVmInputForFunc("claimRewardsViaLiquidStaking", make([][]byte, 0)) - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") - - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid number of arguments") - - vmInput.Arguments = append(vmInput.Arguments, big.NewInt(1).Bytes()) - - _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) - _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - outAcc := eei.outputAccounts[string(userAddress)] - assert.Equal(t, big.NewInt(20), outAcc.OutputTransfers[0].Value) -} - -func TestDelegation_ReDelegateRewardsViaLiquidStaking(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - vmInput := getDefaultVmInputForFunc("reDelegateRewardsViaLiquidStaking", make([][]byte, 0)) - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") - - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid number of arguments") - - vmInput.Arguments = append(vmInput.Arguments, big.NewInt(1).Bytes()) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "no rewards to redelegate via liquid staking") - - _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) - _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(10)}) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key delegation contract config") - - _ = d.saveDelegationContractConfig(&DelegationConfig{MaxDelegationCap: big.NewInt(20), CheckCapOnReDelegateRewards: true}) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key getGlobalFundData") - - _ = d.saveGlobalFundData(&GlobalFundData{TotalActive: big.NewInt(10), TotalUnStaked: big.NewInt(0)}) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key delegation status") - - _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "total delegation cap reached") - - _ = d.saveDelegationContractConfig(&DelegationConfig{MaxDelegationCap: big.NewInt(20)}) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - assert.Equal(t, eei.output[0], big.NewInt(20).Bytes()) - - systemSCContainerStub := &mock.SystemSCContainerStub{GetCalled: func(key []byte) (vm.SystemSmartContract, error) { - return &mock.SystemSCStub{ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - eei.AddReturnMessage("bad call") - return vmcommon.UserError - }}, nil - }} - - _ = eei.SetSystemSCContainer(systemSCContainerStub) - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "bad call") -} - -func TestDelegation_UnDelegateViaLiquidStaking(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - vmInput := getDefaultVmInputForFunc("unDelegateViaLiquidStaking", make([][]byte, 0)) - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") - - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid number of arguments") - - eei.returnMessage = "" - vmInput.Arguments = append(vmInput.Arguments, []byte{1}) - _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) - _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) - _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) - - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "data was not found under requested key getGlobalFundData") - - d.eei.SetStorage(userAddress, nil) - eei.returnMessage = "" - _ = d.saveGlobalFundData(&GlobalFundData{TotalActive: big.NewInt(10), TotalUnStaked: big.NewInt(100)}) - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - - _, delegator, _ := d.getOrCreateDelegatorData(userAddress) - assert.Equal(t, len(delegator.ActiveFund), 0) - assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(10)) - assert.Equal(t, len(delegator.UnStakedFunds), 1) - unStakedFund, _ := d.getFund(delegator.UnStakedFunds[0]) - assert.Equal(t, unStakedFund.Value, big.NewInt(10)) - - globalFund, _ := d.getGlobalFundData() - assert.Equal(t, globalFund.TotalUnStaked, big.NewInt(110)) - assert.Equal(t, globalFund.TotalActive, big.NewInt(0)) -} - -func TestDelegation_ReturnViaLiquidStaking(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - userAddress := bytes.Repeat([]byte{1}, len(vm.LiquidStakingSCAddress)) - vmInput := getDefaultVmInputForFunc("returnViaLiquidStaking", make([][]byte, 0)) - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only liquid staking sc can call this function") - - vmInput.CallerAddr = vm.LiquidStakingSCAddress - vmInput.Arguments = [][]byte{userAddress, big.NewInt(10).Bytes()} - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid number of arguments") - - _ = d.saveRewardData(1, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) - _ = d.saveRewardData(2, &RewardComputationData{RewardsToDistribute: big.NewInt(10), TotalActive: big.NewInt(20)}) - - delegator := &DelegatorData{RewardsCheckpoint: 0, TotalCumulatedRewards: big.NewInt(0), UnClaimedRewards: big.NewInt(0)} - _ = d.addToActiveFund(userAddress, delegator, big.NewInt(10), &DelegationContractStatus{}, true) - _ = d.saveDelegatorData(userAddress, delegator) - - eei.returnMessage = "" - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "invalid number of arguments") - - vmInput.Arguments = append(vmInput.Arguments, []byte{1}) - _ = d.saveDelegationStatus(&DelegationContractStatus{NumUsers: 10}) - returnCode = d.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) - - _, delegator, _ = d.getOrCreateDelegatorData(userAddress) - assert.Equal(t, delegator.UnClaimedRewards, big.NewInt(20)) - assert.Equal(t, delegator.TotalCumulatedRewards, big.NewInt(0)) - fund, _ := d.getFund(delegator.ActiveFund) - assert.Equal(t, fund.Value, big.NewInt(20)) -} diff --git a/vm/systemSmartContracts/eei_test.go b/vm/systemSmartContracts/eei_test.go index 6b322048e25..d57bda7df47 100644 --- a/vm/systemSmartContracts/eei_test.go +++ b/vm/systemSmartContracts/eei_test.go @@ -263,43 +263,3 @@ func TestVmContext_CleanStorage(t *testing.T) { vmCtx.CleanStorageUpdates() assert.Equal(t, 0, len(vmCtx.storageUpdate)) } - -func TestVmContext_ProcessBuiltInFunction(t *testing.T) { - t.Parallel() - - balance := big.NewInt(10) - account, _ := state.NewUserAccount([]byte("123")) - _ = account.AddToBalance(balance) - - blockChainHook := &mock.BlockChainHookStub{ - ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return &vmcommon.VMOutput{ReturnCode: vmcommon.OutOfGas}, nil - }, - } - - argsVMContext := createArgsVMContext() - argsVMContext.BlockChainHook = blockChainHook - vmCtx, _ := NewVMContext(argsVMContext) - - vmOutput, err := vmCtx.ProcessBuiltInFunction(vm.LiquidStakingSCAddress, vm.LiquidStakingSCAddress, "function", [][]byte{}) - assert.Nil(t, vmOutput) - assert.NotNil(t, err) - - outTransfer := vmcommon.OutputTransfer{Value: big.NewInt(10)} - outAcc := &vmcommon.OutputAccount{OutputTransfers: []vmcommon.OutputTransfer{outTransfer}} - blockChainHook = &mock.BlockChainHookStub{ - ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - output := &vmcommon.VMOutput{} - output.OutputAccounts = make(map[string]*vmcommon.OutputAccount) - output.OutputAccounts["address"] = outAcc - return output, nil - }, - } - vmCtx.blockChainHook = blockChainHook - - vmOutput, err = vmCtx.ProcessBuiltInFunction(vm.LiquidStakingSCAddress, vm.LiquidStakingSCAddress, "function", [][]byte{}) - assert.Nil(t, err) - assert.Equal(t, len(vmCtx.outputAccounts), 1) - assert.Equal(t, len(vmOutput.OutputAccounts), 1) - assert.Equal(t, vmCtx.outputAccounts["address"].Address, []byte("address")) -} From b1279d70208d75ceb1e61c73437b31c73bae1c14 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 31 Jan 2023 12:51:43 +0200 Subject: [PATCH 390/958] FEAT: Remove LS files --- epochStart/errors.go | 3 - epochStart/metachain/systemSCs.go | 50 ---- integrationTests/testProcessorNode.go | 68 ------ testscommon/components/components.go | 2 +- vm/factory/systemSCFactory.go | 23 -- vm/systemSmartContracts/delegation.go | 271 --------------------- vm/systemSmartContracts/delegation_test.go | 12 - vm/systemSmartContracts/esdt.go | 63 ----- vm/systemSmartContracts/esdt_test.go | 75 ------ 9 files changed, 1 insertion(+), 566 deletions(-) diff --git a/epochStart/errors.go b/epochStart/errors.go index 7b7efc79c72..2b3b2a5db81 100644 --- a/epochStart/errors.go +++ b/epochStart/errors.go @@ -329,9 +329,6 @@ var ErrNilValidatorInfoStorage = errors.New("nil validator info storage") // ErrNilTrieSyncStatistics signals that nil trie sync statistics has been provided var ErrNilTrieSyncStatistics = errors.New("nil trie sync statistics") -// ErrCouldNotInitLiquidStakingSystemSC signals that liquid staking system sc init failed -var ErrCouldNotInitLiquidStakingSystemSC = errors.New("could not init liquid staking system sc") - // ErrReceivedNewListNodeInStakingV4 signals that a new node has been assigned in common.NewList instead of common.AuctionList after staking v4 var ErrReceivedNewListNodeInStakingV4 = errors.New("new node has been assigned in common.NewList instead of common.AuctionList after staking v4") diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 5b706ec85e3..6c0311e40c8 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -120,18 +120,6 @@ func (s *systemSCProcessor) processWithNewFlags( } } - if s.enableEpochsHandler.IsInitLiquidStakingEnabled() { - tokenID, err := s.initTokenOnMeta() - if err != nil { - return err - } - - err = s.initLiquidStakingSC(tokenID) - if err != nil { - return err - } - } - if s.enableEpochsHandler.IsStakingV4InitEnabled() { err := s.stakeNodesFromQueue(validatorsInfoMap, math.MaxUint32, header.GetNonce(), common.AuctionList) if err != nil { @@ -255,44 +243,6 @@ func (s *systemSCProcessor) initTokenOnMeta() ([]byte, error) { return vmOutput.ReturnData[0], nil } -func (s *systemSCProcessor) initLiquidStakingSC(tokenID []byte) error { - codeMetaData := &vmcommon.CodeMetadata{ - Upgradeable: false, - Payable: false, - Readable: true, - } - - vmInput := &vmcommon.ContractCreateInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.LiquidStakingSCAddress, - Arguments: [][]byte{tokenID}, - CallValue: big.NewInt(0), - }, - ContractCode: vm.LiquidStakingSCAddress, - ContractCodeMetadata: codeMetaData.ToBytes(), - } - - vmOutput, err := s.systemVM.RunSmartContractCreate(vmInput) - if err != nil { - return err - } - if vmOutput.ReturnCode != vmcommon.Ok { - return epochStart.ErrCouldNotInitLiquidStakingSystemSC - } - - err = s.processSCOutputAccounts(vmOutput) - if err != nil { - return err - } - - err = s.updateSystemSCContractsCode(vmInput.ContractCodeMetadata) - if err != nil { - return err - } - - return nil -} - // IsInterfaceNil returns true if underlying object is nil func (s *systemSCProcessor) IsInterfaceNil() bool { return s == nil diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 353a26483a3..e2d4367b764 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "errors" "fmt" - "math" "math/big" "strconv" "sync" @@ -1861,73 +1860,6 @@ func (tpn *TestProcessorNode) InitDelegationManager() { log.LogIfError(err) } -// InitLiquidStaking will initialize the liquid staking contract whenever required -func (tpn *TestProcessorNode) InitLiquidStaking() []byte { - if tpn.ShardCoordinator.SelfId() != core.MetachainShardId { - return nil - } - - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.ESDTSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{}, - GasProvided: math.MaxUint64, - }, - RecipientAddr: vm.ESDTSCAddress, - Function: "initDelegationESDTOnMeta", - } - - systemVM, err := tpn.VMContainer.Get(factory.SystemVirtualMachine) - log.LogIfError(err) - - vmOutput, err := systemVM.RunSmartContractCall(vmInput) - log.LogIfError(err) - if vmOutput.ReturnCode != vmcommon.Ok { - log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) - } - - err = ProcessSCOutputAccounts(vmOutput, tpn.AccntState) - log.LogIfError(err) - - _, err = tpn.AccntState.Commit() - log.LogIfError(err) - - codeMetaData := &vmcommon.CodeMetadata{ - Upgradeable: false, - Payable: false, - Readable: true, - } - - tokenID := vmOutput.ReturnData[0] - vmInputCreate := &vmcommon.ContractCreateInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.LiquidStakingSCAddress, - Arguments: [][]byte{tokenID}, - CallValue: zero, - }, - ContractCode: vm.DelegationManagerSCAddress, - ContractCodeMetadata: codeMetaData.ToBytes(), - } - - vmOutput, err = systemVM.RunSmartContractCreate(vmInputCreate) - log.LogIfError(err) - if vmOutput.ReturnCode != vmcommon.Ok { - log.Error("error while initializing system SC", "return code", vmOutput.ReturnCode) - } - - err = ProcessSCOutputAccounts(vmOutput, tpn.AccntState) - log.LogIfError(err) - - err = tpn.updateSystemSCContractsCode(vmInputCreate.ContractCodeMetadata, vm.LiquidStakingSCAddress) - log.LogIfError(err) - - _, err = tpn.AccntState.Commit() - log.LogIfError(err) - - return tokenID -} - func (tpn *TestProcessorNode) updateSystemSCContractsCode(contractMetadata []byte, scAddress []byte) error { userAcc, err := tpn.getUserAccount(scAddress) if err != nil { diff --git a/testscommon/components/components.go b/testscommon/components/components.go index cb5dcc51e4b..d73035d689b 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -813,7 +813,7 @@ func FillGasMapMetaChainSystemSCsCosts(value uint64) map[string]uint64 { gasMap["GetAllNodeStates"] = value gasMap["ValidatorToDelegation"] = value gasMap["FixWaitingListSize"] = value - gasMap["LiquidStakingOps"] = value + return gasMap } diff --git a/vm/factory/systemSCFactory.go b/vm/factory/systemSCFactory.go index 3cc7e078c20..e6605f9776e 100644 --- a/vm/factory/systemSCFactory.go +++ b/vm/factory/systemSCFactory.go @@ -294,19 +294,6 @@ func (scf *systemSCFactory) createDelegationManagerContract() (vm.SystemSmartCon return delegationManager, err } -func (scf *systemSCFactory) createLiquidStakingContract() (vm.SystemSmartContract, error) { - argsLiquidStaking := systemSmartContracts.ArgsNewLiquidStaking{ - Eei: scf.systemEI, - LiquidStakingSCAddress: vm.LiquidStakingSCAddress, - GasCost: scf.gasCost, - Marshalizer: scf.marshalizer, - Hasher: scf.hasher, - EnableEpochsHandler: scf.enableEpochsHandler, - } - liquidStaking, err := systemSmartContracts.NewLiquidStakingSystemSC(argsLiquidStaking) - return liquidStaking, err -} - // CreateForGenesis instantiates all the system smart contracts and returns a container containing them to be used in the genesis process func (scf *systemSCFactory) CreateForGenesis() (vm.SystemSCContainer, error) { staking, err := scf.createStakingContract() @@ -384,16 +371,6 @@ func (scf *systemSCFactory) Create() (vm.SystemSCContainer, error) { return nil, err } - liquidStaking, err := scf.createLiquidStakingContract() - if err != nil { - return nil, err - } - - err = scf.systemSCsContainer.Add(vm.LiquidStakingSCAddress, liquidStaking) - if err != nil { - return nil, err - } - err = scf.systemEI.SetSystemSCContainer(scf.systemSCsContainer) if err != nil { return nil, err diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 8fa3d40e586..64daee076ae 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -263,16 +263,6 @@ func (d *delegation) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCo return d.addTokens(args) case "correctNodesStatus": return d.correctNodesStatus(args) - case "claimDelegatedPosition": - return d.claimDelegatedPosition(args) - case "claimRewardsViaLiquidStaking": - return d.claimRewardsViaLiquidStaking(args) - case "reDelegateRewardsViaLiquidStaking": - return d.reDelegateRewardsViaLiquidStaking(args) - case "unDelegateViaLiquidStaking": - return d.unDelegateViaLiquidStaking(args) - case "returnViaLiquidStaking": - return d.returnViaLiquidStaking(args) case changeOwner: return d.changeOwner(args) } @@ -1907,10 +1897,6 @@ func (d *delegation) computeAndUpdateRewards(callerAddress []byte, delegator *De if d.enableEpochsHandler.IsComputeRewardCheckpointFlagEnabled() { delegator.RewardsCheckpoint = currentEpoch + 1 } - // nothing to calculate as no active funds - all were computed before - if d.enableEpochsHandler.IsLiquidStakingEnabled() { - delegator.RewardsCheckpoint = currentEpoch + 1 - } return nil } @@ -2854,194 +2840,6 @@ func (d *delegation) addTokens(args *vmcommon.ContractCallInput) vmcommon.Return return vmcommon.Ok } -func (d *delegation) basicCheckForLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !d.enableEpochsHandler.IsLiquidStakingEnabled() { - d.eei.AddReturnMessage(args.Function + " is an unknown function") - return vmcommon.UserError - } - if !bytes.Equal(args.CallerAddr, vm.LiquidStakingSCAddress) { - d.eei.AddReturnMessage("only liquid staking sc can call this function") - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - d.eei.AddReturnMessage("call value must be 0") - return vmcommon.UserError - } - if len(args.Arguments) < 2 { - d.eei.AddReturnMessage("not enough arguments") - return vmcommon.UserError - } - err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.OutOfGas - } - address := args.Arguments[0] - value := big.NewInt(0).SetBytes(args.Arguments[1]) - if value.Cmp(zero) <= 0 { - d.eei.AddReturnMessage("invalid argument for value as bigInt") - return vmcommon.UserError - } - if len(address) != len(d.validatorSCAddr) { - d.eei.AddReturnMessage("invalid address as input") - return vmcommon.UserError - } - if d.isOwner(address) { - d.eei.AddReturnMessage("owner of delegation cannot call liquid staking operations") - return vmcommon.UserError - } - - delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - minDelegationAmount := delegationManagement.MinDelegationAmount - belowMinDelegationAmount := value.Cmp(minDelegationAmount) < 0 - if belowMinDelegationAmount { - d.eei.AddReturnMessage("call value below minimum to operate") - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (d *delegation) claimDelegatedPosition(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := d.basicCheckForLiquidStaking(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - address := args.Arguments[0] - value := big.NewInt(0).SetBytes(args.Arguments[1]) - - isNew, delegator, err := d.getOrCreateDelegatorData(address) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - if isNew { - d.eei.AddReturnMessage("caller is not a delegator") - return vmcommon.UserError - } - - activeFund, err := d.getFund(delegator.ActiveFund) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - if value.Cmp(activeFund.Value) > 0 { - d.eei.AddReturnMessage("not enough funds to claim position") - return vmcommon.UserError - } - - err = d.computeAndUpdateRewards(address, delegator) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - activeFund.Value.Sub(activeFund.Value, value) - err = d.checkRemainingFundValue(activeFund.Value) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - err = d.saveFund(delegator.ActiveFund, activeFund) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - if activeFund.Value.Cmp(zero) == 0 { - delegator.ActiveFund = nil - } - - err = d.saveDelegatorData(address, delegator) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - _, err = d.deleteDelegatorOnClaimRewardsIfNeeded(address, delegator) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - -func (d *delegation) claimRewardsViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := d.basicCheckForLiquidStaking(args) - if returnCode != vmcommon.Ok { - return returnCode - } - if len(args.Arguments) != 3 { - d.eei.AddReturnMessage("invalid number of arguments") - return vmcommon.UserError - } - - address := args.Arguments[0] - value := big.NewInt(0).SetBytes(args.Arguments[1]) - checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) - - totalRewards, err := d.computeRewards(checkPoint, false, value) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - d.eei.Transfer(address, args.RecipientAddr, totalRewards, nil, 0) - return vmcommon.Ok -} - -func (d *delegation) reDelegateRewardsViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := d.basicCheckForLiquidStaking(args) - if returnCode != vmcommon.Ok { - return returnCode - } - if len(args.Arguments) != 3 { - d.eei.AddReturnMessage("invalid number of arguments") - return vmcommon.UserError - } - - value := big.NewInt(0).SetBytes(args.Arguments[1]) - checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) - totalRewards, err := d.computeRewards(checkPoint, false, value) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - if totalRewards.Cmp(zero) <= 0 { - d.eei.AddReturnMessage("no rewards to redelegate via liquid staking") - return vmcommon.UserError - } - - dConfig, dStatus, globalFund, err := d.getConfigStatusAndGlobalFund() - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - globalFund.TotalActive.Add(globalFund.TotalActive, totalRewards) - withDelegationCap := dConfig.MaxDelegationCap.Cmp(zero) != 0 - if withDelegationCap && dConfig.CheckCapOnReDelegateRewards && globalFund.TotalActive.Cmp(dConfig.MaxDelegationCap) > 0 { - d.eei.AddReturnMessage("total delegation cap reached") - return vmcommon.UserError - } - - returnCode = d.executeStakeAndUpdateStatus(dConfig, dStatus, globalFund, totalRewards, args.RecipientAddr) - if returnCode != vmcommon.Ok { - return returnCode - } - - d.eei.Finish(totalRewards.Bytes()) - return vmcommon.Ok -} - func (d *delegation) executeStakeAndUpdateStatus( dConfig *DelegationConfig, dStatus *DelegationContractStatus, @@ -3097,75 +2895,6 @@ func (d *delegation) getConfigStatusAndGlobalFund() (*DelegationConfig, *Delegat return dConfig, dStatus, globalFund, nil } -func (d *delegation) unDelegateViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := d.returnViaLiquidStaking(args) - if returnCode != vmcommon.Ok { - return returnCode - } - - address := args.Arguments[0] - valueToUnDelegate := big.NewInt(0).SetBytes(args.Arguments[1]) - return d.unDelegateValueFromAddress(args, valueToUnDelegate, address, args.RecipientAddr) -} - -func (d *delegation) returnViaLiquidStaking(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - returnCode := d.basicCheckForLiquidStaking(args) - if returnCode != vmcommon.Ok { - return returnCode - } - if len(args.Arguments) != 3 { - d.eei.AddReturnMessage("invalid number of arguments") - return vmcommon.UserError - } - - address := args.Arguments[0] - value := big.NewInt(0).SetBytes(args.Arguments[1]) - checkPoint := uint32(big.NewInt(0).SetBytes(args.Arguments[2]).Uint64()) - rewardsFromPosition, err := d.computeRewards(checkPoint, false, value) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - isNew, delegator, err := d.getOrCreateDelegatorData(address) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - err = d.computeAndUpdateRewards(address, delegator) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - dStatus, err := d.getDelegationStatus() - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - delegator.UnClaimedRewards.Add(delegator.UnClaimedRewards, rewardsFromPosition) - err = d.addToActiveFund(address, delegator, value, dStatus, isNew) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - err = d.saveDelegationStatus(dStatus) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - err = d.saveDelegatorData(address, delegator) - if err != nil { - d.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok -} - func (d *delegation) executeOnValidatorSC(address []byte, function string, args [][]byte, value *big.Int) (*vmcommon.VMOutput, error) { validatorCall := function for _, key := range args { diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 55a1881055a..1f19b24fb7f 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -53,7 +53,6 @@ func createMockArgumentsForDelegation() ArgsNewDelegation { IsComputeRewardCheckpointFlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, IsReDelegateBelowMinCheckFlagEnabledField: true, - IsLiquidStakingEnabledField: true, }, } } @@ -4909,14 +4908,3 @@ func TestDelegationSystemSC_ExecuteChangeOwner(t *testing.T) { assert.Equal(t, []byte("second123"), eei.logs[1].Address) assert.Equal(t, boolToSlice(true), eei.logs[1].Topics[4]) } - -func TestDelegation_FailsIfESDTTransfers(t *testing.T) { - d, eei := createDelegationContractAndEEI() - - vmInput := getDefaultVmInputForFunc("claimDelegatedPosition", make([][]byte, 0)) - vmInput.ESDTTransfers = []*vmcommon.ESDTTransfer{{ESDTValue: big.NewInt(10)}} - - returnCode := d.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "cannot transfer ESDT to system SCs") -} diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 016beb298aa..1bee94b5845 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -201,8 +201,6 @@ func (e *esdt) Execute(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { return e.unsetBurnRoleGlobally(args) case "sendAllTransferRoleAddresses": return e.sendAllTransferRoleAddresses(args) - case "initDelegationESDTOnMeta": - return e.initDelegationESDTOnMeta(args) } e.eei.AddReturnMessage("invalid method to call") @@ -224,67 +222,6 @@ func (e *esdt) init(_ *vmcommon.ContractCallInput) vmcommon.ReturnCode { return vmcommon.Ok } -func (e *esdt) initDelegationESDTOnMeta(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !e.enableEpochsHandler.IsBuiltInFunctionOnMetaFlagEnabled() { - e.eei.AddReturnMessage("invalid method to call") - return vmcommon.FunctionNotFound - } - if !bytes.Equal(args.CallerAddr, e.esdtSCAddress) { - e.eei.AddReturnMessage("only system address can call this") - return vmcommon.UserError - } - if len(args.Arguments) != 0 { - return vmcommon.UserError - } - if args.CallValue.Cmp(zero) != 0 { - return vmcommon.UserError - } - - tokenIdentifier, _, err := e.createNewToken( - vm.LiquidStakingSCAddress, - []byte(e.delegationTicker), - []byte(e.delegationTicker), - big.NewInt(0), - 0, - nil, - []byte(core.SemiFungibleESDT)) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - token, err := e.getExistingToken(tokenIdentifier) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - esdtRole, _ := getRolesForAddress(token, vm.LiquidStakingSCAddress) - esdtRole.Roles = append(esdtRole.Roles, []byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)) - token.SpecialRoles = append(token.SpecialRoles, esdtRole) - - err = e.saveToken(tokenIdentifier, token) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - _, err = e.eei.ProcessBuiltInFunction( - e.esdtSCAddress, - vm.LiquidStakingSCAddress, - core.BuiltInFunctionSetESDTRole, - [][]byte{tokenIdentifier, []byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTBurn)}, - ) - if err != nil { - e.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - - e.eei.Finish(tokenIdentifier) - - return vmcommon.Ok -} - func (e *esdt) checkBasicCreateArguments(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { err := e.eei.UseGas(e.gasCost.MetaChainSystemSCsCost.ESDTIssue) if err != nil { diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index 9141605c047..d49572718ae 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -45,7 +45,6 @@ func createMockArgumentsForESDT() ArgsNewESDTSmartContract { IsESDTNFTCreateOnMultiShardFlagEnabledField: true, IsESDTTransferRoleFlagEnabledField: true, IsESDTMetadataContinuousCleanupFlagEnabledField: true, - IsLiquidStakingEnabledField: true, }, } } @@ -4361,77 +4360,3 @@ func TestEsdt_CheckRolesOnMetaESDT(t *testing.T) { err = e.checkSpecialRolesAccordingToTokenType([][]byte{[]byte("random")}, &ESDTDataV2{TokenType: []byte(metaESDT)}) assert.Equal(t, err, vm.ErrInvalidArgument) } - -func TestEsdt_ExecuteInitDelegationESDT(t *testing.T) { - t.Parallel() - - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ - IsDelegationSmartContractFlagEnabledField: true, - IsESDTFlagEnabledField: true, - IsBuiltInFunctionOnMetaFlagEnabledField: false, - } - - args := createMockArgumentsForESDT() - args.ESDTSCAddress = vm.ESDTSCAddress - args.EnableEpochsHandler = enableEpochsHandler - - argsVMContext := createArgsVMContext() - argsVMContext.EnableEpochsHandler = enableEpochsHandler - eei, _ := NewVMContext(argsVMContext) - args.Eei = eei - e, _ := NewESDTSmartContract(args) - - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: []byte("addr"), - CallValue: big.NewInt(0), - }, - RecipientAddr: []byte("addr"), - Function: "initDelegationESDTOnMeta", - } - - eei.returnMessage = "" - returnCode := e.Execute(vmInput) - assert.Equal(t, vmcommon.FunctionNotFound, returnCode) - assert.Equal(t, eei.returnMessage, "invalid method to call") - - eei.returnMessage = "" - enableEpochsHandler.IsBuiltInFunctionOnMetaFlagEnabledField = true - returnCode = e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, "only system address can call this") - - vmInput.CallerAddr = vm.ESDTSCAddress - vmInput.RecipientAddr = vm.ESDTSCAddress - vmInput.Arguments = [][]byte{{1}} - eei.returnMessage = "" - returnCode = e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - - vmInput.Arguments = [][]byte{} - vmInput.CallValue = big.NewInt(10) - eei.returnMessage = "" - returnCode = e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - - localErr := errors.New("local err") - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - return nil, localErr - }} - - vmInput.CallValue = big.NewInt(0) - eei.returnMessage = "" - returnCode = e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, returnCode) - assert.Equal(t, eei.returnMessage, localErr.Error()) - - eei.blockChainHook = &mock.BlockChainHookStub{ProcessBuiltInFunctionCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { - doesContainTicker := bytes.Contains(input.Arguments[0], []byte(e.delegationTicker)) - assert.True(t, doesContainTicker) - return &vmcommon.VMOutput{}, nil - }} - - eei.returnMessage = "" - returnCode = e.Execute(vmInput) - assert.Equal(t, vmcommon.Ok, returnCode) -} From 66f8a7b1837900d6b7a60095aba25a69e6ff77a2 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 31 Jan 2023 13:24:37 +0200 Subject: [PATCH 391/958] FIX: Test --- vm/factory/systemSCFactory_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index b302735ca2c..7e670e8e036 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -275,7 +275,7 @@ func TestSystemSCFactory_Create(t *testing.T) { container, err := scFactory.Create() assert.Nil(t, err) require.NotNil(t, container) - assert.Equal(t, 7, container.Len()) + assert.Equal(t, 6, container.Len()) } func TestSystemSCFactory_CreateForGenesis(t *testing.T) { From 13c57453e006c240be52483f8859d281e2ed66bc Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 31 Jan 2023 14:43:45 +0200 Subject: [PATCH 392/958] FIX: Remove BuiltInFunctionOnMetaEnableEpoch --- cmd/node/config/enableEpochs.toml | 3 --- common/constants.go | 3 --- common/enablers/enableEpochsHandler.go | 1 - common/enablers/enableEpochsHandler_test.go | 5 ----- common/enablers/epochFlags.go | 13 +++---------- common/interface.go | 1 - config/epochConfig.go | 1 - config/tomlConfig_test.go | 4 ---- epochStart/metachain/systemSCs_test.go | 1 - genesis/process/shardGenesisBlockCreator.go | 1 - .../polynetworkbridge/bridge_test.go | 1 - .../multiShard/softfork/scDeploy_test.go | 2 -- integrationTests/testProcessorNode.go | 1 - .../vm/esdt/process/esdtProcess_test.go | 5 +---- .../vm/txsFee/backwardsCompatibility_test.go | 9 ++++----- node/metrics/metrics.go | 1 - node/metrics/metrics_test.go | 1 - node/nodeRunner.go | 1 - process/smartContract/process.go | 2 +- process/transaction/metaProcess.go | 4 ---- sharding/mock/enableEpochsHandlerMock.go | 5 ----- testscommon/enableEpochsHandlerStub.go | 15 +-------------- 22 files changed, 10 insertions(+), 70 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index d4e6c982d6a..32a4dfd0706 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -106,9 +106,6 @@ # ESDTTransferRoleEnableEpoch represents the epoch when esdt transfer role set is enabled ESDTTransferRoleEnableEpoch = 1 - # BuiltInFunctionOnMetaEnableEpoch represents the epoch when built in function processing on metachain is enabled - BuiltInFunctionOnMetaEnableEpoch = 1000000 - # ComputeRewardCheckpointEnableEpoch represents the epoch when compute rewards checkpoint epoch is enabled ComputeRewardCheckpointEnableEpoch = 1 diff --git a/common/constants.go b/common/constants.go index 487cb129546..8d7b69bdd8f 100644 --- a/common/constants.go +++ b/common/constants.go @@ -493,9 +493,6 @@ const ( // MetricESDTTransferRoleEnableEpoch represents the epoch when the ESDT transfer role feature is enabled MetricESDTTransferRoleEnableEpoch = "erd_esdt_transfer_role_enable_epoch" - // MetricBuiltInFunctionOnMetaEnableEpoch represents the epoch when the builtin functions on metachain are enabled - MetricBuiltInFunctionOnMetaEnableEpoch = "erd_builtin_function_on_meta_enable_epoch" - // MetricWaitingListFixEnableEpoch represents the epoch when the waiting list fix is enabled MetricWaitingListFixEnableEpoch = "erd_waiting_list_fix_enable_epoch" diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 1407ec06a11..81bf3ccf523 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -73,7 +73,6 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.ESDTMultiTransferEnableEpoch, handler.esdtMultiTransferFlag, "esdtMultiTransferFlag") handler.setFlagValue(epoch < handler.enableEpochsConfig.GlobalMintBurnDisableEpoch, handler.globalMintBurnFlag, "globalMintBurnFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.ESDTTransferRoleEnableEpoch, handler.esdtTransferRoleFlag, "esdtTransferRoleFlag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, handler.builtInFunctionOnMetaFlag, "builtInFunctionOnMetaFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.ComputeRewardCheckpointEnableEpoch, handler.computeRewardCheckpointFlag, "computeRewardCheckpointFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.SCRSizeInvariantCheckEnableEpoch, handler.scrSizeInvariantCheckFlag, "scrSizeInvariantCheckFlag") handler.setFlagValue(epoch < handler.enableEpochsConfig.BackwardCompSaveKeyValueEnableEpoch, handler.backwardCompSaveKeyValueFlag, "backwardCompSaveKeyValueFlag") diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index bf81ab8ea47..da1d8b77143 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -49,7 +49,6 @@ func createEnableEpochsConfig() config.EnableEpochs { ESDTMultiTransferEnableEpoch: 33, GlobalMintBurnDisableEpoch: 34, ESDTTransferRoleEnableEpoch: 35, - BuiltInFunctionOnMetaEnableEpoch: 36, ComputeRewardCheckpointEnableEpoch: 37, SCRSizeInvariantCheckEnableEpoch: 38, BackwardCompSaveKeyValueEnableEpoch: 39, @@ -175,7 +174,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsESDTMultiTransferFlagEnabled()) assert.False(t, handler.IsGlobalMintBurnFlagEnabled()) assert.True(t, handler.IsESDTTransferRoleFlagEnabled()) - assert.True(t, handler.IsBuiltInFunctionOnMetaFlagEnabled()) assert.True(t, handler.IsComputeRewardCheckpointFlagEnabled()) assert.True(t, handler.IsSCRSizeInvariantCheckFlagEnabled()) assert.False(t, handler.IsBackwardCompSaveKeyValueFlagEnabled()) @@ -232,7 +230,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { cfg.GovernanceEnableEpoch = epoch cfg.CorrectLastUnjailedEnableEpoch = epoch cfg.StakingV4InitEnableEpoch = epoch - cfg.BuiltInFunctionOnMetaEnableEpoch = epoch handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) require.False(t, check.IfNil(handler)) @@ -280,7 +277,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsESDTMultiTransferFlagEnabled()) assert.False(t, handler.IsGlobalMintBurnFlagEnabled()) assert.True(t, handler.IsESDTTransferRoleFlagEnabled()) - assert.True(t, handler.IsBuiltInFunctionOnMetaFlagEnabled()) assert.True(t, handler.IsComputeRewardCheckpointFlagEnabled()) assert.True(t, handler.IsSCRSizeInvariantCheckFlagEnabled()) assert.False(t, handler.IsBackwardCompSaveKeyValueFlagEnabled()) @@ -380,7 +376,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsESDTMultiTransferFlagEnabled()) assert.True(t, handler.IsGlobalMintBurnFlagEnabled()) assert.False(t, handler.IsESDTTransferRoleFlagEnabled()) - assert.False(t, handler.IsBuiltInFunctionOnMetaFlagEnabled()) assert.False(t, handler.IsComputeRewardCheckpointFlagEnabled()) assert.False(t, handler.IsSCRSizeInvariantCheckFlagEnabled()) assert.True(t, handler.IsBackwardCompSaveKeyValueFlagEnabled()) diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index 6a2e79019f6..8fd3f1c4a9e 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -45,7 +45,6 @@ type epochFlagsHolder struct { esdtMultiTransferFlag *atomic.Flag globalMintBurnFlag *atomic.Flag esdtTransferRoleFlag *atomic.Flag - builtInFunctionOnMetaFlag *atomic.Flag computeRewardCheckpointFlag *atomic.Flag scrSizeInvariantCheckFlag *atomic.Flag backwardCompSaveKeyValueFlag *atomic.Flag @@ -139,7 +138,6 @@ func newEpochFlagsHolder() *epochFlagsHolder { esdtMultiTransferFlag: &atomic.Flag{}, globalMintBurnFlag: &atomic.Flag{}, esdtTransferRoleFlag: &atomic.Flag{}, - builtInFunctionOnMetaFlag: &atomic.Flag{}, computeRewardCheckpointFlag: &atomic.Flag{}, scrSizeInvariantCheckFlag: &atomic.Flag{}, backwardCompSaveKeyValueFlag: &atomic.Flag{}, @@ -397,11 +395,6 @@ func (holder *epochFlagsHolder) IsESDTTransferRoleFlagEnabled() bool { return holder.esdtTransferRoleFlag.IsSet() } -// IsBuiltInFunctionOnMetaFlagEnabled returns true if builtInFunctionOnMetaFlag is enabled -func (holder *epochFlagsHolder) IsBuiltInFunctionOnMetaFlagEnabled() bool { - return holder.builtInFunctionOnMetaFlag.IsSet() -} - // IsComputeRewardCheckpointFlagEnabled returns true if computeRewardCheckpointFlag is enabled func (holder *epochFlagsHolder) IsComputeRewardCheckpointFlagEnabled() bool { return holder.computeRewardCheckpointFlag.IsSet() @@ -613,10 +606,10 @@ func (holder *epochFlagsHolder) IsCheckTransferFlagEnabled() bool { return holder.optimizeNFTStoreFlag.IsSet() } -// IsTransferToMetaFlagEnabled returns true if builtInFunctionOnMetaFlag is enabled -// this is a duplicate for BuiltInFunctionOnMetaEnableEpoch needed for consistency into vm-common +// IsTransferToMetaFlagEnabled returns false +// This is used for consistency into vm-common func (holder *epochFlagsHolder) IsTransferToMetaFlagEnabled() bool { - return holder.builtInFunctionOnMetaFlag.IsSet() + return false } // IsESDTNFTImprovementV1FlagEnabled returns true if esdtMultiTransferFlag is enabled diff --git a/common/interface.go b/common/interface.go index 4d019c3b2c7..b791b3b8829 100644 --- a/common/interface.go +++ b/common/interface.go @@ -285,7 +285,6 @@ type EnableEpochsHandler interface { IsESDTMultiTransferFlagEnabled() bool IsGlobalMintBurnFlagEnabled() bool IsESDTTransferRoleFlagEnabled() bool - IsBuiltInFunctionOnMetaFlagEnabled() bool IsComputeRewardCheckpointFlagEnabled() bool IsSCRSizeInvariantCheckFlagEnabled() bool IsBackwardCompSaveKeyValueFlagEnabled() bool diff --git a/config/epochConfig.go b/config/epochConfig.go index 166aa0fd2b3..004a998dfda 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -49,7 +49,6 @@ type EnableEpochs struct { ESDTMultiTransferEnableEpoch uint32 GlobalMintBurnDisableEpoch uint32 ESDTTransferRoleEnableEpoch uint32 - BuiltInFunctionOnMetaEnableEpoch uint32 ComputeRewardCheckpointEnableEpoch uint32 SCRSizeInvariantCheckEnableEpoch uint32 BackwardCompSaveKeyValueEnableEpoch uint32 diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 92802c97d02..d73b47d686b 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -597,9 +597,6 @@ func TestEnableEpochConfig(t *testing.T) { # ESDTTransferRoleEnableEpoch represents the epoch when esdt transfer role set is enabled ESDTTransferRoleEnableEpoch = 34 - # BuiltInFunctionOnMetaEnableEpoch represents the epoch when built in function processing on metachain is enabled - BuiltInFunctionOnMetaEnableEpoch = 35 - # ComputeRewardCheckpointEnableEpoch represents the epoch when compute rewards checkpoint epoch is enabled ComputeRewardCheckpointEnableEpoch = 36 @@ -744,7 +741,6 @@ func TestEnableEpochConfig(t *testing.T) { ESDTMultiTransferEnableEpoch: 32, GlobalMintBurnDisableEpoch: 33, ESDTTransferRoleEnableEpoch: 34, - BuiltInFunctionOnMetaEnableEpoch: 35, ComputeRewardCheckpointEnableEpoch: 36, SCRSizeInvariantCheckEnableEpoch: 37, BackwardCompSaveKeyValueEnableEpoch: 38, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f0fea647964..8f39efa61de 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -747,7 +747,6 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp enableEpochsConfig.StakeLimitsEnableEpoch = 10 enableEpochsConfig.StakingV4InitEnableEpoch = 444 enableEpochsConfig.StakingV4EnableEpoch = 445 - enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch = 400 epochsConfig := &config.EpochConfig{ EnableEpochs: enableEpochsConfig, } diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index 26bdc0249df..6b209677099 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -97,7 +97,6 @@ func createGenesisConfig() config.EnableEpochs { ESDTMultiTransferEnableEpoch: unreachableEpoch, GlobalMintBurnDisableEpoch: unreachableEpoch, ESDTTransferRoleEnableEpoch: unreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: unreachableEpoch, ComputeRewardCheckpointEnableEpoch: unreachableEpoch, SCRSizeInvariantCheckEnableEpoch: unreachableEpoch, BackwardCompSaveKeyValueEnableEpoch: unreachableEpoch, diff --git a/integrationTests/multiShard/smartContract/polynetworkbridge/bridge_test.go b/integrationTests/multiShard/smartContract/polynetworkbridge/bridge_test.go index ba8e4541542..870cf9e3628 100644 --- a/integrationTests/multiShard/smartContract/polynetworkbridge/bridge_test.go +++ b/integrationTests/multiShard/smartContract/polynetworkbridge/bridge_test.go @@ -29,7 +29,6 @@ func TestBridgeSetupAndBurn(t *testing.T) { enableEpochs := config.EnableEpochs{ GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, FixAsyncCallBackArgsListEnableEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/multiShard/softfork/scDeploy_test.go b/integrationTests/multiShard/softfork/scDeploy_test.go index 00368ae39af..4e4b9eba31e 100644 --- a/integrationTests/multiShard/softfork/scDeploy_test.go +++ b/integrationTests/multiShard/softfork/scDeploy_test.go @@ -25,14 +25,12 @@ func TestScDeploy(t *testing.T) { t.Skip("this is not a short test") } - builtinEnableEpoch := uint32(0) deployEnableEpoch := uint32(1) relayedTxEnableEpoch := uint32(0) penalizedTooMuchGasEnableEpoch := uint32(0) roundsPerEpoch := uint64(10) enableEpochs := integrationTests.CreateEnableEpochsConfig() - enableEpochs.BuiltInFunctionOnMetaEnableEpoch = builtinEnableEpoch enableEpochs.SCDeployEnableEpoch = deployEnableEpoch enableEpochs.RelayedTransactionsEnableEpoch = relayedTxEnableEpoch enableEpochs.PenalizedTooMuchGasEnableEpoch = penalizedTooMuchGasEnableEpoch diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index e2d4367b764..92ee485c778 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2933,7 +2933,6 @@ func CreateEnableEpochsConfig() config.EnableEpochs { ESDTMultiTransferEnableEpoch: UnreachableEpoch, GlobalMintBurnDisableEpoch: UnreachableEpoch, ESDTTransferRoleEnableEpoch: UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: UnreachableEpoch, ComputeRewardCheckpointEnableEpoch: UnreachableEpoch, SCRSizeInvariantCheckEnableEpoch: UnreachableEpoch, BackwardCompSaveKeyValueEnableEpoch: UnreachableEpoch, diff --git a/integrationTests/vm/esdt/process/esdtProcess_test.go b/integrationTests/vm/esdt/process/esdtProcess_test.go index 5bdc8e54ea6..16191844461 100644 --- a/integrationTests/vm/esdt/process/esdtProcess_test.go +++ b/integrationTests/vm/esdt/process/esdtProcess_test.go @@ -43,7 +43,6 @@ func TestESDTIssueAndTransactionsOnMultiShardEnvironment(t *testing.T) { enableEpochs := config.EnableEpochs{ GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, OptimizeGasUsedInCrossMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, @@ -175,7 +174,6 @@ func TestESDTCallBurnOnANonBurnableToken(t *testing.T) { enableEpochs := config.EnableEpochs{ GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, OptimizeGasUsedInCrossMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, @@ -2068,8 +2066,7 @@ func TestIssueAndBurnESDT_MaxGasPerBlockExceeded(t *testing.T) { numMetachainNodes := 1 enableEpochs := config.EnableEpochs{ - GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, + GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( numOfShards, diff --git a/integrationTests/vm/txsFee/backwardsCompatibility_test.go b/integrationTests/vm/txsFee/backwardsCompatibility_test.go index abc67b92d16..d6c0deb5047 100644 --- a/integrationTests/vm/txsFee/backwardsCompatibility_test.go +++ b/integrationTests/vm/txsFee/backwardsCompatibility_test.go @@ -18,11 +18,10 @@ import ( // minGasPrice = 1, gasPerDataByte = 1, minGasLimit = 1 func TestMoveBalanceSelfShouldWorkAndConsumeTxFeeWhenAllFlagsAreDisabled(t *testing.T) { testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{ - PenalizedTooMuchGasEnableEpoch: 100, - BuiltInFunctionOnMetaEnableEpoch: 100, - SCDeployEnableEpoch: 100, - MetaProtectionEnableEpoch: 100, - RelayedTransactionsEnableEpoch: 100, + PenalizedTooMuchGasEnableEpoch: 100, + SCDeployEnableEpoch: 100, + MetaProtectionEnableEpoch: 100, + RelayedTransactionsEnableEpoch: 100, }) require.Nil(t, err) defer testContext.Close() diff --git a/node/metrics/metrics.go b/node/metrics/metrics.go index 21cf67fa35d..566ce79d2e4 100644 --- a/node/metrics/metrics.go +++ b/node/metrics/metrics.go @@ -121,7 +121,6 @@ func InitConfigMetrics( appStatusHandler.SetUInt64Value(common.MetricESDTMultiTransferEnableEpoch, uint64(enableEpochs.ESDTMultiTransferEnableEpoch)) appStatusHandler.SetUInt64Value(common.MetricGlobalMintBurnDisableEpoch, uint64(enableEpochs.GlobalMintBurnDisableEpoch)) appStatusHandler.SetUInt64Value(common.MetricESDTTransferRoleEnableEpoch, uint64(enableEpochs.ESDTTransferRoleEnableEpoch)) - appStatusHandler.SetUInt64Value(common.MetricBuiltInFunctionOnMetaEnableEpoch, uint64(enableEpochs.BuiltInFunctionOnMetaEnableEpoch)) appStatusHandler.SetStringValue(common.MetricTotalSupply, economicsConfig.GlobalSettings.GenesisTotalSupply) appStatusHandler.SetUInt64Value(common.MetricWaitingListFixEnableEpoch, uint64(enableEpochs.WaitingListFixEnableEpoch)) diff --git a/node/metrics/metrics_test.go b/node/metrics/metrics_test.go index cabb8674c14..f31d05807a3 100644 --- a/node/metrics/metrics_test.go +++ b/node/metrics/metrics_test.go @@ -132,7 +132,6 @@ func TestInitConfigMetrics(t *testing.T) { ESDTMultiTransferEnableEpoch: 31, GlobalMintBurnDisableEpoch: 32, ESDTTransferRoleEnableEpoch: 33, - BuiltInFunctionOnMetaEnableEpoch: 34, WaitingListFixEnableEpoch: 35, }, } diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 0bf9eed6b42..bc4a2e8cea4 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -169,7 +169,6 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("esdt and NFT multi transfer"), "epoch", enableEpochs.ESDTMultiTransferEnableEpoch) log.Debug(readEpochFor("contract global mint and burn"), "epoch", enableEpochs.GlobalMintBurnDisableEpoch) log.Debug(readEpochFor("contract transfer role"), "epoch", enableEpochs.ESDTTransferRoleEnableEpoch) - log.Debug(readEpochFor("built in functions on metachain"), "epoch", enableEpochs.BuiltInFunctionOnMetaEnableEpoch) log.Debug(readEpochFor("compute rewards checkpoint on delegation"), "epoch", enableEpochs.ComputeRewardCheckpointEnableEpoch) log.Debug(readEpochFor("esdt NFT create on multiple shards"), "epoch", enableEpochs.ESDTNFTCreateOnMultiShardEnableEpoch) log.Debug(readEpochFor("SCR size invariant check"), "epoch", enableEpochs.SCRSizeInvariantCheckEnableEpoch) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index 027537a7dab..c7f176f008f 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -2732,7 +2732,7 @@ func (sc *scProcessor) ProcessSmartContractResult(scr *smartContractResult.Smart returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err case process.BuiltInFunctionCall: - if sc.shardCoordinator.SelfId() == core.MetachainShardId && !sc.enableEpochsHandler.IsBuiltInFunctionOnMetaFlagEnabled() { + if sc.shardCoordinator.SelfId() == core.MetachainShardId { returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err } diff --git a/process/transaction/metaProcess.go b/process/transaction/metaProcess.go index 4724438b20d..2a5d7ac5ad1 100644 --- a/process/transaction/metaProcess.go +++ b/process/transaction/metaProcess.go @@ -119,10 +119,6 @@ func (txProc *metaTxProcessor) ProcessTransaction(tx *transaction.Transaction) ( case process.SCInvoking: return txProc.processSCInvoking(tx, tx.SndAddr, tx.RcvAddr) case process.BuiltInFunctionCall: - if txProc.enableEpochsHandler.IsBuiltInFunctionOnMetaFlagEnabled() { - return txProc.processBuiltInFunctionCall(tx, tx.SndAddr, tx.RcvAddr) - } - if txProc.enableEpochsHandler.IsESDTFlagEnabled() { return txProc.processSCInvoking(tx, tx.SndAddr, tx.RcvAddr) } diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index ab82535cd14..b65d69cb61c 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -306,11 +306,6 @@ func (mock *EnableEpochsHandlerMock) IsESDTTransferRoleFlagEnabled() bool { return false } -// IsBuiltInFunctionOnMetaFlagEnabled returns false -func (mock *EnableEpochsHandlerMock) IsBuiltInFunctionOnMetaFlagEnabled() bool { - return false -} - // IsComputeRewardCheckpointFlagEnabled returns false func (mock *EnableEpochsHandlerMock) IsComputeRewardCheckpointFlagEnabled() bool { return false diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 7982d15a3e5..9e126efeccc 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -67,7 +67,6 @@ type EnableEpochsHandlerStub struct { IsESDTMultiTransferFlagEnabledField bool IsGlobalMintBurnFlagEnabledField bool IsESDTTransferRoleFlagEnabledField bool - IsBuiltInFunctionOnMetaFlagEnabledField bool IsComputeRewardCheckpointFlagEnabledField bool IsSCRSizeInvariantCheckFlagEnabledField bool IsBackwardCompSaveKeyValueFlagEnabledField bool @@ -108,7 +107,6 @@ type EnableEpochsHandlerStub struct { IsSendAlwaysFlagEnabledField bool IsValueLengthCheckFlagEnabledField bool IsCheckTransferFlagEnabledField bool - IsTransferToMetaFlagEnabledField bool IsESDTNFTImprovementV1FlagEnabledField bool IsSetSenderInEeiOutputTransferFlagEnabledField bool IsChangeDelegationOwnerFlagEnabledField bool @@ -599,14 +597,6 @@ func (stub *EnableEpochsHandlerStub) IsESDTTransferRoleFlagEnabled() bool { return stub.IsESDTTransferRoleFlagEnabledField } -// IsBuiltInFunctionOnMetaFlagEnabled - -func (stub *EnableEpochsHandlerStub) IsBuiltInFunctionOnMetaFlagEnabled() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsBuiltInFunctionOnMetaFlagEnabledField -} - // IsComputeRewardCheckpointFlagEnabled - func (stub *EnableEpochsHandlerStub) IsComputeRewardCheckpointFlagEnabled() bool { stub.RLock() @@ -929,10 +919,7 @@ func (stub *EnableEpochsHandlerStub) IsCheckTransferFlagEnabled() bool { // IsTransferToMetaFlagEnabled - func (stub *EnableEpochsHandlerStub) IsTransferToMetaFlagEnabled() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsTransferToMetaFlagEnabledField + return false } // IsESDTNFTImprovementV1FlagEnabled - From 65da898b842d6cde59c6c7cd58b1c0930edfeaff Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 31 Jan 2023 15:38:09 +0200 Subject: [PATCH 393/958] FIX: Remove WaitingListFixEnableEpoch --- cmd/node/config/enableEpochs.toml | 3 - common/constants.go | 3 - common/enablers/enableEpochsHandler.go | 6 - common/enablers/enableEpochsHandler_test.go | 4 - common/enablers/epochFlags.go | 7 - common/interface.go | 2 - config/epochConfig.go | 1 - config/tomlConfig_test.go | 4 - genesis/process/shardGenesisBlockCreator.go | 1 - integrationTests/nodesCoordinatorFactory.go | 2 - integrationTests/testConsensusNode.go | 36 +++-- integrationTests/testProcessorNode.go | 1 - integrationTests/vm/txsFee/scCalls_test.go | 2 - node/metrics/metrics.go | 1 - node/metrics/metrics_test.go | 3 - node/nodeRunner.go | 1 - sharding/mock/enableEpochsHandlerMock.go | 13 +- .../nodesCoordinator/hashValidatorShuffler.go | 27 +--- .../hashValidatorShuffler_test.go | 142 ++++------------- .../indexHashedNodesCoordinator.go | 33 +--- .../indexHashedNodesCoordinator_test.go | 144 +----------------- statusHandler/statusMetricsProvider.go | 1 - statusHandler/statusMetricsProvider_test.go | 2 - testscommon/enableEpochsHandlerStub.go | 18 --- 24 files changed, 58 insertions(+), 399 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 32a4dfd0706..13ba9714745 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -90,9 +90,6 @@ # ValidatorToDelegationEnableEpoch represents the epoch when the validator-to-delegation feature will be enabled ValidatorToDelegationEnableEpoch = 1 - # WaitingListFixEnableEpoch represents the epoch when the 6 epoch waiting list fix is enabled - WaitingListFixEnableEpoch = 1000000 - # IncrementSCRNonceInMultiTransferEnableEpoch represents the epoch when the fix for preventing the generation of the same SCRs # is enabled. The fix is done by adding an extra increment. IncrementSCRNonceInMultiTransferEnableEpoch = 1 diff --git a/common/constants.go b/common/constants.go index 8d7b69bdd8f..ae05c8931a0 100644 --- a/common/constants.go +++ b/common/constants.go @@ -493,9 +493,6 @@ const ( // MetricESDTTransferRoleEnableEpoch represents the epoch when the ESDT transfer role feature is enabled MetricESDTTransferRoleEnableEpoch = "erd_esdt_transfer_role_enable_epoch" - // MetricWaitingListFixEnableEpoch represents the epoch when the waiting list fix is enabled - MetricWaitingListFixEnableEpoch = "erd_waiting_list_fix_enable_epoch" - // MetricMaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MetricMaxNodesChangeEnableEpoch = "erd_max_nodes_change_enable_epoch" diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 81bf3ccf523..c223cdba899 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -68,7 +68,6 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.SaveJailedAlwaysEnableEpoch, handler.saveJailedAlwaysFlag, "saveJailedAlwaysFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.ReDelegateBelowMinCheckEnableEpoch, handler.reDelegateBelowMinCheckFlag, "reDelegateBelowMinCheckFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.ValidatorToDelegationEnableEpoch, handler.validatorToDelegationFlag, "validatorToDelegationFlag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.WaitingListFixEnableEpoch, handler.waitingListFixFlag, "waitingListFixFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.IncrementSCRNonceInMultiTransferEnableEpoch, handler.incrementSCRNonceInMultiTransferFlag, "incrementSCRNonceInMultiTransferFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.ESDTMultiTransferEnableEpoch, handler.esdtMultiTransferFlag, "esdtMultiTransferFlag") handler.setFlagValue(epoch < handler.enableEpochsConfig.GlobalMintBurnDisableEpoch, handler.globalMintBurnFlag, "globalMintBurnFlag") @@ -154,11 +153,6 @@ func (handler *enableEpochsHandler) BalanceWaitingListsEnableEpoch() uint32 { return handler.enableEpochsConfig.BalanceWaitingListsEnableEpoch } -// WaitingListFixEnableEpoch returns the epoch for waiting list fix -func (handler *enableEpochsHandler) WaitingListFixEnableEpoch() uint32 { - return handler.enableEpochsConfig.WaitingListFixEnableEpoch -} - // MultiESDTTransferAsyncCallBackEnableEpoch returns the epoch when multi esdt transfer fix on callback becomes active func (handler *enableEpochsHandler) MultiESDTTransferAsyncCallBackEnableEpoch() uint32 { return handler.enableEpochsConfig.MultiESDTTransferFixOnCallBackOnEnableEpoch diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index da1d8b77143..4f4af75f8e7 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -43,7 +43,6 @@ func createEnableEpochsConfig() config.EnableEpochs { SaveJailedAlwaysEnableEpoch: 27, ValidatorToDelegationEnableEpoch: 28, ReDelegateBelowMinCheckEnableEpoch: 29, - WaitingListFixEnableEpoch: 30, IncrementSCRNonceInMultiTransferEnableEpoch: 31, ScheduledMiniBlocksEnableEpoch: 32, ESDTMultiTransferEnableEpoch: 33, @@ -169,7 +168,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsSaveJailedAlwaysFlagEnabled()) assert.True(t, handler.IsReDelegateBelowMinCheckFlagEnabled()) assert.True(t, handler.IsValidatorToDelegationFlagEnabled()) - assert.True(t, handler.IsWaitingListFixFlagEnabled()) assert.True(t, handler.IsIncrementSCRNonceInMultiTransferFlagEnabled()) assert.True(t, handler.IsESDTMultiTransferFlagEnabled()) assert.False(t, handler.IsGlobalMintBurnFlagEnabled()) @@ -272,7 +270,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsSaveJailedAlwaysFlagEnabled()) assert.True(t, handler.IsReDelegateBelowMinCheckFlagEnabled()) assert.True(t, handler.IsValidatorToDelegationFlagEnabled()) - assert.True(t, handler.IsWaitingListFixFlagEnabled()) assert.True(t, handler.IsIncrementSCRNonceInMultiTransferFlagEnabled()) assert.True(t, handler.IsESDTMultiTransferFlagEnabled()) assert.False(t, handler.IsGlobalMintBurnFlagEnabled()) @@ -371,7 +368,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsSaveJailedAlwaysFlagEnabled()) assert.False(t, handler.IsReDelegateBelowMinCheckFlagEnabled()) assert.False(t, handler.IsValidatorToDelegationFlagEnabled()) - assert.False(t, handler.IsWaitingListFixFlagEnabled()) assert.False(t, handler.IsIncrementSCRNonceInMultiTransferFlagEnabled()) assert.False(t, handler.IsESDTMultiTransferFlagEnabled()) assert.True(t, handler.IsGlobalMintBurnFlagEnabled()) diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index 8fd3f1c4a9e..8589c217a83 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -40,7 +40,6 @@ type epochFlagsHolder struct { saveJailedAlwaysFlag *atomic.Flag reDelegateBelowMinCheckFlag *atomic.Flag validatorToDelegationFlag *atomic.Flag - waitingListFixFlag *atomic.Flag incrementSCRNonceInMultiTransferFlag *atomic.Flag esdtMultiTransferFlag *atomic.Flag globalMintBurnFlag *atomic.Flag @@ -133,7 +132,6 @@ func newEpochFlagsHolder() *epochFlagsHolder { saveJailedAlwaysFlag: &atomic.Flag{}, reDelegateBelowMinCheckFlag: &atomic.Flag{}, validatorToDelegationFlag: &atomic.Flag{}, - waitingListFixFlag: &atomic.Flag{}, incrementSCRNonceInMultiTransferFlag: &atomic.Flag{}, esdtMultiTransferFlag: &atomic.Flag{}, globalMintBurnFlag: &atomic.Flag{}, @@ -370,11 +368,6 @@ func (holder *epochFlagsHolder) IsValidatorToDelegationFlagEnabled() bool { return holder.validatorToDelegationFlag.IsSet() } -// IsWaitingListFixFlagEnabled returns true if waitingListFixFlag is enabled -func (holder *epochFlagsHolder) IsWaitingListFixFlagEnabled() bool { - return holder.waitingListFixFlag.IsSet() -} - // IsIncrementSCRNonceInMultiTransferFlagEnabled returns true if incrementSCRNonceInMultiTransferFlag is enabled func (holder *epochFlagsHolder) IsIncrementSCRNonceInMultiTransferFlagEnabled() bool { return holder.incrementSCRNonceInMultiTransferFlag.IsSet() diff --git a/common/interface.go b/common/interface.go index b791b3b8829..a6a6436caae 100644 --- a/common/interface.go +++ b/common/interface.go @@ -230,7 +230,6 @@ type EnableEpochsHandler interface { ScheduledMiniBlocksEnableEpoch() uint32 SwitchJailWaitingEnableEpoch() uint32 BalanceWaitingListsEnableEpoch() uint32 - WaitingListFixEnableEpoch() uint32 MultiESDTTransferAsyncCallBackEnableEpoch() uint32 FixOOGReturnCodeEnableEpoch() uint32 RemoveNonUpdatedStorageEnableEpoch() uint32 @@ -280,7 +279,6 @@ type EnableEpochsHandler interface { IsSaveJailedAlwaysFlagEnabled() bool IsReDelegateBelowMinCheckFlagEnabled() bool IsValidatorToDelegationFlagEnabled() bool - IsWaitingListFixFlagEnabled() bool IsIncrementSCRNonceInMultiTransferFlagEnabled() bool IsESDTMultiTransferFlagEnabled() bool IsGlobalMintBurnFlagEnabled() bool diff --git a/config/epochConfig.go b/config/epochConfig.go index 004a998dfda..4a09774615a 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -43,7 +43,6 @@ type EnableEpochs struct { SaveJailedAlwaysEnableEpoch uint32 ValidatorToDelegationEnableEpoch uint32 ReDelegateBelowMinCheckEnableEpoch uint32 - WaitingListFixEnableEpoch uint32 IncrementSCRNonceInMultiTransferEnableEpoch uint32 ScheduledMiniBlocksEnableEpoch uint32 ESDTMultiTransferEnableEpoch uint32 diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index d73b47d686b..970bb23fadd 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -581,9 +581,6 @@ func TestEnableEpochConfig(t *testing.T) { # ValidatorToDelegationEnableEpoch represents the epoch when the validator-to-delegation feature will be enabled ValidatorToDelegationEnableEpoch = 29 - # WaitingListFixEnableEpoch represents the epoch when the 6 epoch waiting list fix is enabled - WaitingListFixEnableEpoch = 30 - # IncrementSCRNonceInMultiTransferEnableEpoch represents the epoch when the fix for preventing the generation of the same SCRs # is enabled. The fix is done by adding an extra increment. IncrementSCRNonceInMultiTransferEnableEpoch = 31 @@ -736,7 +733,6 @@ func TestEnableEpochConfig(t *testing.T) { SaveJailedAlwaysEnableEpoch: 27, ValidatorToDelegationEnableEpoch: 29, ReDelegateBelowMinCheckEnableEpoch: 28, - WaitingListFixEnableEpoch: 30, IncrementSCRNonceInMultiTransferEnableEpoch: 31, ESDTMultiTransferEnableEpoch: 32, GlobalMintBurnDisableEpoch: 33, diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index 6b209677099..fde639983f0 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -92,7 +92,6 @@ func createGenesisConfig() config.EnableEpochs { SaveJailedAlwaysEnableEpoch: unreachableEpoch, ValidatorToDelegationEnableEpoch: unreachableEpoch, ReDelegateBelowMinCheckEnableEpoch: unreachableEpoch, - WaitingListFixEnableEpoch: unreachableEpoch, IncrementSCRNonceInMultiTransferEnableEpoch: unreachableEpoch, ESDTMultiTransferEnableEpoch: unreachableEpoch, GlobalMintBurnDisableEpoch: unreachableEpoch, diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index e56159cf600..40f46a90edc 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -111,7 +111,6 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ - IsWaitingListFixFlagEnabledField: true, IsBalanceWaitingListsFlagEnabledField: true, }, } @@ -140,7 +139,6 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, IsFullArchive: false, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ - IsWaitingListFixFlagEnabledField: true, RefactorPeersMiniBlocksEnableEpochField: UnreachableEpoch, }, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 990af73241c..54f0e0953fb 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -284,25 +284,23 @@ func (tcn *TestConsensusNode) initNodesCoordinator( cache storage.Cacher, ) { argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusSize, - MetaConsensusGroupSize: 1, - Marshalizer: TestMarshalizer, - Hasher: hasher, - Shuffler: &shardingMocks.NodeShufflerMock{}, - EpochStartNotifier: epochStartRegistrationHandler, - BootStorer: CreateMemUnit(), - NbShards: maxShards, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: pkBytes, - ConsensusGroupCache: cache, - ShuffledOutHandler: &chainShardingMocks.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ - IsWaitingListFixFlagEnabledField: true, - }, + ShardConsensusGroupSize: consensusSize, + MetaConsensusGroupSize: 1, + Marshalizer: TestMarshalizer, + Hasher: hasher, + Shuffler: &shardingMocks.NodeShufflerMock{}, + EpochStartNotifier: epochStartRegistrationHandler, + BootStorer: CreateMemUnit(), + NbShards: maxShards, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: pkBytes, + ConsensusGroupCache: cache, + ShuffledOutHandler: &chainShardingMocks.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, StakingV4EnableEpoch: StakingV4Epoch, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 92ee485c778..4a58fdb28e7 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2928,7 +2928,6 @@ func CreateEnableEpochsConfig() config.EnableEpochs { SaveJailedAlwaysEnableEpoch: UnreachableEpoch, ValidatorToDelegationEnableEpoch: UnreachableEpoch, ReDelegateBelowMinCheckEnableEpoch: UnreachableEpoch, - WaitingListFixEnableEpoch: UnreachableEpoch, IncrementSCRNonceInMultiTransferEnableEpoch: UnreachableEpoch, ESDTMultiTransferEnableEpoch: UnreachableEpoch, GlobalMintBurnDisableEpoch: UnreachableEpoch, diff --git a/integrationTests/vm/txsFee/scCalls_test.go b/integrationTests/vm/txsFee/scCalls_test.go index e08de111c30..86bb0e54e1d 100644 --- a/integrationTests/vm/txsFee/scCalls_test.go +++ b/integrationTests/vm/txsFee/scCalls_test.go @@ -58,7 +58,6 @@ func prepareTestContextForEpoch836(tb testing.TB) (*vm.VMTestContext, []byte) { testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGas( config.EnableEpochs{ GovernanceEnableEpoch: unreachableEpoch, - WaitingListFixEnableEpoch: unreachableEpoch, SetSenderInEeiOutputTransferEnableEpoch: unreachableEpoch, RefactorPeersMiniBlocksEnableEpoch: unreachableEpoch, MaxBlockchainHookCountersEnableEpoch: unreachableEpoch, @@ -368,7 +367,6 @@ func prepareTestContextForEpoch460(tb testing.TB) (*vm.VMTestContext, []byte) { testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{ GovernanceEnableEpoch: unreachableEpoch, - WaitingListFixEnableEpoch: unreachableEpoch, ScheduledMiniBlocksEnableEpoch: unreachableEpoch, CorrectJailedNotUnstakedEmptyQueueEpoch: unreachableEpoch, OptimizeNFTStoreEnableEpoch: unreachableEpoch, diff --git a/node/metrics/metrics.go b/node/metrics/metrics.go index 566ce79d2e4..8f91c5421be 100644 --- a/node/metrics/metrics.go +++ b/node/metrics/metrics.go @@ -122,7 +122,6 @@ func InitConfigMetrics( appStatusHandler.SetUInt64Value(common.MetricGlobalMintBurnDisableEpoch, uint64(enableEpochs.GlobalMintBurnDisableEpoch)) appStatusHandler.SetUInt64Value(common.MetricESDTTransferRoleEnableEpoch, uint64(enableEpochs.ESDTTransferRoleEnableEpoch)) appStatusHandler.SetStringValue(common.MetricTotalSupply, economicsConfig.GlobalSettings.GenesisTotalSupply) - appStatusHandler.SetUInt64Value(common.MetricWaitingListFixEnableEpoch, uint64(enableEpochs.WaitingListFixEnableEpoch)) for i, nodesChangeConfig := range enableEpochs.MaxNodesChangeEnableEpoch { epochEnable := fmt.Sprintf("%s%d%s", common.MetricMaxNodesChangeEnableEpoch, i, common.EpochEnableSuffix) diff --git a/node/metrics/metrics_test.go b/node/metrics/metrics_test.go index f31d05807a3..8133d10890a 100644 --- a/node/metrics/metrics_test.go +++ b/node/metrics/metrics_test.go @@ -132,7 +132,6 @@ func TestInitConfigMetrics(t *testing.T) { ESDTMultiTransferEnableEpoch: 31, GlobalMintBurnDisableEpoch: 32, ESDTTransferRoleEnableEpoch: 33, - WaitingListFixEnableEpoch: 35, }, } @@ -170,8 +169,6 @@ func TestInitConfigMetrics(t *testing.T) { "erd_esdt_multi_transfer_enable_epoch": uint32(31), "erd_global_mint_burn_disable_epoch": uint32(32), "erd_esdt_transfer_role_enable_epoch": uint32(33), - "erd_builtin_function_on_meta_enable_epoch": uint32(34), - "erd_waiting_list_fix_enable_epoch": uint32(35), "erd_max_nodes_change_enable_epoch": nil, "erd_total_supply": "12345", "erd_hysteresis": "0.100000", diff --git a/node/nodeRunner.go b/node/nodeRunner.go index bc4a2e8cea4..24fedbc2cff 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -164,7 +164,6 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("save jailed always"), "epoch", enableEpochs.SaveJailedAlwaysEnableEpoch) log.Debug(readEpochFor("validator to delegation"), "epoch", enableEpochs.ValidatorToDelegationEnableEpoch) log.Debug(readEpochFor("re-delegate below minimum check"), "epoch", enableEpochs.ReDelegateBelowMinCheckEnableEpoch) - log.Debug(readEpochFor("waiting waiting list"), "epoch", enableEpochs.WaitingListFixEnableEpoch) log.Debug(readEpochFor("increment SCR nonce in multi transfer"), "epoch", enableEpochs.IncrementSCRNonceInMultiTransferEnableEpoch) log.Debug(readEpochFor("esdt and NFT multi transfer"), "epoch", enableEpochs.ESDTMultiTransferEnableEpoch) log.Debug(readEpochFor("contract global mint and burn"), "epoch", enableEpochs.GlobalMintBurnDisableEpoch) diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index b65d69cb61c..dc9f87a29c4 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -2,7 +2,6 @@ package mock // EnableEpochsHandlerMock - type EnableEpochsHandlerMock struct { - WaitingListFixEnableEpochField uint32 RefactorPeersMiniBlocksEnableEpochField uint32 IsRefactorPeersMiniBlocksFlagEnabledField bool } @@ -27,16 +26,11 @@ func (mock *EnableEpochsHandlerMock) SwitchJailWaitingEnableEpoch() uint32 { return 0 } -// BalanceWaitingListsEnableEpoch returns WaitingListFixEnableEpochField +// BalanceWaitingListsEnableEpoch returns 0 func (mock *EnableEpochsHandlerMock) BalanceWaitingListsEnableEpoch() uint32 { return 0 } -// WaitingListFixEnableEpoch returns WaitingListFixEnableEpochField -func (mock *EnableEpochsHandlerMock) WaitingListFixEnableEpoch() uint32 { - return mock.WaitingListFixEnableEpochField -} - // MultiESDTTransferAsyncCallBackEnableEpoch returns 0 func (mock *EnableEpochsHandlerMock) MultiESDTTransferAsyncCallBackEnableEpoch() uint32 { return 0 @@ -281,11 +275,6 @@ func (mock *EnableEpochsHandlerMock) IsValidatorToDelegationFlagEnabled() bool { return false } -// IsWaitingListFixFlagEnabled returns false -func (mock *EnableEpochsHandlerMock) IsWaitingListFixFlagEnabled() bool { - return false -} - // IsIncrementSCRNonceInMultiTransferFlagEnabled returns false func (mock *EnableEpochsHandlerMock) IsIncrementSCRNonceInMultiTransferFlagEnabled() bool { return false diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index d4c752cb135..731b86f5dc2 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -42,7 +42,6 @@ type shuffleNodesArg struct { nbShards uint32 maxNodesToSwapPerShard uint32 flagBalanceWaitingLists bool - flagWaitingListFix bool flagStakingV4 bool flagStakingV4DistributeAuctionToWaiting bool } @@ -63,7 +62,6 @@ type randHashShuffler struct { mutShufflerParams sync.RWMutex validatorDistributor ValidatorsDistributor flagBalanceWaitingLists atomic.Flag - flagWaitingListFix atomic.Flag enableEpochsHandler common.EnableEpochsHandler stakingV4DistributeAuctionToWaitingEpoch uint32 flagStakingV4DistributeAuctionToWaiting atomic.Flag @@ -195,7 +193,6 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo distributor: rhs.validatorDistributor, maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), - flagWaitingListFix: rhs.flagWaitingListFix.IsSet(), flagStakingV4: rhs.flagStakingV4.IsSet(), flagStakingV4DistributeAuctionToWaiting: rhs.flagStakingV4DistributeAuctionToWaiting.IsSet(), }) @@ -275,18 +272,12 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { eligibleCopy, waitingCopy, numToRemove, - remainingUnstakeLeaving, - int(arg.nodesMeta), - int(arg.nodesPerShard), - arg.flagWaitingListFix) + remainingUnstakeLeaving) newEligible, newWaiting, stillRemainingAdditionalLeaving := removeLeavingNodesFromValidatorMaps( newEligible, newWaiting, numToRemove, - remainingAdditionalLeaving, - int(arg.nodesMeta), - int(arg.nodesPerShard), - arg.flagWaitingListFix) + remainingAdditionalLeaving) stillRemainingInLeaving := append(stillRemainingUnstakeLeaving, stillRemainingAdditionalLeaving...) @@ -404,21 +395,14 @@ func removeLeavingNodesFromValidatorMaps( waiting map[uint32][]Validator, numToRemove map[uint32]int, leaving []Validator, - minNodesMeta int, - minNodesPerShard int, - waitingFixEnabled bool, ) (map[uint32][]Validator, map[uint32][]Validator, []Validator) { stillRemainingInLeaving := make([]Validator, len(leaving)) copy(stillRemainingInLeaving, leaving) - if !waitingFixEnabled { - newWaiting, stillRemainingInLeaving := removeNodesFromMap(waiting, stillRemainingInLeaving, numToRemove) - newEligible, stillRemainingInLeaving := removeNodesFromMap(eligible, stillRemainingInLeaving, numToRemove) - return newEligible, newWaiting, stillRemainingInLeaving - } - - return removeLeavingNodes(eligible, waiting, numToRemove, stillRemainingInLeaving, minNodesMeta, minNodesPerShard) + newWaiting, stillRemainingInLeaving := removeNodesFromMap(waiting, stillRemainingInLeaving, numToRemove) + newEligible, stillRemainingInLeaving := removeNodesFromMap(eligible, stillRemainingInLeaving, numToRemove) + return newEligible, newWaiting, stillRemainingInLeaving } func removeLeavingNodes( @@ -804,7 +788,6 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { rhs.flagBalanceWaitingLists.SetValue(epoch >= rhs.enableEpochsHandler.BalanceWaitingListsEnableEpoch()) log.Debug("balanced waiting lists", "enabled", rhs.flagBalanceWaitingLists.IsSet()) - rhs.flagWaitingListFix.SetValue(epoch >= rhs.enableEpochsHandler.WaitingListFixEnableEpoch()) rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4DistributeAuctionToWaitingEpoch) log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4DistributeAuctionToWaiting.IsSet()) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index a72e1f2ddd1..f52d562fd5b 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -993,10 +993,7 @@ func Test_shuffleOutNodesWithLeaving(t *testing.T) { copyEligibleMap, copyWaitingMap, numToRemove, - leaving, - eligibleNodesPerShard, - eligibleNodesPerShard, - true) + leaving) shuffledOut, newEligible := shuffleOutNodes(newEligible, numToRemove, randomness) shuffleOutList := make([]Validator, 0) for _, shuffledOutPerShard := range shuffledOut { @@ -1031,10 +1028,7 @@ func Test_shuffleOutNodesWithLeavingMoreThanWaiting(t *testing.T) { copyEligibleMap, copyWaitingMap, numToRemove, - leaving, - eligibleNodesPerShard, - eligibleNodesPerShard, - true) + leaving) shuffledOut, newEligible := shuffleOutNodes(newEligible, numToRemove, randomness) shuffleOutList := make([]Validator, 0) @@ -1052,52 +1046,30 @@ func Test_removeLeavingNodesFromValidatorMaps(t *testing.T) { waitingNodesPerShard := 40 nbShards := uint32(2) - tests := []struct { - waitingFixEnabled bool - remainingToRemove int - }{ - { - waitingFixEnabled: false, - remainingToRemove: 18, - }, - { - waitingFixEnabled: true, - remainingToRemove: 20, - }, + leaving := make([]Validator, 0) + + eligibleMap := generateValidatorMap(eligibleNodesPerShard, nbShards) + waitingMap := generateValidatorMap(waitingNodesPerShard, nbShards) + for _, waitingValidators := range waitingMap { + leaving = append(leaving, waitingValidators[:2]...) } - for _, tt := range tests { - t.Run("", func(t *testing.T) { - leaving := make([]Validator, 0) + numToRemove := make(map[uint32]int) - eligibleMap := generateValidatorMap(eligibleNodesPerShard, nbShards) - waitingMap := generateValidatorMap(waitingNodesPerShard, nbShards) - for _, waitingValidators := range waitingMap { - leaving = append(leaving, waitingValidators[:2]...) - } + for shardId := range waitingMap { + numToRemove[shardId] = maxShuffleOutNumber + } + copyEligibleMap := copyValidatorMap(eligibleMap) + copyWaitingMap := copyValidatorMap(waitingMap) - numToRemove := make(map[uint32]int) + _, _, _ = removeLeavingNodesFromValidatorMaps( + copyEligibleMap, + copyWaitingMap, + numToRemove, + leaving) - for shardId := range waitingMap { - numToRemove[shardId] = maxShuffleOutNumber - } - copyEligibleMap := copyValidatorMap(eligibleMap) - copyWaitingMap := copyValidatorMap(waitingMap) - - _, _, _ = removeLeavingNodesFromValidatorMaps( - copyEligibleMap, - copyWaitingMap, - numToRemove, - leaving, - eligibleNodesPerShard, - eligibleNodesPerShard, - tt.waitingFixEnabled, - ) - - for _, remainingToRemove := range numToRemove { - require.Equal(t, tt.remainingToRemove, remainingToRemove) - } - }) + for _, remainingToRemove := range numToRemove { + require.Equal(t, 18, remainingToRemove) } } @@ -1306,12 +1278,6 @@ func TestRandHashShuffler_UpdateNodeListsWaitingListFixDisabled(t *testing.T) { testUpdateNodesAndCheckNumLeaving(t, true) } -func TestRandHashShuffler_UpdateNodeListsWithWaitingListFixEnabled(t *testing.T) { - t.Parallel() - - testUpdateNodesAndCheckNumLeaving(t, false) -} - func testUpdateNodesAndCheckNumLeaving(t *testing.T, beforeFix bool) { eligiblePerShard := 400 eligibleMeta := 10 @@ -1323,11 +1289,6 @@ func testUpdateNodesAndCheckNumLeaving(t *testing.T, beforeFix bool) { numNodesToShuffle := 80 - waitingListFixEnableEpoch := 0 - if beforeFix { - waitingListFixEnableEpoch = 9999 - } - shufflerArgs := &NodesShufflerArgs{ NodesShard: uint32(eligiblePerShard), NodesMeta: uint32(eligibleMeta), @@ -1341,12 +1302,7 @@ func testUpdateNodesAndCheckNumLeaving(t *testing.T, beforeFix bool) { NodesToShufflePerShard: uint32(numNodesToShuffle), }, }, - EnableEpochs: config.EnableEpochs{ - WaitingListFixEnableEpoch: uint32(waitingListFixEnableEpoch), - }, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{ - WaitingListFixEnableEpochField: uint32(waitingListFixEnableEpoch), - }, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1375,34 +1331,15 @@ func testUpdateNodesAndCheckNumLeaving(t *testing.T, beforeFix bool) { } } -func TestRandHashShuffler_UpdateNodeListsWaitingListWithFixCheckWaitingDisabled(t *testing.T) { - t.Parallel() - - testUpdateNodeListsAndCheckWaitingList(t, true) -} - -func TestRandHashShuffler_UpdateNodeListsWaitingListWithFixCheckWaitingEnabled(t *testing.T) { - t.Parallel() - - testUpdateNodeListsAndCheckWaitingList(t, false) -} - -func testUpdateNodeListsAndCheckWaitingList(t *testing.T, beforeFix bool) { +func TestRandHashShuffler_UpdateNodeListsAndCheckWaitingList(t *testing.T) { eligiblePerShard := 400 eligibleMeta := 10 waitingPerShard := 400 nbShards := 1 - numLeaving := 2 - numNodesToShuffle := 80 - waitingListFixEnableEpoch := 0 - if beforeFix { - waitingListFixEnableEpoch = 9999 - } - shufflerArgs := &NodesShufflerArgs{ NodesShard: uint32(eligiblePerShard), NodesMeta: uint32(eligibleMeta), @@ -1416,9 +1353,7 @@ func testUpdateNodeListsAndCheckWaitingList(t *testing.T, beforeFix bool) { NodesToShufflePerShard: uint32(numNodesToShuffle), }, }, - EnableEpochsHandler: &mock.EnableEpochsHandlerMock{ - WaitingListFixEnableEpochField: uint32(waitingListFixEnableEpoch), - }, + EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -1452,9 +1387,7 @@ func testUpdateNodeListsAndCheckWaitingList(t *testing.T, beforeFix bool) { } expectedNumWaitingMovedToEligible := numNodesToShuffle - if beforeFix { - expectedNumWaitingMovedToEligible -= numLeaving - } + expectedNumWaitingMovedToEligible -= numLeaving assert.Equal(t, expectedNumWaitingMovedToEligible, numWaitingListToEligible) } @@ -1762,10 +1695,7 @@ func TestRandHashShuffler_RemoveLeavingNodesFromValidatorMaps_FromEligible(t *te eligibleCopy, waitingCopy, numToRemove, - leavingValidators, - eligiblePerShard, - eligiblePerShard, - true) + leavingValidators) assert.Equal(t, eligiblePerShard-1, len(newEligible[core.MetachainShardId])) assert.Equal(t, waitingPerShard, len(newWaiting[core.MetachainShardId])) @@ -1803,10 +1733,7 @@ func TestRandHashShuffler_RemoveLeavingNodesFromValidatorMaps_FromWaiting(t *tes eligibleCopy, waitingCopy, numToRemove, - leavingValidators, - eligiblePerShard, - eligiblePerShard, - true) + leavingValidators) assert.Equal(t, eligiblePerShard, len(newEligible[core.MetachainShardId])) assert.Equal(t, waitingPerShard-1, len(newWaiting[core.MetachainShardId])) @@ -1842,10 +1769,7 @@ func TestRandHashShuffler_RemoveLeavingNodesFromValidatorMaps_NonExisting(t *tes eligibleCopy, waitingCopy, numToRemove, - leavingValidators, - eligiblePerShard, - eligiblePerShard, - true) + leavingValidators) assert.Equal(t, eligiblePerShard, len(newEligible[core.MetachainShardId])) assert.Equal(t, waitingPerShard, len(newWaiting[core.MetachainShardId])) @@ -1888,10 +1812,7 @@ func TestRandHashShuffler_RemoveLeavingNodesFromValidatorMaps_2Eligible2Waiting2 eligibleCopy, waitingCopy, numToRemove, - leavingValidators, - eligiblePerShard, - eligiblePerShard, - true) + leavingValidators) remainingInEligible := eligiblePerShard - 2 remainingInWaiting := waitingPerShard - 2 @@ -1948,10 +1869,7 @@ func TestRandHashShuffler_RemoveLeavingNodesFromValidatorMaps_2FromEligible2From eligibleCopy, waitingCopy, numToRemove, - leavingValidators, - eligiblePerShard, - eligiblePerShard, - true) + leavingValidators) // removed first 2 from waiting and just one from eligible remainingInEligible := eligiblePerShard - 1 diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index a4c21089f62..4c67c2ba9ca 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -94,7 +94,6 @@ type indexHashedNodesCoordinator struct { publicKeyToValidatorMap map[string]*validatorWithShardID isFullArchive bool chanStopNode chan endProcess.ArgEndProcess - flagWaitingListFix atomicFlags.Flag nodeTypeProvider NodeTypeProviderHandler enableEpochsHandler common.EnableEpochsHandler validatorInfoCacher epochStart.ValidatorInfoCacher @@ -753,7 +752,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( newNodesList := make([]Validator, 0) auctionList := make([]Validator, 0) - if ihnc.flagWaitingListFix.IsSet() && previousEpochConfig == nil { + if previousEpochConfig == nil { return nil, ErrNilPreviousEpochConfig } @@ -777,9 +776,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( log.Debug("leaving node validatorInfo", "pk", validatorInfo.PublicKey) leavingMap[validatorInfo.ShardId] = append(leavingMap[validatorInfo.ShardId], currentValidator) ihnc.addValidatorToPreviousMap( - previousEpochConfig, eligibleMap, - waitingMap, currentValidator, validatorInfo.ShardId) case string(common.NewList): @@ -832,30 +829,11 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( } func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( - previousEpochConfig *epochNodesConfig, eligibleMap map[uint32][]Validator, - waitingMap map[uint32][]Validator, currentValidator *validator, - currentValidatorShardId uint32) { - - if !ihnc.flagWaitingListFix.IsSet() { - eligibleMap[currentValidatorShardId] = append(eligibleMap[currentValidatorShardId], currentValidator) - return - } - - found, shardId := searchInMap(previousEpochConfig.eligibleMap, currentValidator.PubKey()) - if found { - log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) - eligibleMap[shardId] = append(eligibleMap[currentValidatorShardId], currentValidator) - return - } - - found, shardId = searchInMap(previousEpochConfig.waitingMap, currentValidator.PubKey()) - if found { - log.Debug("leaving node found in", "list", "waiting", "shardId", shardId) - waitingMap[shardId] = append(waitingMap[currentValidatorShardId], currentValidator) - return - } + currentValidatorShardId uint32, +) { + eligibleMap[currentValidatorShardId] = append(eligibleMap[currentValidatorShardId], currentValidator) } func (ihnc *indexHashedNodesCoordinator) handleErrorLog(err error, message string) { @@ -1295,9 +1273,6 @@ func (ihnc *indexHashedNodesCoordinator) getShardValidatorInfoData(txHash []byte } func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { - ihnc.flagWaitingListFix.SetValue(epoch >= ihnc.enableEpochsHandler.WaitingListFixEnableEpoch()) - log.Debug("indexHashedNodesCoordinator: waiting list fix", "enabled", ihnc.flagWaitingListFix.IsSet()) - ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4EnableEpoch) log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4.IsSet()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index a677fdb6777..ee5219c6d8d 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -2047,21 +2047,9 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNilPreviousNodesC arguments.SelfPublicKey = pk ihnc, _ := NewIndexHashedNodesCoordinator(arguments) - ihnc.flagWaitingListFix.Reset() validatorInfos := make([]*state.ShardValidatorInfo, 0) - newNodesConfig, err := ihnc.computeNodesConfigFromList(nil, validatorInfos) - - assert.Nil(t, newNodesConfig) - assert.False(t, errors.Is(err, ErrNilPreviousEpochConfig)) - - newNodesConfig, err = ihnc.computeNodesConfigFromList(nil, nil) - - assert.Nil(t, newNodesConfig) - assert.False(t, errors.Is(err, ErrNilPreviousEpochConfig)) - - _ = ihnc.flagWaitingListFix.SetReturningPrevious() - newNodesConfig, err = ihnc.computeNodesConfigFromList(nil, validatorInfos) + newNodesConfig, err := ihnc.computeNodesConfigFromList(nil, validatorInfos) assert.Nil(t, newNodesConfig) assert.True(t, errors.Is(err, ErrNilPreviousEpochConfig)) @@ -2181,135 +2169,6 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * require.Nil(t, newNodesConfig) } -func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix(t *testing.T) { - t.Parallel() - - arguments := createArguments() - pk := []byte("pk") - arguments.SelfPublicKey = pk - ihnc, _ := NewIndexHashedNodesCoordinator(arguments) - _ = ihnc.flagWaitingListFix.SetReturningPrevious() - - shard0Eligible0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk0"), - List: string(common.EligibleList), - Index: 1, - TempRating: 2, - ShardId: 0, - } - shard0Eligible1 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk1"), - List: string(common.EligibleList), - Index: 2, - TempRating: 2, - ShardId: 0, - } - shardmetaEligible0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk2"), - ShardId: core.MetachainShardId, - List: string(common.EligibleList), - Index: 1, - TempRating: 4, - } - shard0Waiting0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk3"), - List: string(common.WaitingList), - Index: 14, - ShardId: 0, - } - shardmetaWaiting0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk4"), - ShardId: core.MetachainShardId, - List: string(common.WaitingList), - Index: 15, - } - shard0New0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk5"), - List: string(common.NewList), Index: 3, - ShardId: 0, - } - shard0Leaving0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk6"), - List: string(common.LeavingList), - ShardId: 0, - } - shardMetaLeaving1 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk7"), - List: string(common.LeavingList), - Index: 1, - ShardId: core.MetachainShardId, - } - - validatorInfos := - []*state.ShardValidatorInfo{ - shard0Eligible0, - shard0Eligible1, - shardmetaEligible0, - shard0Waiting0, - shardmetaWaiting0, - shard0New0, - shard0Leaving0, - shardMetaLeaving1, - } - - previousConfig := &epochNodesConfig{ - eligibleMap: map[uint32][]Validator{ - 0: { - newValidatorMock(shard0Eligible0.PublicKey, 0, 0), - newValidatorMock(shard0Eligible1.PublicKey, 0, 0), - newValidatorMock(shard0Leaving0.PublicKey, 0, 0), - }, - core.MetachainShardId: { - newValidatorMock(shardmetaEligible0.PublicKey, 0, 0), - }, - }, - waitingMap: map[uint32][]Validator{ - 0: { - newValidatorMock(shard0Waiting0.PublicKey, 0, 0), - }, - core.MetachainShardId: { - newValidatorMock(shardmetaWaiting0.PublicKey, 0, 0), - newValidatorMock(shardMetaLeaving1.PublicKey, 0, 0), - }, - }, - } - - newNodesConfig, err := ihnc.computeNodesConfigFromList(previousConfig, validatorInfos) - assert.Nil(t, err) - - assert.Equal(t, uint32(1), newNodesConfig.nbShards) - - verifySizes(t, newNodesConfig) - verifyLeavingNodesInEligibleOrWaiting(t, newNodesConfig) - - // maps have the correct validators inside - eligibleListShardZero := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shard0Eligible0, shard0Eligible1, shard0Leaving0}) - assert.Equal(t, eligibleListShardZero, newNodesConfig.eligibleMap[0]) - eligibleListMeta := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shardmetaEligible0}) - assert.Equal(t, eligibleListMeta, newNodesConfig.eligibleMap[core.MetachainShardId]) - - waitingListShardZero := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shard0Waiting0}) - assert.Equal(t, waitingListShardZero, newNodesConfig.waitingMap[0]) - waitingListMeta := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shardmetaWaiting0, shardMetaLeaving1}) - assert.Equal(t, waitingListMeta, newNodesConfig.waitingMap[core.MetachainShardId]) - - leavingListShardZero := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shard0Leaving0}) - assert.Equal(t, leavingListShardZero, newNodesConfig.leavingMap[0]) - - leavingListMeta := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shardMetaLeaving1}) - assert.Equal(t, leavingListMeta, newNodesConfig.leavingMap[core.MetachainShardId]) - - newListShardZero := createValidatorList(ihnc, - []*state.ShardValidatorInfo{shard0New0}) - assert.Equal(t, newListShardZero, newNodesConfig.newList) -} - func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsNoFix(t *testing.T) { t.Parallel() @@ -2384,7 +2243,6 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsNoFix(t shardMetaLeaving1, } - ihnc.flagWaitingListFix.Reset() newNodesConfig, err := ihnc.computeNodesConfigFromList(previousConfig, validatorInfos) assert.Nil(t, err) diff --git a/statusHandler/statusMetricsProvider.go b/statusHandler/statusMetricsProvider.go index 00f536da84e..60e88009516 100644 --- a/statusHandler/statusMetricsProvider.go +++ b/statusHandler/statusMetricsProvider.go @@ -294,7 +294,6 @@ func (sm *statusMetrics) EnableEpochsMetrics() (map[string]interface{}, error) { enableEpochsMetrics[common.MetricDelegationSmartContractEnableEpoch] = sm.uint64Metrics[common.MetricDelegationSmartContractEnableEpoch] enableEpochsMetrics[common.MetricIncrementSCRNonceInMultiTransferEnableEpoch] = sm.uint64Metrics[common.MetricIncrementSCRNonceInMultiTransferEnableEpoch] enableEpochsMetrics[common.MetricBalanceWaitingListsEnableEpoch] = sm.uint64Metrics[common.MetricBalanceWaitingListsEnableEpoch] - enableEpochsMetrics[common.MetricWaitingListFixEnableEpoch] = sm.uint64Metrics[common.MetricWaitingListFixEnableEpoch] numNodesChangeConfig := sm.uint64Metrics[common.MetricMaxNodesChangeEnableEpoch+"_count"] diff --git a/statusHandler/statusMetricsProvider_test.go b/statusHandler/statusMetricsProvider_test.go index 5d2c2ab664a..cd2284baef6 100644 --- a/statusHandler/statusMetricsProvider_test.go +++ b/statusHandler/statusMetricsProvider_test.go @@ -313,7 +313,6 @@ func TestStatusMetrics_EnableEpochMetrics(t *testing.T) { sm.SetUInt64Value(common.MetricDelegationSmartContractEnableEpoch, 2) sm.SetUInt64Value(common.MetricIncrementSCRNonceInMultiTransferEnableEpoch, 3) sm.SetUInt64Value(common.MetricBalanceWaitingListsEnableEpoch, 4) - sm.SetUInt64Value(common.MetricWaitingListFixEnableEpoch, 1) maxNodesChangeConfig := []map[string]uint64{ { @@ -362,7 +361,6 @@ func TestStatusMetrics_EnableEpochMetrics(t *testing.T) { common.MetricDelegationSmartContractEnableEpoch: uint64(2), common.MetricIncrementSCRNonceInMultiTransferEnableEpoch: uint64(3), common.MetricBalanceWaitingListsEnableEpoch: uint64(4), - common.MetricWaitingListFixEnableEpoch: uint64(1), common.MetricMaxNodesChangeEnableEpoch: []map[string]interface{}{ { diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 9e126efeccc..3f93292d05e 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -13,7 +13,6 @@ type EnableEpochsHandlerStub struct { ScheduledMiniBlocksEnableEpochField uint32 SwitchJailWaitingEnableEpochField uint32 BalanceWaitingListsEnableEpochField uint32 - WaitingListFixEnableEpochField uint32 MultiESDTTransferAsyncCallBackEnableEpochField uint32 FixOOGReturnCodeEnableEpochField uint32 RemoveNonUpdatedStorageEnableEpochField uint32 @@ -62,7 +61,6 @@ type EnableEpochsHandlerStub struct { IsSaveJailedAlwaysFlagEnabledField bool IsReDelegateBelowMinCheckFlagEnabledField bool IsValidatorToDelegationFlagEnabledField bool - IsWaitingListFixFlagEnabledField bool IsIncrementSCRNonceInMultiTransferFlagEnabledField bool IsESDTMultiTransferFlagEnabledField bool IsGlobalMintBurnFlagEnabledField bool @@ -173,14 +171,6 @@ func (stub *EnableEpochsHandlerStub) BalanceWaitingListsEnableEpoch() uint32 { return stub.BalanceWaitingListsEnableEpochField } -// WaitingListFixEnableEpoch - -func (stub *EnableEpochsHandlerStub) WaitingListFixEnableEpoch() uint32 { - stub.RLock() - defer stub.RUnlock() - - return stub.WaitingListFixEnableEpochField -} - // MultiESDTTransferAsyncCallBackEnableEpoch - func (stub *EnableEpochsHandlerStub) MultiESDTTransferAsyncCallBackEnableEpoch() uint32 { stub.RLock() @@ -557,14 +547,6 @@ func (stub *EnableEpochsHandlerStub) IsValidatorToDelegationFlagEnabled() bool { return stub.IsValidatorToDelegationFlagEnabledField } -// IsWaitingListFixFlagEnabled - -func (stub *EnableEpochsHandlerStub) IsWaitingListFixFlagEnabled() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsWaitingListFixFlagEnabledField -} - // IsIncrementSCRNonceInMultiTransferFlagEnabled - func (stub *EnableEpochsHandlerStub) IsIncrementSCRNonceInMultiTransferFlagEnabled() bool { stub.RLock() From 031c20e8fa8ce8789c98f5cd87aab26fb17ece4b Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 2 Feb 2023 12:35:35 +0200 Subject: [PATCH 394/958] FIX: computeNodesConfigFromList using previous config --- common/enablers/enableEpochsHandler.go | 5 + common/interface.go | 1 + sharding/mock/enableEpochsHandlerMock.go | 5 + .../indexHashedNodesCoordinator.go | 30 +++- .../indexHashedNodesCoordinator_test.go | 130 ++++++++++++++++++ testscommon/enableEpochsHandlerStub.go | 9 ++ 6 files changed, 179 insertions(+), 1 deletion(-) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index c223cdba899..3d53d3eae15 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -218,6 +218,11 @@ func (handler *enableEpochsHandler) StakingV4EnableEpoch() uint32 { return handler.enableEpochsConfig.StakingV4EnableEpoch } +// StakingV4InitEpoch returns the epoch when stakingV4 phase1 becomes active +func (handler *enableEpochsHandler) StakingV4InitEpoch() uint32 { + return handler.enableEpochsConfig.StakingV4InitEnableEpoch +} + // IsInterfaceNil returns true if there is no value under the interface func (handler *enableEpochsHandler) IsInterfaceNil() bool { return handler == nil diff --git a/common/interface.go b/common/interface.go index a6a6436caae..c0940a65a75 100644 --- a/common/interface.go +++ b/common/interface.go @@ -243,6 +243,7 @@ type EnableEpochsHandler interface { MiniBlockPartialExecutionEnableEpoch() uint32 RefactorPeersMiniBlocksEnableEpoch() uint32 StakingV4EnableEpoch() uint32 + StakingV4InitEpoch() uint32 IsSCDeployFlagEnabled() bool IsBuiltInFunctionsFlagEnabled() bool IsRelayedTransactionsFlagEnabled() bool diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index dc9f87a29c4..32429321a6f 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -91,6 +91,11 @@ func (mock *EnableEpochsHandlerMock) StakingV4EnableEpoch() uint32 { return 0 } +// StakingV4InitEpoch - +func (mock *EnableEpochsHandlerMock) StakingV4InitEpoch() uint32 { + return 0 +} + // RefactorPeersMiniBlocksEnableEpoch returns 0 func (mock *EnableEpochsHandlerMock) RefactorPeersMiniBlocksEnableEpoch() uint32 { return mock.RefactorPeersMiniBlocksEnableEpochField diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 4c67c2ba9ca..d1bfa412b5f 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -100,6 +100,7 @@ type indexHashedNodesCoordinator struct { stakingV4EnableEpoch uint32 flagStakingV4 atomicFlags.Flag nodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory + flagStakingV4Started atomicFlags.Flag } // NewIndexHashedNodesCoordinator creates a new index hashed group selector @@ -776,7 +777,9 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( log.Debug("leaving node validatorInfo", "pk", validatorInfo.PublicKey) leavingMap[validatorInfo.ShardId] = append(leavingMap[validatorInfo.ShardId], currentValidator) ihnc.addValidatorToPreviousMap( + previousEpochConfig, eligibleMap, + waitingMap, currentValidator, validatorInfo.ShardId) case string(common.NewList): @@ -829,11 +832,33 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( } func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( + previousEpochConfig *epochNodesConfig, eligibleMap map[uint32][]Validator, + waitingMap map[uint32][]Validator, currentValidator *validator, currentValidatorShardId uint32, ) { - eligibleMap[currentValidatorShardId] = append(eligibleMap[currentValidatorShardId], currentValidator) + if !ihnc.flagStakingV4Started.IsSet() { + eligibleMap[currentValidatorShardId] = append(eligibleMap[currentValidatorShardId], currentValidator) + return + } + + found, shardId := searchInMap(previousEpochConfig.eligibleMap, currentValidator.PubKey()) + if found { + log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) + eligibleMap[shardId] = append(eligibleMap[currentValidatorShardId], currentValidator) + return + } + + found, shardId = searchInMap(previousEpochConfig.waitingMap, currentValidator.PubKey()) + if found { + log.Debug("leaving node found in", "list", "waiting", "shardId", shardId) + waitingMap[shardId] = append(waitingMap[currentValidatorShardId], currentValidator) + return + } + + log.Debug("leaving node not in eligible or waiting, probably was in auction/inactive/jailed", + "pk", currentValidator.PubKey(), "shardId", shardId) } func (ihnc *indexHashedNodesCoordinator) handleErrorLog(err error, message string) { @@ -1273,6 +1298,9 @@ func (ihnc *indexHashedNodesCoordinator) getShardValidatorInfoData(txHash []byte } func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { + ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.StakingV4InitEpoch()) + log.Debug("indexHashedNodesCoordinator: staking v4 started", "enabled", ihnc.flagStakingV4Started.IsSet()) + ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4EnableEpoch) log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4.IsSet()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index ee5219c6d8d..7dc811db203 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -2169,6 +2169,135 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * require.Nil(t, newNodesConfig) } +func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix(t *testing.T) { + t.Parallel() + + arguments := createArguments() + pk := []byte("pk") + arguments.SelfPublicKey = pk + ihnc, _ := NewIndexHashedNodesCoordinator(arguments) + _ = ihnc.flagStakingV4Started.SetReturningPrevious() + + shard0Eligible0 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk0"), + List: string(common.EligibleList), + Index: 1, + TempRating: 2, + ShardId: 0, + } + shard0Eligible1 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk1"), + List: string(common.EligibleList), + Index: 2, + TempRating: 2, + ShardId: 0, + } + shardmetaEligible0 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk2"), + ShardId: core.MetachainShardId, + List: string(common.EligibleList), + Index: 1, + TempRating: 4, + } + shard0Waiting0 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk3"), + List: string(common.WaitingList), + Index: 14, + ShardId: 0, + } + shardmetaWaiting0 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk4"), + ShardId: core.MetachainShardId, + List: string(common.WaitingList), + Index: 15, + } + shard0New0 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk5"), + List: string(common.NewList), Index: 3, + ShardId: 0, + } + shard0Leaving0 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk6"), + List: string(common.LeavingList), + ShardId: 0, + } + shardMetaLeaving1 := &state.ShardValidatorInfo{ + PublicKey: []byte("pk7"), + List: string(common.LeavingList), + Index: 1, + ShardId: core.MetachainShardId, + } + + validatorInfos := + []*state.ShardValidatorInfo{ + shard0Eligible0, + shard0Eligible1, + shardmetaEligible0, + shard0Waiting0, + shardmetaWaiting0, + shard0New0, + shard0Leaving0, + shardMetaLeaving1, + } + + previousConfig := &epochNodesConfig{ + eligibleMap: map[uint32][]Validator{ + 0: { + newValidatorMock(shard0Eligible0.PublicKey, 0, 0), + newValidatorMock(shard0Eligible1.PublicKey, 0, 0), + newValidatorMock(shard0Leaving0.PublicKey, 0, 0), + }, + core.MetachainShardId: { + newValidatorMock(shardmetaEligible0.PublicKey, 0, 0), + }, + }, + waitingMap: map[uint32][]Validator{ + 0: { + newValidatorMock(shard0Waiting0.PublicKey, 0, 0), + }, + core.MetachainShardId: { + newValidatorMock(shardmetaWaiting0.PublicKey, 0, 0), + newValidatorMock(shardMetaLeaving1.PublicKey, 0, 0), + }, + }, + } + + newNodesConfig, err := ihnc.computeNodesConfigFromList(previousConfig, validatorInfos) + assert.Nil(t, err) + + assert.Equal(t, uint32(1), newNodesConfig.nbShards) + + verifySizes(t, newNodesConfig) + verifyLeavingNodesInEligibleOrWaiting(t, newNodesConfig) + + // maps have the correct validators inside + eligibleListShardZero := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shard0Eligible0, shard0Eligible1, shard0Leaving0}) + assert.Equal(t, eligibleListShardZero, newNodesConfig.eligibleMap[0]) + eligibleListMeta := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shardmetaEligible0}) + assert.Equal(t, eligibleListMeta, newNodesConfig.eligibleMap[core.MetachainShardId]) + + waitingListShardZero := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shard0Waiting0}) + assert.Equal(t, waitingListShardZero, newNodesConfig.waitingMap[0]) + waitingListMeta := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shardmetaWaiting0, shardMetaLeaving1}) + assert.Equal(t, waitingListMeta, newNodesConfig.waitingMap[core.MetachainShardId]) + + leavingListShardZero := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shard0Leaving0}) + assert.Equal(t, leavingListShardZero, newNodesConfig.leavingMap[0]) + + leavingListMeta := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shardMetaLeaving1}) + assert.Equal(t, leavingListMeta, newNodesConfig.leavingMap[core.MetachainShardId]) + + newListShardZero := createValidatorList(ihnc, + []*state.ShardValidatorInfo{shard0New0}) + assert.Equal(t, newListShardZero, newNodesConfig.newList) +} + func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsNoFix(t *testing.T) { t.Parallel() @@ -2243,6 +2372,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsNoFix(t shardMetaLeaving1, } + ihnc.flagStakingV4Started.Reset() newNodesConfig, err := ihnc.computeNodesConfigFromList(previousConfig, validatorInfos) assert.Nil(t, err) diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 3f93292d05e..0ed27f16115 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -26,6 +26,7 @@ type EnableEpochsHandlerStub struct { MiniBlockPartialExecutionEnableEpochField uint32 RefactorPeersMiniBlocksEnableEpochField uint32 StakingV4EnableEpochField uint32 + StakingV4InitEpochField uint32 IsSCDeployFlagEnabledField bool IsBuiltInFunctionsFlagEnabledField bool IsRelayedTransactionsFlagEnabledField bool @@ -1044,6 +1045,14 @@ func (stub *EnableEpochsHandlerStub) StakingV4EnableEpoch() uint32 { return stub.StakingV4EnableEpochField } +// StakingV4InitEpoch - +func (stub *EnableEpochsHandlerStub) StakingV4InitEpoch() uint32 { + stub.RLock() + defer stub.RUnlock() + + return stub.StakingV4InitEpochField +} + // IsInterfaceNil - func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { return stub == nil From 53d8de1a7ddb279a6ef9224e9f3372b3f8b91e97 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 2 Feb 2023 12:42:14 +0200 Subject: [PATCH 395/958] FIX: Remove unused epochs --- epochStart/metachain/systemSCs.go | 35 ------------------------------- 1 file changed, 35 deletions(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 6c0311e40c8..9be672b3ce9 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -45,11 +45,6 @@ type ArgsNewEpochStartSystemSCProcessing struct { type systemSCProcessor struct { *legacySystemSCProcessor auctionListSelector epochStart.AuctionListSelector - - governanceEnableEpoch uint32 - builtInOnMetaEnableEpoch uint32 - stakingV4EnableEpoch uint32 - enableEpochsHandler common.EnableEpochsHandler } @@ -213,36 +208,6 @@ func (s *systemSCProcessor) updateToGovernanceV2() error { return nil } -func (s *systemSCProcessor) initTokenOnMeta() ([]byte, error) { - vmInput := &vmcommon.ContractCallInput{ - VMInput: vmcommon.VMInput{ - CallerAddr: vm.ESDTSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{}, - GasProvided: math.MaxUint64, - }, - RecipientAddr: vm.ESDTSCAddress, - Function: "initDelegationESDTOnMeta", - } - vmOutput, errRun := s.systemVM.RunSmartContractCall(vmInput) - if errRun != nil { - return nil, fmt.Errorf("%w when setting up NFTs on metachain", errRun) - } - if vmOutput.ReturnCode != vmcommon.Ok { - return nil, fmt.Errorf("got return code %s, return message %s when setting up NFTs on metachain", vmOutput.ReturnCode, vmOutput.ReturnMessage) - } - if len(vmOutput.ReturnData) != 1 { - return nil, fmt.Errorf("invalid return data on initDelegationESDTOnMeta") - } - - err := s.processSCOutputAccounts(vmOutput) - if err != nil { - return nil, err - } - - return vmOutput.ReturnData[0], nil -} - // IsInterfaceNil returns true if underlying object is nil func (s *systemSCProcessor) IsInterfaceNil() bool { return s == nil From 15a346104ce28738b2759567e274736b26644b48 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 2 Feb 2023 12:44:24 +0200 Subject: [PATCH 396/958] FIX: Probably merge commit error --- vm/systemSmartContracts/esdt.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 1bee94b5845..4c5300e76cb 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -1778,12 +1778,11 @@ func (e *esdt) unSetSpecialRole(args *vmcommon.ContractCallInput) vmcommon.Retur e.eei.SendGlobalSettingToAll(e.esdtSCAddress, []byte(esdtTransferData)) } - err := e.saveToken(args.Arguments[0], token) if isTransferRoleInArgs { e.deleteTransferRoleAddressFromSystemAccount(args.Arguments[0], address) } - err = e.saveToken(args.Arguments[0], token) + err := e.saveToken(args.Arguments[0], token) if err != nil { e.eei.AddReturnMessage(err.Error()) return vmcommon.UserError From e8f4b0c266f71d8d7304fd14d2c5a3139e7d82c8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 2 Feb 2023 12:58:45 +0200 Subject: [PATCH 397/958] FIX: Remove IsBuiltInFunctionsFlagEnabledField from tests --- process/smartContract/process_test.go | 7 ------- process/transaction/metaProcess_test.go | 16 +--------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/process/smartContract/process_test.go b/process/smartContract/process_test.go index cc37d77aed4..2ed3ea1548c 100644 --- a/process/smartContract/process_test.go +++ b/process/smartContract/process_test.go @@ -3293,13 +3293,6 @@ func TestScProcessor_ProcessSmartContractResultExecuteSCIfMetaAndBuiltIn(t *test _, err = sc.ProcessSmartContractResult(&scr) require.Nil(t, err) require.True(t, executeCalled) - - executeCalled = false - enableEpochsHandlerStub.IsBuiltInFunctionOnMetaFlagEnabledField = true - enableEpochsHandlerStub.IsBuiltInFunctionsFlagEnabledField = true - _, err = sc.ProcessSmartContractResult(&scr) - require.Nil(t, err) - require.False(t, executeCalled) } func TestScProcessor_ProcessRelayedSCRValueBackToRelayer(t *testing.T) { diff --git a/process/transaction/metaProcess_test.go b/process/transaction/metaProcess_test.go index babe9ff0458..efc5b428a55 100644 --- a/process/transaction/metaProcess_test.go +++ b/process/transaction/metaProcess_test.go @@ -422,8 +422,7 @@ func TestMetaTxProcessor_ProcessTransactionBuiltInCallTxShouldWork(t *testing.T) }, } enableEpochsHandlerStub := &testscommon.EnableEpochsHandlerStub{ - IsBuiltInFunctionOnMetaFlagEnabledField: false, - IsESDTFlagEnabledField: true, + IsESDTFlagEnabledField: true, } args.EnableEpochsHandler = enableEpochsHandlerStub txProc, _ := txproc.NewMetaTxProcessor(args) @@ -432,17 +431,4 @@ func TestMetaTxProcessor_ProcessTransactionBuiltInCallTxShouldWork(t *testing.T) assert.Nil(t, err) assert.True(t, wasCalled) assert.Equal(t, 0, saveAccountCalled) - - builtInCalled := false - scProcessorMock.ExecuteBuiltInFunctionCalled = func(tx data.TransactionHandler, acntSrc, acntDst state.UserAccountHandler) (vmcommon.ReturnCode, error) { - builtInCalled = true - return 0, nil - } - - enableEpochsHandlerStub.IsBuiltInFunctionOnMetaFlagEnabledField = true - - _, err = txProc.ProcessTransaction(&tx) - assert.Nil(t, err) - assert.True(t, builtInCalled) - assert.Equal(t, 0, saveAccountCalled) } From cbf73b8e9d8c3a81ded8fea27e9b077639e41272 Mon Sep 17 00:00:00 2001 From: gabi-vuls Date: Fri, 3 Feb 2023 14:11:27 +0200 Subject: [PATCH 398/958] added extra log --- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index d1bfa412b5f..69a3bc032c6 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -605,7 +605,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa } ihnc.updateEpochFlags(newEpoch) - + log.Debug("indexHashedNodesCoordinator.EpochStartPrepare", "ihnc.currentEpoch", ihnc.currentEpoch) allValidatorInfo, err := ihnc.createValidatorInfoFromBody(body, ihnc.numTotalEligible, newEpoch) if err != nil { log.Error("could not create validator info from body - do nothing on nodesCoordinator epochStartPrepare", "error", err.Error()) From 5cadb2533ce8f038722b02d11ea5b2db3b5ab13a Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 3 Feb 2023 15:35:34 +0200 Subject: [PATCH 399/958] FIX: After review --- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 2 +- sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index d1bfa412b5f..c168cdc0844 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -753,7 +753,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( newNodesList := make([]Validator, 0) auctionList := make([]Validator, 0) - if previousEpochConfig == nil { + if ihnc.flagStakingV4Started.IsSet() && previousEpochConfig == nil { return nil, ErrNilPreviousEpochConfig } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 7dc811db203..5241f086ee9 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -2046,6 +2046,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNilPreviousNodesC pk := []byte("pk") arguments.SelfPublicKey = pk ihnc, _ := NewIndexHashedNodesCoordinator(arguments) + ihnc.flagStakingV4Started.SetReturningPrevious() validatorInfos := make([]*state.ShardValidatorInfo, 0) From c1d9cfe3bdd7b8a82d23aa37e35b242f44669d61 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 3 Feb 2023 15:38:23 +0200 Subject: [PATCH 400/958] FIX: Remove debug line --- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 9f3956cb59a..c168cdc0844 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -605,7 +605,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa } ihnc.updateEpochFlags(newEpoch) - log.Debug("indexHashedNodesCoordinator.EpochStartPrepare", "ihnc.currentEpoch", ihnc.currentEpoch) + allValidatorInfo, err := ihnc.createValidatorInfoFromBody(body, ihnc.numTotalEligible, newEpoch) if err != nil { log.Error("could not create validator info from body - do nothing on nodesCoordinator epochStartPrepare", "error", err.Error()) From b390a952c1b89775198889663e29d25f48c2cf23 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 6 Feb 2023 13:21:57 +0200 Subject: [PATCH 401/958] FEAT: First version without activation flag --- epochStart/metachain/validators.go | 11 +- process/peer/process.go | 1 + .../indexHashedNodesCoordinator.go | 5 +- state/interface.go | 2 + state/peerAccount.go | 1 + state/peerAccountData.pb.go | 192 +++++++++------ state/peerAccountData.proto | 1 + state/validatorInfo.go | 1 + state/validatorInfo.pb.go | 222 +++++++++++++----- state/validatorInfo.proto | 2 + update/genesis/common.go | 1 + 11 files changed, 314 insertions(+), 125 deletions(-) diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index b77a72f55a8..3a4e00d6871 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -175,11 +175,12 @@ func (vic *validatorInfoCreator) getShardValidatorInfoHash(shardValidatorInfo *s func createShardValidatorInfo(validator state.ValidatorInfoHandler) *state.ShardValidatorInfo { return &state.ShardValidatorInfo{ - PublicKey: validator.GetPublicKey(), - ShardId: validator.GetShardId(), - List: validator.GetList(), - Index: validator.GetIndex(), - TempRating: validator.GetTempRating(), + PublicKey: validator.GetPublicKey(), + ShardId: validator.GetShardId(), + List: validator.GetList(), + PreviousList: validator.GetPreviousList(), + Index: validator.GetIndex(), + TempRating: validator.GetTempRating(), } } diff --git a/process/peer/process.go b/process/peer/process.go index 63317ca5397..eb5281a0c9e 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -492,6 +492,7 @@ func (vs *validatorStatistics) PeerAccountToValidatorInfo(peerAccount state.Peer PublicKey: peerAccount.GetBLSPublicKey(), ShardId: peerAccount.GetShardId(), List: list, + PreviousList: peerAccount.GetPreviousList(), Index: peerAccount.GetIndexInList(), TempRating: peerAccount.GetTempRating(), Rating: peerAccount.GetRating(), diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index c168cdc0844..6e548b98462 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -781,7 +781,9 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( eligibleMap, waitingMap, currentValidator, - validatorInfo.ShardId) + validatorInfo.ShardId, + validatorInfo.PreviousList, + ) case string(common.NewList): if ihnc.flagStakingV4.IsSet() { return nil, epochStart.ErrReceivedNewListNodeInStakingV4 @@ -837,6 +839,7 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( waitingMap map[uint32][]Validator, currentValidator *validator, currentValidatorShardId uint32, + previousList string, ) { if !ihnc.flagStakingV4Started.IsSet() { eligibleMap[currentValidatorShardId] = append(eligibleMap[currentValidatorShardId], currentValidator) diff --git a/state/interface.go b/state/interface.go index b15f913e83a..d4c44c3b94b 100644 --- a/state/interface.go +++ b/state/interface.go @@ -32,6 +32,7 @@ type PeerAccountHandler interface { GetAccumulatedFees() *big.Int AddToAccumulatedFees(*big.Int) GetList() string + GetPreviousList() string GetIndexInList() uint32 GetShardId() uint32 SetUnStakedEpoch(epoch uint32) @@ -255,6 +256,7 @@ type ValidatorInfoHandler interface { GetTotalValidatorSuccess() uint32 GetTotalValidatorFailure() uint32 GetTotalValidatorIgnoredSignatures() uint32 + GetPreviousList() string SetPublicKey(publicKey []byte) SetShardId(shardID uint32) diff --git a/state/peerAccount.go b/state/peerAccount.go index edc835199ee..a9f73fc4d6e 100644 --- a/state/peerAccount.go +++ b/state/peerAccount.go @@ -110,6 +110,7 @@ func (pa *peerAccount) SetTempRating(rating uint32) { // SetListAndIndex will update the peer's list (eligible, waiting) and the index inside it with journal func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32) { pa.ShardId = shardID + pa.PreviousList = pa.List pa.List = list pa.IndexInList = index } diff --git a/state/peerAccountData.pb.go b/state/peerAccountData.pb.go index 91b00561487..06b1df1f5b5 100644 --- a/state/peerAccountData.pb.go +++ b/state/peerAccountData.pb.go @@ -249,6 +249,7 @@ type PeerAccountData struct { TotalValidatorIgnoredSignaturesRate uint32 `protobuf:"varint,16,opt,name=TotalValidatorIgnoredSignaturesRate,proto3" json:"totalValidatorIgnoredSignaturesRate"` Nonce uint64 `protobuf:"varint,17,opt,name=Nonce,proto3" json:"nonce"` UnStakedEpoch uint32 `protobuf:"varint,18,opt,name=UnStakedEpoch,proto3" json:"unStakedEpoch"` + PreviousList string `protobuf:"bytes,19,opt,name=PreviousList,proto3" json:"previousList,omitempty"` } func (m *PeerAccountData) Reset() { *m = PeerAccountData{} } @@ -405,6 +406,13 @@ func (m *PeerAccountData) GetUnStakedEpoch() uint32 { return 0 } +func (m *PeerAccountData) GetPreviousList() string { + if m != nil { + return m.PreviousList + } + return "" +} + func init() { proto.RegisterType((*SignRate)(nil), "proto.SignRate") proto.RegisterType((*ValidatorApiResponse)(nil), "proto.ValidatorApiResponse") @@ -414,71 +422,73 @@ func init() { func init() { proto.RegisterFile("peerAccountData.proto", fileDescriptor_26bd0314afcce126) } var fileDescriptor_26bd0314afcce126 = []byte{ - // 1017 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4d, 0x6f, 0xdb, 0x36, - 0x18, 0xb6, 0xda, 0x3a, 0x1f, 0xb4, 0x1d, 0x27, 0x6c, 0xd2, 0xca, 0x59, 0x23, 0xa6, 0x2e, 0xd6, - 0xe5, 0xb0, 0x24, 0xd8, 0x07, 0x30, 0x60, 0x3b, 0x6c, 0x51, 0xd7, 0x0e, 0xde, 0xd2, 0x2c, 0x60, - 0xba, 0xa1, 0xd8, 0x80, 0x01, 0xb4, 0xc4, 0x28, 0x5a, 0xf5, 0x61, 0x48, 0x94, 0x97, 0xdc, 0x76, - 0xdd, 0xad, 0x3f, 0x63, 0xd8, 0x2f, 0xe9, 0x31, 0xc7, 0x9c, 0xb8, 0xc5, 0x39, 0x6c, 0xe0, 0xa9, - 0x3f, 0x61, 0x10, 0x2d, 0x39, 0x92, 0x25, 0x39, 0x3d, 0xd9, 0x7a, 0x9f, 0xe7, 0x7d, 0xf8, 0xf2, - 0xe5, 0xcb, 0x87, 0x60, 0x6d, 0x40, 0x69, 0xb0, 0x67, 0x18, 0x7e, 0xe4, 0xb1, 0xaf, 0x09, 0x23, - 0x3b, 0x83, 0xc0, 0x67, 0x3e, 0xac, 0xcb, 0x9f, 0xf5, 0x6d, 0xcb, 0x66, 0x27, 0x51, 0x7f, 0xc7, - 0xf0, 0xdd, 0x5d, 0xcb, 0xb7, 0xfc, 0x5d, 0x19, 0xee, 0x47, 0xc7, 0xf2, 0x4b, 0x7e, 0xc8, 0x7f, - 0xe3, 0xac, 0xee, 0xb7, 0x60, 0xe1, 0xc8, 0xb6, 0x3c, 0x4c, 0x18, 0x85, 0x1a, 0x00, 0x07, 0x91, - 0x7b, 0x14, 0x19, 0x06, 0x0d, 0x43, 0x55, 0xd9, 0x54, 0xb6, 0x5a, 0x38, 0x13, 0x49, 0xf0, 0x67, - 0xc4, 0x76, 0xa2, 0x80, 0xaa, 0xb7, 0x26, 0x78, 0x12, 0xe9, 0xfe, 0xbb, 0x00, 0x56, 0x7f, 0x24, - 0x8e, 0x6d, 0x12, 0xe6, 0x07, 0x7b, 0x03, 0x1b, 0xd3, 0x70, 0xe0, 0x7b, 0x21, 0x85, 0x3b, 0x00, - 0xbc, 0xa0, 0xee, 0x00, 0x13, 0x66, 0x7b, 0x96, 0x14, 0xbe, 0xa5, 0x2f, 0x09, 0x8e, 0x00, 0x9b, - 0x44, 0x71, 0x86, 0x01, 0xbf, 0x02, 0xcb, 0x07, 0x91, 0xbb, 0x4f, 0x89, 0x49, 0x83, 0xb4, 0x1c, - 0xb9, 0x9c, 0xbe, 0x2a, 0x38, 0x5a, 0xf6, 0xa6, 0x30, 0x5c, 0x60, 0xe7, 0x14, 0xd2, 0x82, 0x6f, - 0x97, 0x28, 0x24, 0x18, 0x2e, 0xb0, 0x61, 0x0f, 0xdc, 0x3d, 0x88, 0xdc, 0xc9, 0x76, 0xd2, 0x32, - 0xee, 0x48, 0x91, 0xfb, 0x82, 0xa3, 0xbb, 0x5e, 0x11, 0xc6, 0x65, 0x39, 0xd3, 0x52, 0x69, 0x3d, - 0xf5, 0x72, 0xa9, 0xb4, 0xa4, 0xb2, 0x1c, 0x68, 0x81, 0x8d, 0x6c, 0xb8, 0x67, 0x79, 0x7e, 0x40, - 0xcd, 0xf8, 0x04, 0x09, 0x8b, 0x02, 0x1a, 0xaa, 0x73, 0x52, 0xf4, 0xa1, 0xe0, 0x68, 0xc3, 0x9b, - 0x45, 0xc4, 0xb3, 0x75, 0x60, 0x17, 0xcc, 0x25, 0xc7, 0x35, 0x2f, 0x8f, 0x0b, 0x08, 0x8e, 0xe6, - 0x82, 0xf1, 0x51, 0x25, 0x08, 0xfc, 0x1c, 0x2c, 0x8d, 0xff, 0x3d, 0xf7, 0x4d, 0xfb, 0xd8, 0xa6, - 0x81, 0xba, 0x20, 0xb9, 0x50, 0x70, 0xb4, 0x14, 0xe4, 0x10, 0x3c, 0xc5, 0x84, 0xdf, 0x83, 0xb5, - 0x17, 0x3e, 0x23, 0x4e, 0xe1, 0x9c, 0x17, 0xe5, 0x06, 0x3a, 0x82, 0xa3, 0x35, 0x56, 0x46, 0xc0, - 0xe5, 0x79, 0x45, 0xc1, 0xb4, 0xcd, 0xa0, 0x4a, 0x30, 0x6d, 0x74, 0x79, 0x1e, 0x7c, 0x09, 0xd4, - 0x14, 0x28, 0x4c, 0x41, 0x43, 0x6a, 0x3e, 0x10, 0x1c, 0xa9, 0xac, 0x82, 0x83, 0x2b, 0xb3, 0x4b, - 0x95, 0xd3, 0x6a, 0x9b, 0x33, 0x94, 0xd3, 0x82, 0x2b, 0xb3, 0xe1, 0x10, 0x74, 0x0b, 0x58, 0x71, - 0x46, 0x5a, 0x72, 0x8d, 0xc7, 0x82, 0xa3, 0x2e, 0xbb, 0x91, 0x8d, 0xdf, 0x41, 0x11, 0xbe, 0x0f, - 0xe6, 0x8f, 0x4e, 0x48, 0x60, 0xf6, 0x4c, 0x75, 0x49, 0x8a, 0x37, 0x04, 0x47, 0xf3, 0xe1, 0x38, - 0x84, 0x53, 0x0c, 0x7e, 0x03, 0xda, 0xd7, 0xcd, 0x60, 0x84, 0x45, 0xa1, 0xda, 0xde, 0x54, 0xb6, - 0x16, 0xf5, 0x0d, 0xc1, 0x51, 0x67, 0x98, 0x87, 0x3e, 0xf4, 0x5d, 0x3b, 0xf6, 0x07, 0x76, 0x86, - 0xa7, 0xb3, 0xba, 0x7f, 0x34, 0x40, 0xfb, 0x30, 0xef, 0x82, 0xf0, 0x53, 0xd0, 0xd4, 0xf7, 0x8f, - 0x0e, 0xa3, 0xbe, 0x63, 0x1b, 0xdf, 0xd1, 0x33, 0x69, 0x33, 0x4d, 0x7d, 0x59, 0x70, 0xd4, 0xec, - 0x3b, 0xe1, 0x24, 0x8e, 0x73, 0x2c, 0xb8, 0x07, 0x5a, 0x98, 0xfe, 0x46, 0x02, 0x73, 0xcf, 0x34, - 0x83, 0xd4, 0x67, 0x9a, 0xfa, 0x7b, 0x82, 0xa3, 0xfb, 0x41, 0x16, 0xc8, 0x94, 0x93, 0xcf, 0xc8, - 0x6e, 0xfe, 0xf6, 0x8c, 0xcd, 0x93, 0x8c, 0x39, 0xa6, 0x33, 0x42, 0x18, 0x95, 0x8e, 0xd2, 0xf8, - 0xb8, 0x3d, 0xf6, 0xe3, 0x9d, 0xd4, 0x8c, 0xf5, 0x07, 0x6f, 0x38, 0xaa, 0x09, 0x8e, 0x56, 0x87, - 0x25, 0x49, 0xb8, 0x54, 0x0a, 0xbe, 0x04, 0x2b, 0xf9, 0xbb, 0x12, 0xeb, 0xd7, 0xcb, 0xf5, 0x3b, - 0x89, 0xfe, 0x8a, 0x33, 0x9d, 0x81, 0x8b, 0x22, 0xf0, 0x57, 0xa0, 0xcd, 0x18, 0x91, 0x78, 0x99, - 0xb1, 0xf1, 0x74, 0x05, 0x47, 0xda, 0x70, 0x26, 0x13, 0xdf, 0xa0, 0x34, 0x65, 0x3d, 0xad, 0x52, - 0xeb, 0xc9, 0xbf, 0x28, 0x0b, 0x92, 0x37, 0xeb, 0x45, 0x79, 0xad, 0x80, 0xf6, 0x9e, 0x61, 0x44, - 0x6e, 0xe4, 0x10, 0x46, 0xcd, 0x67, 0x94, 0x8e, 0x9d, 0xa6, 0xa9, 0x1f, 0xc7, 0xa3, 0x47, 0xf2, - 0xd0, 0xf5, 0x59, 0xff, 0xf5, 0x37, 0x7a, 0xea, 0x12, 0x76, 0xb2, 0xdb, 0xb7, 0xad, 0x9d, 0x9e, - 0xc7, 0xbe, 0xc8, 0xbc, 0xae, 0x6e, 0xe4, 0x30, 0x7b, 0x48, 0x83, 0xf0, 0x74, 0xd7, 0x3d, 0xdd, - 0x36, 0x4e, 0x88, 0xed, 0x6d, 0x1b, 0x7e, 0x40, 0xb7, 0x2d, 0x7f, 0xd7, 0x8c, 0xdf, 0x65, 0xdd, - 0xb6, 0x7a, 0x1e, 0x7b, 0x42, 0x42, 0x46, 0x03, 0x3c, 0xbd, 0x3c, 0xfc, 0x05, 0xac, 0xc7, 0x6f, - 0x2b, 0x75, 0xa8, 0xc1, 0xa8, 0xd9, 0xf3, 0x92, 0x76, 0xeb, 0x8e, 0x6f, 0xbc, 0x0a, 0x13, 0xd7, - 0xd2, 0x04, 0x47, 0xeb, 0x5e, 0x25, 0x0b, 0xcf, 0x50, 0x80, 0x1f, 0x81, 0x46, 0xcf, 0x33, 0xe9, - 0x69, 0xcf, 0xdb, 0xb7, 0x43, 0x96, 0x58, 0x56, 0x5b, 0x70, 0xd4, 0xb0, 0xaf, 0xc3, 0x38, 0xcb, - 0x81, 0x8f, 0xc1, 0x1d, 0xc9, 0x6d, 0xca, 0x4b, 0x29, 0x6d, 0xdc, 0xb1, 0x43, 0x96, 0x19, 0x7d, - 0x89, 0xc3, 0x9f, 0x41, 0xe7, 0x49, 0xfc, 0xb0, 0x1b, 0x51, 0xdc, 0x80, 0xc3, 0xc0, 0x1f, 0xf8, - 0x21, 0x0d, 0x9e, 0xdb, 0x61, 0x38, 0x71, 0x17, 0x79, 0xa3, 0x8d, 0x2a, 0x12, 0xae, 0xce, 0x87, - 0x03, 0xd0, 0x91, 0x8e, 0x53, 0x7a, 0x59, 0x96, 0xca, 0x87, 0xf9, 0x61, 0x32, 0xcc, 0x1d, 0x56, - 0x95, 0x89, 0xab, 0x45, 0xa1, 0x05, 0xee, 0x49, 0xb0, 0x78, 0x77, 0xda, 0xe5, 0xcb, 0x69, 0xc9, - 0x72, 0xf7, 0x58, 0x69, 0x1a, 0xae, 0x90, 0x83, 0x67, 0xe0, 0x51, 0xbe, 0x8a, 0xf2, 0xab, 0xb4, - 0x2c, 0x3b, 0xf8, 0x81, 0xe0, 0xe8, 0x11, 0xbb, 0x99, 0x8e, 0xdf, 0x45, 0x13, 0x22, 0x50, 0x3f, - 0xf0, 0x3d, 0x83, 0xaa, 0x2b, 0x9b, 0xca, 0xd6, 0x1d, 0x7d, 0x51, 0x70, 0x54, 0xf7, 0xe2, 0x00, - 0x1e, 0xc7, 0xe1, 0x67, 0xa0, 0xf5, 0x83, 0x77, 0xc4, 0xc8, 0x2b, 0x6a, 0x3e, 0x1d, 0xf8, 0xc6, - 0x89, 0x0a, 0x65, 0x15, 0x2b, 0x82, 0xa3, 0x56, 0x94, 0x05, 0x70, 0x9e, 0xa7, 0x7f, 0x79, 0x7e, - 0xa9, 0xd5, 0x2e, 0x2e, 0xb5, 0xda, 0xdb, 0x4b, 0x4d, 0xf9, 0x7d, 0xa4, 0x29, 0x7f, 0x8e, 0x34, - 0xe5, 0xcd, 0x48, 0x53, 0xce, 0x47, 0x9a, 0x72, 0x31, 0xd2, 0x94, 0x7f, 0x46, 0x9a, 0xf2, 0xdf, - 0x48, 0xab, 0xbd, 0x1d, 0x69, 0xca, 0xeb, 0x2b, 0xad, 0x76, 0x7e, 0xa5, 0xd5, 0x2e, 0xae, 0xb4, - 0xda, 0x4f, 0xf5, 0x90, 0x11, 0x46, 0xfb, 0x73, 0xb2, 0xbb, 0x9f, 0xfc, 0x1f, 0x00, 0x00, 0xff, - 0xff, 0x24, 0x1b, 0x30, 0xe2, 0xd8, 0x0a, 0x00, 0x00, + // 1044 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xdf, 0x6e, 0xdb, 0xb6, + 0x17, 0xb6, 0xda, 0x38, 0x7f, 0x68, 0x3b, 0x4e, 0x98, 0xa4, 0xb5, 0xf3, 0x6b, 0xc4, 0xd4, 0xc5, + 0xaf, 0xcb, 0xc5, 0x92, 0x60, 0x7f, 0x80, 0x01, 0x1b, 0xb0, 0x2d, 0xea, 0xda, 0xc1, 0x5b, 0x9a, + 0x05, 0x4c, 0x37, 0x14, 0x1b, 0x30, 0x80, 0x96, 0x18, 0x45, 0xab, 0x2c, 0x1a, 0x14, 0xe5, 0x25, + 0x77, 0x7b, 0x84, 0x3e, 0xc6, 0xb0, 0x27, 0xe9, 0xee, 0x72, 0x99, 0x2b, 0x6e, 0x71, 0x2e, 0x36, + 0xf0, 0xaa, 0x8f, 0x30, 0x88, 0x96, 0x12, 0xc9, 0x96, 0x9d, 0x5e, 0xd9, 0x3a, 0xdf, 0x77, 0x3e, + 0x1e, 0xf2, 0x1c, 0x7e, 0x04, 0x6b, 0x3d, 0x4a, 0xf9, 0x9e, 0x6d, 0xb3, 0x28, 0x10, 0x5f, 0x11, + 0x41, 0x76, 0x7a, 0x9c, 0x09, 0x06, 0xcb, 0xfa, 0x67, 0x7d, 0xdb, 0xf5, 0xc4, 0x49, 0xd4, 0xd9, + 0xb1, 0x59, 0x77, 0xd7, 0x65, 0x2e, 0xdb, 0xd5, 0xe1, 0x4e, 0x74, 0xac, 0xbf, 0xf4, 0x87, 0xfe, + 0x37, 0xcc, 0x6a, 0x7d, 0x03, 0xe6, 0x8f, 0x3c, 0x37, 0xc0, 0x44, 0x50, 0x68, 0x02, 0x70, 0x10, + 0x75, 0x8f, 0x22, 0xdb, 0xa6, 0x61, 0xd8, 0x30, 0x36, 0x8d, 0xad, 0x1a, 0xce, 0x44, 0x12, 0xfc, + 0x19, 0xf1, 0xfc, 0x88, 0xd3, 0xc6, 0x9d, 0x6b, 0x3c, 0x89, 0xb4, 0xfe, 0x99, 0x07, 0xab, 0x3f, + 0x10, 0xdf, 0x73, 0x88, 0x60, 0x7c, 0xaf, 0xe7, 0x61, 0x1a, 0xf6, 0x58, 0x10, 0x52, 0xb8, 0x03, + 0xc0, 0x0b, 0xda, 0xed, 0x61, 0x22, 0xbc, 0xc0, 0xd5, 0xc2, 0x77, 0xac, 0x45, 0x25, 0x11, 0x10, + 0xd7, 0x51, 0x9c, 0x61, 0xc0, 0x2f, 0xc1, 0xd2, 0x41, 0xd4, 0xdd, 0xa7, 0xc4, 0xa1, 0x3c, 0x2d, + 0x47, 0x2f, 0x67, 0xad, 0x2a, 0x89, 0x96, 0x82, 0x11, 0x0c, 0x8f, 0xb1, 0x73, 0x0a, 0x69, 0xc1, + 0x77, 0x0b, 0x14, 0x12, 0x0c, 0x8f, 0xb1, 0x61, 0x1b, 0xac, 0x1c, 0x44, 0xdd, 0xeb, 0xed, 0xa4, + 0x65, 0xcc, 0x68, 0x91, 0xfb, 0x4a, 0xa2, 0x95, 0x60, 0x1c, 0xc6, 0x45, 0x39, 0xa3, 0x52, 0x69, + 0x3d, 0xe5, 0x62, 0xa9, 0xb4, 0xa4, 0xa2, 0x1c, 0xe8, 0x82, 0x8d, 0x6c, 0xb8, 0xed, 0x06, 0x8c, + 0x53, 0x27, 0xee, 0x20, 0x11, 0x11, 0xa7, 0x61, 0x63, 0x56, 0x8b, 0x3e, 0x54, 0x12, 0x6d, 0x04, + 0xd3, 0x88, 0x78, 0xba, 0x0e, 0x6c, 0x81, 0xd9, 0xa4, 0x5d, 0x73, 0xba, 0x5d, 0x40, 0x49, 0x34, + 0xcb, 0x87, 0xad, 0x4a, 0x10, 0xf8, 0x29, 0x58, 0x1c, 0xfe, 0x7b, 0xce, 0x1c, 0xef, 0xd8, 0xa3, + 0xbc, 0x31, 0xaf, 0xb9, 0x50, 0x49, 0xb4, 0xc8, 0x73, 0x08, 0x1e, 0x61, 0xc2, 0xef, 0xc0, 0xda, + 0x0b, 0x26, 0x88, 0x3f, 0xd6, 0xe7, 0x05, 0xbd, 0x81, 0xa6, 0x92, 0x68, 0x4d, 0x14, 0x11, 0x70, + 0x71, 0xde, 0xb8, 0x60, 0x7a, 0xcc, 0x60, 0x92, 0x60, 0x7a, 0xd0, 0xc5, 0x79, 0xf0, 0x25, 0x68, + 0xa4, 0xc0, 0xd8, 0x14, 0x54, 0xb4, 0xe6, 0x03, 0x25, 0x51, 0x43, 0x4c, 0xe0, 0xe0, 0x89, 0xd9, + 0x85, 0xca, 0x69, 0xb5, 0xd5, 0x29, 0xca, 0x69, 0xc1, 0x13, 0xb3, 0x61, 0x1f, 0xb4, 0xc6, 0xb0, + 0xf1, 0x19, 0xa9, 0xe9, 0x35, 0x1e, 0x2b, 0x89, 0x5a, 0xe2, 0x56, 0x36, 0x7e, 0x07, 0x45, 0xf8, + 0x7f, 0x30, 0x77, 0x74, 0x42, 0xb8, 0xd3, 0x76, 0x1a, 0x8b, 0x5a, 0xbc, 0xa2, 0x24, 0x9a, 0x0b, + 0x87, 0x21, 0x9c, 0x62, 0xf0, 0x6b, 0x50, 0xbf, 0x39, 0x0c, 0x41, 0x44, 0x14, 0x36, 0xea, 0x9b, + 0xc6, 0xd6, 0x82, 0xb5, 0xa1, 0x24, 0x6a, 0xf6, 0xf3, 0xd0, 0xfb, 0xac, 0xeb, 0xc5, 0xfe, 0x20, + 0xce, 0xf0, 0x68, 0x56, 0xeb, 0xcf, 0x0a, 0xa8, 0x1f, 0xe6, 0x5d, 0x10, 0x7e, 0x0c, 0xaa, 0xd6, + 0xfe, 0xd1, 0x61, 0xd4, 0xf1, 0x3d, 0xfb, 0x5b, 0x7a, 0xa6, 0x6d, 0xa6, 0x6a, 0x2d, 0x29, 0x89, + 0xaa, 0x1d, 0x3f, 0xbc, 0x8e, 0xe3, 0x1c, 0x0b, 0xee, 0x81, 0x1a, 0xa6, 0xbf, 0x12, 0xee, 0xec, + 0x39, 0x0e, 0x4f, 0x7d, 0xa6, 0x6a, 0xfd, 0x4f, 0x49, 0x74, 0x9f, 0x67, 0x81, 0x4c, 0x39, 0xf9, + 0x8c, 0xec, 0xe6, 0xef, 0x4e, 0xd9, 0x3c, 0xc9, 0x98, 0x63, 0x3a, 0x23, 0x44, 0x50, 0xed, 0x28, + 0x95, 0x0f, 0xeb, 0x43, 0x3f, 0xde, 0x49, 0xcd, 0xd8, 0x7a, 0xf0, 0x46, 0xa2, 0x92, 0x92, 0x68, + 0xb5, 0x5f, 0x90, 0x84, 0x0b, 0xa5, 0xe0, 0x4b, 0xb0, 0x9c, 0xbf, 0x2b, 0xb1, 0x7e, 0xb9, 0x58, + 0xbf, 0x99, 0xe8, 0x2f, 0xfb, 0xa3, 0x19, 0x78, 0x5c, 0x04, 0xfe, 0x02, 0xcc, 0x29, 0x23, 0x12, + 0x2f, 0x33, 0x34, 0x9e, 0x96, 0x92, 0xc8, 0xec, 0x4f, 0x65, 0xe2, 0x5b, 0x94, 0x46, 0xac, 0xa7, + 0x56, 0x68, 0x3d, 0xf9, 0x17, 0x65, 0x5e, 0xf3, 0xa6, 0xbd, 0x28, 0xaf, 0x0d, 0x50, 0xdf, 0xb3, + 0xed, 0xa8, 0x1b, 0xf9, 0x44, 0x50, 0xe7, 0x19, 0xa5, 0x43, 0xa7, 0xa9, 0x5a, 0xc7, 0xf1, 0xe8, + 0x91, 0x3c, 0x74, 0xd3, 0xeb, 0x3f, 0xfe, 0x42, 0x4f, 0xbb, 0x44, 0x9c, 0xec, 0x76, 0x3c, 0x77, + 0xa7, 0x1d, 0x88, 0xcf, 0x32, 0xaf, 0x6b, 0x37, 0xf2, 0x85, 0xd7, 0xa7, 0x3c, 0x3c, 0xdd, 0xed, + 0x9e, 0x6e, 0xdb, 0x27, 0xc4, 0x0b, 0xb6, 0x6d, 0xc6, 0xe9, 0xb6, 0xcb, 0x76, 0x9d, 0xf8, 0x5d, + 0xb6, 0x3c, 0xb7, 0x1d, 0x88, 0x27, 0x24, 0x14, 0x94, 0xe3, 0xd1, 0xe5, 0xe1, 0xcf, 0x60, 0x3d, + 0x7e, 0x5b, 0xa9, 0x4f, 0x6d, 0x41, 0x9d, 0x76, 0x90, 0x1c, 0xb7, 0xe5, 0x33, 0xfb, 0x55, 0x98, + 0xb8, 0x96, 0xa9, 0x24, 0x5a, 0x0f, 0x26, 0xb2, 0xf0, 0x14, 0x05, 0xf8, 0x01, 0xa8, 0xb4, 0x03, + 0x87, 0x9e, 0xb6, 0x83, 0x7d, 0x2f, 0x14, 0x89, 0x65, 0xd5, 0x95, 0x44, 0x15, 0xef, 0x26, 0x8c, + 0xb3, 0x1c, 0xf8, 0x18, 0xcc, 0x68, 0x6e, 0x55, 0x5f, 0x4a, 0x6d, 0xe3, 0xbe, 0x17, 0x8a, 0xcc, + 0xe8, 0x6b, 0x1c, 0xfe, 0x04, 0x9a, 0x4f, 0xe2, 0x87, 0xdd, 0x8e, 0xe2, 0x03, 0x38, 0xe4, 0xac, + 0xc7, 0x42, 0xca, 0x9f, 0x7b, 0x61, 0x78, 0xed, 0x2e, 0xfa, 0x46, 0xdb, 0x93, 0x48, 0x78, 0x72, + 0x3e, 0xec, 0x81, 0xa6, 0x76, 0x9c, 0xc2, 0xcb, 0xb2, 0x58, 0x3c, 0xcc, 0x0f, 0x93, 0x61, 0x6e, + 0x8a, 0x49, 0x99, 0x78, 0xb2, 0x28, 0x74, 0xc1, 0x3d, 0x0d, 0x8e, 0xdf, 0x9d, 0x7a, 0xf1, 0x72, + 0x66, 0xb2, 0xdc, 0x3d, 0x51, 0x98, 0x86, 0x27, 0xc8, 0xc1, 0x33, 0xf0, 0x28, 0x5f, 0x45, 0xf1, + 0x55, 0x5a, 0xd2, 0x27, 0xf8, 0x9e, 0x92, 0xe8, 0x91, 0xb8, 0x9d, 0x8e, 0xdf, 0x45, 0x13, 0x22, + 0x50, 0x3e, 0x60, 0x81, 0x4d, 0x1b, 0xcb, 0x9b, 0xc6, 0xd6, 0x8c, 0xb5, 0xa0, 0x24, 0x2a, 0x07, + 0x71, 0x00, 0x0f, 0xe3, 0xf0, 0x13, 0x50, 0xfb, 0x3e, 0x38, 0x12, 0xe4, 0x15, 0x75, 0x9e, 0xf6, + 0x98, 0x7d, 0xd2, 0x80, 0xba, 0x8a, 0x65, 0x25, 0x51, 0x2d, 0xca, 0x02, 0x38, 0xcf, 0x83, 0x9f, + 0x83, 0xea, 0x21, 0xa7, 0x7d, 0x8f, 0x45, 0xa1, 0x1e, 0x9e, 0x15, 0x3d, 0x3c, 0xeb, 0xf1, 0xf1, + 0xf4, 0x32, 0xf1, 0xcc, 0x10, 0xe5, 0xf8, 0xd6, 0x17, 0xe7, 0x97, 0x66, 0xe9, 0xe2, 0xd2, 0x2c, + 0xbd, 0xbd, 0x34, 0x8d, 0xdf, 0x06, 0xa6, 0xf1, 0xfb, 0xc0, 0x34, 0xde, 0x0c, 0x4c, 0xe3, 0x7c, + 0x60, 0x1a, 0x17, 0x03, 0xd3, 0xf8, 0x7b, 0x60, 0x1a, 0xff, 0x0e, 0xcc, 0xd2, 0xdb, 0x81, 0x69, + 0xbc, 0xbe, 0x32, 0x4b, 0xe7, 0x57, 0x66, 0xe9, 0xe2, 0xca, 0x2c, 0xfd, 0x58, 0x0e, 0x05, 0x11, + 0xb4, 0x33, 0xab, 0xbb, 0xf3, 0xd1, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xde, 0xed, 0x5e, 0x5d, + 0x18, 0x0b, 0x00, 0x00, } func (this *SignRate) Equal(that interface{}) bool { @@ -650,6 +660,9 @@ func (this *PeerAccountData) Equal(that interface{}) bool { if this.UnStakedEpoch != that1.UnStakedEpoch { return false } + if this.PreviousList != that1.PreviousList { + return false + } return true } func (this *SignRate) GoString() string { @@ -691,7 +704,7 @@ func (this *PeerAccountData) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 22) + s := make([]string, 0, 23) s = append(s, "&state.PeerAccountData{") s = append(s, "BLSPublicKey: "+fmt.Sprintf("%#v", this.BLSPublicKey)+",\n") s = append(s, "RewardAddress: "+fmt.Sprintf("%#v", this.RewardAddress)+",\n") @@ -711,6 +724,7 @@ func (this *PeerAccountData) GoString() string { s = append(s, "TotalValidatorIgnoredSignaturesRate: "+fmt.Sprintf("%#v", this.TotalValidatorIgnoredSignaturesRate)+",\n") s = append(s, "Nonce: "+fmt.Sprintf("%#v", this.Nonce)+",\n") s = append(s, "UnStakedEpoch: "+fmt.Sprintf("%#v", this.UnStakedEpoch)+",\n") + s = append(s, "PreviousList: "+fmt.Sprintf("%#v", this.PreviousList)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -878,6 +892,15 @@ func (m *PeerAccountData) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PreviousList) > 0 { + i -= len(m.PreviousList) + copy(dAtA[i:], m.PreviousList) + i = encodeVarintPeerAccountData(dAtA, i, uint64(len(m.PreviousList))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } if m.UnStakedEpoch != 0 { i = encodeVarintPeerAccountData(dAtA, i, uint64(m.UnStakedEpoch)) i-- @@ -1151,6 +1174,10 @@ func (m *PeerAccountData) Size() (n int) { if m.UnStakedEpoch != 0 { n += 2 + sovPeerAccountData(uint64(m.UnStakedEpoch)) } + l = len(m.PreviousList) + if l > 0 { + n += 2 + l + sovPeerAccountData(uint64(l)) + } return n } @@ -1218,6 +1245,7 @@ func (this *PeerAccountData) String() string { `TotalValidatorIgnoredSignaturesRate:` + fmt.Sprintf("%v", this.TotalValidatorIgnoredSignaturesRate) + `,`, `Nonce:` + fmt.Sprintf("%v", this.Nonce) + `,`, `UnStakedEpoch:` + fmt.Sprintf("%v", this.UnStakedEpoch) + `,`, + `PreviousList:` + fmt.Sprintf("%v", this.PreviousList) + `,`, `}`, }, "") return s @@ -2137,6 +2165,38 @@ func (m *PeerAccountData) Unmarshal(dAtA []byte) error { break } } + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousList", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerAccountData + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPeerAccountData + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPeerAccountData + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PreviousList = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPeerAccountData(dAtA[iNdEx:]) diff --git a/state/peerAccountData.proto b/state/peerAccountData.proto index 6c499ad712f..d0fd3af1ec2 100644 --- a/state/peerAccountData.proto +++ b/state/peerAccountData.proto @@ -52,4 +52,5 @@ message PeerAccountData { uint32 TotalValidatorIgnoredSignaturesRate = 16 [(gogoproto.jsontag) = "totalValidatorIgnoredSignaturesRate"]; uint64 Nonce = 17 [(gogoproto.jsontag) = "nonce"]; uint32 UnStakedEpoch = 18 [(gogoproto.jsontag) = "unStakedEpoch"]; + string PreviousList = 19 [(gogoproto.jsontag) = "previousList,omitempty"]; } diff --git a/state/validatorInfo.go b/state/validatorInfo.go index 0e9ef09882e..f9779188f65 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -16,6 +16,7 @@ func (vi *ValidatorInfo) SetPublicKey(publicKey []byte) { // SetList sets validator's list func (vi *ValidatorInfo) SetList(list string) { + vi.PreviousList = vi.List vi.List = list } diff --git a/state/validatorInfo.pb.go b/state/validatorInfo.pb.go index 19907c86869..8081e1a4d30 100644 --- a/state/validatorInfo.pb.go +++ b/state/validatorInfo.pb.go @@ -51,6 +51,7 @@ type ValidatorInfo struct { TotalValidatorSuccess uint32 `protobuf:"varint,18,opt,name=TotalValidatorSuccess,proto3" json:"totalValidatorSuccess"` TotalValidatorFailure uint32 `protobuf:"varint,19,opt,name=TotalValidatorFailure,proto3" json:"totalValidatorFailure"` TotalValidatorIgnoredSignatures uint32 `protobuf:"varint,20,opt,name=TotalValidatorIgnoredSignatures,proto3" json:"totalValidatorIgnoredSignatures"` + PreviousList string `protobuf:"bytes,21,opt,name=PreviousList,proto3" json:"previousList,omitempty"` } func (m *ValidatorInfo) Reset() { *m = ValidatorInfo{} } @@ -221,13 +222,21 @@ func (m *ValidatorInfo) GetTotalValidatorIgnoredSignatures() uint32 { return 0 } +func (m *ValidatorInfo) GetPreviousList() string { + if m != nil { + return m.PreviousList + } + return "" +} + // ShardValidatorInfo represents the data regarding a validator that is stored in the PeerMiniblocks type ShardValidatorInfo struct { - PublicKey []byte `protobuf:"bytes,1,opt,name=PublicKey,proto3" json:"publicKey"` - ShardId uint32 `protobuf:"varint,2,opt,name=ShardId,proto3" json:"shardId"` - List string `protobuf:"bytes,3,opt,name=List,proto3" json:"list,omitempty"` - Index uint32 `protobuf:"varint,4,opt,name=Index,proto3" json:"index"` - TempRating uint32 `protobuf:"varint,5,opt,name=TempRating,proto3" json:"tempRating"` + PublicKey []byte `protobuf:"bytes,1,opt,name=PublicKey,proto3" json:"publicKey"` + ShardId uint32 `protobuf:"varint,2,opt,name=ShardId,proto3" json:"shardId"` + List string `protobuf:"bytes,3,opt,name=List,proto3" json:"list,omitempty"` + Index uint32 `protobuf:"varint,4,opt,name=Index,proto3" json:"index"` + TempRating uint32 `protobuf:"varint,5,opt,name=TempRating,proto3" json:"tempRating"` + PreviousList string `protobuf:"bytes,6,opt,name=PreviousList,proto3" json:"previousList,omitempty"` } func (m *ShardValidatorInfo) Reset() { *m = ShardValidatorInfo{} } @@ -293,6 +302,13 @@ func (m *ShardValidatorInfo) GetTempRating() uint32 { return 0 } +func (m *ShardValidatorInfo) GetPreviousList() string { + if m != nil { + return m.PreviousList + } + return "" +} + func init() { proto.RegisterType((*ValidatorInfo)(nil), "proto.ValidatorInfo") proto.RegisterType((*ShardValidatorInfo)(nil), "proto.ShardValidatorInfo") @@ -301,52 +317,54 @@ func init() { func init() { proto.RegisterFile("validatorInfo.proto", fileDescriptor_bf9cdc082f0b2ec2) } var fileDescriptor_bf9cdc082f0b2ec2 = []byte{ - // 714 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x4f, 0x4f, 0x13, 0x41, - 0x18, 0xc6, 0xbb, 0x48, 0x0b, 0x1d, 0x68, 0x81, 0x01, 0x74, 0x41, 0xb3, 0xd3, 0x60, 0x34, 0x4d, - 0xb4, 0xed, 0xc1, 0x83, 0x89, 0x1e, 0x94, 0x1a, 0x49, 0x1a, 0xf1, 0x4f, 0xa6, 0xc4, 0x83, 0x07, - 0x93, 0xe9, 0xee, 0x74, 0x3b, 0x71, 0xff, 0x90, 0xd9, 0xd9, 0x0a, 0x37, 0x3f, 0x02, 0x1f, 0xc3, - 0xf8, 0x49, 0x3c, 0x72, 0xe4, 0xb4, 0xd8, 0xe5, 0x62, 0xe6, 0xc4, 0x47, 0x30, 0x9d, 0x76, 0x69, - 0xb7, 0x2d, 0x78, 0xe2, 0xc4, 0xee, 0xfb, 0x3c, 0xcf, 0x6f, 0x5e, 0xfa, 0x4e, 0xdf, 0x82, 0xf5, - 0x2e, 0x71, 0x98, 0x45, 0x84, 0xcf, 0x1b, 0x5e, 0xdb, 0xaf, 0x1e, 0x72, 0x5f, 0xf8, 0x30, 0xab, - 0xfe, 0x6c, 0x57, 0x6c, 0x26, 0x3a, 0x61, 0xab, 0x6a, 0xfa, 0x6e, 0xcd, 0xf6, 0x6d, 0xbf, 0xa6, - 0xca, 0xad, 0xb0, 0xad, 0xde, 0xd4, 0x8b, 0x7a, 0x1a, 0xa4, 0x76, 0xce, 0x01, 0x28, 0x7c, 0x1e, - 0xa7, 0xc1, 0x27, 0x20, 0xff, 0x29, 0x6c, 0x39, 0xcc, 0x7c, 0x47, 0x8f, 0x75, 0xad, 0xa4, 0x95, - 0x97, 0xeb, 0x05, 0x19, 0xa1, 0xfc, 0x61, 0x52, 0xc4, 0x23, 0x1d, 0x3e, 0x02, 0x0b, 0xcd, 0x0e, - 0xe1, 0x56, 0xc3, 0xd2, 0xe7, 0x4a, 0x5a, 0xb9, 0x50, 0x5f, 0x92, 0x11, 0x5a, 0x08, 0x06, 0x25, - 0x9c, 0x68, 0xf0, 0x01, 0x98, 0xdf, 0x67, 0x81, 0xd0, 0xef, 0x94, 0xb4, 0x72, 0xbe, 0xbe, 0x28, - 0x23, 0x34, 0xef, 0xb0, 0x40, 0x60, 0x55, 0x85, 0x08, 0x64, 0x1b, 0x9e, 0x45, 0x8f, 0xf4, 0x79, - 0x85, 0xc8, 0xcb, 0x08, 0x65, 0x59, 0xbf, 0x80, 0x07, 0x75, 0x58, 0x05, 0xe0, 0x80, 0xba, 0x87, - 0x98, 0x08, 0xe6, 0xd9, 0x7a, 0x56, 0xb9, 0x8a, 0x32, 0x42, 0x40, 0x5c, 0x55, 0xf1, 0x98, 0x03, - 0xee, 0x80, 0xdc, 0xd0, 0x9b, 0x53, 0x5e, 0x20, 0x23, 0x94, 0xe3, 0x03, 0xdf, 0x50, 0x81, 0x2f, - 0x40, 0x71, 0xf0, 0xf4, 0xde, 0xb7, 0x58, 0x9b, 0x51, 0xae, 0x2f, 0x94, 0xb4, 0xf2, 0x5c, 0x1d, - 0xca, 0x08, 0x15, 0x79, 0x4a, 0xc1, 0x13, 0x4e, 0xb8, 0x0b, 0x0a, 0x98, 0x7e, 0x27, 0xdc, 0xda, - 0xb5, 0x2c, 0x4e, 0x83, 0x40, 0x5f, 0x54, 0x1f, 0xd3, 0x7d, 0x19, 0xa1, 0x7b, 0x7c, 0x5c, 0x78, - 0xea, 0xbb, 0xac, 0xdf, 0xa3, 0x38, 0xc6, 0xe9, 0x04, 0x7c, 0x0e, 0x0a, 0xfb, 0x94, 0x58, 0x94, - 0x37, 0x43, 0xd3, 0xec, 0x23, 0xf2, 0xaa, 0xd3, 0x35, 0x19, 0xa1, 0x82, 0x33, 0x2e, 0xe0, 0xb4, - 0x6f, 0x14, 0xdc, 0x23, 0xcc, 0x09, 0x39, 0xd5, 0xc1, 0x64, 0x70, 0x28, 0xe0, 0xb4, 0x0f, 0xbe, - 0x06, 0xab, 0x57, 0x83, 0x4e, 0x0e, 0x5d, 0x52, 0xd9, 0x0d, 0x19, 0xa1, 0xd5, 0xee, 0x84, 0x86, - 0xa7, 0xdc, 0x29, 0x42, 0x72, 0xfa, 0xf2, 0x0c, 0x42, 0xd2, 0xc0, 0x94, 0x1b, 0x7e, 0x05, 0xdb, - 0xa3, 0xcb, 0x66, 0x7b, 0x3e, 0xa7, 0x56, 0x93, 0xd9, 0x1e, 0x11, 0x21, 0xa7, 0x81, 0x5e, 0x50, - 0x2c, 0x43, 0x46, 0x68, 0xbb, 0x7b, 0xad, 0x0b, 0xdf, 0x40, 0xe8, 0xf3, 0x3f, 0x84, 0x6e, 0x93, - 0x3a, 0xd4, 0x14, 0xd4, 0x6a, 0x78, 0xc3, 0xce, 0xeb, 0x8e, 0x6f, 0x7e, 0x0b, 0xf4, 0xe2, 0x88, - 0xef, 0x5d, 0xeb, 0xc2, 0x37, 0x10, 0xe0, 0x89, 0x06, 0x56, 0x76, 0x4d, 0x33, 0x74, 0x43, 0x87, - 0x08, 0x6a, 0xed, 0x51, 0x1a, 0xe8, 0x2b, 0x6a, 0xf6, 0x6d, 0x19, 0xa1, 0x2d, 0x92, 0x96, 0x46, - 0xd3, 0xff, 0x75, 0x8e, 0xde, 0xba, 0x44, 0x74, 0x6a, 0x2d, 0x66, 0x57, 0x1b, 0x9e, 0x78, 0x39, - 0xf6, 0x25, 0x75, 0x43, 0x47, 0xb0, 0x2e, 0xe5, 0xc1, 0x51, 0xcd, 0x3d, 0xaa, 0x98, 0x1d, 0xc2, - 0xbc, 0x8a, 0xe9, 0x73, 0x5a, 0xb1, 0xfd, 0x9a, 0x45, 0x04, 0xa9, 0xd6, 0x99, 0xdd, 0xf0, 0xc4, - 0x1b, 0x12, 0x08, 0xca, 0xf1, 0xe4, 0xf1, 0x70, 0x0f, 0xc0, 0x03, 0x5f, 0x10, 0x27, 0x7d, 0x9b, - 0x56, 0xd5, 0xbf, 0x7a, 0x57, 0x46, 0x08, 0x8a, 0x29, 0x15, 0xcf, 0x48, 0x4c, 0x70, 0x92, 0xf1, - 0xae, 0xcd, 0xe4, 0x24, 0x03, 0x9e, 0x91, 0x80, 0x1f, 0xc1, 0xa6, 0xaa, 0x4e, 0xdd, 0x35, 0xa8, - 0x50, 0x5b, 0x32, 0x42, 0x9b, 0x62, 0x96, 0x01, 0xcf, 0xce, 0x4d, 0x03, 0x93, 0xde, 0xd6, 0xaf, - 0x03, 0x26, 0xed, 0xcd, 0xce, 0x41, 0x17, 0xa0, 0xb4, 0x30, 0x7d, 0x13, 0x37, 0x14, 0xfa, 0xa1, - 0x8c, 0x10, 0x12, 0x37, 0x5b, 0xf1, 0xff, 0x58, 0x3b, 0x3d, 0x0d, 0x40, 0xb5, 0x07, 0x6f, 0x7f, - 0xcd, 0x3e, 0x4e, 0xad, 0x59, 0xb5, 0xc9, 0xfa, 0x6b, 0x76, 0x6c, 0x0b, 0xdd, 0xce, 0xc2, 0xad, - 0xbf, 0x3a, 0xed, 0x19, 0x99, 0xb3, 0x9e, 0x91, 0xb9, 0xec, 0x19, 0xda, 0x8f, 0xd8, 0xd0, 0x7e, - 0xc6, 0x86, 0xf6, 0x3b, 0x36, 0xb4, 0xd3, 0xd8, 0xd0, 0xce, 0x62, 0x43, 0xfb, 0x13, 0x1b, 0xda, - 0xdf, 0xd8, 0xc8, 0x5c, 0xc6, 0x86, 0x76, 0x72, 0x61, 0x64, 0x4e, 0x2f, 0x8c, 0xcc, 0xd9, 0x85, - 0x91, 0xf9, 0x92, 0x0d, 0x04, 0x11, 0xb4, 0x95, 0x53, 0xbf, 0x46, 0xcf, 0xfe, 0x05, 0x00, 0x00, - 0xff, 0xff, 0x5e, 0xa1, 0xc3, 0x5e, 0xda, 0x06, 0x00, 0x00, + // 750 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcf, 0x6e, 0xe2, 0x46, + 0x18, 0xc7, 0x69, 0x20, 0x61, 0x12, 0x48, 0x32, 0xf9, 0x53, 0x87, 0x56, 0x1e, 0x94, 0xaa, 0x15, + 0x52, 0x0b, 0x1c, 0x7a, 0xa8, 0xd4, 0x4a, 0x6d, 0x43, 0xd5, 0x48, 0xa8, 0x69, 0x1b, 0x0d, 0x51, + 0x0f, 0x3d, 0x54, 0x1a, 0xec, 0xc1, 0x8c, 0xea, 0x3f, 0x68, 0x3c, 0xa6, 0xc9, 0xad, 0x8f, 0x90, + 0x37, 0xa8, 0x7a, 0x5b, 0xed, 0x93, 0xec, 0x31, 0xc7, 0x9c, 0x66, 0x37, 0xce, 0x65, 0x35, 0xa7, + 0x3c, 0xc2, 0x8a, 0x01, 0x07, 0x0c, 0x24, 0xab, 0x3d, 0xe4, 0x84, 0xfd, 0xfb, 0x37, 0x1f, 0xf3, + 0x7d, 0x7c, 0x80, 0xdd, 0x21, 0xf1, 0x98, 0x43, 0x44, 0xc8, 0xdb, 0x41, 0x2f, 0x6c, 0x0c, 0x78, + 0x28, 0x42, 0x98, 0xd7, 0x1f, 0x95, 0xba, 0xcb, 0x44, 0x3f, 0xee, 0x36, 0xec, 0xd0, 0x6f, 0xba, + 0xa1, 0x1b, 0x36, 0x35, 0xdc, 0x8d, 0x7b, 0xfa, 0x4d, 0xbf, 0xe8, 0xa7, 0xb1, 0xeb, 0xe8, 0xbf, + 0x0d, 0x50, 0xfa, 0x63, 0x36, 0x0d, 0x7e, 0x09, 0x8a, 0x67, 0x71, 0xd7, 0x63, 0xf6, 0x2f, 0xf4, + 0xd2, 0x34, 0xaa, 0x46, 0x6d, 0xb3, 0x55, 0x52, 0x12, 0x15, 0x07, 0x29, 0x88, 0xa7, 0x3c, 0xfc, + 0x1c, 0xac, 0x75, 0xfa, 0x84, 0x3b, 0x6d, 0xc7, 0x5c, 0xa9, 0x1a, 0xb5, 0x52, 0x6b, 0x43, 0x49, + 0xb4, 0x16, 0x8d, 0x21, 0x9c, 0x72, 0xf0, 0x53, 0xb0, 0x7a, 0xca, 0x22, 0x61, 0x7e, 0x54, 0x35, + 0x6a, 0xc5, 0xd6, 0xba, 0x92, 0x68, 0xd5, 0x63, 0x91, 0xc0, 0x1a, 0x85, 0x08, 0xe4, 0xdb, 0x81, + 0x43, 0x2f, 0xcc, 0x55, 0x1d, 0x51, 0x54, 0x12, 0xe5, 0xd9, 0x08, 0xc0, 0x63, 0x1c, 0x36, 0x00, + 0x38, 0xa7, 0xfe, 0x00, 0x13, 0xc1, 0x02, 0xd7, 0xcc, 0x6b, 0x55, 0x59, 0x49, 0x04, 0xc4, 0x03, + 0x8a, 0x67, 0x14, 0xf0, 0x08, 0x14, 0x26, 0xda, 0x82, 0xd6, 0x02, 0x25, 0x51, 0x81, 0x8f, 0x75, + 0x13, 0x06, 0x7e, 0x0b, 0xca, 0xe3, 0xa7, 0x5f, 0x43, 0x87, 0xf5, 0x18, 0xe5, 0xe6, 0x5a, 0xd5, + 0xa8, 0xad, 0xb4, 0xa0, 0x92, 0xa8, 0xcc, 0x33, 0x0c, 0x9e, 0x53, 0xc2, 0x63, 0x50, 0xc2, 0xf4, + 0x1f, 0xc2, 0x9d, 0x63, 0xc7, 0xe1, 0x34, 0x8a, 0xcc, 0x75, 0x7d, 0x4d, 0x9f, 0x28, 0x89, 0x3e, + 0xe6, 0xb3, 0xc4, 0x57, 0xa1, 0xcf, 0x46, 0x35, 0x8a, 0x4b, 0x9c, 0x75, 0xc0, 0x6f, 0x40, 0xe9, + 0x94, 0x12, 0x87, 0xf2, 0x4e, 0x6c, 0xdb, 0xa3, 0x88, 0xa2, 0xae, 0x74, 0x47, 0x49, 0x54, 0xf2, + 0x66, 0x09, 0x9c, 0xd5, 0x4d, 0x8d, 0x27, 0x84, 0x79, 0x31, 0xa7, 0x26, 0x98, 0x37, 0x4e, 0x08, + 0x9c, 0xd5, 0xc1, 0x1f, 0xc1, 0xf6, 0x43, 0xa3, 0xd3, 0x43, 0x37, 0xb4, 0x77, 0x4f, 0x49, 0xb4, + 0x3d, 0x9c, 0xe3, 0xf0, 0x82, 0x3a, 0x93, 0x90, 0x9e, 0xbe, 0xb9, 0x24, 0x21, 0x2d, 0x60, 0x41, + 0x0d, 0xff, 0x02, 0x95, 0xe9, 0xb0, 0xb9, 0x41, 0xc8, 0xa9, 0xd3, 0x61, 0x6e, 0x40, 0x44, 0xcc, + 0x69, 0x64, 0x96, 0x74, 0x96, 0xa5, 0x24, 0xaa, 0x0c, 0x1f, 0x55, 0xe1, 0x27, 0x12, 0x46, 0xf9, + 0xbf, 0xc5, 0x7e, 0x87, 0x7a, 0xd4, 0x16, 0xd4, 0x69, 0x07, 0x93, 0xca, 0x5b, 0x5e, 0x68, 0xff, + 0x1d, 0x99, 0xe5, 0x69, 0x7e, 0xf0, 0xa8, 0x0a, 0x3f, 0x91, 0x00, 0xaf, 0x0c, 0xb0, 0x75, 0x6c, + 0xdb, 0xb1, 0x1f, 0x7b, 0x44, 0x50, 0xe7, 0x84, 0xd2, 0xc8, 0xdc, 0xd2, 0xbd, 0xef, 0x29, 0x89, + 0x0e, 0x49, 0x96, 0x9a, 0x76, 0xff, 0xe5, 0x6b, 0xf4, 0xb3, 0x4f, 0x44, 0xbf, 0xd9, 0x65, 0x6e, + 0xa3, 0x1d, 0x88, 0xef, 0x66, 0x7e, 0xa4, 0x7e, 0xec, 0x09, 0x36, 0xa4, 0x3c, 0xba, 0x68, 0xfa, + 0x17, 0x75, 0xbb, 0x4f, 0x58, 0x50, 0xb7, 0x43, 0x4e, 0xeb, 0x6e, 0xd8, 0x74, 0x88, 0x20, 0x8d, + 0x16, 0x73, 0xdb, 0x81, 0xf8, 0x89, 0x44, 0x82, 0x72, 0x3c, 0x7f, 0x3c, 0x3c, 0x01, 0xf0, 0x3c, + 0x14, 0xc4, 0xcb, 0x4e, 0xd3, 0xb6, 0xfe, 0xaa, 0x07, 0x4a, 0x22, 0x28, 0x16, 0x58, 0xbc, 0xc4, + 0x31, 0x97, 0x93, 0xb6, 0x77, 0x67, 0x69, 0x4e, 0xda, 0xe0, 0x25, 0x0e, 0xf8, 0x3b, 0xd8, 0xd7, + 0xe8, 0xc2, 0xac, 0x41, 0x1d, 0x75, 0xa8, 0x24, 0xda, 0x17, 0xcb, 0x04, 0x78, 0xb9, 0x6f, 0x31, + 0x30, 0xad, 0x6d, 0xf7, 0xb1, 0xc0, 0xb4, 0xbc, 0xe5, 0x3e, 0xe8, 0x03, 0x94, 0x25, 0x16, 0x27, + 0x71, 0x4f, 0x47, 0x7f, 0xa6, 0x24, 0x42, 0xe2, 0x69, 0x29, 0x7e, 0x5f, 0x16, 0xfc, 0x1e, 0x6c, + 0x9e, 0x71, 0x3a, 0x64, 0x61, 0x1c, 0xe9, 0x1d, 0xb8, 0xaf, 0x77, 0x60, 0x45, 0x49, 0x74, 0x30, + 0x98, 0xc1, 0x67, 0x56, 0x45, 0x46, 0x7f, 0xf4, 0xff, 0x0a, 0x80, 0x7a, 0x8f, 0x3e, 0xff, 0x9a, + 0xfe, 0x22, 0xb3, 0xa6, 0xf5, 0x26, 0xf4, 0xb2, 0xa5, 0x3d, 0xd3, 0xc2, 0x9e, 0xbf, 0xa3, 0xc2, + 0x87, 0xdd, 0x51, 0xeb, 0x87, 0xeb, 0x5b, 0x2b, 0x77, 0x73, 0x6b, 0xe5, 0xee, 0x6f, 0x2d, 0xe3, + 0xdf, 0xc4, 0x32, 0x5e, 0x24, 0x96, 0xf1, 0x2a, 0xb1, 0x8c, 0xeb, 0xc4, 0x32, 0x6e, 0x12, 0xcb, + 0x78, 0x93, 0x58, 0xc6, 0xdb, 0xc4, 0xca, 0xdd, 0x27, 0x96, 0x71, 0x75, 0x67, 0xe5, 0xae, 0xef, + 0xac, 0xdc, 0xcd, 0x9d, 0x95, 0xfb, 0x33, 0x1f, 0x09, 0x22, 0x68, 0xb7, 0xa0, 0xff, 0x0d, 0xbf, + 0x7e, 0x17, 0x00, 0x00, 0xff, 0xff, 0x93, 0xed, 0x72, 0x8e, 0x5a, 0x07, 0x00, 0x00, } func (this *ValidatorInfo) Equal(that interface{}) bool { @@ -431,6 +449,9 @@ func (this *ValidatorInfo) Equal(that interface{}) bool { if this.TotalValidatorIgnoredSignatures != that1.TotalValidatorIgnoredSignatures { return false } + if this.PreviousList != that1.PreviousList { + return false + } return true } func (this *ShardValidatorInfo) Equal(that interface{}) bool { @@ -467,13 +488,16 @@ func (this *ShardValidatorInfo) Equal(that interface{}) bool { if this.TempRating != that1.TempRating { return false } + if this.PreviousList != that1.PreviousList { + return false + } return true } func (this *ValidatorInfo) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 24) + s := make([]string, 0, 25) s = append(s, "&state.ValidatorInfo{") s = append(s, "PublicKey: "+fmt.Sprintf("%#v", this.PublicKey)+",\n") s = append(s, "ShardId: "+fmt.Sprintf("%#v", this.ShardId)+",\n") @@ -495,6 +519,7 @@ func (this *ValidatorInfo) GoString() string { s = append(s, "TotalValidatorSuccess: "+fmt.Sprintf("%#v", this.TotalValidatorSuccess)+",\n") s = append(s, "TotalValidatorFailure: "+fmt.Sprintf("%#v", this.TotalValidatorFailure)+",\n") s = append(s, "TotalValidatorIgnoredSignatures: "+fmt.Sprintf("%#v", this.TotalValidatorIgnoredSignatures)+",\n") + s = append(s, "PreviousList: "+fmt.Sprintf("%#v", this.PreviousList)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -502,13 +527,14 @@ func (this *ShardValidatorInfo) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 9) + s := make([]string, 0, 10) s = append(s, "&state.ShardValidatorInfo{") s = append(s, "PublicKey: "+fmt.Sprintf("%#v", this.PublicKey)+",\n") s = append(s, "ShardId: "+fmt.Sprintf("%#v", this.ShardId)+",\n") s = append(s, "List: "+fmt.Sprintf("%#v", this.List)+",\n") s = append(s, "Index: "+fmt.Sprintf("%#v", this.Index)+",\n") s = append(s, "TempRating: "+fmt.Sprintf("%#v", this.TempRating)+",\n") + s = append(s, "PreviousList: "+fmt.Sprintf("%#v", this.PreviousList)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -540,6 +566,15 @@ func (m *ValidatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PreviousList) > 0 { + i -= len(m.PreviousList) + copy(dAtA[i:], m.PreviousList) + i = encodeVarintValidatorInfo(dAtA, i, uint64(len(m.PreviousList))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + } if m.TotalValidatorIgnoredSignatures != 0 { i = encodeVarintValidatorInfo(dAtA, i, uint64(m.TotalValidatorIgnoredSignatures)) i-- @@ -686,6 +721,13 @@ func (m *ShardValidatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PreviousList) > 0 { + i -= len(m.PreviousList) + copy(dAtA[i:], m.PreviousList) + i = encodeVarintValidatorInfo(dAtA, i, uint64(len(m.PreviousList))) + i-- + dAtA[i] = 0x32 + } if m.TempRating != 0 { i = encodeVarintValidatorInfo(dAtA, i, uint64(m.TempRating)) i-- @@ -800,6 +842,10 @@ func (m *ValidatorInfo) Size() (n int) { if m.TotalValidatorIgnoredSignatures != 0 { n += 2 + sovValidatorInfo(uint64(m.TotalValidatorIgnoredSignatures)) } + l = len(m.PreviousList) + if l > 0 { + n += 2 + l + sovValidatorInfo(uint64(l)) + } return n } @@ -826,6 +872,10 @@ func (m *ShardValidatorInfo) Size() (n int) { if m.TempRating != 0 { n += 1 + sovValidatorInfo(uint64(m.TempRating)) } + l = len(m.PreviousList) + if l > 0 { + n += 1 + l + sovValidatorInfo(uint64(l)) + } return n } @@ -860,6 +910,7 @@ func (this *ValidatorInfo) String() string { `TotalValidatorSuccess:` + fmt.Sprintf("%v", this.TotalValidatorSuccess) + `,`, `TotalValidatorFailure:` + fmt.Sprintf("%v", this.TotalValidatorFailure) + `,`, `TotalValidatorIgnoredSignatures:` + fmt.Sprintf("%v", this.TotalValidatorIgnoredSignatures) + `,`, + `PreviousList:` + fmt.Sprintf("%v", this.PreviousList) + `,`, `}`, }, "") return s @@ -874,6 +925,7 @@ func (this *ShardValidatorInfo) String() string { `List:` + fmt.Sprintf("%v", this.List) + `,`, `Index:` + fmt.Sprintf("%v", this.Index) + `,`, `TempRating:` + fmt.Sprintf("%v", this.TempRating) + `,`, + `PreviousList:` + fmt.Sprintf("%v", this.PreviousList) + `,`, `}`, }, "") return s @@ -1349,6 +1401,38 @@ func (m *ValidatorInfo) Unmarshal(dAtA []byte) error { break } } + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousList", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowValidatorInfo + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthValidatorInfo + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthValidatorInfo + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PreviousList = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipValidatorInfo(dAtA[iNdEx:]) @@ -1525,6 +1609,38 @@ func (m *ShardValidatorInfo) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousList", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowValidatorInfo + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthValidatorInfo + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthValidatorInfo + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PreviousList = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipValidatorInfo(dAtA[iNdEx:]) diff --git a/state/validatorInfo.proto b/state/validatorInfo.proto index c6256810091..85d54e3232b 100644 --- a/state/validatorInfo.proto +++ b/state/validatorInfo.proto @@ -29,6 +29,7 @@ message ValidatorInfo { uint32 TotalValidatorSuccess = 18 [(gogoproto.jsontag) = "totalValidatorSuccess"]; uint32 TotalValidatorFailure = 19 [(gogoproto.jsontag) = "totalValidatorFailure"]; uint32 TotalValidatorIgnoredSignatures = 20 [(gogoproto.jsontag) = "totalValidatorIgnoredSignatures"]; + string PreviousList = 21 [(gogoproto.jsontag) = "previousList,omitempty"]; } // ShardValidatorInfo represents the data regarding a validator that is stored in the PeerMiniblocks @@ -38,4 +39,5 @@ message ShardValidatorInfo { string List = 3 [(gogoproto.jsontag) = "list,omitempty"]; uint32 Index = 4 [(gogoproto.jsontag) = "index"]; uint32 TempRating = 5 [(gogoproto.jsontag) = "tempRating"]; + string PreviousList = 6 [(gogoproto.jsontag) = "previousList,omitempty"]; } diff --git a/update/genesis/common.go b/update/genesis/common.go index 47497906c18..ee545feb82b 100644 --- a/update/genesis/common.go +++ b/update/genesis/common.go @@ -50,6 +50,7 @@ func peerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.Val PublicKey: peerAccount.GetBLSPublicKey(), ShardId: peerAccount.GetShardId(), List: getActualList(peerAccount), + PreviousList: peerAccount.GetPreviousList(), Index: peerAccount.GetIndexInList(), TempRating: peerAccount.GetTempRating(), Rating: peerAccount.GetRating(), From c68c30f560990ed2cdbc486864293f49130e2c61 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 6 Feb 2023 14:44:04 +0200 Subject: [PATCH 402/958] FEAT: Version with enable epoch --- epochStart/metachain/auctionListSelector.go | 2 +- .../metachain/auctionListSelector_test.go | 24 ++-- epochStart/metachain/legacySystemSCs.go | 10 +- epochStart/metachain/rewardsV2_test.go | 2 +- epochStart/metachain/systemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 103 +++++++++--------- process/mock/peerAccountHandlerMock.go | 7 +- process/peer/process.go | 14 +-- process/peer/process_test.go | 6 +- process/peer/validatorsProvider_test.go | 10 +- process/scToProtocol/stakingToPeer.go | 18 +-- process/scToProtocol/stakingToPeer_test.go | 4 +- state/interface.go | 4 +- state/peerAccount.go | 7 +- state/validatorInfo.go | 7 +- 15 files changed, 116 insertions(+), 104 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 1bd87398cc2..81fa12aa980 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -344,7 +344,7 @@ func markAuctionNodesAsSelected( ) error { for _, node := range selectedNodes { newNode := node.ShallowClone() - newNode.SetList(string(common.SelectedFromAuctionList)) + newNode.SetList(string(common.SelectedFromAuctionList), true) err := validatorsInfoMap.Replace(node, newNode) if err != nil { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index d5b8dc55435..15f1b960708 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -236,7 +236,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { owner1StakedKeys := [][]byte{[]byte("pubKey0")} validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1)) args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 2}}) stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) @@ -247,7 +247,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1), }, } require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) @@ -262,8 +262,8 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { owner2StakedKeys := [][]byte{[]byte("pubKey1")} validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, "", 0, owner2)) args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1}}) stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) @@ -275,8 +275,8 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), - createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0), + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1), + createValidatorInfo(owner2StakedKeys[0], common.AuctionList, "", 0, owner2), }, } require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) @@ -291,8 +291,8 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { owner2StakedKeys := [][]byte{[]byte("pubKey1")} validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, owner2, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.AuctionList, "", 0, owner2)) args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 1, NodesToShufflePerShard: 1}}) stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) @@ -304,8 +304,8 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), - createValidatorInfo(owner2StakedKeys[0], common.SelectedFromAuctionList, owner2, 0), + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1), + createValidatorInfo(owner2StakedKeys[0], common.SelectedFromAuctionList, common.AuctionList, 0, owner2), }, } require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) @@ -317,7 +317,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { owner1 := []byte("owner1") owner1StakedKeys := [][]byte{[]byte("pubKey0")} validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.AuctionList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.AuctionList, "", 0, owner1)) args, argsSystemSC := createFullAuctionListSelectorArgs([]config.MaxNodesChangeConfig{{MaxNumNodes: 2}}) stakingcommon.RegisterValidatorKeys(argsSystemSC.UserAccountsDB, owner1, owner1, owner1StakedKeys, big.NewInt(1000), argsSystemSC.Marshalizer) @@ -328,7 +328,7 @@ func TestAuctionListSelector_SelectNodesFromAuction(t *testing.T) { require.Nil(t, err) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { - createValidatorInfo(owner1StakedKeys[0], common.SelectedFromAuctionList, owner1, 0), + createValidatorInfo(owner1StakedKeys[0], common.SelectedFromAuctionList, common.AuctionList, 0, owner1), }, } require.Equal(t, expectedValidatorsInfo, validatorsInfo.GetShardValidatorsInfoMap()) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 2d08de3780a..8c1b22fd8f2 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -290,7 +290,7 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( } validatorLeaving := validatorInfo.ShallowClone() - validatorLeaving.SetList(string(common.LeavingList)) + validatorLeaving.SetList(string(common.LeavingList), s.enableEpochsHandler.IsStakingV4Started()) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { return 0, err @@ -344,7 +344,7 @@ func (s *legacySystemSCProcessor) unStakeOneNode(blsKey []byte, epoch uint32) er return epochStart.ErrWrongTypeAssertion } - peerAccount.SetListAndIndex(peerAccount.GetShardId(), string(common.LeavingList), peerAccount.GetIndexInList()) + peerAccount.SetListAndIndex(peerAccount.GetShardId(), string(common.LeavingList), peerAccount.GetIndexInList(), s.enableEpochsHandler.IsStakingV4Started()) peerAccount.SetUnStakedEpoch(epoch) err = s.peerAccountsDB.SaveAccount(peerAccount) if err != nil { @@ -733,7 +733,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } } - account.SetListAndIndex(jailedValidator.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce)) + account.SetListAndIndex(jailedValidator.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce), s.enableEpochsHandler.IsStakingV4Started()) account.SetTempRating(s.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) @@ -747,7 +747,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( return nil, err } - jailedAccount.SetListAndIndex(jailedValidator.GetShardId(), string(common.JailedList), jailedValidator.GetIndex()) + jailedAccount.SetListAndIndex(jailedValidator.GetShardId(), string(common.JailedList), jailedValidator.GetIndex(), s.enableEpochsHandler.IsStakingV4Started()) jailedAccount.ResetAtNewEpoch() err = s.peerAccountsDB.SaveAccount(jailedAccount) if err != nil { @@ -1223,7 +1223,7 @@ func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( return err } - peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce)) + peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce), s.enableEpochsHandler.IsStakingV4Started()) peerAcc.SetTempRating(s.startRating) peerAcc.SetUnStakedEpoch(common.DefaultUnstakedEpoch) diff --git a/epochStart/metachain/rewardsV2_test.go b/epochStart/metachain/rewardsV2_test.go index 7abea51dea3..d009178424c 100644 --- a/epochStart/metachain/rewardsV2_test.go +++ b/epochStart/metachain/rewardsV2_test.go @@ -1415,7 +1415,7 @@ func TestNewRewardsCreatorV2_computeValidatorInfoPerRewardAddressWithLeavingVali valInfo := createDefaultValidatorInfo(nbEligiblePerShard, args.ShardCoordinator, args.NodesConfigProvider, proposerFee, defaultBlocksPerShard) for _, valList := range valInfo.GetShardValidatorsInfoMap() { for i := 0; i < int(nbLeavingPerShard); i++ { - valList[i].SetList(string(common.LeavingList)) + valList[i].SetList(string(common.LeavingList), false) } } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 9be672b3ce9..e8a3f2c01b0 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -172,7 +172,7 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( } validatorLeaving := validatorInfo.ShallowClone() - validatorLeaving.SetList(string(common.LeavingList)) + validatorLeaving.SetList(string(common.LeavingList), true) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { return err diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 8f39efa61de..d26cb00c9f4 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1768,9 +1768,9 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner3, owner3, owner3ListPubKeysWaiting, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, "", 0, owner1)) + _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, "", 0, owner1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, "", 1, owner2)) args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4InitEnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) @@ -1778,19 +1778,19 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { - createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, owner1, 0), - createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, owner1, 0), - createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, owner1, 0), - createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, owner1, 0), - createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, owner1, 0), + createValidatorInfo(owner1ListPubKeysStaked[0], common.EligibleList, "", 0, owner1), + createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, "", 0, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[0], common.AuctionList, "", 0, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[1], common.AuctionList, "", 0, owner1), + createValidatorInfo(owner1ListPubKeysWaiting[2], common.AuctionList, "", 0, owner1), - createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, owner2, 0), + createValidatorInfo(owner2ListPubKeysWaiting[0], common.AuctionList, "", 0, owner2), - createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, owner3, 0), - createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, owner3, 0), + createValidatorInfo(owner3ListPubKeysWaiting[0], common.AuctionList, "", 0, owner3), + createValidatorInfo(owner3ListPubKeysWaiting[1], common.AuctionList, "", 0, owner3), }, 1: { - createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, owner2, 1), + createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, "", 1, owner2), }, } @@ -1814,8 +1814,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner, owner, ownerStakedKeys, big.NewInt(2000), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, owner, 0)) - _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, owner, 0)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[0], common.AuctionList, "", 0, owner)) + _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, "", 0, owner)) s, _ := NewSystemSCProcessor(args) s.EpochConfirmed(stakingV4EnableEpoch, 0) @@ -1867,30 +1867,30 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing stakingcommon.RegisterValidatorKeys(args.UserAccountsDB, owner7, owner7, owner7StakedKeys, big.NewInt(1500), args.Marshalizer) validatorsInfo := state.NewShardValidatorsInfoMap() - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0)) - _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.AuctionList, owner1, 0)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[1], common.WaitingList, "", 0, owner1)) + _ = validatorsInfo.Add(createValidatorInfo(owner1StakedKeys[2], common.AuctionList, "", 0, owner1)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, owner2, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[0], common.EligibleList, "", 1, owner2)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[1], common.AuctionList, "", 1, owner2)) + _ = validatorsInfo.Add(createValidatorInfo(owner2StakedKeys[2], common.AuctionList, "", 1, owner2)) - _ = validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[0], common.LeavingList, "", 1, owner3)) + _ = validatorsInfo.Add(createValidatorInfo(owner3StakedKeys[1], common.AuctionList, "", 1, owner3)) - _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, owner4, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[2], common.AuctionList, owner4, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[3], common.AuctionList, owner4, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[0], common.JailedList, "", 1, owner4)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[1], common.AuctionList, "", 1, owner4)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[2], common.AuctionList, "", 1, owner4)) + _ = validatorsInfo.Add(createValidatorInfo(owner4StakedKeys[3], common.AuctionList, "", 1, owner4)) - _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[0], common.EligibleList, owner5, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[1], common.AuctionList, owner5, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[0], common.EligibleList, "", 1, owner5)) + _ = validatorsInfo.Add(createValidatorInfo(owner5StakedKeys[1], common.AuctionList, "", 1, owner5)) - _ = validatorsInfo.Add(createValidatorInfo(owner6StakedKeys[0], common.AuctionList, owner6, 1)) - _ = validatorsInfo.Add(createValidatorInfo(owner6StakedKeys[1], common.AuctionList, owner6, 1)) + _ = validatorsInfo.Add(createValidatorInfo(owner6StakedKeys[0], common.AuctionList, "", 1, owner6)) + _ = validatorsInfo.Add(createValidatorInfo(owner6StakedKeys[1], common.AuctionList, "", 1, owner6)) - _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[0], common.EligibleList, owner7, 2)) - _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[1], common.EligibleList, owner7, 2)) + _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[0], common.EligibleList, "", 2, owner7)) + _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[1], common.EligibleList, "", 2, owner7)) s, _ := NewSystemSCProcessor(args) args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4EnableEpoch}) @@ -1955,32 +1955,32 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing expectedValidatorsInfo := map[uint32][]state.ValidatorInfoHandler{ 0: { - createValidatorInfo(owner1StakedKeys[0], common.EligibleList, owner1, 0), - createValidatorInfo(owner1StakedKeys[1], common.WaitingList, owner1, 0), - createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, owner1, 0), + createValidatorInfo(owner1StakedKeys[0], common.EligibleList, "", 0, owner1), + createValidatorInfo(owner1StakedKeys[1], common.WaitingList, "", 0, owner1), + createValidatorInfo(owner1StakedKeys[2], common.SelectedFromAuctionList, common.AuctionList, 0, owner1), }, 1: { - createValidatorInfo(owner2StakedKeys[0], common.EligibleList, owner2, 1), - createValidatorInfo(owner2StakedKeys[1], common.AuctionList, owner2, 1), - createValidatorInfo(owner2StakedKeys[2], common.SelectedFromAuctionList, owner2, 1), + createValidatorInfo(owner2StakedKeys[0], common.EligibleList, "", 1, owner2), + createValidatorInfo(owner2StakedKeys[1], common.AuctionList, "", 1, owner2), + createValidatorInfo(owner2StakedKeys[2], common.SelectedFromAuctionList, common.AuctionList, 1, owner2), - createValidatorInfo(owner3StakedKeys[0], common.LeavingList, owner3, 1), - createValidatorInfo(owner3StakedKeys[1], common.AuctionList, owner3, 1), + createValidatorInfo(owner3StakedKeys[0], common.LeavingList, "", 1, owner3), + createValidatorInfo(owner3StakedKeys[1], common.AuctionList, "", 1, owner3), - createValidatorInfo(owner4StakedKeys[0], common.JailedList, owner4, 1), - createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, owner4, 1), - createValidatorInfo(owner4StakedKeys[2], common.AuctionList, owner4, 1), - createValidatorInfo(owner4StakedKeys[3], common.AuctionList, owner4, 1), + createValidatorInfo(owner4StakedKeys[0], common.JailedList, "", 1, owner4), + createValidatorInfo(owner4StakedKeys[1], common.SelectedFromAuctionList, common.AuctionList, 1, owner4), + createValidatorInfo(owner4StakedKeys[2], common.AuctionList, "", 1, owner4), + createValidatorInfo(owner4StakedKeys[3], common.AuctionList, "", 1, owner4), - createValidatorInfo(owner5StakedKeys[0], common.EligibleList, owner5, 1), - createValidatorInfo(owner5StakedKeys[1], common.LeavingList, owner5, 1), + createValidatorInfo(owner5StakedKeys[0], common.EligibleList, "", 1, owner5), + createValidatorInfo(owner5StakedKeys[1], common.LeavingList, common.AuctionList, 1, owner5), - createValidatorInfo(owner6StakedKeys[0], common.LeavingList, owner6, 1), - createValidatorInfo(owner6StakedKeys[1], common.AuctionList, owner6, 1), + createValidatorInfo(owner6StakedKeys[0], common.LeavingList, common.AuctionList, 1, owner6), + createValidatorInfo(owner6StakedKeys[1], common.AuctionList, "", 1, owner6), }, 2: { - createValidatorInfo(owner7StakedKeys[0], common.LeavingList, owner7, 2), - createValidatorInfo(owner7StakedKeys[1], common.EligibleList, owner7, 2), + createValidatorInfo(owner7StakedKeys[0], common.LeavingList, common.EligibleList, 2, owner7), + createValidatorInfo(owner7StakedKeys[1], common.EligibleList, "", 2, owner7), }, } @@ -2114,12 +2114,13 @@ func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, staked } // This func sets rating and temp rating with the start rating value used in createFullArgumentsForSystemSCProcessing -func createValidatorInfo(pubKey []byte, list common.PeerType, owner []byte, shardID uint32) *state.ValidatorInfo { +func createValidatorInfo(pubKey []byte, list common.PeerType, previousList common.PeerType, shardID uint32, owner []byte) *state.ValidatorInfo { rating := uint32(5) return &state.ValidatorInfo{ PublicKey: pubKey, List: string(list), + PreviousList: string(previousList), ShardId: shardID, RewardAddress: owner, AccumulatedFees: zero, diff --git a/process/mock/peerAccountHandlerMock.go b/process/mock/peerAccountHandlerMock.go index e2b9b9f42e1..08370b1b27f 100644 --- a/process/mock/peerAccountHandlerMock.go +++ b/process/mock/peerAccountHandlerMock.go @@ -51,6 +51,11 @@ func (p *PeerAccountHandlerMock) GetList() string { return "" } +// GetPreviousList - +func (p *PeerAccountHandlerMock) GetPreviousList() string { + return "" +} + // GetIndexInList - func (p *PeerAccountHandlerMock) GetIndexInList() uint32 { return 0 @@ -290,7 +295,7 @@ func (p *PeerAccountHandlerMock) SetConsecutiveProposerMisses(consecutiveMisses } // SetListAndIndex - -func (p *PeerAccountHandlerMock) SetListAndIndex(shardID uint32, list string, index uint32) { +func (p *PeerAccountHandlerMock) SetListAndIndex(shardID uint32, list string, index uint32, _ bool) { if p.SetListAndIndexCalled != nil { p.SetListAndIndexCalled(shardID, list, index) } diff --git a/process/peer/process.go b/process/peer/process.go index eb5281a0c9e..728eb93b7ec 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -238,11 +238,11 @@ func (vs *validatorStatistics) saveUpdatesForList( isNodeWithLowRating := vs.isValidatorWithLowRating(peerAcc) isNodeJailed := vs.enableEpochsHandler.IsSwitchJailWaitingFlagEnabled() && peerType == common.InactiveList && isNodeWithLowRating if isNodeJailed { - peerAcc.SetListAndIndex(shardID, string(common.JailedList), uint32(index)) + peerAcc.SetListAndIndex(shardID, string(common.JailedList), uint32(index), vs.enableEpochsHandler.IsStakingV4Started()) } else if isNodeLeaving { - peerAcc.SetListAndIndex(shardID, string(common.LeavingList), uint32(index)) + peerAcc.SetListAndIndex(shardID, string(common.LeavingList), uint32(index), vs.enableEpochsHandler.IsStakingV4Started()) } else { - peerAcc.SetListAndIndex(shardID, string(peerType), uint32(index)) + peerAcc.SetListAndIndex(shardID, string(peerType), uint32(index), vs.enableEpochsHandler.IsStakingV4Started()) } err = vs.peerAdapter.SaveAccount(peerAcc) @@ -545,7 +545,7 @@ func (vs *validatorStatistics) jailValidatorIfBadRatingAndInactive(validatorAcco return } - validatorAccount.SetListAndIndex(validatorAccount.GetShardId(), string(common.JailedList), validatorAccount.GetIndexInList()) + validatorAccount.SetListAndIndex(validatorAccount.GetShardId(), string(common.JailedList), validatorAccount.GetIndexInList(), vs.enableEpochsHandler.IsStakingV4Started()) } func (vs *validatorStatistics) unmarshalPeer(pa []byte) (state.PeerAccountHandler, error) { @@ -713,12 +713,12 @@ func (vs *validatorStatistics) setToJailedIfNeeded( } if validator.GetList() == string(common.JailedList) && peerAccount.GetList() != string(common.JailedList) { - peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex()) + peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex(), vs.enableEpochsHandler.IsStakingV4Started()) return } if vs.isValidatorWithLowRating(peerAccount) { - peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex()) + peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex(), vs.enableEpochsHandler.IsStakingV4Started()) } } @@ -980,7 +980,7 @@ func (vs *validatorStatistics) savePeerAccountData( peerAccount.SetRating(startRating) peerAccount.SetTempRating(startRating) - peerAccount.SetListAndIndex(shardID, string(peerType), index) + peerAccount.SetListAndIndex(shardID, string(peerType), index, vs.enableEpochsHandler.IsStakingV4Started()) return vs.peerAdapter.SaveAccount(peerAccount) } diff --git a/process/peer/process_test.go b/process/peer/process_test.go index a6cdf86b48e..6b1a9439682 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2264,7 +2264,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochComputesJustEligible _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) - validatorWaiting.SetList(string(common.WaitingList)) + validatorWaiting.SetList(string(common.WaitingList), false) _ = vi.Add(validatorWaiting) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) @@ -2306,11 +2306,11 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochV2ComputesEligibleLe vi := state.NewShardValidatorsInfoMap() validatorLeaving := createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) - validatorLeaving.SetList(string(common.LeavingList)) + validatorLeaving.SetList(string(common.LeavingList), false) _ = vi.Add(validatorLeaving) validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) - validatorWaiting.SetList(string(common.WaitingList)) + validatorWaiting.SetList(string(common.WaitingList), false) _ = vi.Add(validatorWaiting) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 7325926075f..4954ebd632e 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -914,23 +914,23 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { args.AuctionListSelector = &stakingcommon.AuctionListSelectorStub{ SelectNodesFromAuctionListCalled: func(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { selectedV1 := v1.ShallowClone() - selectedV1.SetList(string(common.SelectedFromAuctionList)) + selectedV1.SetList(string(common.SelectedFromAuctionList), false) _ = validatorsInfoMap.Replace(v1, selectedV1) selectedV2 := v2.ShallowClone() - selectedV2.SetList(string(common.SelectedFromAuctionList)) + selectedV2.SetList(string(common.SelectedFromAuctionList), false) _ = validatorsInfoMap.Replace(v2, selectedV2) selectedV3 := v3.ShallowClone() - selectedV3.SetList(string(common.SelectedFromAuctionList)) + selectedV3.SetList(string(common.SelectedFromAuctionList), false) _ = validatorsInfoMap.Replace(v3, selectedV3) selectedV5 := v5.ShallowClone() - selectedV5.SetList(string(common.SelectedFromAuctionList)) + selectedV5.SetList(string(common.SelectedFromAuctionList), false) _ = validatorsInfoMap.Replace(v5, selectedV5) selectedV12 := v12.ShallowClone() - selectedV12.SetList(string(common.SelectedFromAuctionList)) + selectedV12.SetList(string(common.SelectedFromAuctionList), false) _ = validatorsInfoMap.Replace(v12, selectedV12) return nil diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index 4cff2ab4794..7132e7f2f2a 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -238,13 +238,13 @@ func (stp *stakingToPeer) updatePeerStateV1( if !isJailed { if stakingData.StakedNonce == nonce && !isValidator { - account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.RegisterNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.RegisterNonce), stp.enableEpochsHandler.IsStakingV4Started()) account.SetTempRating(stp.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) } if stakingData.UnStakedNonce == nonce && account.GetList() != string(common.InactiveList) { - account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce), stp.enableEpochsHandler.IsStakingV4Started()) account.SetUnStakedEpoch(stakingData.UnStakedEpoch) } } @@ -255,7 +255,7 @@ func (stp *stakingToPeer) updatePeerStateV1( } if !isValidator && account.GetUnStakedEpoch() == common.DefaultUnstakedEpoch { - account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.UnJailedNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) } } @@ -285,7 +285,7 @@ func (stp *stakingToPeer) updatePeerState( stakingData.UnJailedNonce == nonce && account.GetList() == string(common.JailedList) if isUnJailForInactive { log.Debug("unJail for inactive node changed status to inactive list", "blsKey", account.GetBLSPublicKey(), "unStakedEpoch", stakingData.UnStakedEpoch) - account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) if account.GetTempRating() < stp.unJailRating { account.SetTempRating(stp.unJailRating) } @@ -331,14 +331,14 @@ func (stp *stakingToPeer) updatePeerState( if !stakingData.Jailed { if stakingData.StakedNonce == nonce && !isValidator { log.Debug("node is staked, changed status to", "list", newNodesList, "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.StakedNonce)) + account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.StakedNonce), stp.enableEpochsHandler.IsStakingV4Started()) account.SetTempRating(stp.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) } if stakingData.UnStakedNonce == nonce && account.GetList() != string(common.InactiveList) { log.Debug("node is unStaked, changed status to leaving list", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce), stp.enableEpochsHandler.IsStakingV4Started()) account.SetUnStakedEpoch(stakingData.UnStakedEpoch) } } @@ -352,19 +352,19 @@ func (stp *stakingToPeer) updatePeerState( isNewValidator := !isValidator && stakingData.Staked if isNewValidator { log.Debug("node is unJailed and staked, changing status to", "list", newNodesList, "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.UnJailedNonce)) + account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) } if account.GetList() == string(common.JailedList) { log.Debug("node is unJailed and not staked, changing status to inactive list", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) account.SetUnStakedEpoch(stakingData.UnStakedEpoch) } } if stakingData.JailedNonce == nonce && account.GetList() != string(common.InactiveList) { log.Debug("node is jailed, setting status to leaving", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.JailedNonce)) + account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.JailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) account.SetTempRating(stp.jailRating) } diff --git a/process/scToProtocol/stakingToPeer_test.go b/process/scToProtocol/stakingToPeer_test.go index 7355788289d..bf3e712a90a 100644 --- a/process/scToProtocol/stakingToPeer_test.go +++ b/process/scToProtocol/stakingToPeer_test.go @@ -700,7 +700,7 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) assert.Equal(t, string(common.LeavingList), peerAccount.GetList()) - peerAccount.SetListAndIndex(0, string(common.EligibleList), 5) + peerAccount.SetListAndIndex(0, string(common.EligibleList), 5, false) stakingData.JailedNonce = 12 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.JailedNonce) assert.Equal(t, string(common.LeavingList), peerAccount.GetList()) @@ -768,7 +768,7 @@ func TestStakingToPeer_UnJailFromInactive(t *testing.T) { _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) assert.Equal(t, string(common.LeavingList), peerAccount.GetList()) - peerAccount.SetListAndIndex(0, string(common.JailedList), 5) + peerAccount.SetListAndIndex(0, string(common.JailedList), 5, false) stakingData.UnJailedNonce = 14 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.Equal(t, string(common.InactiveList), peerAccount.GetList()) diff --git a/state/interface.go b/state/interface.go index d4c44c3b94b..024a18b9113 100644 --- a/state/interface.go +++ b/state/interface.go @@ -50,7 +50,7 @@ type PeerAccountHandler interface { GetTotalLeaderSuccessRate() SignRate GetTotalValidatorSuccessRate() SignRate GetTotalValidatorIgnoredSignaturesRate() uint32 - SetListAndIndex(shardID uint32, list string, index uint32) + SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousList bool) GetRating() uint32 SetRating(uint32) GetTempRating() uint32 @@ -260,7 +260,7 @@ type ValidatorInfoHandler interface { SetPublicKey(publicKey []byte) SetShardId(shardID uint32) - SetList(list string) + SetList(list string, updatePreviousList bool) SetIndex(index uint32) SetTempRating(tempRating uint32) SetRating(rating uint32) diff --git a/state/peerAccount.go b/state/peerAccount.go index a9f73fc4d6e..1f361602ba6 100644 --- a/state/peerAccount.go +++ b/state/peerAccount.go @@ -108,9 +108,12 @@ func (pa *peerAccount) SetTempRating(rating uint32) { } // SetListAndIndex will update the peer's list (eligible, waiting) and the index inside it with journal -func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32) { +func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousList bool) { + if updatePreviousList { + pa.PreviousList = pa.List + } + pa.ShardId = shardID - pa.PreviousList = pa.List pa.List = list pa.IndexInList = index } diff --git a/state/validatorInfo.go b/state/validatorInfo.go index f9779188f65..040c6efba4c 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -15,8 +15,11 @@ func (vi *ValidatorInfo) SetPublicKey(publicKey []byte) { } // SetList sets validator's list -func (vi *ValidatorInfo) SetList(list string) { - vi.PreviousList = vi.List +func (vi *ValidatorInfo) SetList(list string, updatePreviousList bool) { + if updatePreviousList { + vi.PreviousList = vi.List + } + vi.List = list } From 8b986163d69a562c0551ba6e397be86972e6c127 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 6 Feb 2023 15:37:39 +0200 Subject: [PATCH 403/958] FIX: computeNodesConfig in nodes coordinator --- .../indexHashedNodesCoordinator.go | 37 ++++---- .../indexHashedNodesCoordinatorLite.go | 2 +- .../indexHashedNodesCoordinator_test.go | 87 ++++--------------- 3 files changed, 33 insertions(+), 93 deletions(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 6e548b98462..227caf71d88 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -629,7 +629,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa ihnc.mutNodesConfig.RUnlock() // TODO: compare with previous nodesConfig if exists - newNodesConfig, err := ihnc.computeNodesConfigFromList(copiedPrevious, allValidatorInfo) + newNodesConfig, err := ihnc.computeNodesConfigFromList(allValidatorInfo) if err != nil { log.Error("could not compute nodes config from list - do nothing on nodesCoordinator epochStartPrepare") return @@ -744,7 +744,6 @@ func (ihnc *indexHashedNodesCoordinator) GetChance(_ uint32) uint32 { } func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( - previousEpochConfig *epochNodesConfig, validatorInfos []*state.ShardValidatorInfo, ) (*epochNodesConfig, error) { eligibleMap := make(map[uint32][]Validator) @@ -752,11 +751,6 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( leavingMap := make(map[uint32][]Validator) newNodesList := make([]Validator, 0) auctionList := make([]Validator, 0) - - if ihnc.flagStakingV4Started.IsSet() && previousEpochConfig == nil { - return nil, ErrNilPreviousEpochConfig - } - if len(validatorInfos) == 0 { log.Warn("computeNodesConfigFromList - validatorInfos len is 0") } @@ -774,15 +768,16 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.EligibleList): eligibleMap[validatorInfo.ShardId] = append(eligibleMap[validatorInfo.ShardId], currentValidator) case string(common.LeavingList): - log.Debug("leaving node validatorInfo", "pk", validatorInfo.PublicKey) + log.Debug("leaving node validatorInfo", + "pk", validatorInfo.PublicKey, + "previous list", validatorInfo.PreviousList, + "shardId", validatorInfo.ShardId) leavingMap[validatorInfo.ShardId] = append(leavingMap[validatorInfo.ShardId], currentValidator) ihnc.addValidatorToPreviousMap( - previousEpochConfig, eligibleMap, waitingMap, currentValidator, - validatorInfo.ShardId, - validatorInfo.PreviousList, + validatorInfo, ) case string(common.NewList): if ihnc.flagStakingV4.IsSet() { @@ -834,33 +829,31 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( } func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( - previousEpochConfig *epochNodesConfig, eligibleMap map[uint32][]Validator, waitingMap map[uint32][]Validator, currentValidator *validator, - currentValidatorShardId uint32, - previousList string, + validatorInfo *state.ShardValidatorInfo, ) { + shardId := validatorInfo.ShardId if !ihnc.flagStakingV4Started.IsSet() { - eligibleMap[currentValidatorShardId] = append(eligibleMap[currentValidatorShardId], currentValidator) + eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) return } - found, shardId := searchInMap(previousEpochConfig.eligibleMap, currentValidator.PubKey()) - if found { + previousList := validatorInfo.PreviousList + if previousList == string(common.EligibleList) { log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) - eligibleMap[shardId] = append(eligibleMap[currentValidatorShardId], currentValidator) + eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) return } - found, shardId = searchInMap(previousEpochConfig.waitingMap, currentValidator.PubKey()) - if found { + if previousList == string(common.WaitingList) { log.Debug("leaving node found in", "list", "waiting", "shardId", shardId) - waitingMap[shardId] = append(waitingMap[currentValidatorShardId], currentValidator) + waitingMap[shardId] = append(waitingMap[shardId], currentValidator) return } - log.Debug("leaving node not in eligible or waiting, probably was in auction/inactive/jailed", + log.Debug("leaving node not in eligible or waiting", "previous list", previousList, "pk", currentValidator.PubKey(), "shardId", shardId) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go index 42d539956e2..3b80e8bdd23 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorLite.go @@ -6,7 +6,7 @@ import ( // SetNodesConfigFromValidatorsInfo sets epoch config based on validators list configuration func (ihnc *indexHashedNodesCoordinator) SetNodesConfigFromValidatorsInfo(epoch uint32, randomness []byte, validatorsInfo []*state.ShardValidatorInfo) error { - newNodesConfig, err := ihnc.computeNodesConfigFromList(&epochNodesConfig{}, validatorsInfo) + newNodesConfig, err := ihnc.computeNodesConfigFromList(validatorsInfo) if err != nil { return err } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 5241f086ee9..f841d696460 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -2039,27 +2039,6 @@ func TestIndexHashedNodesCoordinator_ShuffleOutNilConfig(t *testing.T) { require.Equal(t, expectedShardForNotFound, newShard) } -func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNilPreviousNodesConfig(t *testing.T) { - t.Parallel() - - arguments := createArguments() - pk := []byte("pk") - arguments.SelfPublicKey = pk - ihnc, _ := NewIndexHashedNodesCoordinator(arguments) - ihnc.flagStakingV4Started.SetReturningPrevious() - - validatorInfos := make([]*state.ShardValidatorInfo, 0) - - newNodesConfig, err := ihnc.computeNodesConfigFromList(nil, validatorInfos) - assert.Nil(t, newNodesConfig) - assert.True(t, errors.Is(err, ErrNilPreviousEpochConfig)) - - newNodesConfig, err = ihnc.computeNodesConfigFromList(nil, nil) - - assert.Nil(t, newNodesConfig) - assert.True(t, errors.Is(err, ErrNilPreviousEpochConfig)) -} - func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNoValidators(t *testing.T) { t.Parallel() @@ -2069,12 +2048,12 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNoValidators(t *t ihnc, _ := NewIndexHashedNodesCoordinator(arguments) validatorInfos := make([]*state.ShardValidatorInfo, 0) - newNodesConfig, err := ihnc.computeNodesConfigFromList(&epochNodesConfig{}, validatorInfos) + newNodesConfig, err := ihnc.computeNodesConfigFromList(validatorInfos) assert.Nil(t, newNodesConfig) assert.True(t, errors.Is(err, ErrMapSizeZero)) - newNodesConfig, err = ihnc.computeNodesConfigFromList(&epochNodesConfig{}, nil) + newNodesConfig, err = ihnc.computeNodesConfigFromList(nil) assert.Nil(t, newNodesConfig) assert.True(t, errors.Is(err, ErrMapSizeZero)) @@ -2106,7 +2085,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListNilPk(t *testing. }, } - newNodesConfig, err := ihnc.computeNodesConfigFromList(&epochNodesConfig{}, validatorInfos) + newNodesConfig, err := ihnc.computeNodesConfigFromList(validatorInfos) assert.Nil(t, newNodesConfig) assert.NotNil(t, err) @@ -2141,21 +2120,13 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * } validatorInfos := []*state.ShardValidatorInfo{shard0Eligible, shard0Auction, shard1Auction} - previousConfig := &epochNodesConfig{ - eligibleMap: map[uint32][]Validator{ - 0: { - newValidatorMock(shard0Eligible.PublicKey, 0, 0), - }, - }, - } - - newNodesConfig, err := nc.computeNodesConfigFromList(previousConfig, validatorInfos) + newNodesConfig, err := nc.computeNodesConfigFromList(validatorInfos) require.Equal(t, ErrReceivedAuctionValidatorsBeforeStakingV4, err) require.Nil(t, newNodesConfig) nc.updateEpochFlags(stakingV4Epoch) - newNodesConfig, err = nc.computeNodesConfigFromList(previousConfig, validatorInfos) + newNodesConfig, err = nc.computeNodesConfigFromList(validatorInfos) require.Nil(t, err) v1, _ := NewValidator([]byte("pk2"), 1, 2) v2, _ := NewValidator([]byte("pk1"), 1, 3) @@ -2165,7 +2136,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListWithStakingV4(t * PublicKey: []byte("pk3"), List: string(common.NewList), }) - newNodesConfig, err = nc.computeNodesConfigFromList(previousConfig, validatorInfos) + newNodesConfig, err = nc.computeNodesConfigFromList(validatorInfos) require.Equal(t, epochStart.ErrReceivedNewListNodeInStakingV4, err) require.Nil(t, newNodesConfig) } @@ -2218,15 +2189,17 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix ShardId: 0, } shard0Leaving0 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk6"), - List: string(common.LeavingList), - ShardId: 0, + PublicKey: []byte("pk6"), + List: string(common.LeavingList), + PreviousList: string(common.EligibleList), + ShardId: 0, } shardMetaLeaving1 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk7"), - List: string(common.LeavingList), - Index: 1, - ShardId: core.MetachainShardId, + PublicKey: []byte("pk7"), + List: string(common.LeavingList), + PreviousList: string(common.WaitingList), + Index: 1, + ShardId: core.MetachainShardId, } validatorInfos := @@ -2241,29 +2214,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix shardMetaLeaving1, } - previousConfig := &epochNodesConfig{ - eligibleMap: map[uint32][]Validator{ - 0: { - newValidatorMock(shard0Eligible0.PublicKey, 0, 0), - newValidatorMock(shard0Eligible1.PublicKey, 0, 0), - newValidatorMock(shard0Leaving0.PublicKey, 0, 0), - }, - core.MetachainShardId: { - newValidatorMock(shardmetaEligible0.PublicKey, 0, 0), - }, - }, - waitingMap: map[uint32][]Validator{ - 0: { - newValidatorMock(shard0Waiting0.PublicKey, 0, 0), - }, - core.MetachainShardId: { - newValidatorMock(shardmetaWaiting0.PublicKey, 0, 0), - newValidatorMock(shardMetaLeaving1.PublicKey, 0, 0), - }, - }, - } - - newNodesConfig, err := ihnc.computeNodesConfigFromList(previousConfig, validatorInfos) + newNodesConfig, err := ihnc.computeNodesConfigFromList(validatorInfos) assert.Nil(t, err) assert.Equal(t, uint32(1), newNodesConfig.nbShards) @@ -2357,10 +2308,6 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsNoFix(t ShardId: core.MetachainShardId, } - previousConfig := &epochNodesConfig{ - eligibleMap: map[uint32][]Validator{}, - } - validatorInfos := []*state.ShardValidatorInfo{ shard0Eligible0, @@ -2374,7 +2321,7 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsNoFix(t } ihnc.flagStakingV4Started.Reset() - newNodesConfig, err := ihnc.computeNodesConfigFromList(previousConfig, validatorInfos) + newNodesConfig, err := ihnc.computeNodesConfigFromList(validatorInfos) assert.Nil(t, err) assert.Equal(t, uint32(1), newNodesConfig.nbShards) From 6aa5d087ffe52dfd0191ab2c51b17a8186629941 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 6 Feb 2023 16:08:13 +0200 Subject: [PATCH 404/958] FIX: Delete previous config --- .../indexHashedNodesCoordinator.go | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 227caf71d88..2be7369c2ee 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -591,7 +591,8 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa return } - if _, ok := metaHdr.(*block.MetaBlock); !ok { + metaBlock, castOk := metaHdr.(*block.MetaBlock) + if !castOk { log.Error("could not process EpochStartPrepare on nodesCoordinator - not metaBlock") return } @@ -612,22 +613,6 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa return } - ihnc.mutNodesConfig.RLock() - previousConfig := ihnc.nodesConfig[ihnc.currentEpoch] - if previousConfig == nil { - log.Error("previous nodes config is nil") - ihnc.mutNodesConfig.RUnlock() - return - } - - // TODO: remove the copy if no changes are done to the maps - copiedPrevious := &epochNodesConfig{} - copiedPrevious.eligibleMap = copyValidatorMap(previousConfig.eligibleMap) - copiedPrevious.waitingMap = copyValidatorMap(previousConfig.waitingMap) - copiedPrevious.nbShards = previousConfig.nbShards - - ihnc.mutNodesConfig.RUnlock() - // TODO: compare with previous nodesConfig if exists newNodesConfig, err := ihnc.computeNodesConfigFromList(allValidatorInfo) if err != nil { @@ -635,10 +620,11 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa return } - if copiedPrevious.nbShards != newNodesConfig.nbShards { + prevNumOfShards := uint32(len(metaBlock.ShardInfo)) + if prevNumOfShards != newNodesConfig.nbShards { log.Warn("number of shards does not match", "previous epoch", ihnc.currentEpoch, - "previous number of shards", copiedPrevious.nbShards, + "previous number of shards", prevNumOfShards, "new epoch", newEpoch, "new number of shards", newNodesConfig.nbShards) } From e0fe9741dd46989b83761346fd0595374af87a5c Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 7 Feb 2023 16:56:02 +0200 Subject: [PATCH 405/958] FIX: Rename enable epochs to steps --- cmd/node/config/enableEpochs.toml | 15 +++--- common/enablers/enableEpochsHandler.go | 18 +++---- common/enablers/enableEpochsHandler_test.go | 8 ++-- common/interface.go | 2 +- config/epochConfig.go | 6 +-- epochStart/bootstrap/process_test.go | 2 +- epochStart/bootstrap/syncValidatorStatus.go | 2 +- .../metachain/auctionListSelector_test.go | 2 +- .../metachain/stakingDataProvider_test.go | 4 +- epochStart/metachain/systemSCs_test.go | 10 ++-- factory/bootstrap/bootstrapComponents.go | 2 +- factory/bootstrap/shardingFactory.go | 4 +- genesis/process/shardGenesisBlockCreator.go | 6 +-- .../consensusComponents_test.go | 2 +- .../heartbeatComponents_test.go | 2 +- .../processComponents_test.go | 2 +- .../statusComponents/statusComponents_test.go | 2 +- ...nsactionsInMultiShardedEnvironment_test.go | 12 ++--- ...ansactionInMultiShardedEnvironment_test.go | 12 ++--- .../startInEpoch/startInEpoch_test.go | 14 +++--- .../multiShard/softfork/scDeploy_test.go | 6 +-- integrationTests/nodesCoordinatorFactory.go | 2 +- integrationTests/testConsensusNode.go | 2 +- integrationTests/testInitializer.go | 12 ++--- integrationTests/testProcessorNode.go | 6 +-- .../testProcessorNodeWithCoordinator.go | 32 ++++++------- .../testProcessorNodeWithMultisigner.go | 18 +++---- .../vm/staking/baseTestMetaProcessor.go | 10 ++-- .../vm/staking/componentsHolderCreator.go | 10 ++-- .../vm/staking/nodesCoordiantorCreator.go | 6 +-- integrationTests/vm/staking/stakingV4_test.go | 4 +- .../vm/staking/testMetaProcessor.go | 2 +- .../vm/systemVM/stakingSC_test.go | 12 ++--- .../vm/txsFee/validatorSC_test.go | 22 ++++----- node/nodeRunner.go | 8 ++-- process/peer/process_test.go | 6 +-- sharding/mock/enableEpochsHandlerMock.go | 4 +- .../nodesCoordinator/hashValidatorShuffler.go | 48 +++++++++---------- .../hashValidatorShuffler_test.go | 38 +++++++-------- .../indexHashedNodesCoordinator.go | 6 +-- .../indexHashedNodesCoordinatorRegistry.go | 2 +- .../indexHashedNodesCoordinator_test.go | 2 +- .../nodesCoordinatorRegistryFactory.go | 12 ++--- sharding/nodesCoordinator/shardingArgs.go | 2 +- testscommon/enableEpochsHandlerStub.go | 8 ++-- 45 files changed, 204 insertions(+), 203 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 13ba9714745..cb6f536d10d 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -242,22 +242,23 @@ # StakeLimitsEnableEpoch represents the epoch when stake limits on validators are enabled StakeLimitsEnableEpoch = 5 - # StakingV4InitEnableEpoch represents the epoch when staking v4 is initialized. This is the epoch in which + # StakingV4Step1EnableEpoch represents the epoch when staking v4 is initialized. This is the epoch in which # all nodes from staking queue are moved in the auction list - StakingV4InitEnableEpoch = 4 + StakingV4Step1EnableEpoch = 4 - # StakingV4EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4InitEnableEpoch - StakingV4EnableEpoch = 5 + # StakingV4Step2EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4Step1EnableEpoch. + In this epoch, all shuffled out nodes are moved to auction nodes. No auction nodes selection is done yet. + StakingV4Step2EnableEpoch = 5 - # StakingV4DistributeAuctionToWaitingEpoch represents the epoch in which selected nodes from auction will be distributed to waiting list - StakingV4DistributeAuctionToWaitingEpoch = 6 + # StakingV4Step3EnableEpoch represents the epoch in which selected nodes from auction will be distributed to waiting list + StakingV4Step3EnableEpoch = 6 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 }, # Staking v4 configuration, where: - # - Enable epoch = StakingV4DistributeAuctionToWaitingEpoch + # - Enable epoch = StakingV4Step3EnableEpoch # - NodesToShufflePerShard = same as previous entry in MaxNodesChangeEnableEpoch # - MaxNumNodes = (MaxNumNodesFromPreviousEpochEnable - (numOfShards+1)*NodesToShufflePerShard) { EpochEnable = 6, MaxNumNodes = 48, NodesToShufflePerShard = 2 }, diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 3d53d3eae15..0cfcd74ca7e 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -116,11 +116,11 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.WipeSingleNFTLiquidityDecreaseEnableEpoch, handler.wipeSingleNFTLiquidityDecreaseFlag, "wipeSingleNFTLiquidityDecreaseFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.AlwaysSaveTokenMetaDataEnableEpoch, handler.alwaysSaveTokenMetaDataFlag, "alwaysSaveTokenMetaDataFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakeLimitsEnableEpoch, handler.stakeLimitsFlag, "stakeLimitsFlag") - handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4InitFlag, "stakingV4InitFlag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4EnableEpoch, handler.stakingV4Flag, "stakingV4Flag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") - handler.setFlagValue(epoch < handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingQueueEnabledFlag, "stakingQueueEnabledFlag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4InitEnableEpoch, handler.stakingV4StartedFlag, "stakingV4StartedFlag") + handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingV4InitFlag, "stakingV4InitFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step2EnableEpoch, handler.stakingV4Flag, "stakingV4Flag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step3EnableEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") + handler.setFlagValue(epoch < handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingQueueEnabledFlag, "stakingQueueEnabledFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingV4StartedFlag, "stakingV4StartedFlag") } func (handler *enableEpochsHandler) setFlagValue(value bool, flag *atomic.Flag, flagName string) { @@ -213,14 +213,14 @@ func (handler *enableEpochsHandler) RefactorPeersMiniBlocksEnableEpoch() uint32 return handler.enableEpochsConfig.RefactorPeersMiniBlocksEnableEpoch } -// StakingV4EnableEpoch returns the epoch when stakingV4 becomes active -func (handler *enableEpochsHandler) StakingV4EnableEpoch() uint32 { - return handler.enableEpochsConfig.StakingV4EnableEpoch +// StakingV4Step2EnableEpoch returns the epoch when stakingV4 becomes active +func (handler *enableEpochsHandler) StakingV4Step2EnableEpoch() uint32 { + return handler.enableEpochsConfig.StakingV4Step2EnableEpoch } // StakingV4InitEpoch returns the epoch when stakingV4 phase1 becomes active func (handler *enableEpochsHandler) StakingV4InitEpoch() uint32 { - return handler.enableEpochsConfig.StakingV4InitEnableEpoch + return handler.enableEpochsConfig.StakingV4Step1EnableEpoch } // IsInterfaceNil returns true if there is no value under the interface diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 4f4af75f8e7..9ee00bac94d 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -89,9 +89,9 @@ func createEnableEpochsConfig() config.EnableEpochs { WipeSingleNFTLiquidityDecreaseEnableEpoch: 75, AlwaysSaveTokenMetaDataEnableEpoch: 76, StakeLimitsEnableEpoch: 77, - StakingV4InitEnableEpoch: 78, - StakingV4EnableEpoch: 79, - StakingV4DistributeAuctionToWaitingEpoch: 80, + StakingV4Step1EnableEpoch: 78, + StakingV4Step2EnableEpoch: 79, + StakingV4Step3EnableEpoch: 80, } } @@ -227,7 +227,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { cfg.ESDTEnableEpoch = epoch cfg.GovernanceEnableEpoch = epoch cfg.CorrectLastUnjailedEnableEpoch = epoch - cfg.StakingV4InitEnableEpoch = epoch + cfg.StakingV4Step1EnableEpoch = epoch handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) require.False(t, check.IfNil(handler)) diff --git a/common/interface.go b/common/interface.go index c0940a65a75..4fd8fe8206e 100644 --- a/common/interface.go +++ b/common/interface.go @@ -242,7 +242,7 @@ type EnableEpochsHandler interface { StorageAPICostOptimizationEnableEpoch() uint32 MiniBlockPartialExecutionEnableEpoch() uint32 RefactorPeersMiniBlocksEnableEpoch() uint32 - StakingV4EnableEpoch() uint32 + StakingV4Step2EnableEpoch() uint32 StakingV4InitEpoch() uint32 IsSCDeployFlagEnabled() bool IsBuiltInFunctionsFlagEnabled() bool diff --git a/config/epochConfig.go b/config/epochConfig.go index 4a09774615a..05fa063afc8 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -92,9 +92,9 @@ type EnableEpochs struct { AlwaysSaveTokenMetaDataEnableEpoch uint32 BLSMultiSignerEnableEpoch []MultiSignerConfig StakeLimitsEnableEpoch uint32 - StakingV4InitEnableEpoch uint32 - StakingV4EnableEpoch uint32 - StakingV4DistributeAuctionToWaitingEpoch uint32 + StakingV4Step1EnableEpoch uint32 + StakingV4Step2EnableEpoch uint32 + StakingV4Step3EnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index 61f074515c5..dd4f97c1790 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -78,7 +78,7 @@ func createComponentsForEpochStart() (*mock.CoreComponentsMock, *mock.CryptoComp ProcessStatusHandlerInstance: &testscommon.ProcessStatusHandlerStub{}, HardforkTriggerPubKeyField: []byte("provided hardfork pub key"), EnableEpochsHandlerField: &testscommon.EnableEpochsHandlerStub{ - StakingV4EnableEpochField: 99999, + StakingV4Step2EnableEpochField: 99999, }, }, &mock.CryptoComponentsMock{ diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index 8a0c307b901..b8460a23fc7 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -132,7 +132,7 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat EnableEpochsHandler: args.EnableEpochsHandler, ValidatorInfoCacher: s.dataPool.CurrentEpochValidatorInfo(), NodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: args.EnableEpochsHandler.StakingV4EnableEpoch(), + StakingV4Step2EnableEpoch: args.EnableEpochsHandler.StakingV4Step2EnableEpoch(), } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 15f1b960708..5bbe9777654 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -49,7 +49,7 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) argsSystemSC.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ - EpochField: stakingV4EnableEpoch, + EpochField: stakingV4Step2EnableEpoch, }) argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider return AuctionListSelectorArgs{ diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index abd134fcc2c..8b31bd621ef 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -23,8 +23,8 @@ import ( "github.com/stretchr/testify/require" ) -const stakingV4InitEnableEpoch = 444 -const stakingV4EnableEpoch = 445 +const stakingV4Step1EnableEpoch = 444 +const stakingV4Step2EnableEpoch = 445 func createStakingDataProviderArgs() StakingDataProviderArgs { return StakingDataProviderArgs{ diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index d26cb00c9f4..5eeccd0eb68 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -745,8 +745,8 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp peerAccountsDB := createAccountsDB(hasher, marshalizer, factory.NewPeerAccountCreator(), trieFactoryManager) en := forking.NewGenericEpochNotifier() enableEpochsConfig.StakeLimitsEnableEpoch = 10 - enableEpochsConfig.StakingV4InitEnableEpoch = 444 - enableEpochsConfig.StakingV4EnableEpoch = 445 + enableEpochsConfig.StakingV4Step1EnableEpoch = 444 + enableEpochsConfig.StakingV4Step2EnableEpoch = 445 epochsConfig := &config.EpochConfig{ EnableEpochs: enableEpochsConfig, } @@ -1772,7 +1772,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) _ = validatorsInfo.Add(createValidatorInfo(owner1ListPubKeysStaked[1], common.WaitingList, "", 0, owner1)) _ = validatorsInfo.Add(createValidatorInfo(owner2ListPubKeysStaked[0], common.EligibleList, "", 1, owner2)) - args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4InitEnableEpoch}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4Step1EnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Nil(t, err) @@ -1818,7 +1818,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa _ = validatorsInfo.Add(createValidatorInfo(ownerStakedKeys[1], common.AuctionList, "", 0, owner)) s, _ := NewSystemSCProcessor(args) - s.EpochConfirmed(stakingV4EnableEpoch, 0) + s.EpochConfirmed(stakingV4Step2EnableEpoch, 0) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) require.Equal(t, errProcessStakingData, err) @@ -1893,7 +1893,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing _ = validatorsInfo.Add(createValidatorInfo(owner7StakedKeys[1], common.EligibleList, "", 2, owner7)) s, _ := NewSystemSCProcessor(args) - args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4EnableEpoch}) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4Step2EnableEpoch}) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{PrevRandSeed: []byte("pubKey7")}) require.Nil(t, err) diff --git a/factory/bootstrap/bootstrapComponents.go b/factory/bootstrap/bootstrapComponents.go index dd2f7cb059c..e99b5ab8f80 100644 --- a/factory/bootstrap/bootstrapComponents.go +++ b/factory/bootstrap/bootstrapComponents.go @@ -183,7 +183,7 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory( bcf.coreComponents.InternalMarshalizer(), - bcf.coreComponents.EnableEpochsHandler().StakingV4EnableEpoch(), + bcf.coreComponents.EnableEpochsHandler().StakingV4Step2EnableEpoch(), ) if err != nil { return nil, err diff --git a/factory/bootstrap/shardingFactory.go b/factory/bootstrap/shardingFactory.go index 518ce1cb697..342cde72561 100644 --- a/factory/bootstrap/shardingFactory.go +++ b/factory/bootstrap/shardingFactory.go @@ -108,7 +108,7 @@ func CreateNodesCoordinator( enableEpochsHandler common.EnableEpochsHandler, validatorInfoCacher epochStart.ValidatorInfoCacher, nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, - stakingV4EnableEpoch uint32, + stakingV4Step2EnableEpoch uint32, ) (nodesCoordinator.NodesCoordinator, error) { if chanNodeStop == nil { return nil, nodesCoordinator.ErrNilNodeStopChannel @@ -200,7 +200,7 @@ func CreateNodesCoordinator( EnableEpochsHandler: enableEpochsHandler, ValidatorInfoCacher: validatorInfoCacher, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index fde639983f0..d96562d98cb 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -138,9 +138,9 @@ func createGenesisConfig() config.EnableEpochs { MaxBlockchainHookCountersEnableEpoch: unreachableEpoch, BLSMultiSignerEnableEpoch: blsMultiSignerEnableEpoch, StakeLimitsEnableEpoch: unreachableEpoch, - StakingV4InitEnableEpoch: unreachableEpoch, - StakingV4EnableEpoch: unreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: unreachableEpoch, + StakingV4Step1EnableEpoch: unreachableEpoch, + StakingV4Step2EnableEpoch: unreachableEpoch, + StakingV4Step3EnableEpoch: unreachableEpoch, } } diff --git a/integrationTests/factory/consensusComponents/consensusComponents_test.go b/integrationTests/factory/consensusComponents/consensusComponents_test.go index babab5686bf..5ff84df3f51 100644 --- a/integrationTests/factory/consensusComponents/consensusComponents_test.go +++ b/integrationTests/factory/consensusComponents/consensusComponents_test.go @@ -69,7 +69,7 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go b/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go index 26c457375d4..6f2e8d0eaa8 100644 --- a/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go +++ b/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go @@ -69,7 +69,7 @@ func TestHeartbeatComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/processComponents/processComponents_test.go b/integrationTests/factory/processComponents/processComponents_test.go index 916a4fe6b01..17085d152e6 100644 --- a/integrationTests/factory/processComponents/processComponents_test.go +++ b/integrationTests/factory/processComponents/processComponents_test.go @@ -70,7 +70,7 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/statusComponents/statusComponents_test.go b/integrationTests/factory/statusComponents/statusComponents_test.go index 6b26de9e478..15a63ba56b4 100644 --- a/integrationTests/factory/statusComponents/statusComponents_test.go +++ b/integrationTests/factory/statusComponents/statusComponents_test.go @@ -70,7 +70,7 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go index b0b598e2f98..dd964aeb745 100644 --- a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go +++ b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment/epochStartChangeWithContinuousTransactionsInMultiShardedEnvironment_test.go @@ -20,12 +20,12 @@ func TestEpochStartChangeWithContinuousTransactionsInMultiShardedEnvironment(t * numMetachainNodes := 3 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4EnableEpoch: integrationTests.UnreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step1EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step2EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step3EnableEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go index a42a8ff246a..d14eb086de6 100644 --- a/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go +++ b/integrationTests/multiShard/endOfEpoch/epochStartChangeWithoutTransactionInMultiShardedEnvironment/epochStartChangeWithoutTransactionInMultiShardedEnvironment_test.go @@ -19,12 +19,12 @@ func TestEpochStartChangeWithoutTransactionInMultiShardedEnvironment(t *testing. numMetachainNodes := 2 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4EnableEpoch: integrationTests.UnreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step1EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step2EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step3EnableEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index a8732873ab5..fc7e4f01385 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -60,13 +60,13 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui numMetachainNodes := 3 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, - RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4EnableEpoch: integrationTests.UnreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step1EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step2EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step3EnableEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/multiShard/softfork/scDeploy_test.go b/integrationTests/multiShard/softfork/scDeploy_test.go index 4e4b9eba31e..1c15f80aa2c 100644 --- a/integrationTests/multiShard/softfork/scDeploy_test.go +++ b/integrationTests/multiShard/softfork/scDeploy_test.go @@ -34,9 +34,9 @@ func TestScDeploy(t *testing.T) { enableEpochs.SCDeployEnableEpoch = deployEnableEpoch enableEpochs.RelayedTransactionsEnableEpoch = relayedTxEnableEpoch enableEpochs.PenalizedTooMuchGasEnableEpoch = penalizedTooMuchGasEnableEpoch - enableEpochs.StakingV4InitEnableEpoch = integrationTests.StakingV4InitEpoch - enableEpochs.StakingV4EnableEpoch = integrationTests.StakingV4Epoch - enableEpochs.StakingV4DistributeAuctionToWaitingEpoch = integrationTests.StakingV4DistributeAuctionToWaiting + enableEpochs.StakingV4Step1EnableEpoch = integrationTests.StakingV4InitEpoch + enableEpochs.StakingV4Step2EnableEpoch = integrationTests.StakingV4Epoch + enableEpochs.StakingV4Step3EnableEpoch = integrationTests.StakingV4DistributeAuctionToWaiting shardNode := integrationTests.NewTestProcessorNode(integrationTests.ArgTestProcessorNode{ MaxShards: 1, diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 40f46a90edc..6b51b51fb59 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -80,7 +80,7 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd }, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Epoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) if err != nil { diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 54f0e0953fb..52592628dd6 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -303,7 +303,7 @@ func (tcn *TestConsensusNode) initNodesCoordinator( EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, - StakingV4EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Epoch, } tcn.NodesCoordinator, _ = nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 34f47443ff2..6f19c7bf319 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -1457,9 +1457,9 @@ func CreateNodesWithFullGenesis( enableEpochsConfig := GetDefaultEnableEpochsConfig() enableEpochsConfig.StakingV2EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4InitEnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4Step1EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4Step2EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4Step3EnableEpoch = UnreachableEpoch economicsConfig := createDefaultEconomicsConfig() economicsConfig.GlobalSettings.YearSettings = append( @@ -1528,9 +1528,9 @@ func CreateNodesWithCustomStateCheckpointModulus( enableEpochsConfig := GetDefaultEnableEpochsConfig() enableEpochsConfig.StakingV2EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4InitEnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4DistributeAuctionToWaitingEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4Step1EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4Step2EnableEpoch = UnreachableEpoch + enableEpochsConfig.StakingV4Step3EnableEpoch = UnreachableEpoch scm := &IntWrapper{ Value: stateCheckpointModulus, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 4a58fdb28e7..e4d5e5ff77e 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -3257,8 +3257,8 @@ func GetDefaultEnableEpochsConfig() *config.EnableEpochs { ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, FailExecutionOnEveryAPIErrorEnableEpoch: UnreachableEpoch, - StakingV4InitEnableEpoch: UnreachableEpoch, - StakingV4EnableEpoch: UnreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: UnreachableEpoch, + StakingV4Step1EnableEpoch: UnreachableEpoch, + StakingV4Step2EnableEpoch: UnreachableEpoch, + StakingV4Step3EnableEpoch: UnreachableEpoch, } } diff --git a/integrationTests/testProcessorNodeWithCoordinator.go b/integrationTests/testProcessorNodeWithCoordinator.go index b8427fd26ec..599ade701e8 100644 --- a/integrationTests/testProcessorNodeWithCoordinator.go +++ b/integrationTests/testProcessorNodeWithCoordinator.go @@ -60,22 +60,22 @@ func CreateProcessorNodesWithNodesCoordinator( for i, v := range validatorList { lruCache, _ := cache.NewLRUCache(10000) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: numShards, - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: waitingMapForNodesCoordinator, - SelfPublicKey: v.PubKeyBytes(), - ConsensusGroupCache: lruCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - IsFullArchive: false, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - StakingV4EnableEpoch: StakingV4Epoch, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: numShards, + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: waitingMapForNodesCoordinator, + SelfPublicKey: v.PubKeyBytes(), + ConsensusGroupCache: lruCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + IsFullArchive: false, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + StakingV4Step2EnableEpoch: StakingV4Epoch, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 8c03ff31ce3..30bafa4ac8a 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -230,13 +230,13 @@ func CreateNodesWithNodesCoordinatorFactory( } epochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, - RefactorPeersMiniBlocksEnableEpoch: UnreachableEpoch, - StakingV4EnableEpoch: UnreachableEpoch, - StakingV4InitEnableEpoch: UnreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: UnreachableEpoch, + StakingV2EnableEpoch: UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, + RefactorPeersMiniBlocksEnableEpoch: UnreachableEpoch, + StakingV4Step2EnableEpoch: UnreachableEpoch, + StakingV4Step1EnableEpoch: UnreachableEpoch, + StakingV4Step3EnableEpoch: UnreachableEpoch, } nodesMap := make(map[uint32][]*TestProcessorNode) @@ -438,7 +438,7 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( IsFullArchive: false, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - StakingV4EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Epoch, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -560,7 +560,7 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Epoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index c9ff341edcf..1feebf69a94 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -35,11 +35,11 @@ import ( ) const ( - stakingV4InitEpoch = 1 - stakingV4EnableEpoch = 2 - stakingV4DistributeAuctionToWaitingEpoch = 3 - addressLength = 15 - nodePrice = 1000 + stakingV4InitEpoch = 1 + stakingV4Step2EnableEpoch = 2 + stakingV4Step3EnableEpoch = 3 + addressLength = 15 + nodePrice = 1000 ) func haveTime() bool { return true } diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index ed20496a8fb..97d75a02a0a 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -61,10 +61,10 @@ func createComponentHolders(numOfShards uint32) ( func createCoreComponents() factory.CoreComponentsHolder { epochNotifier := forking.NewGenericEpochNotifier() configEnableEpochs := config.EnableEpochs{ - StakingV4EnableEpoch: stakingV4EnableEpoch, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, - RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, + StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step3EnableEpoch: stakingV4Step3EnableEpoch, + RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, } enableEpochsHandler, _ := enablers.NewEnableEpochsHandler(configEnableEpochs, epochNotifier) @@ -123,7 +123,7 @@ func createBootstrapComponents( shardCoordinator, _ := sharding.NewMultiShardCoordinator(numOfShards, core.MetachainShardId) ncr, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( marshaller, - stakingV4EnableEpoch, + stakingV4Step2EnableEpoch, ) return &mainFactoryMocks.BootstrapComponentsStub{ diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 8fa998ccb82..875eb08cef4 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -45,8 +45,8 @@ func createNodesCoordinator( ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: maxNodesConfig, EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: stakingV4EnableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: stakingV4DistributeAuctionToWaitingEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, + StakingV4Step3EnableEpoch: stakingV4Step3EnableEpoch, }, EnableEpochsHandler: coreComponents.EnableEpochsHandler(), } @@ -69,7 +69,7 @@ func createNodesCoordinator( Shuffler: nodeShuffler, BootStorer: bootStorer, EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, NodeTypeProvider: coreComponents.NodeTypeProvider(), EnableEpochsHandler: coreComponents.EnableEpochsHandler(), diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 6d9f9854cae..8aa723c4279 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -322,7 +322,7 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { NodesToShufflePerShard: 1, }, { - EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, + EpochEnable: stakingV4Step3EnableEpoch, MaxNumNodes: 10, NodesToShufflePerShard: 1, }, @@ -791,7 +791,7 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { NodesToShufflePerShard: 1, }, { - EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, + EpochEnable: stakingV4Step3EnableEpoch, MaxNumNodes: 4, NodesToShufflePerShard: 1, }, diff --git a/integrationTests/vm/staking/testMetaProcessor.go b/integrationTests/vm/staking/testMetaProcessor.go index 7a70a152d65..168287b66bc 100644 --- a/integrationTests/vm/staking/testMetaProcessor.go +++ b/integrationTests/vm/staking/testMetaProcessor.go @@ -89,7 +89,7 @@ func createMaxNodesConfig( ) maxNodesConfig = append(maxNodesConfig, config.MaxNodesChangeConfig{ - EpochEnable: stakingV4DistributeAuctionToWaitingEpoch, + EpochEnable: stakingV4Step3EnableEpoch, MaxNumNodes: totalNodes - numOfNodesToShufflePerShard*(numOfShards+1), NodesToShufflePerShard: numOfNodesToShufflePerShard, }, diff --git a/integrationTests/vm/systemVM/stakingSC_test.go b/integrationTests/vm/systemVM/stakingSC_test.go index cd18133ceb8..1da2cae905a 100644 --- a/integrationTests/vm/systemVM/stakingSC_test.go +++ b/integrationTests/vm/systemVM/stakingSC_test.go @@ -31,12 +31,12 @@ func TestStakingUnstakingAndUnbondingOnMultiShardEnvironment(t *testing.T) { numMetachainNodes := 2 enableEpochsConfig := config.EnableEpochs{ - StakingV2EnableEpoch: integrationTests.UnreachableEpoch, - ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4InitEnableEpoch: integrationTests.UnreachableEpoch, - StakingV4EnableEpoch: integrationTests.UnreachableEpoch, - StakingV4DistributeAuctionToWaitingEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step1EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step2EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step3EnableEpoch: integrationTests.UnreachableEpoch, } nodes := integrationTests.CreateNodesWithEnableEpochs( diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index dee87416715..71d03e97b49 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -30,7 +30,7 @@ const ( noTokensToUnBondMessage = "no tokens that can be unbond at this time" delegationManagementKey = "delegationManagement" stakingV4InitEpoch = 4443 - stakingV4EnableEpoch = 4444 + stakingV4Step2EnableEpoch = 4444 ) var ( @@ -110,8 +110,8 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( core.MetachainShardId, config.EnableEpochs{ - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, ) @@ -146,15 +146,15 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes func TestValidatorsSC_DoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *testing.T) { argUnbondTokensV1 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 20000, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV1) argUnbondTokensV2 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 0, - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV2) } @@ -191,8 +191,8 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens( testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( core.MetachainShardId, config.EnableEpochs{ - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, ) @@ -244,8 +244,8 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeNodesAndUnBondNodesShouldRefund(t testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( core.MetachainShardId, config.EnableEpochs{ - StakingV4InitEnableEpoch: stakingV4InitEpoch, - StakingV4EnableEpoch: stakingV4EnableEpoch, + StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, ) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 24fedbc2cff..76493b83485 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -204,9 +204,9 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("runtime memstore limit"), "epoch", enableEpochs.RuntimeMemStoreLimitEnableEpoch) log.Debug(readEpochFor("max blockchainhook counters"), "epoch", enableEpochs.MaxBlockchainHookCountersEnableEpoch) log.Debug(readEpochFor("limit validators"), "epoch", enableEpochs.StakeLimitsEnableEpoch) - log.Debug(readEpochFor("staking v4 init"), "epoch", enableEpochs.StakingV4InitEnableEpoch) - log.Debug(readEpochFor("staking v4 enable"), "epoch", enableEpochs.StakingV4EnableEpoch) - log.Debug(readEpochFor("staking v4 distribute auction to waiting"), "epoch", enableEpochs.StakingV4DistributeAuctionToWaitingEpoch) + log.Debug(readEpochFor("staking v4 init"), "epoch", enableEpochs.StakingV4Step1EnableEpoch) + log.Debug(readEpochFor("staking v4 enable"), "epoch", enableEpochs.StakingV4Step2EnableEpoch) + log.Debug(readEpochFor("staking v4 distribute auction to waiting"), "epoch", enableEpochs.StakingV4Step3EnableEpoch) gasSchedule := configs.EpochConfig.GasSchedule @@ -377,7 +377,7 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4EnableEpoch, + configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) if err != nil { return true, err diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 6b1a9439682..920f92bbc46 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2697,11 +2697,11 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t return mapNodes, nil }, } - stakingV4EnableEpochCalledCt := 0 + stakingV4Step2EnableEpochCalledCt := 0 arguments.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ IsStakingV4EnabledCalled: func() bool { - stakingV4EnableEpochCalledCt++ - switch stakingV4EnableEpochCalledCt { + stakingV4Step2EnableEpochCalledCt++ + switch stakingV4Step2EnableEpochCalledCt { case 1: return false case 2: diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 32429321a6f..ebc9eb65f70 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -86,8 +86,8 @@ func (mock *EnableEpochsHandlerMock) MiniBlockPartialExecutionEnableEpoch() uint return 0 } -// StakingV4EnableEpoch - -func (mock *EnableEpochsHandlerMock) StakingV4EnableEpoch() uint32 { +// StakingV4Step2EnableEpoch - +func (mock *EnableEpochsHandlerMock) StakingV4Step2EnableEpoch() uint32 { return 0 } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 731b86f5dc2..2fe5a2a0e46 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -52,21 +52,21 @@ type randHashShuffler struct { // when reinitialization of node in new shard is implemented shuffleBetweenShards bool - adaptivity bool - nodesShard uint32 - nodesMeta uint32 - shardHysteresis uint32 - metaHysteresis uint32 - activeNodesConfig config.MaxNodesChangeConfig - availableNodesConfigs []config.MaxNodesChangeConfig - mutShufflerParams sync.RWMutex - validatorDistributor ValidatorsDistributor - flagBalanceWaitingLists atomic.Flag - enableEpochsHandler common.EnableEpochsHandler - stakingV4DistributeAuctionToWaitingEpoch uint32 - flagStakingV4DistributeAuctionToWaiting atomic.Flag - stakingV4EnableEpoch uint32 - flagStakingV4 atomic.Flag + adaptivity bool + nodesShard uint32 + nodesMeta uint32 + shardHysteresis uint32 + metaHysteresis uint32 + activeNodesConfig config.MaxNodesChangeConfig + availableNodesConfigs []config.MaxNodesChangeConfig + mutShufflerParams sync.RWMutex + validatorDistributor ValidatorsDistributor + flagBalanceWaitingLists atomic.Flag + enableEpochsHandler common.EnableEpochsHandler + stakingV4Step3EnableEpoch uint32 + flagStakingV4DistributeAuctionToWaiting atomic.Flag + stakingV4Step2EnableEpoch uint32 + flagStakingV4 atomic.Flag } // NewHashValidatorsShuffler creates a validator shuffler that uses a hash between validator key and a given @@ -82,8 +82,8 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro var configs []config.MaxNodesChangeConfig log.Debug("hashValidatorShuffler: enable epoch for max nodes change", "epoch", args.MaxNodesEnableConfig) - log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.EnableEpochs.StakingV4EnableEpoch) - log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.EnableEpochs.StakingV4DistributeAuctionToWaitingEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.EnableEpochs.StakingV4Step2EnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.EnableEpochs.StakingV4Step3EnableEpoch) if args.MaxNodesEnableConfig != nil { configs = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) @@ -92,11 +92,11 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro log.Debug("Shuffler created", "shuffleBetweenShards", args.ShuffleBetweenShards) rxs := &randHashShuffler{ - shuffleBetweenShards: args.ShuffleBetweenShards, - availableNodesConfigs: configs, - enableEpochsHandler: args.EnableEpochsHandler, - stakingV4DistributeAuctionToWaitingEpoch: args.EnableEpochs.StakingV4DistributeAuctionToWaitingEpoch, - stakingV4EnableEpoch: args.EnableEpochs.StakingV4EnableEpoch, + shuffleBetweenShards: args.ShuffleBetweenShards, + availableNodesConfigs: configs, + enableEpochsHandler: args.EnableEpochsHandler, + stakingV4Step3EnableEpoch: args.EnableEpochs.StakingV4Step3EnableEpoch, + stakingV4Step2EnableEpoch: args.EnableEpochs.StakingV4Step2EnableEpoch, } rxs.UpdateParams(args.NodesShard, args.NodesMeta, args.Hysteresis, args.Adaptivity) @@ -789,10 +789,10 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { rhs.flagBalanceWaitingLists.SetValue(epoch >= rhs.enableEpochsHandler.BalanceWaitingListsEnableEpoch()) log.Debug("balanced waiting lists", "enabled", rhs.flagBalanceWaitingLists.IsSet()) - rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4DistributeAuctionToWaitingEpoch) + rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4Step3EnableEpoch) log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4DistributeAuctionToWaiting.IsSet()) - rhs.flagStakingV4.SetValue(epoch >= rhs.stakingV4EnableEpoch) + rhs.flagStakingV4.SetValue(epoch >= rhs.stakingV4Step2EnableEpoch) log.Debug("staking v4", "enabled", rhs.flagStakingV4.IsSet()) } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index f52d562fd5b..cae9ad879ce 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -194,8 +194,8 @@ func createHashShufflerInter() (*randHashShuffler, error) { ShuffleBetweenShards: true, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + StakingV4Step2EnableEpoch: 443, + StakingV4Step3EnableEpoch: 444, }, } @@ -212,8 +212,8 @@ func createHashShufflerIntraShards() (*randHashShuffler, error) { Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + StakingV4Step2EnableEpoch: 443, + StakingV4Step3EnableEpoch: 444, }, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } @@ -1164,17 +1164,17 @@ func TestRandHashShuffler_UpdateParams(t *testing.T) { require.Nil(t, err) shuffler2 := &randHashShuffler{ - nodesShard: 200, - nodesMeta: 200, - shardHysteresis: 0, - metaHysteresis: 0, - adaptivity: true, - shuffleBetweenShards: true, - validatorDistributor: &CrossShardValidatorDistributor{}, - availableNodesConfigs: nil, - stakingV4EnableEpoch: 443, - stakingV4DistributeAuctionToWaitingEpoch: 444, - enableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + nodesShard: 200, + nodesMeta: 200, + shardHysteresis: 0, + metaHysteresis: 0, + adaptivity: true, + shuffleBetweenShards: true, + validatorDistributor: &CrossShardValidatorDistributor{}, + availableNodesConfigs: nil, + stakingV4Step2EnableEpoch: 443, + stakingV4Step3EnableEpoch: 444, + enableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } shuffler.UpdateParams( @@ -2321,8 +2321,8 @@ func TestRandHashShuffler_UpdateNodeLists_All(t *testing.T) { Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + StakingV4Step2EnableEpoch: 443, + StakingV4Step3EnableEpoch: 444, }, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } @@ -2674,8 +2674,8 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, EnableEpochs: config.EnableEpochs{ - StakingV4EnableEpoch: 443, - StakingV4DistributeAuctionToWaitingEpoch: 444, + StakingV4Step2EnableEpoch: 443, + StakingV4Step3EnableEpoch: 444, }, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 2be7369c2ee..7be52c61b37 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -97,7 +97,7 @@ type indexHashedNodesCoordinator struct { nodeTypeProvider NodeTypeProviderHandler enableEpochsHandler common.EnableEpochsHandler validatorInfoCacher epochStart.ValidatorInfoCacher - stakingV4EnableEpoch uint32 + stakingV4Step2EnableEpoch uint32 flagStakingV4 atomicFlags.Flag nodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory flagStakingV4Started atomicFlags.Flag @@ -149,7 +149,7 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed isFullArchive: arguments.IsFullArchive, enableEpochsHandler: arguments.EnableEpochsHandler, validatorInfoCacher: arguments.ValidatorInfoCacher, - stakingV4EnableEpoch: arguments.StakingV4EnableEpoch, + stakingV4Step2EnableEpoch: arguments.StakingV4Step2EnableEpoch, nodesCoordinatorRegistryFactory: arguments.NodesCoordinatorRegistryFactory, } @@ -1283,6 +1283,6 @@ func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.StakingV4InitEpoch()) log.Debug("indexHashedNodesCoordinator: staking v4 started", "enabled", ihnc.flagStakingV4Started.IsSet()) - ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4EnableEpoch) + ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4Step2EnableEpoch) log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4.IsSet()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go index 8f15d34ff0f..0548477aa49 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go @@ -74,7 +74,7 @@ func (ihnc *indexHashedNodesCoordinator) saveState(key []byte, epoch uint32) err // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry func (ihnc *indexHashedNodesCoordinator) NodesCoordinatorToRegistry(epoch uint32) NodesCoordinatorRegistryHandler { - if epoch >= ihnc.stakingV4EnableEpoch { + if epoch >= ihnc.stakingV4Step2EnableEpoch { log.Debug("indexHashedNodesCoordinator.NodesCoordinatorToRegistry called with auction registry", "epoch", epoch) return ihnc.nodesCoordinatorToRegistryWithAuction() } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index f841d696460..ef369139e6d 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -129,7 +129,7 @@ func createArguments() ArgNodesCoordinator { IsRefactorPeersMiniBlocksFlagEnabledField: true, }, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - StakingV4EnableEpoch: stakingV4Epoch, + StakingV4Step2EnableEpoch: stakingV4Epoch, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } return arguments diff --git a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go index 72669b3ea6b..0ef508fbf89 100644 --- a/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go +++ b/sharding/nodesCoordinator/nodesCoordinatorRegistryFactory.go @@ -8,23 +8,23 @@ import ( ) type nodesCoordinatorRegistryFactory struct { - marshaller marshal.Marshalizer - stakingV4EnableEpoch uint32 + marshaller marshal.Marshalizer + stakingV4Step2EnableEpoch uint32 } // NewNodesCoordinatorRegistryFactory creates a nodes coordinator registry factory which will create a // NodesCoordinatorRegistryHandler from a buffer depending on the epoch func NewNodesCoordinatorRegistryFactory( marshaller marshal.Marshalizer, - stakingV4EnableEpoch uint32, + stakingV4Step2EnableEpoch uint32, ) (*nodesCoordinatorRegistryFactory, error) { if check.IfNil(marshaller) { return nil, ErrNilMarshalizer } return &nodesCoordinatorRegistryFactory{ - marshaller: marshaller, - stakingV4EnableEpoch: stakingV4EnableEpoch, + marshaller: marshaller, + stakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, nil } @@ -66,7 +66,7 @@ func createOldRegistry(buff []byte) (*NodesCoordinatorRegistry, error) { // GetRegistryData returns the registry data as buffer. Old version uses json marshaller, while new version uses proto marshaller func (ncf *nodesCoordinatorRegistryFactory) GetRegistryData(registry NodesCoordinatorRegistryHandler, epoch uint32) ([]byte, error) { - if epoch >= ncf.stakingV4EnableEpoch { + if epoch >= ncf.stakingV4Step2EnableEpoch { log.Debug("nodesCoordinatorRegistryFactory.GetRegistryData called with auction after staking v4", "epoch", epoch) return ncf.marshaller.Marshal(registry) } diff --git a/sharding/nodesCoordinator/shardingArgs.go b/sharding/nodesCoordinator/shardingArgs.go index fe235aea7f9..2fa91f9055a 100644 --- a/sharding/nodesCoordinator/shardingArgs.go +++ b/sharding/nodesCoordinator/shardingArgs.go @@ -32,6 +32,6 @@ type ArgNodesCoordinator struct { IsFullArchive bool EnableEpochsHandler common.EnableEpochsHandler ValidatorInfoCacher epochStart.ValidatorInfoCacher - StakingV4EnableEpoch uint32 + StakingV4Step2EnableEpoch uint32 NodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory } diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 0ed27f16115..d757356d3c9 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -25,7 +25,7 @@ type EnableEpochsHandlerStub struct { StorageAPICostOptimizationEnableEpochField uint32 MiniBlockPartialExecutionEnableEpochField uint32 RefactorPeersMiniBlocksEnableEpochField uint32 - StakingV4EnableEpochField uint32 + StakingV4Step2EnableEpochField uint32 StakingV4InitEpochField uint32 IsSCDeployFlagEnabledField bool IsBuiltInFunctionsFlagEnabledField bool @@ -1037,12 +1037,12 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Started() bool { return stub.IsStakingV4StartedField } -// StakingV4EnableEpoch - -func (stub *EnableEpochsHandlerStub) StakingV4EnableEpoch() uint32 { +// StakingV4Step2EnableEpoch - +func (stub *EnableEpochsHandlerStub) StakingV4Step2EnableEpoch() uint32 { stub.RLock() defer stub.RUnlock() - return stub.StakingV4EnableEpochField + return stub.StakingV4Step2EnableEpochField } // StakingV4InitEpoch - From 38edc35ef94df9d8c2ae5a3f6e2388bb6e48b2a6 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 7 Feb 2023 17:30:37 +0200 Subject: [PATCH 406/958] FIX: Rename stakingV4 epoch steps --- common/enablers/enableEpochsHandler.go | 6 ++-- common/enablers/epochFlags.go | 30 +++++++++---------- common/interface.go | 6 ++-- epochStart/metachain/legacySystemSCs.go | 6 ++-- epochStart/metachain/stakingDataProvider.go | 4 +-- epochStart/metachain/systemSCs.go | 4 +-- process/peer/process.go | 2 +- sharding/mock/enableEpochsHandlerMock.go | 12 ++++---- testscommon/enableEpochsHandlerStub.go | 12 ++++---- vm/systemSmartContracts/stakingWaitingList.go | 8 ++--- 10 files changed, 45 insertions(+), 45 deletions(-) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 0cfcd74ca7e..0ea423b4582 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -116,9 +116,9 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.WipeSingleNFTLiquidityDecreaseEnableEpoch, handler.wipeSingleNFTLiquidityDecreaseFlag, "wipeSingleNFTLiquidityDecreaseFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.AlwaysSaveTokenMetaDataEnableEpoch, handler.alwaysSaveTokenMetaDataFlag, "alwaysSaveTokenMetaDataFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakeLimitsEnableEpoch, handler.stakeLimitsFlag, "stakeLimitsFlag") - handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingV4InitFlag, "stakingV4InitFlag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step2EnableEpoch, handler.stakingV4Flag, "stakingV4Flag") - handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step3EnableEpoch, handler.stakingV4DistributeAuctionToWaitingFlag, "stakingV4DistributeAuctionToWaitingFlag") + handler.setFlagValue(epoch == handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingV4Step1Flag, "stakingV4Step1Flag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step2EnableEpoch, handler.stakingV4Step2Flag, "stakingV4Step2Flag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step3EnableEpoch, handler.stakingV4Step3Flag, "stakingV4Step3Flag") handler.setFlagValue(epoch < handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingQueueEnabledFlag, "stakingQueueEnabledFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.StakingV4Step1EnableEpoch, handler.stakingV4StartedFlag, "stakingV4StartedFlag") } diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index 8589c217a83..e75b93eb4b7 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -88,9 +88,9 @@ type epochFlagsHolder struct { wipeSingleNFTLiquidityDecreaseFlag *atomic.Flag alwaysSaveTokenMetaDataFlag *atomic.Flag stakeLimitsFlag *atomic.Flag - stakingV4InitFlag *atomic.Flag - stakingV4Flag *atomic.Flag - stakingV4DistributeAuctionToWaitingFlag *atomic.Flag + stakingV4Step1Flag *atomic.Flag + stakingV4Step2Flag *atomic.Flag + stakingV4Step3Flag *atomic.Flag stakingQueueEnabledFlag *atomic.Flag stakingV4StartedFlag *atomic.Flag } @@ -180,9 +180,9 @@ func newEpochFlagsHolder() *epochFlagsHolder { wipeSingleNFTLiquidityDecreaseFlag: &atomic.Flag{}, alwaysSaveTokenMetaDataFlag: &atomic.Flag{}, stakeLimitsFlag: &atomic.Flag{}, - stakingV4InitFlag: &atomic.Flag{}, - stakingV4Flag: &atomic.Flag{}, - stakingV4DistributeAuctionToWaitingFlag: &atomic.Flag{}, + stakingV4Step1Flag: &atomic.Flag{}, + stakingV4Step2Flag: &atomic.Flag{}, + stakingV4Step3Flag: &atomic.Flag{}, stakingQueueEnabledFlag: &atomic.Flag{}, stakingV4StartedFlag: &atomic.Flag{}, } @@ -656,19 +656,19 @@ func (holder *epochFlagsHolder) IsStakeLimitsFlagEnabled() bool { return holder.stakeLimitsFlag.IsSet() } -// IsStakingV4InitEnabled returns true if stakingV4InitFlag is enabled -func (holder *epochFlagsHolder) IsStakingV4InitEnabled() bool { - return holder.stakingV4InitFlag.IsSet() +// IsStakingV4Step1Enabled returns true if stakingV4Step1Flag is enabled +func (holder *epochFlagsHolder) IsStakingV4Step1Enabled() bool { + return holder.stakingV4Step1Flag.IsSet() } -// IsStakingV4Enabled returns true if stakingV4Flag is enabled -func (holder *epochFlagsHolder) IsStakingV4Enabled() bool { - return holder.stakingV4Flag.IsSet() +// IsStakingV4Step2Enabled returns true if stakingV4Step2Flag is enabled +func (holder *epochFlagsHolder) IsStakingV4Step2Enabled() bool { + return holder.stakingV4Step2Flag.IsSet() } -// IsStakingV4DistributeAuctionToWaitingEnabled returns true if stakeLimitsFlag is enabled -func (holder *epochFlagsHolder) IsStakingV4DistributeAuctionToWaitingEnabled() bool { - return holder.stakingV4DistributeAuctionToWaitingFlag.IsSet() +// IsStakingV4Step3Enabled returns true if stakingV4Step3Flag is enabled +func (holder *epochFlagsHolder) IsStakingV4Step3Enabled() bool { + return holder.stakingV4Step3Flag.IsSet() } // IsStakingQueueEnabled returns true if stakingQueueEnabledFlag is enabled diff --git a/common/interface.go b/common/interface.go index 4fd8fe8206e..f6b91721d2e 100644 --- a/common/interface.go +++ b/common/interface.go @@ -336,9 +336,9 @@ type EnableEpochsHandler interface { IsWipeSingleNFTLiquidityDecreaseEnabled() bool IsAlwaysSaveTokenMetaDataEnabled() bool IsStakeLimitsFlagEnabled() bool - IsStakingV4InitEnabled() bool - IsStakingV4Enabled() bool - IsStakingV4DistributeAuctionToWaitingEnabled() bool + IsStakingV4Step1Enabled() bool + IsStakingV4Step2Enabled() bool + IsStakingV4Step3Enabled() bool IsStakingQueueEnabled() bool IsStakingV4Started() bool diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 8c1b22fd8f2..e7594bac8db 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -172,14 +172,14 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Enabled() { + if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Step2Enabled() { err := s.cleanAdditionalQueue() if err != nil { return err } } - if s.enableEpochsHandler.IsSwitchJailWaitingFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Enabled() { + if s.enableEpochsHandler.IsSwitchJailWaitingFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Step2Enabled() { err := s.computeNumWaitingPerShard(validatorsInfoMap) if err != nil { return err @@ -191,7 +191,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsStakingV2FlagEnabled() && !s.enableEpochsHandler.IsStakingV4Enabled() { + if s.enableEpochsHandler.IsStakingV2FlagEnabled() && !s.enableEpochsHandler.IsStakingV4Step2Enabled() { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index ab3c5871183..46259d5d4c4 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -447,7 +447,7 @@ func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.Shard list := validator.GetList() pubKey := validator.GetPublicKey() - if sdp.enableEpochsHandler.IsStakingV4Enabled() && list == string(common.NewList) { + if sdp.enableEpochsHandler.IsStakingV4Step2Enabled() && list == string(common.NewList) { return nil, fmt.Errorf("%w, bls key = %s", epochStart.ErrReceivedNewListNodeInStakingV4, hex.EncodeToString(pubKey), @@ -517,7 +517,7 @@ func (sdp *stakingDataProvider) arrangeBlsKeysByStatus(mapBlsKeyStatus map[strin func (sdp *stakingDataProvider) getNewNodesList() string { newNodesList := string(common.NewList) - if sdp.enableEpochsHandler.IsStakingV4Enabled() { + if sdp.enableEpochsHandler.IsStakingV4Step2Enabled() { newNodesList = string(common.AuctionList) } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index e8a3f2c01b0..d9dc452faf2 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -115,14 +115,14 @@ func (s *systemSCProcessor) processWithNewFlags( } } - if s.enableEpochsHandler.IsStakingV4InitEnabled() { + if s.enableEpochsHandler.IsStakingV4Step1Enabled() { err := s.stakeNodesFromQueue(validatorsInfoMap, math.MaxUint32, header.GetNonce(), common.AuctionList) if err != nil { return err } } - if s.enableEpochsHandler.IsStakingV4Enabled() { + if s.enableEpochsHandler.IsStakingV4Step2Enabled() { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err diff --git a/process/peer/process.go b/process/peer/process.go index 728eb93b7ec..a5dd2168031 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -183,7 +183,7 @@ func (vs *validatorStatistics) saveNodesCoordinatorUpdates(epoch uint32) (bool, } nodeForcedToRemain = nodeForcedToRemain || tmpNodeForcedToRemain - if vs.enableEpochsHandler.IsStakingV4Enabled() { + if vs.enableEpochsHandler.IsStakingV4Step2Enabled() { nodesMap, err = vs.nodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) if err != nil { return false, err diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index ebc9eb65f70..0645fef83bf 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -555,18 +555,18 @@ func (mock *EnableEpochsHandlerMock) IsStakeLimitsFlagEnabled() bool { return false } -// IsStakingV4InitEnabled - -func (mock *EnableEpochsHandlerMock) IsStakingV4InitEnabled() bool { +// IsStakingV4Step1Enabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4Step1Enabled() bool { return false } -// IsStakingV4Enabled - -func (mock *EnableEpochsHandlerMock) IsStakingV4Enabled() bool { +// IsStakingV4Step2Enabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4Step2Enabled() bool { return false } -// IsStakingV4DistributeAuctionToWaitingEnabled - -func (mock *EnableEpochsHandlerMock) IsStakingV4DistributeAuctionToWaitingEnabled() bool { +// IsStakingV4Step3Enabled - +func (mock *EnableEpochsHandlerMock) IsStakingV4Step3Enabled() bool { return false } diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index d757356d3c9..9c16dad7ef8 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -993,16 +993,16 @@ func (stub *EnableEpochsHandlerStub) IsStakeLimitsFlagEnabled() bool { return stub.IsStakeLimitsFlagEnabledField } -// IsStakingV4InitEnabled - -func (stub *EnableEpochsHandlerStub) IsStakingV4InitEnabled() bool { +// IsStakingV4Step1Enabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4Step1Enabled() bool { stub.RLock() defer stub.RUnlock() return stub.IsStakingV4InitFlagEnabledField } -// IsStakingV4Enabled - -func (stub *EnableEpochsHandlerStub) IsStakingV4Enabled() bool { +// IsStakingV4Step2Enabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4Step2Enabled() bool { stub.RLock() defer stub.RUnlock() @@ -1013,8 +1013,8 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Enabled() bool { return stub.IsStakingV4FlagEnabledField } -// IsStakingV4DistributeAuctionToWaitingEnabled - -func (stub *EnableEpochsHandlerStub) IsStakingV4DistributeAuctionToWaitingEnabled() bool { +// IsStakingV4Step3Enabled - +func (stub *EnableEpochsHandlerStub) IsStakingV4Step3Enabled() bool { stub.RLock() defer stub.RUnlock() diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index b3d3d5f9c3f..b64bbf28996 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -458,7 +458,7 @@ func createWaitingListKey(blsKey []byte) []byte { } func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -642,7 +642,7 @@ func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) // backward compatibility return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -730,7 +730,7 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -806,7 +806,7 @@ func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcom s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4InitEnabled() { + if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } From 67ed6748da74cf4953393f0b1ef05cf70b875dc6 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 8 Feb 2023 15:57:21 +0200 Subject: [PATCH 407/958] FIX: Rename stakingV4 epoch steps --- cmd/node/config/enableEpochs.toml | 2 +- common/enablers/enableEpochsHandler.go | 4 +- common/enablers/enableEpochsHandler_test.go | 18 +-- common/interface.go | 2 +- .../metachain/stakingDataProvider_test.go | 12 +- .../multiShard/softfork/scDeploy_test.go | 6 +- integrationTests/nodesCoordinatorFactory.go | 6 +- integrationTests/testConsensusNode.go | 2 +- integrationTests/testProcessorNode.go | 12 +- .../testProcessorNodeWithCoordinator.go | 2 +- .../testProcessorNodeWithMultisigner.go | 8 +- .../vm/staking/baseTestMetaProcessor.go | 2 +- .../vm/staking/componentsHolderCreator.go | 2 +- .../vm/txsFee/validatorSC_test.go | 12 +- process/peer/process_test.go | 2 +- sharding/mock/enableEpochsHandlerMock.go | 4 +- .../nodesCoordinator/hashValidatorShuffler.go | 141 +++++++----------- .../indexHashedNodesCoordinator.go | 14 +- .../indexHashedNodesCoordinator_test.go | 2 +- testscommon/enableEpochsHandlerStub.go | 26 ++-- vm/systemSmartContracts/staking_test.go | 8 +- 21 files changed, 124 insertions(+), 163 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index cb6f536d10d..c445e2fe5c6 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -247,7 +247,7 @@ StakingV4Step1EnableEpoch = 4 # StakingV4Step2EnableEpoch represents the epoch when staking v4 is enabled. Should have a greater value than StakingV4Step1EnableEpoch. - In this epoch, all shuffled out nodes are moved to auction nodes. No auction nodes selection is done yet. + # From this epoch, all shuffled out nodes are moved to auction nodes. No auction nodes selection is done yet. StakingV4Step2EnableEpoch = 5 # StakingV4Step3EnableEpoch represents the epoch in which selected nodes from auction will be distributed to waiting list diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 0ea423b4582..fee497fb36c 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -218,8 +218,8 @@ func (handler *enableEpochsHandler) StakingV4Step2EnableEpoch() uint32 { return handler.enableEpochsConfig.StakingV4Step2EnableEpoch } -// StakingV4InitEpoch returns the epoch when stakingV4 phase1 becomes active -func (handler *enableEpochsHandler) StakingV4InitEpoch() uint32 { +// StakingV4Step1EnableEpoch returns the epoch when stakingV4 phase1 becomes active +func (handler *enableEpochsHandler) StakingV4Step1EnableEpoch() uint32 { return handler.enableEpochsConfig.StakingV4Step1EnableEpoch } diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 9ee00bac94d..87b93f39a02 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -212,9 +212,9 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.True(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) assert.True(t, handler.IsStakeLimitsFlagEnabled()) - assert.False(t, handler.IsStakingV4InitEnabled()) // epoch == limit - assert.True(t, handler.IsStakingV4Enabled()) - assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) + assert.False(t, handler.IsStakingV4Step1Enabled()) // epoch == limit + assert.True(t, handler.IsStakingV4Step2Enabled()) + assert.True(t, handler.IsStakingV4Step3Enabled()) assert.False(t, handler.IsStakingQueueEnabled()) assert.True(t, handler.IsStakingV4Started()) }) @@ -316,9 +316,9 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) assert.True(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) assert.True(t, handler.IsStakeLimitsFlagEnabled()) - assert.True(t, handler.IsStakingV4InitEnabled()) - assert.True(t, handler.IsStakingV4Enabled()) - assert.True(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) + assert.True(t, handler.IsStakingV4Step1Enabled()) + assert.True(t, handler.IsStakingV4Step2Enabled()) + assert.True(t, handler.IsStakingV4Step3Enabled()) assert.False(t, handler.IsStakingQueueEnabled()) assert.True(t, handler.IsStakingV4Started()) }) @@ -414,9 +414,9 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) assert.False(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) assert.False(t, handler.IsStakeLimitsFlagEnabled()) - assert.False(t, handler.IsStakingV4InitEnabled()) - assert.False(t, handler.IsStakingV4Enabled()) - assert.False(t, handler.IsStakingV4DistributeAuctionToWaitingEnabled()) + assert.False(t, handler.IsStakingV4Step1Enabled()) + assert.False(t, handler.IsStakingV4Step2Enabled()) + assert.False(t, handler.IsStakingV4Step3Enabled()) assert.True(t, handler.IsStakingQueueEnabled()) assert.False(t, handler.IsStakingV4Started()) }) diff --git a/common/interface.go b/common/interface.go index f6b91721d2e..99a8867f2c2 100644 --- a/common/interface.go +++ b/common/interface.go @@ -243,7 +243,7 @@ type EnableEpochsHandler interface { MiniBlockPartialExecutionEnableEpoch() uint32 RefactorPeersMiniBlocksEnableEpoch() uint32 StakingV4Step2EnableEpoch() uint32 - StakingV4InitEpoch() uint32 + StakingV4Step1EnableEpoch() uint32 IsSCDeployFlagEnabled() bool IsBuiltInFunctionsFlagEnabled() bool IsRelayedTransactionsFlagEnabled() bool diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index 8b31bd621ef..c283bca9dbb 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -271,7 +271,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4ReceivedNewList _ = valInfo.Add(v2) sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) require.Error(t, err) @@ -334,7 +334,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithS _ = valInfo.Add(v1) sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} sdp.cache[owner].blsKeys = append(sdp.cache[owner].blsKeys, []byte("newKey")) sdp.cache[owner].totalStaked = big.NewInt(2500) @@ -551,7 +551,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -565,7 +565,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -581,7 +581,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -597,7 +597,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4FlagEnabledField: true} + sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, diff --git a/integrationTests/multiShard/softfork/scDeploy_test.go b/integrationTests/multiShard/softfork/scDeploy_test.go index 1c15f80aa2c..9115089a4f2 100644 --- a/integrationTests/multiShard/softfork/scDeploy_test.go +++ b/integrationTests/multiShard/softfork/scDeploy_test.go @@ -34,9 +34,9 @@ func TestScDeploy(t *testing.T) { enableEpochs.SCDeployEnableEpoch = deployEnableEpoch enableEpochs.RelayedTransactionsEnableEpoch = relayedTxEnableEpoch enableEpochs.PenalizedTooMuchGasEnableEpoch = penalizedTooMuchGasEnableEpoch - enableEpochs.StakingV4Step1EnableEpoch = integrationTests.StakingV4InitEpoch - enableEpochs.StakingV4Step2EnableEpoch = integrationTests.StakingV4Epoch - enableEpochs.StakingV4Step3EnableEpoch = integrationTests.StakingV4DistributeAuctionToWaiting + enableEpochs.StakingV4Step1EnableEpoch = integrationTests.StakingV4Step1EnableEpoch + enableEpochs.StakingV4Step2EnableEpoch = integrationTests.StakingV4Step2EnableEpoch + enableEpochs.StakingV4Step3EnableEpoch = integrationTests.StakingV4Step3EnableEpoch shardNode := integrationTests.NewTestProcessorNode(integrationTests.ArgTestProcessorNode{ MaxShards: 1, diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 6b51b51fb59..fb0b717c9fb 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -55,7 +55,7 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(nodeShufflerArgs) nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( TestMarshalizer, - StakingV4Epoch, + StakingV4Step2EnableEpoch, ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: arg.shardConsensusGroupSize, @@ -80,7 +80,7 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd }, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4Step2EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) if err != nil { @@ -118,7 +118,7 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( TestMarshalizer, - StakingV4Epoch, + StakingV4Step2EnableEpoch, ) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ ShardConsensusGroupSize: arg.shardConsensusGroupSize, diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 52592628dd6..43d5720cd5a 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -303,7 +303,7 @@ func (tcn *TestConsensusNode) initNodesCoordinator( EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, - StakingV4Step2EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } tcn.NodesCoordinator, _ = nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index e4d5e5ff77e..d8083479e6d 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -219,14 +219,14 @@ const stateCheckpointModulus = uint(100) // UnreachableEpoch defines an unreachable epoch for integration tests const UnreachableEpoch = uint32(1000000) -// StakingV4InitEpoch defines the epoch for integration tests when stakingV4 init is enabled -const StakingV4InitEpoch = 4443 +// StakingV4Step1EnableEpoch defines the epoch for integration tests when stakingV4 init is enabled +const StakingV4Step1EnableEpoch = 4443 -// StakingV4Epoch defines the epoch for integration tests when stakingV4 is enabled; should be greater than StakingV2Epoch -const StakingV4Epoch = 4444 +// StakingV4Step2EnableEpoch defines the epoch for integration tests when stakingV4 is enabled; should be greater than StakingV2Epoch +const StakingV4Step2EnableEpoch = 4444 -// StakingV4DistributeAuctionToWaiting defines the epoch for integration tests when nodes distribution from auction to waiting list is enabled in staking v4 -const StakingV4DistributeAuctionToWaiting = 4445 +// StakingV4Step3EnableEpoch defines the epoch for integration tests when nodes distribution from auction to waiting list is enabled in staking v4 +const StakingV4Step3EnableEpoch = 4445 // ScheduledMiniBlocksEnableEpoch defines the epoch for integration tests when scheduled nini blocks are enabled const ScheduledMiniBlocksEnableEpoch = 1000 diff --git a/integrationTests/testProcessorNodeWithCoordinator.go b/integrationTests/testProcessorNodeWithCoordinator.go index 599ade701e8..a346f343ea3 100644 --- a/integrationTests/testProcessorNodeWithCoordinator.go +++ b/integrationTests/testProcessorNodeWithCoordinator.go @@ -75,7 +75,7 @@ func CreateProcessorNodesWithNodesCoordinator( IsFullArchive: false, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - StakingV4Step2EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 30bafa4ac8a..b1c81962a12 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -413,7 +413,7 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - StakingV4Epoch, + StakingV4Step2EnableEpoch, ) completeNodesList := make([]Connectable, 0) for shardId, validatorList := range validatorsMap { @@ -438,7 +438,7 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( IsFullArchive: false, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - StakingV4Step2EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -533,7 +533,7 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( &testscommon.MarshalizerMock{}, - StakingV4Epoch, + StakingV4Step2EnableEpoch, ) completeNodesList := make([]Connectable, 0) for shardId, validatorList := range validatorsMap { @@ -560,7 +560,7 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4Step2EnableEpoch: StakingV4Epoch, + StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index 1feebf69a94..fe922b2d13e 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -35,7 +35,7 @@ import ( ) const ( - stakingV4InitEpoch = 1 + stakingV4Step1EnableEpoch = 1 stakingV4Step2EnableEpoch = 2 stakingV4Step3EnableEpoch = 3 addressLength = 15 diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 97d75a02a0a..9d858208277 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -61,8 +61,8 @@ func createComponentHolders(numOfShards uint32) ( func createCoreComponents() factory.CoreComponentsHolder { epochNotifier := forking.NewGenericEpochNotifier() configEnableEpochs := config.EnableEpochs{ + StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, - StakingV4Step1EnableEpoch: stakingV4InitEpoch, StakingV4Step3EnableEpoch: stakingV4Step3EnableEpoch, RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, } diff --git a/integrationTests/vm/txsFee/validatorSC_test.go b/integrationTests/vm/txsFee/validatorSC_test.go index 71d03e97b49..fbce4f9e3ce 100644 --- a/integrationTests/vm/txsFee/validatorSC_test.go +++ b/integrationTests/vm/txsFee/validatorSC_test.go @@ -29,7 +29,7 @@ const ( cannotUnBondTokensMessage = "cannot unBond tokens, the validator would remain without min deposit, nodes are still active" noTokensToUnBondMessage = "no tokens that can be unbond at this time" delegationManagementKey = "delegationManagement" - stakingV4InitEpoch = 4443 + stakingV4Step1EnableEpoch = 4443 stakingV4Step2EnableEpoch = 4444 ) @@ -110,7 +110,7 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( core.MetachainShardId, config.EnableEpochs{ - StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, ) @@ -146,14 +146,14 @@ func TestValidatorsSC_DoStakePutInQueueUnStakeAndUnBondTokensShouldRefund(t *tes func TestValidatorsSC_DoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t *testing.T) { argUnbondTokensV1 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 20000, - StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV1) argUnbondTokensV2 := config.EnableEpochs{ UnbondTokensV2EnableEpoch: 0, - StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, } testValidatorsSCDoStakeWithTopUpValueTryToUnStakeTokensAndUnBondTokens(t, argUnbondTokensV2) @@ -191,7 +191,7 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeAndUnBondShouldRefundUnBondTokens( testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( core.MetachainShardId, config.EnableEpochs{ - StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, ) @@ -244,7 +244,7 @@ func TestValidatorsSC_ToStakePutInQueueUnStakeNodesAndUnBondNodesShouldRefund(t testContextMeta, err := vm.CreatePreparedTxProcessorWithVMsMultiShard( core.MetachainShardId, config.EnableEpochs{ - StakingV4Step1EnableEpoch: stakingV4InitEpoch, + StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, }, ) diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 920f92bbc46..0206815a47e 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2699,7 +2699,7 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t } stakingV4Step2EnableEpochCalledCt := 0 arguments.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ - IsStakingV4EnabledCalled: func() bool { + IsStakingV4Step2Called: func() bool { stakingV4Step2EnableEpochCalledCt++ switch stakingV4Step2EnableEpochCalledCt { case 1: diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 0645fef83bf..2e743c5e9bf 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -91,8 +91,8 @@ func (mock *EnableEpochsHandlerMock) StakingV4Step2EnableEpoch() uint32 { return 0 } -// StakingV4InitEpoch - -func (mock *EnableEpochsHandlerMock) StakingV4InitEpoch() uint32 { +// StakingV4Step1EnableEpoch - +func (mock *EnableEpochsHandlerMock) StakingV4Step1EnableEpoch() uint32 { return 0 } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 2fe5a2a0e46..4e62a71b8ef 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -29,21 +29,21 @@ type NodesShufflerArgs struct { } type shuffleNodesArg struct { - eligible map[uint32][]Validator - waiting map[uint32][]Validator - unstakeLeaving []Validator - additionalLeaving []Validator - newNodes []Validator - auction []Validator - randomness []byte - distributor ValidatorsDistributor - nodesMeta uint32 - nodesPerShard uint32 - nbShards uint32 - maxNodesToSwapPerShard uint32 - flagBalanceWaitingLists bool - flagStakingV4 bool - flagStakingV4DistributeAuctionToWaiting bool + eligible map[uint32][]Validator + waiting map[uint32][]Validator + unstakeLeaving []Validator + additionalLeaving []Validator + newNodes []Validator + auction []Validator + randomness []byte + distributor ValidatorsDistributor + nodesMeta uint32 + nodesPerShard uint32 + nbShards uint32 + maxNodesToSwapPerShard uint32 + flagBalanceWaitingLists bool + flagStakingV4Step2 bool + flagStakingV4Step3 bool } // TODO: Decide if transaction load statistics will be used for limiting the number of shards @@ -52,21 +52,21 @@ type randHashShuffler struct { // when reinitialization of node in new shard is implemented shuffleBetweenShards bool - adaptivity bool - nodesShard uint32 - nodesMeta uint32 - shardHysteresis uint32 - metaHysteresis uint32 - activeNodesConfig config.MaxNodesChangeConfig - availableNodesConfigs []config.MaxNodesChangeConfig - mutShufflerParams sync.RWMutex - validatorDistributor ValidatorsDistributor - flagBalanceWaitingLists atomic.Flag - enableEpochsHandler common.EnableEpochsHandler - stakingV4Step3EnableEpoch uint32 - flagStakingV4DistributeAuctionToWaiting atomic.Flag - stakingV4Step2EnableEpoch uint32 - flagStakingV4 atomic.Flag + adaptivity bool + nodesShard uint32 + nodesMeta uint32 + shardHysteresis uint32 + metaHysteresis uint32 + activeNodesConfig config.MaxNodesChangeConfig + availableNodesConfigs []config.MaxNodesChangeConfig + mutShufflerParams sync.RWMutex + validatorDistributor ValidatorsDistributor + flagBalanceWaitingLists atomic.Flag + enableEpochsHandler common.EnableEpochsHandler + stakingV4Step2EnableEpoch uint32 + flagStakingV4Step2 atomic.Flag + stakingV4Step3EnableEpoch uint32 + flagStakingV4Step3 atomic.Flag } // NewHashValidatorsShuffler creates a validator shuffler that uses a hash between validator key and a given @@ -180,21 +180,21 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo } return shuffleNodes(shuffleNodesArg{ - eligible: eligibleAfterReshard, - waiting: waitingAfterReshard, - unstakeLeaving: args.UnStakeLeaving, - additionalLeaving: args.AdditionalLeaving, - newNodes: args.NewNodes, - auction: args.Auction, - randomness: args.Rand, - nodesMeta: nodesMeta, - nodesPerShard: nodesPerShard, - nbShards: args.NbShards, - distributor: rhs.validatorDistributor, - maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, - flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), - flagStakingV4: rhs.flagStakingV4.IsSet(), - flagStakingV4DistributeAuctionToWaiting: rhs.flagStakingV4DistributeAuctionToWaiting.IsSet(), + eligible: eligibleAfterReshard, + waiting: waitingAfterReshard, + unstakeLeaving: args.UnStakeLeaving, + additionalLeaving: args.AdditionalLeaving, + newNodes: args.NewNodes, + auction: args.Auction, + randomness: args.Rand, + nodesMeta: nodesMeta, + nodesPerShard: nodesPerShard, + nbShards: args.NbShards, + distributor: rhs.validatorDistributor, + maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, + flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), + flagStakingV4Step2: rhs.flagStakingV4Step2.IsSet(), + flagStakingV4Step3: rhs.flagStakingV4Step3.IsSet(), }) } @@ -293,14 +293,14 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - if arg.flagStakingV4DistributeAuctionToWaiting { + if arg.flagStakingV4Step3 { // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) if err != nil { log.Warn("distributeValidators auction list failed", "error", err) } } - if !arg.flagStakingV4 { + if !arg.flagStakingV4Step2 { // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) if err != nil { @@ -405,45 +405,6 @@ func removeLeavingNodesFromValidatorMaps( return newEligible, newWaiting, stillRemainingInLeaving } -func removeLeavingNodes( - eligible map[uint32][]Validator, - waiting map[uint32][]Validator, - numToRemove map[uint32]int, - stillRemainingInLeaving []Validator, - minNodesMeta int, - minNodesPerShard int, -) (map[uint32][]Validator, map[uint32][]Validator, []Validator) { - maxNumToRemoveFromWaiting := make(map[uint32]int) - for shardId := range eligible { - computedMinNumberOfNodes := computeMinNumberOfNodes(eligible, waiting, shardId, minNodesMeta, minNodesPerShard) - maxNumToRemoveFromWaiting[shardId] = computedMinNumberOfNodes - } - - newWaiting, stillRemainingInLeaving := removeNodesFromMap(waiting, stillRemainingInLeaving, maxNumToRemoveFromWaiting) - - for shardId, toRemove := range numToRemove { - computedMinNumberOfNodes := computeMinNumberOfNodes(eligible, waiting, shardId, minNodesMeta, minNodesPerShard) - if toRemove > computedMinNumberOfNodes { - numToRemove[shardId] = computedMinNumberOfNodes - } - } - - newEligible, stillRemainingInLeaving := removeNodesFromMap(eligible, stillRemainingInLeaving, numToRemove) - return newEligible, newWaiting, stillRemainingInLeaving -} - -func computeMinNumberOfNodes(eligible map[uint32][]Validator, waiting map[uint32][]Validator, shardId uint32, minNodesMeta int, minNodesPerShard int) int { - minimumNumberOfNodes := minNodesPerShard - if shardId == core.MetachainShardId { - minimumNumberOfNodes = minNodesMeta - } - computedMinNumberOfNodes := len(eligible[shardId]) + len(waiting[shardId]) - minimumNumberOfNodes - if computedMinNumberOfNodes < 0 { - computedMinNumberOfNodes = 0 - } - return computedMinNumberOfNodes -} - // computeNewShards determines the new number of shards based on the number of nodes in the network func (rhs *randHashShuffler) computeNewShards( eligible map[uint32][]Validator, @@ -789,11 +750,11 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { rhs.flagBalanceWaitingLists.SetValue(epoch >= rhs.enableEpochsHandler.BalanceWaitingListsEnableEpoch()) log.Debug("balanced waiting lists", "enabled", rhs.flagBalanceWaitingLists.IsSet()) - rhs.flagStakingV4DistributeAuctionToWaiting.SetValue(epoch >= rhs.stakingV4Step3EnableEpoch) - log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4DistributeAuctionToWaiting.IsSet()) + rhs.flagStakingV4Step3.SetValue(epoch >= rhs.stakingV4Step3EnableEpoch) + log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4Step3.IsSet()) - rhs.flagStakingV4.SetValue(epoch >= rhs.stakingV4Step2EnableEpoch) - log.Debug("staking v4", "enabled", rhs.flagStakingV4.IsSet()) + rhs.flagStakingV4Step2.SetValue(epoch >= rhs.stakingV4Step2EnableEpoch) + log.Debug("staking v4", "enabled", rhs.flagStakingV4Step2.IsSet()) } func (rhs *randHashShuffler) sortConfigs() { diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 7be52c61b37..246573e6bee 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -98,7 +98,7 @@ type indexHashedNodesCoordinator struct { enableEpochsHandler common.EnableEpochsHandler validatorInfoCacher epochStart.ValidatorInfoCacher stakingV4Step2EnableEpoch uint32 - flagStakingV4 atomicFlags.Flag + flagStakingV4Step2 atomicFlags.Flag nodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory flagStakingV4Started atomicFlags.Flag } @@ -766,7 +766,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( validatorInfo, ) case string(common.NewList): - if ihnc.flagStakingV4.IsSet() { + if ihnc.flagStakingV4Step2.IsSet() { return nil, epochStart.ErrReceivedNewListNodeInStakingV4 } log.Debug("new node registered", "pk", validatorInfo.PublicKey) @@ -776,7 +776,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.JailedList): log.Debug("jailed validator", "pk", validatorInfo.PublicKey) case string(common.SelectedFromAuctionList): - if ihnc.flagStakingV4.IsSet() { + if ihnc.flagStakingV4Step2.IsSet() { auctionList = append(auctionList, currentValidator) } else { return nil, ErrReceivedAuctionValidatorsBeforeStakingV4 @@ -1071,7 +1071,7 @@ func (ihnc *indexHashedNodesCoordinator) computeShardForSelfPublicKey(nodesConfi return shardId, true } - if ihnc.flagStakingV4.IsSet() { + if ihnc.flagStakingV4Step2.IsSet() { found, shardId = searchInMap(nodesConfig.shuffledOutMap, pubKey) if found { log.Trace("computeShardForSelfPublicKey found validator in shuffled out", @@ -1280,9 +1280,9 @@ func (ihnc *indexHashedNodesCoordinator) getShardValidatorInfoData(txHash []byte } func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { - ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.StakingV4InitEpoch()) + ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.StakingV4Step1EnableEpoch()) log.Debug("indexHashedNodesCoordinator: staking v4 started", "enabled", ihnc.flagStakingV4Started.IsSet()) - ihnc.flagStakingV4.SetValue(epoch >= ihnc.stakingV4Step2EnableEpoch) - log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4.IsSet()) + ihnc.flagStakingV4Step2.SetValue(epoch >= ihnc.stakingV4Step2EnableEpoch) + log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4Step2.IsSet()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index ef369139e6d..70ee687bd57 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -1400,7 +1400,7 @@ func TestIndexHashedNodesCoordinator_computeShardForSelfPublicKeyWithStakingV4(t require.Equal(t, nc.shardIDAsObserver, computedShardId) require.False(t, isValidator) - nc.flagStakingV4.SetValue(true) + nc.flagStakingV4Step2.SetValue(true) computedShardId, isValidator = nc.computeShardForSelfPublicKey(nc.nodesConfig[epoch]) require.Equal(t, metaShard, computedShardId) diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 9c16dad7ef8..55463234639 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -26,7 +26,7 @@ type EnableEpochsHandlerStub struct { MiniBlockPartialExecutionEnableEpochField uint32 RefactorPeersMiniBlocksEnableEpochField uint32 StakingV4Step2EnableEpochField uint32 - StakingV4InitEpochField uint32 + StakingV4Step1EnableEpochField uint32 IsSCDeployFlagEnabledField bool IsBuiltInFunctionsFlagEnabledField bool IsRelayedTransactionsFlagEnabledField bool @@ -117,12 +117,12 @@ type EnableEpochsHandlerStub struct { IsWipeSingleNFTLiquidityDecreaseEnabledField bool IsAlwaysSaveTokenMetaDataEnabledField bool IsStakeLimitsFlagEnabledField bool - IsStakingV4InitFlagEnabledField bool - IsStakingV4FlagEnabledField bool - IsStakingV4DistributeAuctionToWaitingEnabledField bool + IsStakingV4Step1FlagEnabledField bool + IsStakingV4Step2FlagEnabledField bool + IsStakingV4Step3FlagEnabledField bool IsStakingQueueEnabledField bool IsStakingV4StartedField bool - IsStakingV4EnabledCalled func() bool + IsStakingV4Step2Called func() bool } // ResetPenalizedTooMuchGasFlag - @@ -998,7 +998,7 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Step1Enabled() bool { stub.RLock() defer stub.RUnlock() - return stub.IsStakingV4InitFlagEnabledField + return stub.IsStakingV4Step1FlagEnabledField } // IsStakingV4Step2Enabled - @@ -1006,11 +1006,11 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Step2Enabled() bool { stub.RLock() defer stub.RUnlock() - if stub.IsStakingV4EnabledCalled != nil { - return stub.IsStakingV4EnabledCalled() + if stub.IsStakingV4Step2Called != nil { + return stub.IsStakingV4Step2Called() } - return stub.IsStakingV4FlagEnabledField + return stub.IsStakingV4Step2FlagEnabledField } // IsStakingV4Step3Enabled - @@ -1018,7 +1018,7 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Step3Enabled() bool { stub.RLock() defer stub.RUnlock() - return stub.IsStakingV4DistributeAuctionToWaitingEnabledField + return stub.IsStakingV4Step3FlagEnabledField } // IsStakingQueueEnabled - @@ -1045,12 +1045,12 @@ func (stub *EnableEpochsHandlerStub) StakingV4Step2EnableEpoch() uint32 { return stub.StakingV4Step2EnableEpochField } -// StakingV4InitEpoch - -func (stub *EnableEpochsHandlerStub) StakingV4InitEpoch() uint32 { +// StakingV4Step1EnableEpoch - +func (stub *EnableEpochsHandlerStub) StakingV4Step1EnableEpoch() uint32 { stub.RLock() defer stub.RUnlock() - return stub.StakingV4InitEpochField + return stub.StakingV4Step1EnableEpochField } // IsInterfaceNil - diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 701dbddea18..b5115318a2f 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -61,8 +61,8 @@ func createMockStakingScArgumentsWithSystemScAddresses( IsCorrectFirstQueuedFlagEnabledField: true, IsCorrectJailedNotUnStakedEmptyQueueFlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, - IsStakingV4FlagEnabledField: false, - IsStakingV4InitFlagEnabledField: false, + IsStakingV4Step2FlagEnabledField: false, + IsStakingV4Step1FlagEnabledField: false, }, } } @@ -3406,7 +3406,7 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { IsCorrectJailedNotUnStakedEmptyQueueFlagEnabledField: true, IsSwitchJailWaitingFlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, - IsStakingV4InitFlagEnabledField: true, + IsStakingV4Step1FlagEnabledField: true, IsStakingV4StartedField: true, IsStakingV2FlagEnabledField: true, } @@ -3469,7 +3469,7 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) - enableEpochsHandler.IsStakingV4InitFlagEnabledField = false + enableEpochsHandler.IsStakingV4Step1FlagEnabledField = false // All functions from above are not allowed anymore starting STAKING V4 epoch eei.CleanCache() arguments.Function = "getQueueIndex" From 32fe65818949c96390571321cbeb2e4e5c6794d0 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 8 Feb 2023 16:21:11 +0200 Subject: [PATCH 408/958] FIX: Rename stakingV4 epoch steps --- integrationTests/vm/staking/stakingV4_test.go | 70 +++++++++---------- node/nodeRunner.go | 6 +- .../nodesCoordinator/hashValidatorShuffler.go | 4 +- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 8aa723c4279..8f665cdd32b 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -141,46 +141,46 @@ func TestStakingV4(t *testing.T) { // 2. Check config after staking v4 initialization node.Process(t, 5) - nodesConfigStakingV4Init := node.NodesConfig - require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.eligible), totalEligible) - require.Len(t, getAllPubKeys(nodesConfigStakingV4Init.waiting), totalWaiting) - require.Empty(t, nodesConfigStakingV4Init.queue) - require.Empty(t, nodesConfigStakingV4Init.shuffledOut) - requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Init.auction) + nodesConfigStakingV4Step1 := node.NodesConfig + require.Len(t, getAllPubKeys(nodesConfigStakingV4Step1.eligible), totalEligible) + require.Len(t, getAllPubKeys(nodesConfigStakingV4Step1.waiting), totalWaiting) + require.Empty(t, nodesConfigStakingV4Step1.queue) + require.Empty(t, nodesConfigStakingV4Step1.shuffledOut) + requireSameSliceDifferentOrder(t, initialNodes.queue, nodesConfigStakingV4Step1.auction) // 3. Check config after first staking v4 epoch, WITHOUT distribution from auction -> waiting node.Process(t, 6) - nodesConfigStakingV4 := node.NodesConfig - require.Len(t, getAllPubKeys(nodesConfigStakingV4.eligible), totalEligible) // 1600 + nodesConfigStakingV4Step2 := node.NodesConfig + require.Len(t, getAllPubKeys(nodesConfigStakingV4Step2.eligible), totalEligible) // 1600 numOfShuffledOut := int((numOfShards + 1) * numOfNodesToShufflePerShard) // 320 - require.Len(t, getAllPubKeys(nodesConfigStakingV4.shuffledOut), numOfShuffledOut) + require.Len(t, getAllPubKeys(nodesConfigStakingV4Step2.shuffledOut), numOfShuffledOut) newWaiting := totalWaiting - numOfShuffledOut // 1280 (1600 - 320) - require.Len(t, getAllPubKeys(nodesConfigStakingV4.waiting), newWaiting) + require.Len(t, getAllPubKeys(nodesConfigStakingV4Step2.waiting), newWaiting) // 380 (320 from shuffled out + 60 from initial staking queue -> auction from stakingV4 init) - auctionListSize := numOfShuffledOut + len(nodesConfigStakingV4Init.auction) - require.Len(t, nodesConfigStakingV4.auction, auctionListSize) - requireSliceContains(t, nodesConfigStakingV4.auction, nodesConfigStakingV4Init.auction) + auctionListSize := numOfShuffledOut + len(nodesConfigStakingV4Step1.auction) + require.Len(t, nodesConfigStakingV4Step2.auction, auctionListSize) + requireSliceContains(t, nodesConfigStakingV4Step2.auction, nodesConfigStakingV4Step1.auction) - require.Empty(t, nodesConfigStakingV4.queue) - require.Empty(t, nodesConfigStakingV4.leaving) + require.Empty(t, nodesConfigStakingV4Step2.queue) + require.Empty(t, nodesConfigStakingV4Step2.leaving) // 320 nodes which are now in eligible are from previous waiting list - requireSliceContainsNumOfElements(t, getAllPubKeys(nodesConfigStakingV4.eligible), getAllPubKeys(nodesConfigStakingV4Init.waiting), numOfShuffledOut) + requireSliceContainsNumOfElements(t, getAllPubKeys(nodesConfigStakingV4Step2.eligible), getAllPubKeys(nodesConfigStakingV4Step1.waiting), numOfShuffledOut) // All shuffled out are from previous staking v4 init eligible - requireMapContains(t, nodesConfigStakingV4Init.eligible, getAllPubKeys(nodesConfigStakingV4.shuffledOut)) + requireMapContains(t, nodesConfigStakingV4Step1.eligible, getAllPubKeys(nodesConfigStakingV4Step2.shuffledOut)) // All shuffled out are in auction - requireSliceContains(t, nodesConfigStakingV4.auction, getAllPubKeys(nodesConfigStakingV4.shuffledOut)) + requireSliceContains(t, nodesConfigStakingV4Step2.auction, getAllPubKeys(nodesConfigStakingV4Step2.shuffledOut)) // No auction node from previous epoch has been moved to waiting - requireMapDoesNotContain(t, nodesConfigStakingV4.waiting, nodesConfigStakingV4Init.auction) + requireMapDoesNotContain(t, nodesConfigStakingV4Step2.waiting, nodesConfigStakingV4Step1.auction) epochs := 0 - prevConfig := nodesConfigStakingV4 + prevConfig := nodesConfigStakingV4Step2 numOfSelectedNodesFromAuction := numOfShuffledOut // 320, since we will always fill shuffled out nodes with this config numOfUnselectedNodesFromAuction := auctionListSize - numOfShuffledOut // 60 = 380 - 320 for epochs < 10 { @@ -289,7 +289,7 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { TotalStake: big.NewInt(5 * nodePrice), } - // Owner3 has 2 nodes in staking queue with with topUp = nodePrice + // Owner3 has 2 nodes in staking queue with topUp = nodePrice owner3 := "owner3" owner3Stats := &OwnerStats{ StakingQueueKeys: pubKeys[14:16], @@ -407,7 +407,7 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { // Meanwhile, owner4 had never unStaked EGLD => his node from auction list will be distributed to waiting unStake(t, []byte(owner3), node.AccountsAdapter, node.Marshaller, big.NewInt(2*nodePrice)) - // 4. Check config in epoch = staking v4 distribute auction to waiting + // 4. Check config in epoch = staking v4 step3 node.Process(t, 5) currNodesConfig = node.NodesConfig requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.leaving), owner3StakingQueue, 1) @@ -533,7 +533,7 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { TotalStake: big.NewInt(4 * nodePrice), }, } - // 2. Check in epoch = staking v4 when 2 new nodes are staked + // 2. Check in epoch = staking v4 step2 when 2 new nodes are staked node.Process(t, 4) node.ProcessStake(t, newNodes2) currNodesConfig = node.NodesConfig @@ -541,9 +541,9 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { require.Empty(t, currNodesConfig.queue) requireSliceContainsNumOfElements(t, currNodesConfig.auction, queue, 7) - // 3. Epoch = staking v4 distribute auction to waiting + // 3. Epoch = staking v4 step3 // Only the new 2 owners + owner3 had enough top up to be distributed to waiting. - // Meanwhile; owner1 which had 0 top up, still has his bls keys in auction, along with newOwner0 + // Meanwhile, owner1 which had 0 top up, still has his bls keys in auction, along with newOwner0 node.Process(t, 5) currNodesConfig = node.NodesConfig require.Empty(t, currNodesConfig.queue) @@ -654,7 +654,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Len(t, currNodesConfig.queue, 5) requireSameSliceDifferentOrder(t, queue, currNodesConfig.queue) - // 2. Check config after staking v4 init + // 2. Check config after staking v4 step1 node.Process(t, 3) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) @@ -670,8 +670,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { node.ProcessUnStake(t, map[string][][]byte{ owner3: {owner3StakingQueue[1]}, }) - unStakedNodesInStakingV4InitEpoch := make([][]byte, 0) - unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner3StakingQueue[1]) + unStakedNodesInStakingV4Step1Epoch := make([][]byte, 0) + unStakedNodesInStakingV4Step1Epoch = append(unStakedNodesInStakingV4Step1Epoch, owner3StakingQueue[1]) currNodesConfig = node.NodesConfig queue = remove(queue, owner3StakingQueue[1]) require.Len(t, currNodesConfig.auction, 4) @@ -683,8 +683,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { node.ProcessUnStake(t, map[string][][]byte{ owner1: {owner1StakingQueue[1], owner1Stats.WaitingBlsKeys[0][0]}, }) - unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner1StakingQueue[1]) - unStakedNodesInStakingV4InitEpoch = append(unStakedNodesInStakingV4InitEpoch, owner1Stats.WaitingBlsKeys[0][0]) + unStakedNodesInStakingV4Step1Epoch = append(unStakedNodesInStakingV4Step1Epoch, owner1StakingQueue[1]) + unStakedNodesInStakingV4Step1Epoch = append(unStakedNodesInStakingV4Step1Epoch, owner1Stats.WaitingBlsKeys[0][0]) currNodesConfig = node.NodesConfig queue = remove(queue, owner1StakingQueue[1]) require.Len(t, currNodesConfig.auction, 3) @@ -692,14 +692,14 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { require.Empty(t, currNodesConfig.queue) require.Empty(t, currNodesConfig.new) - // 3. Check config in epoch = staking v4 epoch + // 3. Check config in epoch = staking v4 step2 node.Process(t, 3) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) require.Len(t, getAllPubKeys(currNodesConfig.leaving), 3) // All unStaked nodes in previous epoch are now leaving - requireMapContains(t, currNodesConfig.leaving, unStakedNodesInStakingV4InitEpoch) + requireMapContains(t, currNodesConfig.leaving, unStakedNodesInStakingV4Step1Epoch) // 3.1 Owner2 unStakes one of his nodes from auction node.ProcessUnStake(t, map[string][][]byte{ owner2: {owner2StakingQueue[1]}, @@ -847,14 +847,14 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) require.Empty(t, currNodesConfig.queue) - // 2.1 Epoch = stakingV4Init; unJail one of the jailed nodes and expect it is sent to auction + // 2.1 Epoch = stakingV4Step1; unJail one of the jailed nodes and expect it is sent to auction node.ProcessUnJail(t, jailedNodes[:1]) currNodesConfig = node.NodesConfig queue = append(queue, jailedNodes[0]) require.Empty(t, currNodesConfig.queue) requireSameSliceDifferentOrder(t, currNodesConfig.auction, queue) - // 3. Epoch = stakingV4; unJail the other jailed node and expect it is sent to auction + // 3. Epoch = stakingV4Step2; unJail the other jailed node and expect it is sent to auction node.Process(t, 4) node.ProcessUnJail(t, jailedNodes[1:]) currNodesConfig = node.NodesConfig @@ -867,7 +867,7 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { newJailed := getAllPubKeys(currNodesConfig.waiting)[:1] node.ProcessJail(t, newJailed) - // 4. Epoch = stakingV4DistributeAuctionToWaiting; + // 4. Epoch = stakingV4Step3; // 4.1 Expect jailed node from waiting list is now leaving node.Process(t, 4) currNodesConfig = node.NodesConfig diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 76493b83485..5628db1afa2 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -204,9 +204,9 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("runtime memstore limit"), "epoch", enableEpochs.RuntimeMemStoreLimitEnableEpoch) log.Debug(readEpochFor("max blockchainhook counters"), "epoch", enableEpochs.MaxBlockchainHookCountersEnableEpoch) log.Debug(readEpochFor("limit validators"), "epoch", enableEpochs.StakeLimitsEnableEpoch) - log.Debug(readEpochFor("staking v4 init"), "epoch", enableEpochs.StakingV4Step1EnableEpoch) - log.Debug(readEpochFor("staking v4 enable"), "epoch", enableEpochs.StakingV4Step2EnableEpoch) - log.Debug(readEpochFor("staking v4 distribute auction to waiting"), "epoch", enableEpochs.StakingV4Step3EnableEpoch) + log.Debug(readEpochFor("staking v4 step 1"), "epoch", enableEpochs.StakingV4Step1EnableEpoch) + log.Debug(readEpochFor("staking v4 step 2"), "epoch", enableEpochs.StakingV4Step2EnableEpoch) + log.Debug(readEpochFor("staking v4 step 3"), "epoch", enableEpochs.StakingV4Step3EnableEpoch) gasSchedule := configs.EpochConfig.GasSchedule diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 4e62a71b8ef..595966e31a6 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -82,8 +82,8 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro var configs []config.MaxNodesChangeConfig log.Debug("hashValidatorShuffler: enable epoch for max nodes change", "epoch", args.MaxNodesEnableConfig) - log.Debug("hashValidatorShuffler: enable epoch for staking v4", "epoch", args.EnableEpochs.StakingV4Step2EnableEpoch) - log.Debug("hashValidatorShuffler: enable epoch for staking v4 distribute auction list to waiting list", "epoch", args.EnableEpochs.StakingV4Step3EnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4 step 2", "epoch", args.EnableEpochs.StakingV4Step2EnableEpoch) + log.Debug("hashValidatorShuffler: enable epoch for staking v4 step 3", "epoch", args.EnableEpochs.StakingV4Step3EnableEpoch) if args.MaxNodesEnableConfig != nil { configs = make([]config.MaxNodesChangeConfig, len(args.MaxNodesEnableConfig)) From c9a28f1ca96b4b96a90270bebf56c42e39192df8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 8 Feb 2023 17:20:28 +0200 Subject: [PATCH 409/958] FIX: After self review --- sharding/nodesCoordinator/hashValidatorShuffler.go | 4 ++-- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 595966e31a6..2fcdd4bb1ef 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -751,10 +751,10 @@ func (rhs *randHashShuffler) UpdateShufflerConfig(epoch uint32) { log.Debug("balanced waiting lists", "enabled", rhs.flagBalanceWaitingLists.IsSet()) rhs.flagStakingV4Step3.SetValue(epoch >= rhs.stakingV4Step3EnableEpoch) - log.Debug("staking v4 distribute auction to waiting", "enabled", rhs.flagStakingV4Step3.IsSet()) + log.Debug("staking v4 step3", "enabled", rhs.flagStakingV4Step3.IsSet()) rhs.flagStakingV4Step2.SetValue(epoch >= rhs.stakingV4Step2EnableEpoch) - log.Debug("staking v4", "enabled", rhs.flagStakingV4Step2.IsSet()) + log.Debug("staking v4 step2", "enabled", rhs.flagStakingV4Step2.IsSet()) } func (rhs *randHashShuffler) sortConfigs() { diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 246573e6bee..b05ed506fda 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -1281,8 +1281,8 @@ func (ihnc *indexHashedNodesCoordinator) getShardValidatorInfoData(txHash []byte func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.StakingV4Step1EnableEpoch()) - log.Debug("indexHashedNodesCoordinator: staking v4 started", "enabled", ihnc.flagStakingV4Started.IsSet()) + log.Debug("indexHashedNodesCoordinator: flagStakingV4Started", "enabled", ihnc.flagStakingV4Started.IsSet()) ihnc.flagStakingV4Step2.SetValue(epoch >= ihnc.stakingV4Step2EnableEpoch) - log.Debug("indexHashedNodesCoordinator: staking v4", "enabled", ihnc.flagStakingV4Step2.IsSet()) + log.Debug("indexHashedNodesCoordinator: flagStakingV4Step2", "enabled", ihnc.flagStakingV4Step2.IsSet()) } From 5eaf2f2732efbaf4d170211d2501623884e3f709 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 9 Feb 2023 10:40:24 +0200 Subject: [PATCH 410/958] FIX: Add PreviousIndex for validators --- epochStart/metachain/validators.go | 13 +- process/mock/peerAccountHandlerMock.go | 5 + process/peer/process.go | 1 + .../indexHashedNodesCoordinator.go | 13 +- .../indexHashedNodesCoordinator_test.go | 11 +- state/interface.go | 4 +- state/peerAccount.go | 5 +- state/peerAccountData.pb.go | 179 ++++++++++------ state/peerAccountData.proto | 1 + state/validatorInfo.pb.go | 196 +++++++++++++----- state/validatorInfo.proto | 14 +- update/genesis/common.go | 1 + 12 files changed, 297 insertions(+), 146 deletions(-) diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index 3a4e00d6871..b751760b936 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -175,12 +175,13 @@ func (vic *validatorInfoCreator) getShardValidatorInfoHash(shardValidatorInfo *s func createShardValidatorInfo(validator state.ValidatorInfoHandler) *state.ShardValidatorInfo { return &state.ShardValidatorInfo{ - PublicKey: validator.GetPublicKey(), - ShardId: validator.GetShardId(), - List: validator.GetList(), - PreviousList: validator.GetPreviousList(), - Index: validator.GetIndex(), - TempRating: validator.GetTempRating(), + PublicKey: validator.GetPublicKey(), + ShardId: validator.GetShardId(), + List: validator.GetList(), + PreviousList: validator.GetPreviousList(), + Index: validator.GetIndex(), + PreviousIndex: validator.GetPreviousIndex(), + TempRating: validator.GetTempRating(), } } diff --git a/process/mock/peerAccountHandlerMock.go b/process/mock/peerAccountHandlerMock.go index 08370b1b27f..928fdfb0433 100644 --- a/process/mock/peerAccountHandlerMock.go +++ b/process/mock/peerAccountHandlerMock.go @@ -61,6 +61,11 @@ func (p *PeerAccountHandlerMock) GetIndexInList() uint32 { return 0 } +// GetPreviousIndexInList - +func (p *PeerAccountHandlerMock) GetPreviousIndexInList() uint32 { + return 0 +} + // GetBLSPublicKey - func (p *PeerAccountHandlerMock) GetBLSPublicKey() []byte { return nil diff --git a/process/peer/process.go b/process/peer/process.go index 728eb93b7ec..2f46ce1cb1f 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -494,6 +494,7 @@ func (vs *validatorStatistics) PeerAccountToValidatorInfo(peerAccount state.Peer List: list, PreviousList: peerAccount.GetPreviousList(), Index: peerAccount.GetIndexInList(), + PreviousIndex: peerAccount.GetPreviousIndexInList(), TempRating: peerAccount.GetTempRating(), Rating: peerAccount.GetRating(), RatingModifier: ratingModifier, diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 2be7369c2ee..259eebb0deb 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -757,6 +757,8 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( log.Debug("leaving node validatorInfo", "pk", validatorInfo.PublicKey, "previous list", validatorInfo.PreviousList, + "current index", validatorInfo.Index, + "previous index", validatorInfo.PreviousIndex, "shardId", validatorInfo.ShardId) leavingMap[validatorInfo.ShardId] = append(leavingMap[validatorInfo.ShardId], currentValidator) ihnc.addValidatorToPreviousMap( @@ -776,6 +778,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.JailedList): log.Debug("jailed validator", "pk", validatorInfo.PublicKey) case string(common.SelectedFromAuctionList): + log.Debug("selected node from auction", "pk", validatorInfo.PublicKey) if ihnc.flagStakingV4.IsSet() { auctionList = append(auctionList, currentValidator) } else { @@ -829,18 +832,24 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( previousList := validatorInfo.PreviousList if previousList == string(common.EligibleList) { log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) + currentValidator.index = validatorInfo.PreviousIndex eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) return } if previousList == string(common.WaitingList) { log.Debug("leaving node found in", "list", "waiting", "shardId", shardId) + currentValidator.index = validatorInfo.PreviousIndex waitingMap[shardId] = append(waitingMap[shardId], currentValidator) return } - log.Debug("leaving node not in eligible or waiting", "previous list", previousList, - "pk", currentValidator.PubKey(), "shardId", shardId) + log.Debug("leaving node not found in eligible or waiting", + "previous list", previousList, + "current index", validatorInfo.Index, + "previous index", validatorInfo.PreviousIndex, + "pk", currentValidator.PubKey(), + "shardId", shardId) } func (ihnc *indexHashedNodesCoordinator) handleErrorLog(err error, message string) { diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index f841d696460..e6e0a32b9a9 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -2195,11 +2195,12 @@ func TestIndexHashedNodesCoordinator_computeNodesConfigFromListValidatorsWithFix ShardId: 0, } shardMetaLeaving1 := &state.ShardValidatorInfo{ - PublicKey: []byte("pk7"), - List: string(common.LeavingList), - PreviousList: string(common.WaitingList), - Index: 1, - ShardId: core.MetachainShardId, + PublicKey: []byte("pk7"), + List: string(common.LeavingList), + PreviousList: string(common.WaitingList), + Index: 1, + PreviousIndex: 1, + ShardId: core.MetachainShardId, } validatorInfos := diff --git a/state/interface.go b/state/interface.go index 024a18b9113..190517c548e 100644 --- a/state/interface.go +++ b/state/interface.go @@ -34,6 +34,7 @@ type PeerAccountHandler interface { GetList() string GetPreviousList() string GetIndexInList() uint32 + GetPreviousIndexInList() uint32 GetShardId() uint32 SetUnStakedEpoch(epoch uint32) GetUnStakedEpoch() uint32 @@ -50,7 +51,7 @@ type PeerAccountHandler interface { GetTotalLeaderSuccessRate() SignRate GetTotalValidatorSuccessRate() SignRate GetTotalValidatorIgnoredSignaturesRate() uint32 - SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousList bool) + SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousValues bool) GetRating() uint32 SetRating(uint32) GetTempRating() uint32 @@ -240,6 +241,7 @@ type ValidatorInfoHandler interface { GetShardId() uint32 GetList() string GetIndex() uint32 + GetPreviousIndex() uint32 GetTempRating() uint32 GetRating() uint32 GetRatingModifier() float32 diff --git a/state/peerAccount.go b/state/peerAccount.go index 1f361602ba6..8fac7b9e38c 100644 --- a/state/peerAccount.go +++ b/state/peerAccount.go @@ -108,9 +108,10 @@ func (pa *peerAccount) SetTempRating(rating uint32) { } // SetListAndIndex will update the peer's list (eligible, waiting) and the index inside it with journal -func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousList bool) { - if updatePreviousList { +func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousValues bool) { + if updatePreviousValues { pa.PreviousList = pa.List + pa.PreviousIndexInList = pa.IndexInList } pa.ShardId = shardID diff --git a/state/peerAccountData.pb.go b/state/peerAccountData.pb.go index 06b1df1f5b5..f6b40f2d7ec 100644 --- a/state/peerAccountData.pb.go +++ b/state/peerAccountData.pb.go @@ -250,6 +250,7 @@ type PeerAccountData struct { Nonce uint64 `protobuf:"varint,17,opt,name=Nonce,proto3" json:"nonce"` UnStakedEpoch uint32 `protobuf:"varint,18,opt,name=UnStakedEpoch,proto3" json:"unStakedEpoch"` PreviousList string `protobuf:"bytes,19,opt,name=PreviousList,proto3" json:"previousList,omitempty"` + PreviousIndexInList uint32 `protobuf:"varint,20,opt,name=PreviousIndexInList,proto3" json:"previousIndexInList,omitempty"` } func (m *PeerAccountData) Reset() { *m = PeerAccountData{} } @@ -413,6 +414,13 @@ func (m *PeerAccountData) GetPreviousList() string { return "" } +func (m *PeerAccountData) GetPreviousIndexInList() uint32 { + if m != nil { + return m.PreviousIndexInList + } + return 0 +} + func init() { proto.RegisterType((*SignRate)(nil), "proto.SignRate") proto.RegisterType((*ValidatorApiResponse)(nil), "proto.ValidatorApiResponse") @@ -422,73 +430,74 @@ func init() { func init() { proto.RegisterFile("peerAccountData.proto", fileDescriptor_26bd0314afcce126) } var fileDescriptor_26bd0314afcce126 = []byte{ - // 1044 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xdf, 0x6e, 0xdb, 0xb6, - 0x17, 0xb6, 0xda, 0x38, 0x7f, 0x68, 0x3b, 0x4e, 0x98, 0xa4, 0xb5, 0xf3, 0x6b, 0xc4, 0xd4, 0xc5, - 0xaf, 0xcb, 0xc5, 0x92, 0x60, 0x7f, 0x80, 0x01, 0x1b, 0xb0, 0x2d, 0xea, 0xda, 0xc1, 0x5b, 0x9a, - 0x05, 0x4c, 0x37, 0x14, 0x1b, 0x30, 0x80, 0x96, 0x18, 0x45, 0xab, 0x2c, 0x1a, 0x14, 0xe5, 0x25, - 0x77, 0x7b, 0x84, 0x3e, 0xc6, 0xb0, 0x27, 0xe9, 0xee, 0x72, 0x99, 0x2b, 0x6e, 0x71, 0x2e, 0x36, - 0xf0, 0xaa, 0x8f, 0x30, 0x88, 0x96, 0x12, 0xc9, 0x96, 0x9d, 0x5e, 0xd9, 0x3a, 0xdf, 0x77, 0x3e, - 0x1e, 0xf2, 0x1c, 0x7e, 0x04, 0x6b, 0x3d, 0x4a, 0xf9, 0x9e, 0x6d, 0xb3, 0x28, 0x10, 0x5f, 0x11, - 0x41, 0x76, 0x7a, 0x9c, 0x09, 0x06, 0xcb, 0xfa, 0x67, 0x7d, 0xdb, 0xf5, 0xc4, 0x49, 0xd4, 0xd9, - 0xb1, 0x59, 0x77, 0xd7, 0x65, 0x2e, 0xdb, 0xd5, 0xe1, 0x4e, 0x74, 0xac, 0xbf, 0xf4, 0x87, 0xfe, - 0x37, 0xcc, 0x6a, 0x7d, 0x03, 0xe6, 0x8f, 0x3c, 0x37, 0xc0, 0x44, 0x50, 0x68, 0x02, 0x70, 0x10, - 0x75, 0x8f, 0x22, 0xdb, 0xa6, 0x61, 0xd8, 0x30, 0x36, 0x8d, 0xad, 0x1a, 0xce, 0x44, 0x12, 0xfc, - 0x19, 0xf1, 0xfc, 0x88, 0xd3, 0xc6, 0x9d, 0x6b, 0x3c, 0x89, 0xb4, 0xfe, 0x99, 0x07, 0xab, 0x3f, - 0x10, 0xdf, 0x73, 0x88, 0x60, 0x7c, 0xaf, 0xe7, 0x61, 0x1a, 0xf6, 0x58, 0x10, 0x52, 0xb8, 0x03, - 0xc0, 0x0b, 0xda, 0xed, 0x61, 0x22, 0xbc, 0xc0, 0xd5, 0xc2, 0x77, 0xac, 0x45, 0x25, 0x11, 0x10, - 0xd7, 0x51, 0x9c, 0x61, 0xc0, 0x2f, 0xc1, 0xd2, 0x41, 0xd4, 0xdd, 0xa7, 0xc4, 0xa1, 0x3c, 0x2d, - 0x47, 0x2f, 0x67, 0xad, 0x2a, 0x89, 0x96, 0x82, 0x11, 0x0c, 0x8f, 0xb1, 0x73, 0x0a, 0x69, 0xc1, - 0x77, 0x0b, 0x14, 0x12, 0x0c, 0x8f, 0xb1, 0x61, 0x1b, 0xac, 0x1c, 0x44, 0xdd, 0xeb, 0xed, 0xa4, - 0x65, 0xcc, 0x68, 0x91, 0xfb, 0x4a, 0xa2, 0x95, 0x60, 0x1c, 0xc6, 0x45, 0x39, 0xa3, 0x52, 0x69, - 0x3d, 0xe5, 0x62, 0xa9, 0xb4, 0xa4, 0xa2, 0x1c, 0xe8, 0x82, 0x8d, 0x6c, 0xb8, 0xed, 0x06, 0x8c, - 0x53, 0x27, 0xee, 0x20, 0x11, 0x11, 0xa7, 0x61, 0x63, 0x56, 0x8b, 0x3e, 0x54, 0x12, 0x6d, 0x04, - 0xd3, 0x88, 0x78, 0xba, 0x0e, 0x6c, 0x81, 0xd9, 0xa4, 0x5d, 0x73, 0xba, 0x5d, 0x40, 0x49, 0x34, - 0xcb, 0x87, 0xad, 0x4a, 0x10, 0xf8, 0x29, 0x58, 0x1c, 0xfe, 0x7b, 0xce, 0x1c, 0xef, 0xd8, 0xa3, - 0xbc, 0x31, 0xaf, 0xb9, 0x50, 0x49, 0xb4, 0xc8, 0x73, 0x08, 0x1e, 0x61, 0xc2, 0xef, 0xc0, 0xda, - 0x0b, 0x26, 0x88, 0x3f, 0xd6, 0xe7, 0x05, 0xbd, 0x81, 0xa6, 0x92, 0x68, 0x4d, 0x14, 0x11, 0x70, - 0x71, 0xde, 0xb8, 0x60, 0x7a, 0xcc, 0x60, 0x92, 0x60, 0x7a, 0xd0, 0xc5, 0x79, 0xf0, 0x25, 0x68, - 0xa4, 0xc0, 0xd8, 0x14, 0x54, 0xb4, 0xe6, 0x03, 0x25, 0x51, 0x43, 0x4c, 0xe0, 0xe0, 0x89, 0xd9, - 0x85, 0xca, 0x69, 0xb5, 0xd5, 0x29, 0xca, 0x69, 0xc1, 0x13, 0xb3, 0x61, 0x1f, 0xb4, 0xc6, 0xb0, - 0xf1, 0x19, 0xa9, 0xe9, 0x35, 0x1e, 0x2b, 0x89, 0x5a, 0xe2, 0x56, 0x36, 0x7e, 0x07, 0x45, 0xf8, - 0x7f, 0x30, 0x77, 0x74, 0x42, 0xb8, 0xd3, 0x76, 0x1a, 0x8b, 0x5a, 0xbc, 0xa2, 0x24, 0x9a, 0x0b, - 0x87, 0x21, 0x9c, 0x62, 0xf0, 0x6b, 0x50, 0xbf, 0x39, 0x0c, 0x41, 0x44, 0x14, 0x36, 0xea, 0x9b, - 0xc6, 0xd6, 0x82, 0xb5, 0xa1, 0x24, 0x6a, 0xf6, 0xf3, 0xd0, 0xfb, 0xac, 0xeb, 0xc5, 0xfe, 0x20, - 0xce, 0xf0, 0x68, 0x56, 0xeb, 0xcf, 0x0a, 0xa8, 0x1f, 0xe6, 0x5d, 0x10, 0x7e, 0x0c, 0xaa, 0xd6, - 0xfe, 0xd1, 0x61, 0xd4, 0xf1, 0x3d, 0xfb, 0x5b, 0x7a, 0xa6, 0x6d, 0xa6, 0x6a, 0x2d, 0x29, 0x89, - 0xaa, 0x1d, 0x3f, 0xbc, 0x8e, 0xe3, 0x1c, 0x0b, 0xee, 0x81, 0x1a, 0xa6, 0xbf, 0x12, 0xee, 0xec, - 0x39, 0x0e, 0x4f, 0x7d, 0xa6, 0x6a, 0xfd, 0x4f, 0x49, 0x74, 0x9f, 0x67, 0x81, 0x4c, 0x39, 0xf9, - 0x8c, 0xec, 0xe6, 0xef, 0x4e, 0xd9, 0x3c, 0xc9, 0x98, 0x63, 0x3a, 0x23, 0x44, 0x50, 0xed, 0x28, - 0x95, 0x0f, 0xeb, 0x43, 0x3f, 0xde, 0x49, 0xcd, 0xd8, 0x7a, 0xf0, 0x46, 0xa2, 0x92, 0x92, 0x68, - 0xb5, 0x5f, 0x90, 0x84, 0x0b, 0xa5, 0xe0, 0x4b, 0xb0, 0x9c, 0xbf, 0x2b, 0xb1, 0x7e, 0xb9, 0x58, - 0xbf, 0x99, 0xe8, 0x2f, 0xfb, 0xa3, 0x19, 0x78, 0x5c, 0x04, 0xfe, 0x02, 0xcc, 0x29, 0x23, 0x12, - 0x2f, 0x33, 0x34, 0x9e, 0x96, 0x92, 0xc8, 0xec, 0x4f, 0x65, 0xe2, 0x5b, 0x94, 0x46, 0xac, 0xa7, - 0x56, 0x68, 0x3d, 0xf9, 0x17, 0x65, 0x5e, 0xf3, 0xa6, 0xbd, 0x28, 0xaf, 0x0d, 0x50, 0xdf, 0xb3, - 0xed, 0xa8, 0x1b, 0xf9, 0x44, 0x50, 0xe7, 0x19, 0xa5, 0x43, 0xa7, 0xa9, 0x5a, 0xc7, 0xf1, 0xe8, - 0x91, 0x3c, 0x74, 0xd3, 0xeb, 0x3f, 0xfe, 0x42, 0x4f, 0xbb, 0x44, 0x9c, 0xec, 0x76, 0x3c, 0x77, - 0xa7, 0x1d, 0x88, 0xcf, 0x32, 0xaf, 0x6b, 0x37, 0xf2, 0x85, 0xd7, 0xa7, 0x3c, 0x3c, 0xdd, 0xed, - 0x9e, 0x6e, 0xdb, 0x27, 0xc4, 0x0b, 0xb6, 0x6d, 0xc6, 0xe9, 0xb6, 0xcb, 0x76, 0x9d, 0xf8, 0x5d, - 0xb6, 0x3c, 0xb7, 0x1d, 0x88, 0x27, 0x24, 0x14, 0x94, 0xe3, 0xd1, 0xe5, 0xe1, 0xcf, 0x60, 0x3d, - 0x7e, 0x5b, 0xa9, 0x4f, 0x6d, 0x41, 0x9d, 0x76, 0x90, 0x1c, 0xb7, 0xe5, 0x33, 0xfb, 0x55, 0x98, - 0xb8, 0x96, 0xa9, 0x24, 0x5a, 0x0f, 0x26, 0xb2, 0xf0, 0x14, 0x05, 0xf8, 0x01, 0xa8, 0xb4, 0x03, - 0x87, 0x9e, 0xb6, 0x83, 0x7d, 0x2f, 0x14, 0x89, 0x65, 0xd5, 0x95, 0x44, 0x15, 0xef, 0x26, 0x8c, - 0xb3, 0x1c, 0xf8, 0x18, 0xcc, 0x68, 0x6e, 0x55, 0x5f, 0x4a, 0x6d, 0xe3, 0xbe, 0x17, 0x8a, 0xcc, - 0xe8, 0x6b, 0x1c, 0xfe, 0x04, 0x9a, 0x4f, 0xe2, 0x87, 0xdd, 0x8e, 0xe2, 0x03, 0x38, 0xe4, 0xac, - 0xc7, 0x42, 0xca, 0x9f, 0x7b, 0x61, 0x78, 0xed, 0x2e, 0xfa, 0x46, 0xdb, 0x93, 0x48, 0x78, 0x72, - 0x3e, 0xec, 0x81, 0xa6, 0x76, 0x9c, 0xc2, 0xcb, 0xb2, 0x58, 0x3c, 0xcc, 0x0f, 0x93, 0x61, 0x6e, - 0x8a, 0x49, 0x99, 0x78, 0xb2, 0x28, 0x74, 0xc1, 0x3d, 0x0d, 0x8e, 0xdf, 0x9d, 0x7a, 0xf1, 0x72, - 0x66, 0xb2, 0xdc, 0x3d, 0x51, 0x98, 0x86, 0x27, 0xc8, 0xc1, 0x33, 0xf0, 0x28, 0x5f, 0x45, 0xf1, - 0x55, 0x5a, 0xd2, 0x27, 0xf8, 0x9e, 0x92, 0xe8, 0x91, 0xb8, 0x9d, 0x8e, 0xdf, 0x45, 0x13, 0x22, - 0x50, 0x3e, 0x60, 0x81, 0x4d, 0x1b, 0xcb, 0x9b, 0xc6, 0xd6, 0x8c, 0xb5, 0xa0, 0x24, 0x2a, 0x07, - 0x71, 0x00, 0x0f, 0xe3, 0xf0, 0x13, 0x50, 0xfb, 0x3e, 0x38, 0x12, 0xe4, 0x15, 0x75, 0x9e, 0xf6, - 0x98, 0x7d, 0xd2, 0x80, 0xba, 0x8a, 0x65, 0x25, 0x51, 0x2d, 0xca, 0x02, 0x38, 0xcf, 0x83, 0x9f, - 0x83, 0xea, 0x21, 0xa7, 0x7d, 0x8f, 0x45, 0xa1, 0x1e, 0x9e, 0x15, 0x3d, 0x3c, 0xeb, 0xf1, 0xf1, - 0xf4, 0x32, 0xf1, 0xcc, 0x10, 0xe5, 0xf8, 0xd6, 0x17, 0xe7, 0x97, 0x66, 0xe9, 0xe2, 0xd2, 0x2c, - 0xbd, 0xbd, 0x34, 0x8d, 0xdf, 0x06, 0xa6, 0xf1, 0xfb, 0xc0, 0x34, 0xde, 0x0c, 0x4c, 0xe3, 0x7c, - 0x60, 0x1a, 0x17, 0x03, 0xd3, 0xf8, 0x7b, 0x60, 0x1a, 0xff, 0x0e, 0xcc, 0xd2, 0xdb, 0x81, 0x69, - 0xbc, 0xbe, 0x32, 0x4b, 0xe7, 0x57, 0x66, 0xe9, 0xe2, 0xca, 0x2c, 0xfd, 0x58, 0x0e, 0x05, 0x11, - 0xb4, 0x33, 0xab, 0xbb, 0xf3, 0xd1, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xde, 0xed, 0x5e, 0x5d, - 0x18, 0x0b, 0x00, 0x00, + // 1063 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0xdb, 0x46, + 0x17, 0x15, 0x13, 0xcb, 0x3f, 0x63, 0xc9, 0xb2, 0xc7, 0x76, 0x22, 0xf9, 0x8b, 0x39, 0x8e, 0x82, + 0x2f, 0xf5, 0xa2, 0xb6, 0xd1, 0x1f, 0xa0, 0x40, 0x0b, 0xb4, 0x35, 0xd3, 0xa4, 0x50, 0xeb, 0xb8, + 0xc6, 0x28, 0x2d, 0x82, 0x16, 0x28, 0x30, 0x22, 0xc7, 0x34, 0x1b, 0x8a, 0x14, 0x86, 0x43, 0xd5, + 0xde, 0xf5, 0x11, 0xf2, 0x04, 0x5d, 0x17, 0x7d, 0x92, 0x2c, 0xbd, 0xf4, 0x6a, 0x5a, 0xcb, 0x8b, + 0x16, 0xb3, 0xca, 0x23, 0x14, 0x1c, 0x91, 0x36, 0x29, 0x92, 0x72, 0x56, 0x16, 0xef, 0x39, 0xf7, + 0xcc, 0x9d, 0xb9, 0x77, 0xce, 0x18, 0xac, 0x0f, 0x28, 0x65, 0xfb, 0xa6, 0xe9, 0x87, 0x1e, 0xff, + 0x8a, 0x70, 0xb2, 0x3b, 0x60, 0x3e, 0xf7, 0x61, 0x55, 0xfd, 0xd9, 0xd8, 0xb1, 0x1d, 0x7e, 0x12, + 0xf6, 0x76, 0x4d, 0xbf, 0xbf, 0x67, 0xfb, 0xb6, 0xbf, 0xa7, 0xc2, 0xbd, 0xf0, 0x58, 0x7d, 0xa9, + 0x0f, 0xf5, 0x6b, 0x9c, 0xd5, 0xfe, 0x06, 0xcc, 0x77, 0x1d, 0xdb, 0xc3, 0x84, 0x53, 0xa8, 0x03, + 0x70, 0x18, 0xf6, 0xbb, 0xa1, 0x69, 0xd2, 0x20, 0x68, 0x6a, 0x5b, 0xda, 0x76, 0x1d, 0xa7, 0x22, + 0x31, 0xfe, 0x8c, 0x38, 0x6e, 0xc8, 0x68, 0xf3, 0xce, 0x35, 0x1e, 0x47, 0xda, 0xff, 0xcc, 0x83, + 0xb5, 0x1f, 0x88, 0xeb, 0x58, 0x84, 0xfb, 0x6c, 0x7f, 0xe0, 0x60, 0x1a, 0x0c, 0x7c, 0x2f, 0xa0, + 0x70, 0x17, 0x80, 0x17, 0xb4, 0x3f, 0xc0, 0x84, 0x3b, 0x9e, 0xad, 0x84, 0xef, 0x18, 0x4b, 0x52, + 0x20, 0xc0, 0xaf, 0xa3, 0x38, 0xc5, 0x80, 0x5f, 0x82, 0xe5, 0xc3, 0xb0, 0x7f, 0x40, 0x89, 0x45, + 0x59, 0x52, 0x8e, 0x5a, 0xce, 0x58, 0x93, 0x02, 0x2d, 0x7b, 0x13, 0x18, 0xce, 0xb1, 0x33, 0x0a, + 0x49, 0xc1, 0x77, 0x0b, 0x14, 0x62, 0x0c, 0xe7, 0xd8, 0xb0, 0x03, 0x56, 0x0f, 0xc3, 0xfe, 0xf5, + 0x76, 0x92, 0x32, 0x66, 0x94, 0xc8, 0x7d, 0x29, 0xd0, 0xaa, 0x97, 0x87, 0x71, 0x51, 0xce, 0xa4, + 0x54, 0x52, 0x4f, 0xb5, 0x58, 0x2a, 0x29, 0xa9, 0x28, 0x07, 0xda, 0x60, 0x33, 0x1d, 0xee, 0xd8, + 0x9e, 0xcf, 0xa8, 0x15, 0x75, 0x90, 0xf0, 0x90, 0xd1, 0xa0, 0x39, 0xab, 0x44, 0x1f, 0x4a, 0x81, + 0x36, 0xbd, 0x69, 0x44, 0x3c, 0x5d, 0x07, 0xb6, 0xc1, 0x6c, 0xdc, 0xae, 0x39, 0xd5, 0x2e, 0x20, + 0x05, 0x9a, 0x65, 0xe3, 0x56, 0xc5, 0x08, 0xfc, 0x14, 0x2c, 0x8d, 0x7f, 0x3d, 0xf7, 0x2d, 0xe7, + 0xd8, 0xa1, 0xac, 0x39, 0xaf, 0xb8, 0x50, 0x0a, 0xb4, 0xc4, 0x32, 0x08, 0x9e, 0x60, 0xc2, 0xef, + 0xc0, 0xfa, 0x0b, 0x9f, 0x13, 0x37, 0xd7, 0xe7, 0x05, 0xb5, 0x81, 0x96, 0x14, 0x68, 0x9d, 0x17, + 0x11, 0x70, 0x71, 0x5e, 0x5e, 0x30, 0x39, 0x66, 0x50, 0x26, 0x98, 0x1c, 0x74, 0x71, 0x1e, 0x7c, + 0x09, 0x9a, 0x09, 0x90, 0x9b, 0x82, 0x45, 0xa5, 0xf9, 0x40, 0x0a, 0xd4, 0xe4, 0x25, 0x1c, 0x5c, + 0x9a, 0x5d, 0xa8, 0x9c, 0x54, 0x5b, 0x9b, 0xa2, 0x9c, 0x14, 0x5c, 0x9a, 0x0d, 0x87, 0xa0, 0x9d, + 0xc3, 0xf2, 0x33, 0x52, 0x57, 0x6b, 0x3c, 0x96, 0x02, 0xb5, 0xf9, 0xad, 0x6c, 0xfc, 0x0e, 0x8a, + 0xf0, 0xff, 0x60, 0xae, 0x7b, 0x42, 0x98, 0xd5, 0xb1, 0x9a, 0x4b, 0x4a, 0x7c, 0x51, 0x0a, 0x34, + 0x17, 0x8c, 0x43, 0x38, 0xc1, 0xe0, 0xd7, 0xa0, 0x71, 0x73, 0x18, 0x9c, 0xf0, 0x30, 0x68, 0x36, + 0xb6, 0xb4, 0xed, 0x05, 0x63, 0x53, 0x0a, 0xd4, 0x1a, 0x66, 0xa1, 0xf7, 0xfd, 0xbe, 0x13, 0xf9, + 0x03, 0x3f, 0xc3, 0x93, 0x59, 0xed, 0xdf, 0x6b, 0xa0, 0x71, 0x94, 0x75, 0x41, 0xf8, 0x31, 0xa8, + 0x19, 0x07, 0xdd, 0xa3, 0xb0, 0xe7, 0x3a, 0xe6, 0xb7, 0xf4, 0x4c, 0xd9, 0x4c, 0xcd, 0x58, 0x96, + 0x02, 0xd5, 0x7a, 0x6e, 0x70, 0x1d, 0xc7, 0x19, 0x16, 0xdc, 0x07, 0x75, 0x4c, 0x7f, 0x25, 0xcc, + 0xda, 0xb7, 0x2c, 0x96, 0xf8, 0x4c, 0xcd, 0xf8, 0x9f, 0x14, 0xe8, 0x3e, 0x4b, 0x03, 0xa9, 0x72, + 0xb2, 0x19, 0xe9, 0xcd, 0xdf, 0x9d, 0xb2, 0x79, 0x92, 0x32, 0xc7, 0x64, 0x46, 0x08, 0xa7, 0xca, + 0x51, 0x16, 0x3f, 0x6c, 0x8c, 0xfd, 0x78, 0x37, 0x31, 0x63, 0xe3, 0xc1, 0x1b, 0x81, 0x2a, 0x52, + 0xa0, 0xb5, 0x61, 0x41, 0x12, 0x2e, 0x94, 0x82, 0x2f, 0xc1, 0x4a, 0xf6, 0xae, 0x44, 0xfa, 0xd5, + 0x62, 0xfd, 0x56, 0xac, 0xbf, 0xe2, 0x4e, 0x66, 0xe0, 0xbc, 0x08, 0xfc, 0x05, 0xe8, 0x53, 0x46, + 0x24, 0x5a, 0x66, 0x6c, 0x3c, 0x6d, 0x29, 0x90, 0x3e, 0x9c, 0xca, 0xc4, 0xb7, 0x28, 0x4d, 0x58, + 0x4f, 0xbd, 0xd0, 0x7a, 0xb2, 0x2f, 0xca, 0xbc, 0xe2, 0x4d, 0x7b, 0x51, 0x5e, 0x6b, 0xa0, 0xb1, + 0x6f, 0x9a, 0x61, 0x3f, 0x74, 0x09, 0xa7, 0xd6, 0x33, 0x4a, 0xc7, 0x4e, 0x53, 0x33, 0x8e, 0xa3, + 0xd1, 0x23, 0x59, 0xe8, 0xa6, 0xd7, 0x7f, 0xfe, 0x85, 0x9e, 0xf6, 0x09, 0x3f, 0xd9, 0xeb, 0x39, + 0xf6, 0x6e, 0xc7, 0xe3, 0x9f, 0xa5, 0x5e, 0xd7, 0x7e, 0xe8, 0x72, 0x67, 0x48, 0x59, 0x70, 0xba, + 0xd7, 0x3f, 0xdd, 0x31, 0x4f, 0x88, 0xe3, 0xed, 0x98, 0x3e, 0xa3, 0x3b, 0xb6, 0xbf, 0x67, 0x45, + 0xef, 0xb2, 0xe1, 0xd8, 0x1d, 0x8f, 0x3f, 0x21, 0x01, 0xa7, 0x0c, 0x4f, 0x2e, 0x0f, 0x7f, 0x06, + 0x1b, 0xd1, 0xdb, 0x4a, 0x5d, 0x6a, 0x72, 0x6a, 0x75, 0xbc, 0xf8, 0xb8, 0x0d, 0xd7, 0x37, 0x5f, + 0x05, 0xb1, 0x6b, 0xe9, 0x52, 0xa0, 0x0d, 0xaf, 0x94, 0x85, 0xa7, 0x28, 0xc0, 0x0f, 0xc0, 0x62, + 0xc7, 0xb3, 0xe8, 0x69, 0xc7, 0x3b, 0x70, 0x02, 0x1e, 0x5b, 0x56, 0x43, 0x0a, 0xb4, 0xe8, 0xdc, + 0x84, 0x71, 0x9a, 0x03, 0x1f, 0x83, 0x19, 0xc5, 0xad, 0xa9, 0x4b, 0xa9, 0x6c, 0xdc, 0x75, 0x02, + 0x9e, 0x1a, 0x7d, 0x85, 0xc3, 0x9f, 0x40, 0xeb, 0x49, 0xf4, 0xb0, 0x9b, 0x61, 0x74, 0x00, 0x47, + 0xcc, 0x1f, 0xf8, 0x01, 0x65, 0xcf, 0x9d, 0x20, 0xb8, 0x76, 0x17, 0x75, 0xa3, 0xcd, 0x32, 0x12, + 0x2e, 0xcf, 0x87, 0x03, 0xd0, 0x52, 0x8e, 0x53, 0x78, 0x59, 0x96, 0x8a, 0x87, 0xf9, 0x61, 0x3c, + 0xcc, 0x2d, 0x5e, 0x96, 0x89, 0xcb, 0x45, 0xa1, 0x0d, 0xee, 0x29, 0x30, 0x7f, 0x77, 0x1a, 0xc5, + 0xcb, 0xe9, 0xf1, 0x72, 0xf7, 0x78, 0x61, 0x1a, 0x2e, 0x91, 0x83, 0x67, 0xe0, 0x51, 0xb6, 0x8a, + 0xe2, 0xab, 0xb4, 0xac, 0x4e, 0xf0, 0x3d, 0x29, 0xd0, 0x23, 0x7e, 0x3b, 0x1d, 0xbf, 0x8b, 0x26, + 0x44, 0xa0, 0x7a, 0xe8, 0x7b, 0x26, 0x6d, 0xae, 0x6c, 0x69, 0xdb, 0x33, 0xc6, 0x82, 0x14, 0xa8, + 0xea, 0x45, 0x01, 0x3c, 0x8e, 0xc3, 0x4f, 0x40, 0xfd, 0x7b, 0xaf, 0xcb, 0xc9, 0x2b, 0x6a, 0x3d, + 0x1d, 0xf8, 0xe6, 0x49, 0x13, 0xaa, 0x2a, 0x56, 0xa4, 0x40, 0xf5, 0x30, 0x0d, 0xe0, 0x2c, 0x0f, + 0x7e, 0x0e, 0x6a, 0x47, 0x8c, 0x0e, 0x1d, 0x3f, 0x0c, 0xd4, 0xf0, 0xac, 0xaa, 0xe1, 0xd9, 0x88, + 0x8e, 0x67, 0x90, 0x8a, 0xa7, 0x86, 0x28, 0xc3, 0x87, 0x5d, 0xb0, 0x9a, 0x7c, 0xa7, 0xe7, 0x75, + 0xed, 0xe6, 0x1f, 0x99, 0x41, 0x1e, 0x4e, 0xa9, 0x15, 0x65, 0x1b, 0x5f, 0x9c, 0x5f, 0xea, 0x95, + 0x8b, 0x4b, 0xbd, 0xf2, 0xf6, 0x52, 0xd7, 0x7e, 0x1b, 0xe9, 0xda, 0x1f, 0x23, 0x5d, 0x7b, 0x33, + 0xd2, 0xb5, 0xf3, 0x91, 0xae, 0x5d, 0x8c, 0x74, 0xed, 0xef, 0x91, 0xae, 0xfd, 0x3b, 0xd2, 0x2b, + 0x6f, 0x47, 0xba, 0xf6, 0xfa, 0x4a, 0xaf, 0x9c, 0x5f, 0xe9, 0x95, 0x8b, 0x2b, 0xbd, 0xf2, 0x63, + 0x35, 0xe0, 0x84, 0xd3, 0xde, 0xac, 0x6a, 0xf9, 0x47, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xdd, + 0x14, 0xe4, 0x72, 0x6d, 0x0b, 0x00, 0x00, } func (this *SignRate) Equal(that interface{}) bool { @@ -663,6 +672,9 @@ func (this *PeerAccountData) Equal(that interface{}) bool { if this.PreviousList != that1.PreviousList { return false } + if this.PreviousIndexInList != that1.PreviousIndexInList { + return false + } return true } func (this *SignRate) GoString() string { @@ -704,7 +716,7 @@ func (this *PeerAccountData) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 23) + s := make([]string, 0, 24) s = append(s, "&state.PeerAccountData{") s = append(s, "BLSPublicKey: "+fmt.Sprintf("%#v", this.BLSPublicKey)+",\n") s = append(s, "RewardAddress: "+fmt.Sprintf("%#v", this.RewardAddress)+",\n") @@ -725,6 +737,7 @@ func (this *PeerAccountData) GoString() string { s = append(s, "Nonce: "+fmt.Sprintf("%#v", this.Nonce)+",\n") s = append(s, "UnStakedEpoch: "+fmt.Sprintf("%#v", this.UnStakedEpoch)+",\n") s = append(s, "PreviousList: "+fmt.Sprintf("%#v", this.PreviousList)+",\n") + s = append(s, "PreviousIndexInList: "+fmt.Sprintf("%#v", this.PreviousIndexInList)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -892,6 +905,13 @@ func (m *PeerAccountData) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PreviousIndexInList != 0 { + i = encodeVarintPeerAccountData(dAtA, i, uint64(m.PreviousIndexInList)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa0 + } if len(m.PreviousList) > 0 { i -= len(m.PreviousList) copy(dAtA[i:], m.PreviousList) @@ -1178,6 +1198,9 @@ func (m *PeerAccountData) Size() (n int) { if l > 0 { n += 2 + l + sovPeerAccountData(uint64(l)) } + if m.PreviousIndexInList != 0 { + n += 2 + sovPeerAccountData(uint64(m.PreviousIndexInList)) + } return n } @@ -1246,6 +1269,7 @@ func (this *PeerAccountData) String() string { `Nonce:` + fmt.Sprintf("%v", this.Nonce) + `,`, `UnStakedEpoch:` + fmt.Sprintf("%v", this.UnStakedEpoch) + `,`, `PreviousList:` + fmt.Sprintf("%v", this.PreviousList) + `,`, + `PreviousIndexInList:` + fmt.Sprintf("%v", this.PreviousIndexInList) + `,`, `}`, }, "") return s @@ -2197,6 +2221,25 @@ func (m *PeerAccountData) Unmarshal(dAtA []byte) error { } m.PreviousList = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 20: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousIndexInList", wireType) + } + m.PreviousIndexInList = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerAccountData + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PreviousIndexInList |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipPeerAccountData(dAtA[iNdEx:]) diff --git a/state/peerAccountData.proto b/state/peerAccountData.proto index d0fd3af1ec2..2f6e7583beb 100644 --- a/state/peerAccountData.proto +++ b/state/peerAccountData.proto @@ -53,4 +53,5 @@ message PeerAccountData { uint64 Nonce = 17 [(gogoproto.jsontag) = "nonce"]; uint32 UnStakedEpoch = 18 [(gogoproto.jsontag) = "unStakedEpoch"]; string PreviousList = 19 [(gogoproto.jsontag) = "previousList,omitempty"]; + uint32 PreviousIndexInList = 20 [(gogoproto.jsontag) = "previousIndexInList,omitempty"]; } diff --git a/state/validatorInfo.pb.go b/state/validatorInfo.pb.go index 8081e1a4d30..3261e3da880 100644 --- a/state/validatorInfo.pb.go +++ b/state/validatorInfo.pb.go @@ -52,6 +52,7 @@ type ValidatorInfo struct { TotalValidatorFailure uint32 `protobuf:"varint,19,opt,name=TotalValidatorFailure,proto3" json:"totalValidatorFailure"` TotalValidatorIgnoredSignatures uint32 `protobuf:"varint,20,opt,name=TotalValidatorIgnoredSignatures,proto3" json:"totalValidatorIgnoredSignatures"` PreviousList string `protobuf:"bytes,21,opt,name=PreviousList,proto3" json:"previousList,omitempty"` + PreviousIndex uint32 `protobuf:"varint,22,opt,name=PreviousIndex,proto3" json:"previousIndex,omitempty"` } func (m *ValidatorInfo) Reset() { *m = ValidatorInfo{} } @@ -229,14 +230,22 @@ func (m *ValidatorInfo) GetPreviousList() string { return "" } +func (m *ValidatorInfo) GetPreviousIndex() uint32 { + if m != nil { + return m.PreviousIndex + } + return 0 +} + // ShardValidatorInfo represents the data regarding a validator that is stored in the PeerMiniblocks type ShardValidatorInfo struct { - PublicKey []byte `protobuf:"bytes,1,opt,name=PublicKey,proto3" json:"publicKey"` - ShardId uint32 `protobuf:"varint,2,opt,name=ShardId,proto3" json:"shardId"` - List string `protobuf:"bytes,3,opt,name=List,proto3" json:"list,omitempty"` - Index uint32 `protobuf:"varint,4,opt,name=Index,proto3" json:"index"` - TempRating uint32 `protobuf:"varint,5,opt,name=TempRating,proto3" json:"tempRating"` - PreviousList string `protobuf:"bytes,6,opt,name=PreviousList,proto3" json:"previousList,omitempty"` + PublicKey []byte `protobuf:"bytes,1,opt,name=PublicKey,proto3" json:"publicKey"` + ShardId uint32 `protobuf:"varint,2,opt,name=ShardId,proto3" json:"shardId"` + List string `protobuf:"bytes,3,opt,name=List,proto3" json:"list,omitempty"` + Index uint32 `protobuf:"varint,4,opt,name=Index,proto3" json:"index"` + TempRating uint32 `protobuf:"varint,5,opt,name=TempRating,proto3" json:"tempRating"` + PreviousList string `protobuf:"bytes,6,opt,name=PreviousList,proto3" json:"previousList,omitempty"` + PreviousIndex uint32 `protobuf:"varint,7,opt,name=PreviousIndex,proto3" json:"previousIndex,omitempty"` } func (m *ShardValidatorInfo) Reset() { *m = ShardValidatorInfo{} } @@ -309,6 +318,13 @@ func (m *ShardValidatorInfo) GetPreviousList() string { return "" } +func (m *ShardValidatorInfo) GetPreviousIndex() uint32 { + if m != nil { + return m.PreviousIndex + } + return 0 +} + func init() { proto.RegisterType((*ValidatorInfo)(nil), "proto.ValidatorInfo") proto.RegisterType((*ShardValidatorInfo)(nil), "proto.ShardValidatorInfo") @@ -317,54 +333,56 @@ func init() { func init() { proto.RegisterFile("validatorInfo.proto", fileDescriptor_bf9cdc082f0b2ec2) } var fileDescriptor_bf9cdc082f0b2ec2 = []byte{ - // 750 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcf, 0x6e, 0xe2, 0x46, - 0x18, 0xc7, 0x69, 0x20, 0x61, 0x12, 0x48, 0x32, 0xf9, 0x53, 0x87, 0x56, 0x1e, 0x94, 0xaa, 0x15, - 0x52, 0x0b, 0x1c, 0x7a, 0xa8, 0xd4, 0x4a, 0x6d, 0x43, 0xd5, 0x48, 0xa8, 0x69, 0x1b, 0x0d, 0x51, - 0x0f, 0x3d, 0x54, 0x1a, 0xec, 0xc1, 0x8c, 0xea, 0x3f, 0x68, 0x3c, 0xa6, 0xc9, 0xad, 0x8f, 0x90, - 0x37, 0xa8, 0x7a, 0x5b, 0xed, 0x93, 0xec, 0x31, 0xc7, 0x9c, 0x66, 0x37, 0xce, 0x65, 0x35, 0xa7, - 0x3c, 0xc2, 0x8a, 0x01, 0x07, 0x0c, 0x24, 0xab, 0x3d, 0xe4, 0x84, 0xfd, 0xfb, 0x37, 0x1f, 0xf3, - 0x7d, 0x7c, 0x80, 0xdd, 0x21, 0xf1, 0x98, 0x43, 0x44, 0xc8, 0xdb, 0x41, 0x2f, 0x6c, 0x0c, 0x78, - 0x28, 0x42, 0x98, 0xd7, 0x1f, 0x95, 0xba, 0xcb, 0x44, 0x3f, 0xee, 0x36, 0xec, 0xd0, 0x6f, 0xba, - 0xa1, 0x1b, 0x36, 0x35, 0xdc, 0x8d, 0x7b, 0xfa, 0x4d, 0xbf, 0xe8, 0xa7, 0xb1, 0xeb, 0xe8, 0xbf, - 0x0d, 0x50, 0xfa, 0x63, 0x36, 0x0d, 0x7e, 0x09, 0x8a, 0x67, 0x71, 0xd7, 0x63, 0xf6, 0x2f, 0xf4, - 0xd2, 0x34, 0xaa, 0x46, 0x6d, 0xb3, 0x55, 0x52, 0x12, 0x15, 0x07, 0x29, 0x88, 0xa7, 0x3c, 0xfc, - 0x1c, 0xac, 0x75, 0xfa, 0x84, 0x3b, 0x6d, 0xc7, 0x5c, 0xa9, 0x1a, 0xb5, 0x52, 0x6b, 0x43, 0x49, - 0xb4, 0x16, 0x8d, 0x21, 0x9c, 0x72, 0xf0, 0x53, 0xb0, 0x7a, 0xca, 0x22, 0x61, 0x7e, 0x54, 0x35, - 0x6a, 0xc5, 0xd6, 0xba, 0x92, 0x68, 0xd5, 0x63, 0x91, 0xc0, 0x1a, 0x85, 0x08, 0xe4, 0xdb, 0x81, - 0x43, 0x2f, 0xcc, 0x55, 0x1d, 0x51, 0x54, 0x12, 0xe5, 0xd9, 0x08, 0xc0, 0x63, 0x1c, 0x36, 0x00, - 0x38, 0xa7, 0xfe, 0x00, 0x13, 0xc1, 0x02, 0xd7, 0xcc, 0x6b, 0x55, 0x59, 0x49, 0x04, 0xc4, 0x03, - 0x8a, 0x67, 0x14, 0xf0, 0x08, 0x14, 0x26, 0xda, 0x82, 0xd6, 0x02, 0x25, 0x51, 0x81, 0x8f, 0x75, - 0x13, 0x06, 0x7e, 0x0b, 0xca, 0xe3, 0xa7, 0x5f, 0x43, 0x87, 0xf5, 0x18, 0xe5, 0xe6, 0x5a, 0xd5, - 0xa8, 0xad, 0xb4, 0xa0, 0x92, 0xa8, 0xcc, 0x33, 0x0c, 0x9e, 0x53, 0xc2, 0x63, 0x50, 0xc2, 0xf4, - 0x1f, 0xc2, 0x9d, 0x63, 0xc7, 0xe1, 0x34, 0x8a, 0xcc, 0x75, 0x7d, 0x4d, 0x9f, 0x28, 0x89, 0x3e, - 0xe6, 0xb3, 0xc4, 0x57, 0xa1, 0xcf, 0x46, 0x35, 0x8a, 0x4b, 0x9c, 0x75, 0xc0, 0x6f, 0x40, 0xe9, - 0x94, 0x12, 0x87, 0xf2, 0x4e, 0x6c, 0xdb, 0xa3, 0x88, 0xa2, 0xae, 0x74, 0x47, 0x49, 0x54, 0xf2, - 0x66, 0x09, 0x9c, 0xd5, 0x4d, 0x8d, 0x27, 0x84, 0x79, 0x31, 0xa7, 0x26, 0x98, 0x37, 0x4e, 0x08, - 0x9c, 0xd5, 0xc1, 0x1f, 0xc1, 0xf6, 0x43, 0xa3, 0xd3, 0x43, 0x37, 0xb4, 0x77, 0x4f, 0x49, 0xb4, - 0x3d, 0x9c, 0xe3, 0xf0, 0x82, 0x3a, 0x93, 0x90, 0x9e, 0xbe, 0xb9, 0x24, 0x21, 0x2d, 0x60, 0x41, - 0x0d, 0xff, 0x02, 0x95, 0xe9, 0xb0, 0xb9, 0x41, 0xc8, 0xa9, 0xd3, 0x61, 0x6e, 0x40, 0x44, 0xcc, - 0x69, 0x64, 0x96, 0x74, 0x96, 0xa5, 0x24, 0xaa, 0x0c, 0x1f, 0x55, 0xe1, 0x27, 0x12, 0x46, 0xf9, - 0xbf, 0xc5, 0x7e, 0x87, 0x7a, 0xd4, 0x16, 0xd4, 0x69, 0x07, 0x93, 0xca, 0x5b, 0x5e, 0x68, 0xff, - 0x1d, 0x99, 0xe5, 0x69, 0x7e, 0xf0, 0xa8, 0x0a, 0x3f, 0x91, 0x00, 0xaf, 0x0c, 0xb0, 0x75, 0x6c, - 0xdb, 0xb1, 0x1f, 0x7b, 0x44, 0x50, 0xe7, 0x84, 0xd2, 0xc8, 0xdc, 0xd2, 0xbd, 0xef, 0x29, 0x89, - 0x0e, 0x49, 0x96, 0x9a, 0x76, 0xff, 0xe5, 0x6b, 0xf4, 0xb3, 0x4f, 0x44, 0xbf, 0xd9, 0x65, 0x6e, - 0xa3, 0x1d, 0x88, 0xef, 0x66, 0x7e, 0xa4, 0x7e, 0xec, 0x09, 0x36, 0xa4, 0x3c, 0xba, 0x68, 0xfa, - 0x17, 0x75, 0xbb, 0x4f, 0x58, 0x50, 0xb7, 0x43, 0x4e, 0xeb, 0x6e, 0xd8, 0x74, 0x88, 0x20, 0x8d, - 0x16, 0x73, 0xdb, 0x81, 0xf8, 0x89, 0x44, 0x82, 0x72, 0x3c, 0x7f, 0x3c, 0x3c, 0x01, 0xf0, 0x3c, - 0x14, 0xc4, 0xcb, 0x4e, 0xd3, 0xb6, 0xfe, 0xaa, 0x07, 0x4a, 0x22, 0x28, 0x16, 0x58, 0xbc, 0xc4, - 0x31, 0x97, 0x93, 0xb6, 0x77, 0x67, 0x69, 0x4e, 0xda, 0xe0, 0x25, 0x0e, 0xf8, 0x3b, 0xd8, 0xd7, - 0xe8, 0xc2, 0xac, 0x41, 0x1d, 0x75, 0xa8, 0x24, 0xda, 0x17, 0xcb, 0x04, 0x78, 0xb9, 0x6f, 0x31, - 0x30, 0xad, 0x6d, 0xf7, 0xb1, 0xc0, 0xb4, 0xbc, 0xe5, 0x3e, 0xe8, 0x03, 0x94, 0x25, 0x16, 0x27, - 0x71, 0x4f, 0x47, 0x7f, 0xa6, 0x24, 0x42, 0xe2, 0x69, 0x29, 0x7e, 0x5f, 0x16, 0xfc, 0x1e, 0x6c, - 0x9e, 0x71, 0x3a, 0x64, 0x61, 0x1c, 0xe9, 0x1d, 0xb8, 0xaf, 0x77, 0x60, 0x45, 0x49, 0x74, 0x30, - 0x98, 0xc1, 0x67, 0x56, 0x45, 0x46, 0x7f, 0xf4, 0xff, 0x0a, 0x80, 0x7a, 0x8f, 0x3e, 0xff, 0x9a, - 0xfe, 0x22, 0xb3, 0xa6, 0xf5, 0x26, 0xf4, 0xb2, 0xa5, 0x3d, 0xd3, 0xc2, 0x9e, 0xbf, 0xa3, 0xc2, - 0x87, 0xdd, 0x51, 0xeb, 0x87, 0xeb, 0x5b, 0x2b, 0x77, 0x73, 0x6b, 0xe5, 0xee, 0x6f, 0x2d, 0xe3, - 0xdf, 0xc4, 0x32, 0x5e, 0x24, 0x96, 0xf1, 0x2a, 0xb1, 0x8c, 0xeb, 0xc4, 0x32, 0x6e, 0x12, 0xcb, - 0x78, 0x93, 0x58, 0xc6, 0xdb, 0xc4, 0xca, 0xdd, 0x27, 0x96, 0x71, 0x75, 0x67, 0xe5, 0xae, 0xef, - 0xac, 0xdc, 0xcd, 0x9d, 0x95, 0xfb, 0x33, 0x1f, 0x09, 0x22, 0x68, 0xb7, 0xa0, 0xff, 0x0d, 0xbf, - 0x7e, 0x17, 0x00, 0x00, 0xff, 0xff, 0x93, 0xed, 0x72, 0x8e, 0x5a, 0x07, 0x00, 0x00, + // 770 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x4d, 0x6f, 0xf3, 0x34, + 0x1c, 0x6f, 0xc6, 0xda, 0x3e, 0xf5, 0xd6, 0x3e, 0x9b, 0xf7, 0x42, 0x56, 0x50, 0x5c, 0x0d, 0x81, + 0x2a, 0x41, 0xdb, 0x03, 0x07, 0x24, 0x90, 0x80, 0x15, 0x31, 0xa9, 0x62, 0xc0, 0xe4, 0x4e, 0x1c, + 0x38, 0x20, 0xb9, 0x89, 0x9b, 0x5a, 0xe4, 0xa5, 0x72, 0x9c, 0xb2, 0xdd, 0xf8, 0x08, 0xfb, 0x18, + 0x88, 0x4f, 0xc2, 0x71, 0xc7, 0x9d, 0x0c, 0xcb, 0x38, 0x20, 0x9f, 0xf6, 0x11, 0x50, 0xdd, 0x66, + 0x4d, 0xda, 0x6e, 0x08, 0x3d, 0xda, 0xa9, 0xf1, 0xff, 0xf7, 0xe2, 0x7f, 0xfc, 0x77, 0x7f, 0x01, + 0x7b, 0x13, 0xe2, 0x31, 0x87, 0x88, 0x90, 0xf7, 0x82, 0x61, 0xd8, 0x1e, 0xf3, 0x50, 0x84, 0xb0, + 0xa8, 0x7f, 0xea, 0x2d, 0x97, 0x89, 0x51, 0x3c, 0x68, 0xdb, 0xa1, 0xdf, 0x71, 0x43, 0x37, 0xec, + 0xe8, 0xf2, 0x20, 0x1e, 0xea, 0x95, 0x5e, 0xe8, 0xa7, 0x99, 0xea, 0x38, 0xd9, 0x02, 0xd5, 0x1f, + 0xb2, 0x6e, 0xf0, 0x43, 0x50, 0x39, 0x8f, 0x07, 0x1e, 0xb3, 0xbf, 0xa1, 0x57, 0xa6, 0xd1, 0x30, + 0x9a, 0xdb, 0xdd, 0xaa, 0x92, 0xa8, 0x32, 0x4e, 0x8b, 0x78, 0x81, 0xc3, 0xf7, 0x41, 0xb9, 0x3f, + 0x22, 0xdc, 0xe9, 0x39, 0xe6, 0x46, 0xc3, 0x68, 0x56, 0xbb, 0x5b, 0x4a, 0xa2, 0x72, 0x34, 0x2b, + 0xe1, 0x14, 0x83, 0xef, 0x82, 0xcd, 0x33, 0x16, 0x09, 0xf3, 0xad, 0x86, 0xd1, 0xac, 0x74, 0x5f, + 0x29, 0x89, 0x36, 0x3d, 0x16, 0x09, 0xac, 0xab, 0x10, 0x81, 0x62, 0x2f, 0x70, 0xe8, 0xa5, 0xb9, + 0xa9, 0x2d, 0x2a, 0x4a, 0xa2, 0x22, 0x9b, 0x16, 0xf0, 0xac, 0x0e, 0xdb, 0x00, 0x5c, 0x50, 0x7f, + 0x8c, 0x89, 0x60, 0x81, 0x6b, 0x16, 0x35, 0xab, 0xa6, 0x24, 0x02, 0xe2, 0xb1, 0x8a, 0x33, 0x0c, + 0x78, 0x0c, 0x4a, 0x73, 0x6e, 0x49, 0x73, 0x81, 0x92, 0xa8, 0xc4, 0x67, 0xbc, 0x39, 0x02, 0x3f, + 0x05, 0xb5, 0xd9, 0xd3, 0xb7, 0xa1, 0xc3, 0x86, 0x8c, 0x72, 0xb3, 0xdc, 0x30, 0x9a, 0x1b, 0x5d, + 0xa8, 0x24, 0xaa, 0xf1, 0x1c, 0x82, 0x97, 0x98, 0xf0, 0x04, 0x54, 0x31, 0xfd, 0x85, 0x70, 0xe7, + 0xc4, 0x71, 0x38, 0x8d, 0x22, 0xf3, 0x95, 0x3e, 0xa6, 0x77, 0x94, 0x44, 0x6f, 0xf3, 0x2c, 0xf0, + 0x51, 0xe8, 0xb3, 0x69, 0x8f, 0xe2, 0x0a, 0xe7, 0x15, 0xf0, 0x13, 0x50, 0x3d, 0xa3, 0xc4, 0xa1, + 0xbc, 0x1f, 0xdb, 0xf6, 0xd4, 0xa2, 0xa2, 0x3b, 0xdd, 0x55, 0x12, 0x55, 0xbd, 0x2c, 0x80, 0xf3, + 0xbc, 0x85, 0xf0, 0x94, 0x30, 0x2f, 0xe6, 0xd4, 0x04, 0xcb, 0xc2, 0x39, 0x80, 0xf3, 0x3c, 0xf8, + 0x25, 0xd8, 0x79, 0x1c, 0x74, 0xba, 0xe9, 0x96, 0xd6, 0xee, 0x2b, 0x89, 0x76, 0x26, 0x4b, 0x18, + 0x5e, 0x61, 0xe7, 0x1c, 0xd2, 0xdd, 0xb7, 0xd7, 0x38, 0xa4, 0x0d, 0xac, 0xb0, 0xe1, 0x4f, 0xa0, + 0xbe, 0xb8, 0x6c, 0x6e, 0x10, 0x72, 0xea, 0xf4, 0x99, 0x1b, 0x10, 0x11, 0x73, 0x1a, 0x99, 0x55, + 0xed, 0x65, 0x29, 0x89, 0xea, 0x93, 0x27, 0x59, 0xf8, 0x19, 0x87, 0xa9, 0xff, 0x77, 0xb1, 0xdf, + 0xa7, 0x1e, 0xb5, 0x05, 0x75, 0x7a, 0xc1, 0xbc, 0xf3, 0xae, 0x17, 0xda, 0x3f, 0x47, 0x66, 0x6d, + 0xe1, 0x1f, 0x3c, 0xc9, 0xc2, 0xcf, 0x38, 0xc0, 0x6b, 0x03, 0xbc, 0x3e, 0xb1, 0xed, 0xd8, 0x8f, + 0x3d, 0x22, 0xa8, 0x73, 0x4a, 0x69, 0x64, 0xbe, 0xd6, 0xb3, 0x1f, 0x2a, 0x89, 0x8e, 0x48, 0x1e, + 0x5a, 0x4c, 0xff, 0xf7, 0x3f, 0xd1, 0xd7, 0x3e, 0x11, 0xa3, 0xce, 0x80, 0xb9, 0xed, 0x5e, 0x20, + 0x3e, 0xcb, 0xfc, 0x49, 0xfd, 0xd8, 0x13, 0x6c, 0x42, 0x79, 0x74, 0xd9, 0xf1, 0x2f, 0x5b, 0xf6, + 0x88, 0xb0, 0xa0, 0x65, 0x87, 0x9c, 0xb6, 0xdc, 0xb0, 0xe3, 0x10, 0x41, 0xda, 0x5d, 0xe6, 0xf6, + 0x02, 0xf1, 0x15, 0x89, 0x04, 0xe5, 0x78, 0x79, 0x7b, 0x78, 0x0a, 0xe0, 0x45, 0x28, 0x88, 0x97, + 0xbf, 0x4d, 0x3b, 0xfa, 0x55, 0x0f, 0x95, 0x44, 0x50, 0xac, 0xa0, 0x78, 0x8d, 0x62, 0xc9, 0x27, + 0x1d, 0xef, 0xee, 0x5a, 0x9f, 0x74, 0xc0, 0x6b, 0x14, 0xf0, 0x7b, 0x70, 0xa0, 0xab, 0x2b, 0x77, + 0x0d, 0x6a, 0xab, 0x23, 0x25, 0xd1, 0x81, 0x58, 0x47, 0xc0, 0xeb, 0x75, 0xab, 0x86, 0x69, 0x6f, + 0x7b, 0x4f, 0x19, 0xa6, 0xed, 0xad, 0xd7, 0x41, 0x1f, 0xa0, 0x3c, 0xb0, 0x7a, 0x13, 0xf7, 0xb5, + 0xf5, 0x7b, 0x4a, 0x22, 0x24, 0x9e, 0xa7, 0xe2, 0xff, 0xf2, 0x82, 0x9f, 0x83, 0xed, 0x73, 0x4e, + 0x27, 0x2c, 0x8c, 0x23, 0x9d, 0x81, 0x07, 0x3a, 0x03, 0xeb, 0x4a, 0xa2, 0xc3, 0x71, 0xa6, 0x9e, + 0x89, 0x8a, 0x1c, 0x7f, 0x1a, 0x36, 0xe9, 0x7a, 0x96, 0x92, 0x87, 0xba, 0x39, 0x1d, 0x36, 0xe3, + 0x2c, 0x90, 0x0d, 0x9b, 0x9c, 0xe2, 0xf8, 0xef, 0x0d, 0x00, 0x75, 0x14, 0xbf, 0x7c, 0xd2, 0x7f, + 0x90, 0x4b, 0x7a, 0x1d, 0xa6, 0x5e, 0xfe, 0xed, 0x5e, 0x28, 0xf3, 0x97, 0x8f, 0xb9, 0xf4, 0xa6, + 0xc7, 0x5c, 0xfe, 0xbf, 0xc7, 0xdc, 0xfd, 0xe2, 0xe6, 0xce, 0x2a, 0xdc, 0xde, 0x59, 0x85, 0x87, + 0x3b, 0xcb, 0xf8, 0x35, 0xb1, 0x8c, 0xdf, 0x12, 0xcb, 0xf8, 0x23, 0xb1, 0x8c, 0x9b, 0xc4, 0x32, + 0x6e, 0x13, 0xcb, 0xf8, 0x2b, 0xb1, 0x8c, 0x7f, 0x12, 0xab, 0xf0, 0x90, 0x58, 0xc6, 0xf5, 0xbd, + 0x55, 0xb8, 0xb9, 0xb7, 0x0a, 0xb7, 0xf7, 0x56, 0xe1, 0xc7, 0x62, 0x24, 0x88, 0xa0, 0x83, 0x92, + 0xfe, 0x26, 0x7f, 0xfc, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x69, 0x2e, 0x1c, 0xe0, 0x07, + 0x00, 0x00, } func (this *ValidatorInfo) Equal(that interface{}) bool { @@ -452,6 +470,9 @@ func (this *ValidatorInfo) Equal(that interface{}) bool { if this.PreviousList != that1.PreviousList { return false } + if this.PreviousIndex != that1.PreviousIndex { + return false + } return true } func (this *ShardValidatorInfo) Equal(that interface{}) bool { @@ -491,13 +512,16 @@ func (this *ShardValidatorInfo) Equal(that interface{}) bool { if this.PreviousList != that1.PreviousList { return false } + if this.PreviousIndex != that1.PreviousIndex { + return false + } return true } func (this *ValidatorInfo) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 25) + s := make([]string, 0, 26) s = append(s, "&state.ValidatorInfo{") s = append(s, "PublicKey: "+fmt.Sprintf("%#v", this.PublicKey)+",\n") s = append(s, "ShardId: "+fmt.Sprintf("%#v", this.ShardId)+",\n") @@ -520,6 +544,7 @@ func (this *ValidatorInfo) GoString() string { s = append(s, "TotalValidatorFailure: "+fmt.Sprintf("%#v", this.TotalValidatorFailure)+",\n") s = append(s, "TotalValidatorIgnoredSignatures: "+fmt.Sprintf("%#v", this.TotalValidatorIgnoredSignatures)+",\n") s = append(s, "PreviousList: "+fmt.Sprintf("%#v", this.PreviousList)+",\n") + s = append(s, "PreviousIndex: "+fmt.Sprintf("%#v", this.PreviousIndex)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -527,7 +552,7 @@ func (this *ShardValidatorInfo) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 10) + s := make([]string, 0, 11) s = append(s, "&state.ShardValidatorInfo{") s = append(s, "PublicKey: "+fmt.Sprintf("%#v", this.PublicKey)+",\n") s = append(s, "ShardId: "+fmt.Sprintf("%#v", this.ShardId)+",\n") @@ -535,6 +560,7 @@ func (this *ShardValidatorInfo) GoString() string { s = append(s, "Index: "+fmt.Sprintf("%#v", this.Index)+",\n") s = append(s, "TempRating: "+fmt.Sprintf("%#v", this.TempRating)+",\n") s = append(s, "PreviousList: "+fmt.Sprintf("%#v", this.PreviousList)+",\n") + s = append(s, "PreviousIndex: "+fmt.Sprintf("%#v", this.PreviousIndex)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -566,6 +592,13 @@ func (m *ValidatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PreviousIndex != 0 { + i = encodeVarintValidatorInfo(dAtA, i, uint64(m.PreviousIndex)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb0 + } if len(m.PreviousList) > 0 { i -= len(m.PreviousList) copy(dAtA[i:], m.PreviousList) @@ -721,6 +754,11 @@ func (m *ShardValidatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PreviousIndex != 0 { + i = encodeVarintValidatorInfo(dAtA, i, uint64(m.PreviousIndex)) + i-- + dAtA[i] = 0x38 + } if len(m.PreviousList) > 0 { i -= len(m.PreviousList) copy(dAtA[i:], m.PreviousList) @@ -846,6 +884,9 @@ func (m *ValidatorInfo) Size() (n int) { if l > 0 { n += 2 + l + sovValidatorInfo(uint64(l)) } + if m.PreviousIndex != 0 { + n += 2 + sovValidatorInfo(uint64(m.PreviousIndex)) + } return n } @@ -876,6 +917,9 @@ func (m *ShardValidatorInfo) Size() (n int) { if l > 0 { n += 1 + l + sovValidatorInfo(uint64(l)) } + if m.PreviousIndex != 0 { + n += 1 + sovValidatorInfo(uint64(m.PreviousIndex)) + } return n } @@ -911,6 +955,7 @@ func (this *ValidatorInfo) String() string { `TotalValidatorFailure:` + fmt.Sprintf("%v", this.TotalValidatorFailure) + `,`, `TotalValidatorIgnoredSignatures:` + fmt.Sprintf("%v", this.TotalValidatorIgnoredSignatures) + `,`, `PreviousList:` + fmt.Sprintf("%v", this.PreviousList) + `,`, + `PreviousIndex:` + fmt.Sprintf("%v", this.PreviousIndex) + `,`, `}`, }, "") return s @@ -926,6 +971,7 @@ func (this *ShardValidatorInfo) String() string { `Index:` + fmt.Sprintf("%v", this.Index) + `,`, `TempRating:` + fmt.Sprintf("%v", this.TempRating) + `,`, `PreviousList:` + fmt.Sprintf("%v", this.PreviousList) + `,`, + `PreviousIndex:` + fmt.Sprintf("%v", this.PreviousIndex) + `,`, `}`, }, "") return s @@ -1433,6 +1479,25 @@ func (m *ValidatorInfo) Unmarshal(dAtA []byte) error { } m.PreviousList = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 22: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousIndex", wireType) + } + m.PreviousIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowValidatorInfo + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PreviousIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipValidatorInfo(dAtA[iNdEx:]) @@ -1641,6 +1706,25 @@ func (m *ShardValidatorInfo) Unmarshal(dAtA []byte) error { } m.PreviousList = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousIndex", wireType) + } + m.PreviousIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowValidatorInfo + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PreviousIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipValidatorInfo(dAtA[iNdEx:]) diff --git a/state/validatorInfo.proto b/state/validatorInfo.proto index 85d54e3232b..2df2149d8f5 100644 --- a/state/validatorInfo.proto +++ b/state/validatorInfo.proto @@ -30,14 +30,16 @@ message ValidatorInfo { uint32 TotalValidatorFailure = 19 [(gogoproto.jsontag) = "totalValidatorFailure"]; uint32 TotalValidatorIgnoredSignatures = 20 [(gogoproto.jsontag) = "totalValidatorIgnoredSignatures"]; string PreviousList = 21 [(gogoproto.jsontag) = "previousList,omitempty"]; + uint32 PreviousIndex = 22 [(gogoproto.jsontag) = "previousIndex,omitempty"]; } // ShardValidatorInfo represents the data regarding a validator that is stored in the PeerMiniblocks message ShardValidatorInfo { - bytes PublicKey = 1 [(gogoproto.jsontag) = "publicKey"]; - uint32 ShardId = 2 [(gogoproto.jsontag) = "shardId"]; - string List = 3 [(gogoproto.jsontag) = "list,omitempty"]; - uint32 Index = 4 [(gogoproto.jsontag) = "index"]; - uint32 TempRating = 5 [(gogoproto.jsontag) = "tempRating"]; - string PreviousList = 6 [(gogoproto.jsontag) = "previousList,omitempty"]; + bytes PublicKey = 1 [(gogoproto.jsontag) = "publicKey"]; + uint32 ShardId = 2 [(gogoproto.jsontag) = "shardId"]; + string List = 3 [(gogoproto.jsontag) = "list,omitempty"]; + uint32 Index = 4 [(gogoproto.jsontag) = "index"]; + uint32 TempRating = 5 [(gogoproto.jsontag) = "tempRating"]; + string PreviousList = 6 [(gogoproto.jsontag) = "previousList,omitempty"]; + uint32 PreviousIndex = 7 [(gogoproto.jsontag) = "previousIndex,omitempty"]; } diff --git a/update/genesis/common.go b/update/genesis/common.go index ee545feb82b..10ea22fbf6b 100644 --- a/update/genesis/common.go +++ b/update/genesis/common.go @@ -52,6 +52,7 @@ func peerAccountToValidatorInfo(peerAccount state.PeerAccountHandler) *state.Val List: getActualList(peerAccount), PreviousList: peerAccount.GetPreviousList(), Index: peerAccount.GetIndexInList(), + PreviousIndex: peerAccount.GetPreviousIndexInList(), TempRating: peerAccount.GetTempRating(), Rating: peerAccount.GetRating(), RewardAddress: peerAccount.GetRewardAddress(), From b0eb486d7cefaf9f7eb05c7537961e6bb7935aef Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Feb 2023 15:33:15 +0200 Subject: [PATCH 411/958] FIX: Set PreviousIndex when setting validator to leaving --- epochStart/metachain/auctionListSelector.go | 3 ++- epochStart/metachain/legacySystemSCs.go | 2 +- epochStart/metachain/rewardsV2_test.go | 2 +- epochStart/metachain/systemSCs.go | 2 +- process/peer/validatorsProvider_test.go | 10 +++++----- state/interface.go | 4 +++- state/validatorInfo.go | 15 +++++++++++++-- 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 81fa12aa980..b01ce492d3e 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -344,7 +344,8 @@ func markAuctionNodesAsSelected( ) error { for _, node := range selectedNodes { newNode := node.ShallowClone() - newNode.SetList(string(common.SelectedFromAuctionList), true) + newNode.SetPreviousList(node.GetList()) + newNode.SetList(string(common.SelectedFromAuctionList)) err := validatorsInfoMap.Replace(node, newNode) if err != nil { diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 8c1b22fd8f2..4e9ab017fcd 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -290,7 +290,7 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( } validatorLeaving := validatorInfo.ShallowClone() - validatorLeaving.SetList(string(common.LeavingList), s.enableEpochsHandler.IsStakingV4Started()) + validatorLeaving.SetListAndIndex(string(common.LeavingList), validatorLeaving.GetIndex(), s.enableEpochsHandler.IsStakingV4Started()) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { return 0, err diff --git a/epochStart/metachain/rewardsV2_test.go b/epochStart/metachain/rewardsV2_test.go index d009178424c..7abea51dea3 100644 --- a/epochStart/metachain/rewardsV2_test.go +++ b/epochStart/metachain/rewardsV2_test.go @@ -1415,7 +1415,7 @@ func TestNewRewardsCreatorV2_computeValidatorInfoPerRewardAddressWithLeavingVali valInfo := createDefaultValidatorInfo(nbEligiblePerShard, args.ShardCoordinator, args.NodesConfigProvider, proposerFee, defaultBlocksPerShard) for _, valList := range valInfo.GetShardValidatorsInfoMap() { for i := 0; i < int(nbLeavingPerShard); i++ { - valList[i].SetList(string(common.LeavingList), false) + valList[i].SetList(string(common.LeavingList)) } } diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index e8a3f2c01b0..f9a124d0c7f 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -172,7 +172,7 @@ func (s *systemSCProcessor) unStakeNodesWithNotEnoughFundsWithStakingV4( } validatorLeaving := validatorInfo.ShallowClone() - validatorLeaving.SetList(string(common.LeavingList), true) + validatorLeaving.SetListAndIndex(string(common.LeavingList), validatorLeaving.GetIndex(), true) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { return err diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 4954ebd632e..7325926075f 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -914,23 +914,23 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { args.AuctionListSelector = &stakingcommon.AuctionListSelectorStub{ SelectNodesFromAuctionListCalled: func(validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte) error { selectedV1 := v1.ShallowClone() - selectedV1.SetList(string(common.SelectedFromAuctionList), false) + selectedV1.SetList(string(common.SelectedFromAuctionList)) _ = validatorsInfoMap.Replace(v1, selectedV1) selectedV2 := v2.ShallowClone() - selectedV2.SetList(string(common.SelectedFromAuctionList), false) + selectedV2.SetList(string(common.SelectedFromAuctionList)) _ = validatorsInfoMap.Replace(v2, selectedV2) selectedV3 := v3.ShallowClone() - selectedV3.SetList(string(common.SelectedFromAuctionList), false) + selectedV3.SetList(string(common.SelectedFromAuctionList)) _ = validatorsInfoMap.Replace(v3, selectedV3) selectedV5 := v5.ShallowClone() - selectedV5.SetList(string(common.SelectedFromAuctionList), false) + selectedV5.SetList(string(common.SelectedFromAuctionList)) _ = validatorsInfoMap.Replace(v5, selectedV5) selectedV12 := v12.ShallowClone() - selectedV12.SetList(string(common.SelectedFromAuctionList), false) + selectedV12.SetList(string(common.SelectedFromAuctionList)) _ = validatorsInfoMap.Replace(v12, selectedV12) return nil diff --git a/state/interface.go b/state/interface.go index 190517c548e..405b49c727a 100644 --- a/state/interface.go +++ b/state/interface.go @@ -262,8 +262,10 @@ type ValidatorInfoHandler interface { SetPublicKey(publicKey []byte) SetShardId(shardID uint32) - SetList(list string, updatePreviousList bool) + SetPreviousList(list string) + SetList(list string) SetIndex(index uint32) + SetListAndIndex(list string, index uint32, updatePreviousValues bool) SetTempRating(tempRating uint32) SetRating(rating uint32) SetRatingModifier(ratingModifier float32) diff --git a/state/validatorInfo.go b/state/validatorInfo.go index 040c6efba4c..c6ea6d06001 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -15,12 +15,23 @@ func (vi *ValidatorInfo) SetPublicKey(publicKey []byte) { } // SetList sets validator's list -func (vi *ValidatorInfo) SetList(list string, updatePreviousList bool) { - if updatePreviousList { +func (vi *ValidatorInfo) SetList(list string) { + vi.List = list +} + +// SetPreviousList sets validator's previous list +func (vi *ValidatorInfo) SetPreviousList(list string) { + vi.PreviousList = list +} + +func (vi *ValidatorInfo) SetListAndIndex(list string, index uint32, updatePreviousValues bool) { + if updatePreviousValues { + vi.PreviousIndex = vi.Index vi.PreviousList = vi.List } vi.List = list + vi.Index = index } // SetShardId sets validator's public shard id From c08a8c188e6121d4277bf40bf66e0e5c897a573f Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Feb 2023 15:38:28 +0200 Subject: [PATCH 412/958] FIX: Linter --- process/peer/process_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/process/peer/process_test.go b/process/peer/process_test.go index 6b1a9439682..a6cdf86b48e 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2264,7 +2264,7 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochComputesJustEligible _ = vi.Add(createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1)) validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) - validatorWaiting.SetList(string(common.WaitingList), false) + validatorWaiting.SetList(string(common.WaitingList)) _ = vi.Add(validatorWaiting) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) @@ -2306,11 +2306,11 @@ func TestValidatorStatistics_ProcessValidatorInfosEndOfEpochV2ComputesEligibleLe vi := state.NewShardValidatorsInfoMap() validatorLeaving := createMockValidatorInfo(core.MetachainShardId, tempRating1, validatorSuccess1, validatorIgnored1, validatorFailure1) - validatorLeaving.SetList(string(common.LeavingList), false) + validatorLeaving.SetList(string(common.LeavingList)) _ = vi.Add(validatorLeaving) validatorWaiting := createMockValidatorInfo(0, tempRating2, validatorSuccess2, validatorIgnored2, validatorFailure2) - validatorWaiting.SetList(string(common.WaitingList), false) + validatorWaiting.SetList(string(common.WaitingList)) _ = vi.Add(validatorWaiting) err := validatorStatistics.ProcessRatingsEndOfEpoch(vi, 1) From 9eb580b8234973234d1abc5c949d25f45bcacc76 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Feb 2023 14:36:36 +0200 Subject: [PATCH 413/958] FIX: After review --- .../testProcessorNodeWithMultisigner.go | 2 +- .../nodesCoordinator/hashValidatorShuffler.go | 2 +- testscommon/enableEpochsHandlerStub.go | 68 +++++++++---------- vm/systemSmartContracts/staking_test.go | 2 +- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index b1c81962a12..70fa27d0751 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -234,8 +234,8 @@ func CreateNodesWithNodesCoordinatorFactory( ScheduledMiniBlocksEnableEpoch: UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, RefactorPeersMiniBlocksEnableEpoch: UnreachableEpoch, - StakingV4Step2EnableEpoch: UnreachableEpoch, StakingV4Step1EnableEpoch: UnreachableEpoch, + StakingV4Step2EnableEpoch: UnreachableEpoch, StakingV4Step3EnableEpoch: UnreachableEpoch, } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 2fcdd4bb1ef..89b3beb5fc5 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -95,8 +95,8 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro shuffleBetweenShards: args.ShuffleBetweenShards, availableNodesConfigs: configs, enableEpochsHandler: args.EnableEpochsHandler, - stakingV4Step3EnableEpoch: args.EnableEpochs.StakingV4Step3EnableEpoch, stakingV4Step2EnableEpoch: args.EnableEpochs.StakingV4Step2EnableEpoch, + stakingV4Step3EnableEpoch: args.EnableEpochs.StakingV4Step3EnableEpoch, } rxs.UpdateParams(args.NodesShard, args.NodesMeta, args.Hysteresis, args.Adaptivity) diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 55463234639..3f17cdc9a26 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -8,6 +8,7 @@ import ( type EnableEpochsHandlerStub struct { sync.RWMutex ResetPenalizedTooMuchGasFlagCalled func() + IsStakingV4Step2Called func() bool BlockGasAndFeesReCheckEnableEpochField uint32 StakingV2EnableEpochField uint32 ScheduledMiniBlocksEnableEpochField uint32 @@ -25,8 +26,8 @@ type EnableEpochsHandlerStub struct { StorageAPICostOptimizationEnableEpochField uint32 MiniBlockPartialExecutionEnableEpochField uint32 RefactorPeersMiniBlocksEnableEpochField uint32 - StakingV4Step2EnableEpochField uint32 StakingV4Step1EnableEpochField uint32 + StakingV4Step2EnableEpochField uint32 IsSCDeployFlagEnabledField bool IsBuiltInFunctionsFlagEnabledField bool IsRelayedTransactionsFlagEnabledField bool @@ -122,7 +123,6 @@ type EnableEpochsHandlerStub struct { IsStakingV4Step3FlagEnabledField bool IsStakingQueueEnabledField bool IsStakingV4StartedField bool - IsStakingV4Step2Called func() bool } // ResetPenalizedTooMuchGasFlag - @@ -268,6 +268,22 @@ func (stub *EnableEpochsHandlerStub) RefactorPeersMiniBlocksEnableEpoch() uint32 return stub.RefactorPeersMiniBlocksEnableEpochField } +// StakingV4Step1EnableEpoch - +func (stub *EnableEpochsHandlerStub) StakingV4Step1EnableEpoch() uint32 { + stub.RLock() + defer stub.RUnlock() + + return stub.StakingV4Step1EnableEpochField +} + +// StakingV4Step2EnableEpoch - +func (stub *EnableEpochsHandlerStub) StakingV4Step2EnableEpoch() uint32 { + stub.RLock() + defer stub.RUnlock() + + return stub.StakingV4Step2EnableEpochField +} + // IsSCDeployFlagEnabled - func (stub *EnableEpochsHandlerStub) IsSCDeployFlagEnabled() bool { stub.RLock() @@ -993,6 +1009,22 @@ func (stub *EnableEpochsHandlerStub) IsStakeLimitsFlagEnabled() bool { return stub.IsStakeLimitsFlagEnabledField } +// IsStakingQueueEnabled - +func (stub *EnableEpochsHandlerStub) IsStakingQueueEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingQueueEnabledField +} + +// IsStakingV4Started - +func (stub *EnableEpochsHandlerStub) IsStakingV4Started() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsStakingV4StartedField +} + // IsStakingV4Step1Enabled - func (stub *EnableEpochsHandlerStub) IsStakingV4Step1Enabled() bool { stub.RLock() @@ -1021,38 +1053,6 @@ func (stub *EnableEpochsHandlerStub) IsStakingV4Step3Enabled() bool { return stub.IsStakingV4Step3FlagEnabledField } -// IsStakingQueueEnabled - -func (stub *EnableEpochsHandlerStub) IsStakingQueueEnabled() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsStakingQueueEnabledField -} - -// IsStakingV4Started - -func (stub *EnableEpochsHandlerStub) IsStakingV4Started() bool { - stub.RLock() - defer stub.RUnlock() - - return stub.IsStakingV4StartedField -} - -// StakingV4Step2EnableEpoch - -func (stub *EnableEpochsHandlerStub) StakingV4Step2EnableEpoch() uint32 { - stub.RLock() - defer stub.RUnlock() - - return stub.StakingV4Step2EnableEpochField -} - -// StakingV4Step1EnableEpoch - -func (stub *EnableEpochsHandlerStub) StakingV4Step1EnableEpoch() uint32 { - stub.RLock() - defer stub.RUnlock() - - return stub.StakingV4Step1EnableEpochField -} - // IsInterfaceNil - func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { return stub == nil diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index b5115318a2f..f1a3c445b4f 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -61,8 +61,8 @@ func createMockStakingScArgumentsWithSystemScAddresses( IsCorrectFirstQueuedFlagEnabledField: true, IsCorrectJailedNotUnStakedEmptyQueueFlagEnabledField: true, IsValidatorToDelegationFlagEnabledField: true, - IsStakingV4Step2FlagEnabledField: false, IsStakingV4Step1FlagEnabledField: false, + IsStakingV4Step2FlagEnabledField: false, }, } } From ba6d253585996804ecbcc1786d0e3e94f9fff228 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Feb 2023 17:52:17 +0200 Subject: [PATCH 414/958] FEAT: Add first version of checking stakingV4 config --- cmd/node/main.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/cmd/node/main.go b/cmd/node/main.go index 0d080a7864c..a70248cb10e 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -97,6 +97,12 @@ func startNodeRunner(c *cli.Context, log logger.Logger, version string) error { return errCfg } + // check config here + errCheckEpochsCfg := sanityCheckEnableEpochsStakingV4(cfgs, log) + if errCheckEpochsCfg != nil { + return errCfg + } + errCfgOverride := overridableConfig.OverrideConfigValues(cfgs.PreferencesConfig.Preferences.OverridableConfigTomlValues, cfgs) if errCfgOverride != nil { return errCfgOverride @@ -248,6 +254,59 @@ func readConfigs(ctx *cli.Context, log logger.Logger) (*config.Configs, error) { }, nil } +func sanityCheckEnableEpochsStakingV4(cfg *config.Configs, log logger.Logger) error { + enableEpochsCfg := cfg.EpochConfig.EnableEpochs + stakingV4StepsInOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch < enableEpochsCfg.StakingV4Step2EnableEpoch) && + (enableEpochsCfg.StakingV4Step2EnableEpoch < enableEpochsCfg.StakingV4Step3EnableEpoch) + + if !stakingV4StepsInOrder { + return fmt.Errorf("staking v4 enable epochs are not in ascending order" + + "; expected StakingV4Step1EnableEpoch < StakingV4Step2EnableEpoch < StakingV4Step3EnableEpoch") + } + + stakingV4StepsInExpectedOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch == enableEpochsCfg.StakingV4Step2EnableEpoch-1) && + (enableEpochsCfg.StakingV4Step2EnableEpoch == enableEpochsCfg.StakingV4Step3EnableEpoch-1) + if !stakingV4StepsInExpectedOrder { + log.Warn("staking v4 enable epoch steps should be in cardinal order " + + "(e.g.: StakingV4Step1EnableEpoch = 2, StakingV4Step2EnableEpoch = 3, StakingV4Step3EnableEpoch = 4)" + + "; can leave them as they are for playground purposes" + + ", but DO NOT use them in production, since system's behavior is undefined") + } + + maxNodesConfigAdaptedForStakingV4 := false + for idx, maxNodesChangeCfg := range enableEpochsCfg.MaxNodesChangeEnableEpoch { + if maxNodesChangeCfg.EpochEnable == enableEpochsCfg.StakingV4Step2EnableEpoch { + maxNodesConfigAdaptedForStakingV4 = true + + if idx == 0 { + log.Warn(fmt.Sprintf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, ", enableEpochsCfg.StakingV4Step3EnableEpoch) + + "but no previous config change entry in MaxNodesChangeEnableEpoch") + } else { + prevMaxNodesChange := enableEpochsCfg.MaxNodesChangeEnableEpoch[idx-1] + if prevMaxNodesChange.NodesToShufflePerShard != maxNodesChangeCfg.NodesToShufflePerShard { + log.Warn("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard with EnableEpoch = StakingV4Step3EnableEpoch" + + "; can leave them as they are for playground purposes, but DO NOT use them in production, since this will influence rewards") + } + + numShards := cfg.GeneralConfig.GeneralSettings.GenesisMaxNumberOfShards + expectedMaxNumNodes := prevMaxNodesChange.MaxNumNodes - (numShards + 1) - prevMaxNodesChange.NodesToShufflePerShard + if expectedMaxNumNodes != maxNodesChangeCfg.MaxNumNodes { + return fmt.Errorf(fmt.Sprintf("expcted MaxNodesChangeEnableEpoch.MaxNumNodes for StakingV4Step3EnableEpoch = %d, but got %d", + expectedMaxNumNodes, maxNodesChangeCfg.MaxNumNodes)) + } + } + + break + } + } + + if !maxNodesConfigAdaptedForStakingV4 { + return fmt.Errorf("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch(%d)", enableEpochsCfg.StakingV4Step3EnableEpoch) + } + + return nil +} + func attachFileLogger(log logger.Logger, flagsConfig *config.ContextFlagsConfig) (factory.FileLoggingHandler, error) { var fileLogging factory.FileLoggingHandler var err error From e631a642f6df9d588e6fe153096823ef016bdea8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 14 Feb 2023 11:51:04 +0200 Subject: [PATCH 415/958] FEAT: Move config checker in separate file --- cmd/node/main.go | 64 +++--------------------------- config/configChecker.go | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 59 deletions(-) create mode 100644 config/configChecker.go diff --git a/cmd/node/main.go b/cmd/node/main.go index a70248cb10e..0fe6c016303 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -97,17 +97,16 @@ func startNodeRunner(c *cli.Context, log logger.Logger, version string) error { return errCfg } - // check config here - errCheckEpochsCfg := sanityCheckEnableEpochsStakingV4(cfgs, log) - if errCheckEpochsCfg != nil { - return errCfg - } - errCfgOverride := overridableConfig.OverrideConfigValues(cfgs.PreferencesConfig.Preferences.OverridableConfigTomlValues, cfgs) if errCfgOverride != nil { return errCfgOverride } + errCheckEpochsCfg := config.SanityCheckEnableEpochsStakingV4(cfgs) + if errCheckEpochsCfg != nil { + return errCfg + } + if !check.IfNil(fileLogging) { timeLogLifeSpan := time.Second * time.Duration(cfgs.GeneralConfig.Logs.LogFileLifeSpanInSec) sizeLogLifeSpanInMB := uint64(cfgs.GeneralConfig.Logs.LogFileLifeSpanInMB) @@ -254,59 +253,6 @@ func readConfigs(ctx *cli.Context, log logger.Logger) (*config.Configs, error) { }, nil } -func sanityCheckEnableEpochsStakingV4(cfg *config.Configs, log logger.Logger) error { - enableEpochsCfg := cfg.EpochConfig.EnableEpochs - stakingV4StepsInOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch < enableEpochsCfg.StakingV4Step2EnableEpoch) && - (enableEpochsCfg.StakingV4Step2EnableEpoch < enableEpochsCfg.StakingV4Step3EnableEpoch) - - if !stakingV4StepsInOrder { - return fmt.Errorf("staking v4 enable epochs are not in ascending order" + - "; expected StakingV4Step1EnableEpoch < StakingV4Step2EnableEpoch < StakingV4Step3EnableEpoch") - } - - stakingV4StepsInExpectedOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch == enableEpochsCfg.StakingV4Step2EnableEpoch-1) && - (enableEpochsCfg.StakingV4Step2EnableEpoch == enableEpochsCfg.StakingV4Step3EnableEpoch-1) - if !stakingV4StepsInExpectedOrder { - log.Warn("staking v4 enable epoch steps should be in cardinal order " + - "(e.g.: StakingV4Step1EnableEpoch = 2, StakingV4Step2EnableEpoch = 3, StakingV4Step3EnableEpoch = 4)" + - "; can leave them as they are for playground purposes" + - ", but DO NOT use them in production, since system's behavior is undefined") - } - - maxNodesConfigAdaptedForStakingV4 := false - for idx, maxNodesChangeCfg := range enableEpochsCfg.MaxNodesChangeEnableEpoch { - if maxNodesChangeCfg.EpochEnable == enableEpochsCfg.StakingV4Step2EnableEpoch { - maxNodesConfigAdaptedForStakingV4 = true - - if idx == 0 { - log.Warn(fmt.Sprintf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, ", enableEpochsCfg.StakingV4Step3EnableEpoch) + - "but no previous config change entry in MaxNodesChangeEnableEpoch") - } else { - prevMaxNodesChange := enableEpochsCfg.MaxNodesChangeEnableEpoch[idx-1] - if prevMaxNodesChange.NodesToShufflePerShard != maxNodesChangeCfg.NodesToShufflePerShard { - log.Warn("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard with EnableEpoch = StakingV4Step3EnableEpoch" + - "; can leave them as they are for playground purposes, but DO NOT use them in production, since this will influence rewards") - } - - numShards := cfg.GeneralConfig.GeneralSettings.GenesisMaxNumberOfShards - expectedMaxNumNodes := prevMaxNodesChange.MaxNumNodes - (numShards + 1) - prevMaxNodesChange.NodesToShufflePerShard - if expectedMaxNumNodes != maxNodesChangeCfg.MaxNumNodes { - return fmt.Errorf(fmt.Sprintf("expcted MaxNodesChangeEnableEpoch.MaxNumNodes for StakingV4Step3EnableEpoch = %d, but got %d", - expectedMaxNumNodes, maxNodesChangeCfg.MaxNumNodes)) - } - } - - break - } - } - - if !maxNodesConfigAdaptedForStakingV4 { - return fmt.Errorf("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch(%d)", enableEpochsCfg.StakingV4Step3EnableEpoch) - } - - return nil -} - func attachFileLogger(log logger.Logger, flagsConfig *config.ContextFlagsConfig) (factory.FileLoggingHandler, error) { var fileLogging factory.FileLoggingHandler var err error diff --git a/config/configChecker.go b/config/configChecker.go new file mode 100644 index 00000000000..4b88b78b968 --- /dev/null +++ b/config/configChecker.go @@ -0,0 +1,86 @@ +package config + +import ( + "fmt" + + logger "github.com/multiversx/mx-chain-logger-go" +) + +var log = logger.GetOrCreate("configChecker") + +func SanityCheckEnableEpochsStakingV4(cfg *Configs) error { + enableEpochsCfg := cfg.EpochConfig.EnableEpochs + err := checkStakingV4EpochsOrder(enableEpochsCfg) + if err != nil { + return err + } + + numOfShards := cfg.GeneralConfig.GeneralSettings.GenesisMaxNumberOfShards + return checkStakingV4MaxNodesChangeCfg(enableEpochsCfg, numOfShards) +} + +func checkStakingV4EpochsOrder(enableEpochsCfg EnableEpochs) error { + stakingV4StepsInOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch < enableEpochsCfg.StakingV4Step2EnableEpoch) && + (enableEpochsCfg.StakingV4Step2EnableEpoch < enableEpochsCfg.StakingV4Step3EnableEpoch) + + if !stakingV4StepsInOrder { + return fmt.Errorf("staking v4 enable epochs are not in ascending order" + + "; expected StakingV4Step1EnableEpoch < StakingV4Step2EnableEpoch < StakingV4Step3EnableEpoch") + } + + stakingV4StepsInExpectedOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch == enableEpochsCfg.StakingV4Step2EnableEpoch-1) && + (enableEpochsCfg.StakingV4Step2EnableEpoch == enableEpochsCfg.StakingV4Step3EnableEpoch-1) + if !stakingV4StepsInExpectedOrder { + log.Warn("staking v4 enable epoch steps should be in cardinal order " + + "(e.g.: StakingV4Step1EnableEpoch = 2, StakingV4Step2EnableEpoch = 3, StakingV4Step3EnableEpoch = 4)" + + "; can leave them as they are for playground purposes" + + ", but DO NOT use them in production, since system's behavior is undefined") + } + + return nil +} + +func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards uint32) error { + maxNodesConfigAdaptedForStakingV4 := false + + for idx, currMaxNodesChangeCfg := range enableEpochsCfg.MaxNodesChangeEnableEpoch { + if currMaxNodesChangeCfg.EpochEnable == enableEpochsCfg.StakingV4Step3EnableEpoch { + + maxNodesConfigAdaptedForStakingV4 = true + if idx == 0 { + log.Warn(fmt.Sprintf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, ", enableEpochsCfg.StakingV4Step3EnableEpoch) + + "but no previous config change entry in MaxNodesChangeEnableEpoch") + } else { + prevMaxNodesChange := enableEpochsCfg.MaxNodesChangeEnableEpoch[idx-1] + err := checkMaxNodesChangedCorrectly(prevMaxNodesChange, currMaxNodesChangeCfg, numOfShards) + if err != nil { + return err + } + } + + break + } + } + + if !maxNodesConfigAdaptedForStakingV4 { + return fmt.Errorf("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch(%d)", enableEpochsCfg.StakingV4Step3EnableEpoch) + } + + return nil +} + +func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, currMaxNodesChange MaxNodesChangeConfig, numOfShards uint32) error { + if prevMaxNodesChange.NodesToShufflePerShard != currMaxNodesChange.NodesToShufflePerShard { + log.Warn("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard" + + " with EnableEpoch = StakingV4Step3EnableEpoch; can leave them as they are for playground purposes," + + " but DO NOT use them in production, since this will influence rewards") + } + + expectedMaxNumNodes := prevMaxNodesChange.MaxNumNodes - (numOfShards + 1) - prevMaxNodesChange.NodesToShufflePerShard + if expectedMaxNumNodes != currMaxNodesChange.MaxNumNodes { + return fmt.Errorf(fmt.Sprintf("expcted MaxNodesChangeEnableEpoch.MaxNumNodes for StakingV4Step3EnableEpoch = %d, but got %d", + expectedMaxNumNodes, currMaxNodesChange.MaxNumNodes)) + } + + return nil +} From 187972c7c5b68cc76cfcbea3559da3db3890842e Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 14 Feb 2023 13:36:40 +0200 Subject: [PATCH 416/958] FEAT: Add unit tests for configChecker.go --- config/configChecker.go | 14 ++-- config/configChecker_test.go | 141 +++++++++++++++++++++++++++++++++++ config/errors.go | 7 ++ 3 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 config/configChecker_test.go create mode 100644 config/errors.go diff --git a/config/configChecker.go b/config/configChecker.go index 4b88b78b968..759f268ed9b 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -24,8 +24,7 @@ func checkStakingV4EpochsOrder(enableEpochsCfg EnableEpochs) error { (enableEpochsCfg.StakingV4Step2EnableEpoch < enableEpochsCfg.StakingV4Step3EnableEpoch) if !stakingV4StepsInOrder { - return fmt.Errorf("staking v4 enable epochs are not in ascending order" + - "; expected StakingV4Step1EnableEpoch < StakingV4Step2EnableEpoch < StakingV4Step3EnableEpoch") + return errStakingV4StepsNotInOrder } stakingV4StepsInExpectedOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch == enableEpochsCfg.StakingV4Step2EnableEpoch-1) && @@ -49,7 +48,7 @@ func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards u maxNodesConfigAdaptedForStakingV4 = true if idx == 0 { log.Warn(fmt.Sprintf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, ", enableEpochsCfg.StakingV4Step3EnableEpoch) + - "but no previous config change entry in MaxNodesChangeEnableEpoch") + "but no previous config change entry in MaxNodesChangeEnableEpoch, DO NOT use this config in production") } else { prevMaxNodesChange := enableEpochsCfg.MaxNodesChangeEnableEpoch[idx-1] err := checkMaxNodesChangedCorrectly(prevMaxNodesChange, currMaxNodesChangeCfg, numOfShards) @@ -63,7 +62,7 @@ func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards u } if !maxNodesConfigAdaptedForStakingV4 { - return fmt.Errorf("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch(%d)", enableEpochsCfg.StakingV4Step3EnableEpoch) + return fmt.Errorf("%w = %d", errNoMaxNodesConfigChangeForStakingV4, enableEpochsCfg.StakingV4Step3EnableEpoch) } return nil @@ -76,10 +75,11 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr " but DO NOT use them in production, since this will influence rewards") } - expectedMaxNumNodes := prevMaxNodesChange.MaxNumNodes - (numOfShards + 1) - prevMaxNodesChange.NodesToShufflePerShard + totalShuffled := (numOfShards + 1) * prevMaxNodesChange.NodesToShufflePerShard + expectedMaxNumNodes := prevMaxNodesChange.MaxNumNodes - totalShuffled if expectedMaxNumNodes != currMaxNodesChange.MaxNumNodes { - return fmt.Errorf(fmt.Sprintf("expcted MaxNodesChangeEnableEpoch.MaxNumNodes for StakingV4Step3EnableEpoch = %d, but got %d", - expectedMaxNumNodes, currMaxNodesChange.MaxNumNodes)) + return fmt.Errorf("expected MaxNodesChangeEnableEpoch.MaxNumNodes for StakingV4Step3EnableEpoch = %d, but got %d", + expectedMaxNumNodes, currMaxNodesChange.MaxNumNodes) } return nil diff --git a/config/configChecker_test.go b/config/configChecker_test.go new file mode 100644 index 00000000000..7e7dca6a49a --- /dev/null +++ b/config/configChecker_test.go @@ -0,0 +1,141 @@ +package config + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func generateCorrectConfig() *Configs { + return &Configs{ + EpochConfig: &EpochConfig{ + EnableEpochs: EnableEpochs{ + StakingV4Step1EnableEpoch: 4, + StakingV4Step2EnableEpoch: 5, + StakingV4Step3EnableEpoch: 6, + MaxNodesChangeEnableEpoch: []MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + }, + { + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + }, + }, + }, + GeneralConfig: &Config{ + GeneralSettings: GeneralSettingsConfig{ + GenesisMaxNumberOfShards: 3, + }, + }, + } +} + +func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { + t.Parallel() + + t.Run("correct config, should work", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + err := SanityCheckEnableEpochsStakingV4(cfg) + require.Nil(t, err) + }) + + t.Run("staking v4 steps not in ascending order, should return error", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 5 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 + err := SanityCheckEnableEpochsStakingV4(cfg) + require.Equal(t, errStakingV4StepsNotInOrder, err) + + cfg = generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + err = SanityCheckEnableEpochsStakingV4(cfg) + require.Equal(t, errStakingV4StepsNotInOrder, err) + }) + + t.Run("staking v4 steps not in ascending order, should work", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 + + err := SanityCheckEnableEpochsStakingV4(cfg) + require.Nil(t, err) + }) + + t.Run("no previous config for max nodes change, should work", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + { + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + } + + err := SanityCheckEnableEpochsStakingV4(cfg) + require.Nil(t, err) + }) + + t.Run("no max nodes config change for StakingV4Step3EnableEpoch, should return error", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + { + EpochEnable: 444, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + } + + err := SanityCheckEnableEpochsStakingV4(cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), errNoMaxNodesConfigChangeForStakingV4.Error())) + require.True(t, strings.Contains(err.Error(), "6")) + }) + + t.Run("stakingV4 config for max nodes changed with different nodes to shuffle, should work", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[1].NodesToShufflePerShard = 2 + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].NodesToShufflePerShard = 4 + + err := SanityCheckEnableEpochsStakingV4(cfg) + require.Nil(t, err) + }) + + t.Run("stakingV4 config for max nodes changed with wrong max num nodes, should return error", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].MaxNumNodes = 56 + + err := SanityCheckEnableEpochsStakingV4(cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), "expected")) + require.True(t, strings.Contains(err.Error(), "48")) + require.True(t, strings.Contains(err.Error(), "got")) + require.True(t, strings.Contains(err.Error(), "56")) + }) +} diff --git a/config/errors.go b/config/errors.go new file mode 100644 index 00000000000..91f04f9cd35 --- /dev/null +++ b/config/errors.go @@ -0,0 +1,7 @@ +package config + +import "errors" + +var errStakingV4StepsNotInOrder = errors.New("staking v4 enable epochs are not in ascending order; expected StakingV4Step1EnableEpoch < StakingV4Step2EnableEpoch < StakingV4Step3EnableEpoch") + +var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch") From 32181f0a0662f1e838ea31952f7e342a9f31b187 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 14 Feb 2023 13:40:24 +0200 Subject: [PATCH 417/958] FIX: Unit test --- config/configChecker_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 7e7dca6a49a..bcf5fdc9dfe 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -68,16 +68,28 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { require.Equal(t, errStakingV4StepsNotInOrder, err) }) - t.Run("staking v4 steps not in ascending order, should work", func(t *testing.T) { + t.Run("staking v4 steps not in cardinal order, should work", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 - err := SanityCheckEnableEpochsStakingV4(cfg) require.Nil(t, err) + + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 + err = SanityCheckEnableEpochsStakingV4(cfg) + require.Nil(t, err) + + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 + err = SanityCheckEnableEpochsStakingV4(cfg) + require.Nil(t, err) }) t.Run("no previous config for max nodes change, should work", func(t *testing.T) { From e67fd44a64cbdea402311e5aa00b590fb634ec33 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 14 Feb 2023 17:20:12 +0200 Subject: [PATCH 418/958] FIX: After review --- config/configChecker.go | 48 ++++++++++++------------------------ config/configChecker_test.go | 43 ++++++++++++++++++++++++++------ config/errors.go | 8 +++++- 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index 759f268ed9b..5bad41d2839 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -2,55 +2,41 @@ package config import ( "fmt" - - logger "github.com/multiversx/mx-chain-logger-go" ) -var log = logger.GetOrCreate("configChecker") - +// SanityCheckEnableEpochsStakingV4 checks if the enable epoch configs for stakingV4 are set correctly func SanityCheckEnableEpochsStakingV4(cfg *Configs) error { enableEpochsCfg := cfg.EpochConfig.EnableEpochs - err := checkStakingV4EpochsOrder(enableEpochsCfg) - if err != nil { - return err + if !areStakingV4StepsInOrder(enableEpochsCfg) { + return errStakingV4StepsNotInOrder } numOfShards := cfg.GeneralConfig.GeneralSettings.GenesisMaxNumberOfShards return checkStakingV4MaxNodesChangeCfg(enableEpochsCfg, numOfShards) } -func checkStakingV4EpochsOrder(enableEpochsCfg EnableEpochs) error { - stakingV4StepsInOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch < enableEpochsCfg.StakingV4Step2EnableEpoch) && - (enableEpochsCfg.StakingV4Step2EnableEpoch < enableEpochsCfg.StakingV4Step3EnableEpoch) - - if !stakingV4StepsInOrder { - return errStakingV4StepsNotInOrder - } - - stakingV4StepsInExpectedOrder := (enableEpochsCfg.StakingV4Step1EnableEpoch == enableEpochsCfg.StakingV4Step2EnableEpoch-1) && +func areStakingV4StepsInOrder(enableEpochsCfg EnableEpochs) bool { + return (enableEpochsCfg.StakingV4Step1EnableEpoch == enableEpochsCfg.StakingV4Step2EnableEpoch-1) && (enableEpochsCfg.StakingV4Step2EnableEpoch == enableEpochsCfg.StakingV4Step3EnableEpoch-1) - if !stakingV4StepsInExpectedOrder { - log.Warn("staking v4 enable epoch steps should be in cardinal order " + - "(e.g.: StakingV4Step1EnableEpoch = 2, StakingV4Step2EnableEpoch = 3, StakingV4Step3EnableEpoch = 4)" + - "; can leave them as they are for playground purposes" + - ", but DO NOT use them in production, since system's behavior is undefined") - } - - return nil } func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards uint32) error { + maxNodesChangeCfg := enableEpochsCfg.MaxNodesChangeEnableEpoch + if len(maxNodesChangeCfg) <= 1 { + return errNotEnoughMaxNodesChanges + } + maxNodesConfigAdaptedForStakingV4 := false - for idx, currMaxNodesChangeCfg := range enableEpochsCfg.MaxNodesChangeEnableEpoch { + for idx, currMaxNodesChangeCfg := range maxNodesChangeCfg { if currMaxNodesChangeCfg.EpochEnable == enableEpochsCfg.StakingV4Step3EnableEpoch { - maxNodesConfigAdaptedForStakingV4 = true + if idx == 0 { - log.Warn(fmt.Sprintf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, ", enableEpochsCfg.StakingV4Step3EnableEpoch) + - "but no previous config change entry in MaxNodesChangeEnableEpoch, DO NOT use this config in production") + return fmt.Errorf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, but %w ", + enableEpochsCfg.StakingV4Step3EnableEpoch, errNoMaxNodesConfigBeforeStakingV4) } else { - prevMaxNodesChange := enableEpochsCfg.MaxNodesChangeEnableEpoch[idx-1] + prevMaxNodesChange := maxNodesChangeCfg[idx-1] err := checkMaxNodesChangedCorrectly(prevMaxNodesChange, currMaxNodesChangeCfg, numOfShards) if err != nil { return err @@ -70,9 +56,7 @@ func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards u func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, currMaxNodesChange MaxNodesChangeConfig, numOfShards uint32) error { if prevMaxNodesChange.NodesToShufflePerShard != currMaxNodesChange.NodesToShufflePerShard { - log.Warn("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard" + - " with EnableEpoch = StakingV4Step3EnableEpoch; can leave them as they are for playground purposes," + - " but DO NOT use them in production, since this will influence rewards") + return errMismatchNodesToShuffle } totalShuffled := (numOfShards + 1) * prevMaxNodesChange.NodesToShufflePerShard diff --git a/config/configChecker_test.go b/config/configChecker_test.go index bcf5fdc9dfe..3e89dad2b94 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -68,7 +68,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { require.Equal(t, errStakingV4StepsNotInOrder, err) }) - t.Run("staking v4 steps not in cardinal order, should work", func(t *testing.T) { + t.Run("staking v4 steps not in cardinal order, should return error", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() @@ -77,22 +77,22 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 err := SanityCheckEnableEpochsStakingV4(cfg) - require.Nil(t, err) + require.Equal(t, errStakingV4StepsNotInOrder, err) cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 2 cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 err = SanityCheckEnableEpochsStakingV4(cfg) - require.Nil(t, err) + require.Equal(t, errStakingV4StepsNotInOrder, err) cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 err = SanityCheckEnableEpochsStakingV4(cfg) - require.Nil(t, err) + require.Equal(t, errStakingV4StepsNotInOrder, err) }) - t.Run("no previous config for max nodes change, should work", func(t *testing.T) { + t.Run("no previous config for max nodes change, should return error", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() @@ -105,7 +105,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { } err := SanityCheckEnableEpochsStakingV4(cfg) - require.Nil(t, err) + require.Equal(t, errNotEnoughMaxNodesChanges, err) }) t.Run("no max nodes config change for StakingV4Step3EnableEpoch, should return error", func(t *testing.T) { @@ -113,6 +113,11 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { cfg := generateCorrectConfig() cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + { + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, { EpochEnable: 444, MaxNumNodes: 48, @@ -126,7 +131,29 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { require.True(t, strings.Contains(err.Error(), "6")) }) - t.Run("stakingV4 config for max nodes changed with different nodes to shuffle, should work", func(t *testing.T) { + t.Run("max nodes config change for StakingV4Step3EnableEpoch has no previous config change, should return error", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + { + EpochEnable: cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 444, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + } + + err := SanityCheckEnableEpochsStakingV4(cfg) + require.NotNil(t, err) + require.ErrorIs(t, err, errNoMaxNodesConfigBeforeStakingV4) + }) + + t.Run("stakingV4 config for max nodes changed with different nodes to shuffle, should return error", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() @@ -134,7 +161,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].NodesToShufflePerShard = 4 err := SanityCheckEnableEpochsStakingV4(cfg) - require.Nil(t, err) + require.ErrorIs(t, err, errMismatchNodesToShuffle) }) t.Run("stakingV4 config for max nodes changed with wrong max num nodes, should return error", func(t *testing.T) { diff --git a/config/errors.go b/config/errors.go index 91f04f9cd35..17409d84916 100644 --- a/config/errors.go +++ b/config/errors.go @@ -2,6 +2,12 @@ package config import "errors" -var errStakingV4StepsNotInOrder = errors.New("staking v4 enable epochs are not in ascending order; expected StakingV4Step1EnableEpoch < StakingV4Step2EnableEpoch < StakingV4Step3EnableEpoch") +var errStakingV4StepsNotInOrder = errors.New("staking v4 enable epoch steps should be in cardinal order(e.g.: StakingV4Step1EnableEpoch = 2, StakingV4Step2EnableEpoch = 3, StakingV4Step3EnableEpoch = 4)") + +var errNotEnoughMaxNodesChanges = errors.New("not enough entries in MaxNodesChangeEnableEpoch config; expected one entry before stakingV4 and another one starting StakingV4Step3EnableEpoch") + +var errNoMaxNodesConfigBeforeStakingV4 = errors.New("no previous config change entry in MaxNodesChangeEnableEpoch before entry with EpochEnable = StakingV4Step3EnableEpoch") + +var errMismatchNodesToShuffle = errors.New("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard with EnableEpoch = StakingV4Step3EnableEpoch") var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch") From 85cd6ae1c815ae744e2eeff477e756c534e59111 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 15 Feb 2023 11:23:15 +0200 Subject: [PATCH 419/958] CLN: Remove unused IsTransferToMetaFlagEnabled --- common/enablers/epochFlags.go | 6 ------ common/interface.go | 1 - go.mod | 2 +- go.sum | 4 ++-- sharding/mock/enableEpochsHandlerMock.go | 5 ----- testscommon/enableEpochsHandlerStub.go | 5 ----- 6 files changed, 3 insertions(+), 20 deletions(-) diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index e75b93eb4b7..ce6649d9f83 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -599,12 +599,6 @@ func (holder *epochFlagsHolder) IsCheckTransferFlagEnabled() bool { return holder.optimizeNFTStoreFlag.IsSet() } -// IsTransferToMetaFlagEnabled returns false -// This is used for consistency into vm-common -func (holder *epochFlagsHolder) IsTransferToMetaFlagEnabled() bool { - return false -} - // IsESDTNFTImprovementV1FlagEnabled returns true if esdtMultiTransferFlag is enabled // this is a duplicate for ESDTMultiTransferEnableEpoch needed for consistency into vm-common func (holder *epochFlagsHolder) IsESDTNFTImprovementV1FlagEnabled() bool { diff --git a/common/interface.go b/common/interface.go index 99a8867f2c2..679817be8af 100644 --- a/common/interface.go +++ b/common/interface.go @@ -324,7 +324,6 @@ type EnableEpochsHandler interface { IsSendAlwaysFlagEnabled() bool IsValueLengthCheckFlagEnabled() bool IsCheckTransferFlagEnabled() bool - IsTransferToMetaFlagEnabled() bool IsESDTNFTImprovementV1FlagEnabled() bool IsSetSenderInEeiOutputTransferFlagEnabled() bool IsChangeDelegationOwnerFlagEnabled() bool diff --git a/go.mod b/go.mod index bebb90b0036..c6bc3e6a3ee 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.11 github.com/multiversx/mx-chain-p2p-go v1.0.10 github.com/multiversx/mx-chain-storage-go v1.0.7 - github.com/multiversx/mx-chain-vm-common-go v1.3.36 + github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.49 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.50 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.74 diff --git a/go.sum b/go.sum index 620ecd0584b..4d282f9215a 100644 --- a/go.sum +++ b/go.sum @@ -608,8 +608,8 @@ github.com/multiversx/mx-chain-p2p-go v1.0.10/go.mod h1:j9Ueo2ptCnL7TQvQg6KS/KWA github.com/multiversx/mx-chain-storage-go v1.0.7 h1:UqLo/OLTD3IHiE/TB/SEdNRV1GG2f1R6vIP5ehHwCNw= github.com/multiversx/mx-chain-storage-go v1.0.7/go.mod h1:gtKoV32Cg2Uy8deHzF8Ud0qAl0zv92FvWgPSYIP0Zmg= github.com/multiversx/mx-chain-vm-common-go v1.3.34/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= -github.com/multiversx/mx-chain-vm-common-go v1.3.36 h1:9TViMK+vqTHss9cnGKtzOWzsxI/LWIetAYzrgf4H/w0= -github.com/multiversx/mx-chain-vm-common-go v1.3.36/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= +github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376 h1:XQ/1vzldHMV2C+bc+pIKbDUYrVauUt1tOWsha1U2T6g= +github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.49 h1:Qbe+QvpUzodoOJEu+j6uK/erhnLfQBwNGiAEyP1XlQI= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.49/go.mod h1:+2IkboTtZ75oZ2Lzx7gNWbLP6BQ5GYa1MJQXPcfzu60= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.50 h1:+JlYeStjpPqyRGzfLCwnR4Zya3nA34SJjj/1DP1HtXk= diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 2e743c5e9bf..ba38ca3ccb7 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -500,11 +500,6 @@ func (mock *EnableEpochsHandlerMock) IsCheckTransferFlagEnabled() bool { return false } -// IsTransferToMetaFlagEnabled returns false -func (mock *EnableEpochsHandlerMock) IsTransferToMetaFlagEnabled() bool { - return false -} - // IsESDTNFTImprovementV1FlagEnabled returns false func (mock *EnableEpochsHandlerMock) IsESDTNFTImprovementV1FlagEnabled() bool { return false diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 3f17cdc9a26..bc74c99ab33 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -916,11 +916,6 @@ func (stub *EnableEpochsHandlerStub) IsCheckTransferFlagEnabled() bool { return stub.IsCheckTransferFlagEnabledField } -// IsTransferToMetaFlagEnabled - -func (stub *EnableEpochsHandlerStub) IsTransferToMetaFlagEnabled() bool { - return false -} - // IsESDTNFTImprovementV1FlagEnabled - func (stub *EnableEpochsHandlerStub) IsESDTNFTImprovementV1FlagEnabled() bool { stub.RLock() From db21359a84ce832fab85ebcf27f74df6e8c545a4 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 16 Feb 2023 11:34:58 +0200 Subject: [PATCH 420/958] FIX: go mod --- go.mod | 2 +- go.sum | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7fa2fc38c04..7b65edfecd5 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.11 github.com/multiversx/mx-chain-p2p-go v1.0.11 github.com/multiversx/mx-chain-storage-go v1.0.7 - github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376 + github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.50 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.51 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.76 diff --git a/go.sum b/go.sum index 75ab2e47087..fd81ddebf72 100644 --- a/go.sum +++ b/go.sum @@ -610,6 +610,7 @@ github.com/multiversx/mx-chain-p2p-go v1.0.11/go.mod h1:j9Ueo2ptCnL7TQvQg6KS/KWA github.com/multiversx/mx-chain-storage-go v1.0.7 h1:UqLo/OLTD3IHiE/TB/SEdNRV1GG2f1R6vIP5ehHwCNw= github.com/multiversx/mx-chain-storage-go v1.0.7/go.mod h1:gtKoV32Cg2Uy8deHzF8Ud0qAl0zv92FvWgPSYIP0Zmg= github.com/multiversx/mx-chain-vm-common-go v1.3.34/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= +github.com/multiversx/mx-chain-vm-common-go v1.3.36/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376 h1:XQ/1vzldHMV2C+bc+pIKbDUYrVauUt1tOWsha1U2T6g= github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.50 h1:ScUq7/wq78vthMTQ6v5Ux1DvSMQMHxQ2Sl7aPP26q1w= From 4157398771f1159d4cc754893e4ea5a76e05ad6a Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 16 Feb 2023 11:56:56 +0200 Subject: [PATCH 421/958] FIX: Remove warn --- .../nodesCoordinator/indexHashedNodesCoordinator.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index cd4ba11d765..48a511361c3 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -591,7 +591,7 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa return } - metaBlock, castOk := metaHdr.(*block.MetaBlock) + _, castOk := metaHdr.(*block.MetaBlock) if !castOk { log.Error("could not process EpochStartPrepare on nodesCoordinator - not metaBlock") return @@ -620,15 +620,6 @@ func (ihnc *indexHashedNodesCoordinator) EpochStartPrepare(metaHdr data.HeaderHa return } - prevNumOfShards := uint32(len(metaBlock.ShardInfo)) - if prevNumOfShards != newNodesConfig.nbShards { - log.Warn("number of shards does not match", - "previous epoch", ihnc.currentEpoch, - "previous number of shards", prevNumOfShards, - "new epoch", newEpoch, - "new number of shards", newNodesConfig.nbShards) - } - additionalLeavingMap, err := ihnc.nodesCoordinatorHelper.ComputeAdditionalLeaving(allValidatorInfo) if err != nil { log.Error("could not compute additionalLeaving Nodes - do nothing on nodesCoordinator epochStartPrepare") From 5bca1bbfd50232770e45d97f11fa3236a91be429 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 6 Mar 2023 14:14:44 +0200 Subject: [PATCH 422/958] FEAT: Add integration test which fails for now --- integrationTests/vm/staking/stakingV4_test.go | 166 ++++++++++++++++++ vm/systemSmartContracts/delegation.go | 16 -- 2 files changed, 166 insertions(+), 16 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 8f665cdd32b..a0c8713b9b1 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -901,3 +901,169 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { requireSameSliceDifferentOrder(t, queue, currNodesConfig.auction) require.Empty(t, node.NodesConfig.queue) } + +// This is an edge case with exactly 1 in waiting +func TestStakingV4_ExactlyOneNodeInWaitingEveryEpoch(t *testing.T) { + pubKeys := generateAddresses(0, 20) + + owner1 := "owner1" + owner1Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:4], + 0: pubKeys[4:8], + }, + WaitingBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[8:10], + 0: pubKeys[10:12], + }, + TotalStake: big.NewInt(20 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 2, + ShardConsensusGroupSize: 2, + MinNumberOfEligibleShardNodes: 4, + MinNumberOfEligibleMetaNodes: 4, + NumOfShards: 1, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 12, + NodesToShufflePerShard: 1, + }, + { + EpochEnable: stakingV4Step3EnableEpoch, + MaxNumNodes: 10, + NodesToShufflePerShard: 1, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + node.Process(t, 7*4+2) +} + +func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T) { + pubKeys := generateAddresses(0, 20) + + owner1 := "owner1" + owner1Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:4], + 0: pubKeys[4:8], + }, + WaitingBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[8:9], + 0: pubKeys[9:10], + }, + TotalStake: big.NewInt(20 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 2, + ShardConsensusGroupSize: 2, + MinNumberOfEligibleShardNodes: 4, + MinNumberOfEligibleMetaNodes: 4, + NumOfShards: 1, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 10, + NodesToShufflePerShard: 1, + }, + { + EpochEnable: stakingV4Step3EnableEpoch, + MaxNumNodes: 8, + NodesToShufflePerShard: 1, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + prevNodesConfig := currNodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 1) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // 2. Epoch = StakingV4Step1, configuration should be the same, nodes from eligible should be shuffled + node.Process(t, 6) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 1) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + + prevNodesConfig = currNodesConfig + + // 3. Epoch = StakingV4Step2, shuffled nodes from eligible are sent to auction, waiting list remains empty + node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 0) + require.Len(t, currNodesConfig.auction, 2) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + + // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) + + prevNodesConfig = currNodesConfig + + // 4. Epoch = StakingV4Step3, auction nodes from previous epoch should be sent directly to waiting list, since waiting list was empty + node.Process(t, 5) + + /* Test fails from here, should work with fix + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 0) + require.Len(t, currNodesConfig.auction, 2) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + + // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) + */ +} diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index 2f89ed72d79..e269e633df5 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -2883,22 +2883,6 @@ func (d *delegation) executeStakeAndUpdateStatus( return vmcommon.Ok } -func (d *delegation) getConfigStatusAndGlobalFund() (*DelegationConfig, *DelegationContractStatus, *GlobalFundData, error) { - dConfig, err := d.getDelegationContractConfig() - if err != nil { - return nil, nil, nil, err - } - globalFund, err := d.getGlobalFundData() - if err != nil { - return nil, nil, nil, err - } - dStatus, err := d.getDelegationStatus() - if err != nil { - return nil, nil, nil, err - } - return dConfig, dStatus, globalFund, nil -} - func (d *delegation) executeOnValidatorSC(address []byte, function string, args [][]byte, value *big.Int) (*vmcommon.VMOutput, error) { validatorCall := function for _, key := range args { From 6d4b2f803c48ae51e00c7639881833cefc3b6005 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 7 Mar 2023 12:01:39 +0200 Subject: [PATCH 423/958] FEAT: Add todo workflow --- integrationTests/vm/staking/stakingV4_test.go | 4 ++-- sharding/nodesCoordinator/hashValidatorShuffler.go | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index a0c8713b9b1..0f2341c248e 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1051,7 +1051,7 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T // 4. Epoch = StakingV4Step3, auction nodes from previous epoch should be sent directly to waiting list, since waiting list was empty node.Process(t, 5) - /* Test fails from here, should work with fix + /*Test fails from here, should work with fix currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) @@ -1063,7 +1063,7 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), prevNodesConfig.auction, 2) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) */ } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 89b3beb5fc5..6c06af41d44 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -283,6 +283,11 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { shuffledOutMap, newEligible := shuffleOutNodes(newEligible, numToRemove, arg.randomness) + // Here check that if allNodes(waitingList/newWaiting) < allNodes(shuffledOutMap) then select nodes from auction + // Compute numNodesToFillWaiting = allNodes(shuffledOutMap) - allNodes(waitingList) + // Easy case If: numNodesToFillWaiting > allNodes(auction) => move all auction list to waiting + // Else: select best nodes from auction to fill waiting list + err = moveMaxNumNodesToMap(newEligible, newWaiting, arg.nodesMeta, arg.nodesPerShard) if err != nil { log.Warn("moveNodesToMap failed", "error", err) From 26e8245fd7b6504bdeffdfa683327008b95c9d1d Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 7 Mar 2023 13:34:30 +0200 Subject: [PATCH 424/958] FEAT: Possible solution for easy case --- integrationTests/vm/staking/stakingV4_test.go | 32 ++++++++++--------- .../nodesCoordinator/hashValidatorShuffler.go | 31 +++++++++++++++++- .../hashValidatorShufflerWithAuction.go | 11 +++++++ 3 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 0f2341c248e..ef175ff66a5 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1032,21 +1032,21 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T // 3. Epoch = StakingV4Step2, shuffled nodes from eligible are sent to auction, waiting list remains empty node.Process(t, 5) - currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 0) - require.Len(t, currNodesConfig.auction, 2) - requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) - - // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) - - prevNodesConfig = currNodesConfig + //currNodesConfig = node.NodesConfig + //require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + //require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) + //require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + //require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) + //require.Len(t, currNodesConfig.eligible[0], 4) + //require.Len(t, currNodesConfig.waiting[0], 0) + //require.Len(t, currNodesConfig.auction, 2) + //requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + // + //// Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + //requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + //requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) + // + //prevNodesConfig = currNodesConfig // 4. Epoch = StakingV4Step3, auction nodes from previous epoch should be sent directly to waiting list, since waiting list was empty node.Process(t, 5) @@ -1066,4 +1066,6 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), prevNodesConfig.auction, 2) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) */ + + node.Process(t, 5) } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 6c06af41d44..a818fb43b33 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -283,6 +283,24 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { shuffledOutMap, newEligible := shuffleOutNodes(newEligible, numToRemove, arg.randomness) + numShuffled := getNumPubKeys(shuffledOutMap) + numNewWaiting := getNumPubKeys(newWaiting) + numSelectedAuction := uint32(len(arg.auction)) + totalNewWaiting := numNewWaiting + numSelectedAuction + + shouldFillWaitingList := false + if numShuffled >= totalNewWaiting { + numNeededNodesToFillWaiting := numShuffled - totalNewWaiting + log.Warn("not enough nodes in waiting for next epoch after shuffling current validators into auction", + "numShuffled", numShuffled, + "numNewWaiting", numNewWaiting, + "numSelectedAuction", numSelectedAuction, + "numNeededNodesToFillWaiting", numNeededNodesToFillWaiting) + + if arg.flagStakingV4Step2 { + shouldFillWaitingList = true + } + } // Here check that if allNodes(waitingList/newWaiting) < allNodes(shuffledOutMap) then select nodes from auction // Compute numNodesToFillWaiting = allNodes(shuffledOutMap) - allNodes(waitingList) // Easy case If: numNodesToFillWaiting > allNodes(auction) => move all auction list to waiting @@ -298,13 +316,24 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - if arg.flagStakingV4Step3 { + if arg.flagStakingV4Step3 && !shouldFillWaitingList { // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) if err != nil { log.Warn("distributeValidators auction list failed", "error", err) } } + + if arg.flagStakingV4Step2 && shouldFillWaitingList { + + log.Warn("distributing shuffled out nodes to waiting list instead of auction") + // Distribute validators from SHUFFLED OUT -> WAITING + err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) + if err != nil { + log.Warn("distributeValidators shuffledOut failed", "error", err) + } + } + if !arg.flagStakingV4Step2 { // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) diff --git a/sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go b/sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go new file mode 100644 index 00000000000..77edafcc52a --- /dev/null +++ b/sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go @@ -0,0 +1,11 @@ +package nodesCoordinator + +func getNumPubKeys(shardValidatorsMap map[uint32][]Validator) uint32 { + numPubKeys := uint32(0) + + for _, validatorsInShard := range shardValidatorsMap { + numPubKeys += uint32(len(validatorsInShard)) + } + + return numPubKeys +} From 9712fc0f4ceaba4e03868cbb6c3ca7595885b32f Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 7 Mar 2023 18:31:38 +0200 Subject: [PATCH 425/958] FEAT: Possible solution --- .../nodesCoordinator/hashValidatorShuffler.go | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index a818fb43b33..7cc0acd8914 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -41,6 +41,7 @@ type shuffleNodesArg struct { nodesPerShard uint32 nbShards uint32 maxNodesToSwapPerShard uint32 + maxNumNodes uint32 flagBalanceWaitingLists bool flagStakingV4Step2 bool flagStakingV4Step3 bool @@ -195,6 +196,7 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), flagStakingV4Step2: rhs.flagStakingV4Step2.IsSet(), flagStakingV4Step3: rhs.flagStakingV4Step3.IsSet(), + maxNumNodes: rhs.activeNodesConfig.MaxNumNodes, }) } @@ -284,22 +286,26 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { shuffledOutMap, newEligible := shuffleOutNodes(newEligible, numToRemove, arg.randomness) numShuffled := getNumPubKeys(shuffledOutMap) + numNewEligible := getNumPubKeys(newEligible) numNewWaiting := getNumPubKeys(newWaiting) + numSelectedAuction := uint32(len(arg.auction)) totalNewWaiting := numNewWaiting + numSelectedAuction - shouldFillWaitingList := false - if numShuffled >= totalNewWaiting { - numNeededNodesToFillWaiting := numShuffled - totalNewWaiting - log.Warn("not enough nodes in waiting for next epoch after shuffling current validators into auction", + totalNodes := totalNewWaiting + numNewEligible + numShuffled + + distributeShuffledToWaiting := false + if totalNodes <= arg.maxNumNodes || (numNewEligible+numShuffled) <= arg.maxNumNodes { + log.Warn("num of total nodes in waiting is too low after shuffling; will distribute "+ + "shuffled out nodes directly in waiting and skip sending them to auction", "numShuffled", numShuffled, - "numNewWaiting", numNewWaiting, + "numNewEligible", numNewEligible, "numSelectedAuction", numSelectedAuction, - "numNeededNodesToFillWaiting", numNeededNodesToFillWaiting) + "totalNewWaiting", totalNewWaiting, + "totalNodes", totalNodes, + "maxNumNodes", arg.maxNumNodes) - if arg.flagStakingV4Step2 { - shouldFillWaitingList = true - } + distributeShuffledToWaiting = arg.flagStakingV4Step2 } // Here check that if allNodes(waitingList/newWaiting) < allNodes(shuffledOutMap) then select nodes from auction // Compute numNodesToFillWaiting = allNodes(shuffledOutMap) - allNodes(waitingList) @@ -316,7 +322,9 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - if arg.flagStakingV4Step3 && !shouldFillWaitingList { + if arg.flagStakingV4Step3 && !distributeShuffledToWaiting { + log.Debug("distributing selected nodes from auction to waiting") + // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) if err != nil { @@ -324,9 +332,9 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { } } - if arg.flagStakingV4Step2 && shouldFillWaitingList { + if distributeShuffledToWaiting { + log.Debug("distributing shuffled out nodes to waiting in staking V4") - log.Warn("distributing shuffled out nodes to waiting list instead of auction") // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) if err != nil { From 721748776aed2bd06cb8d50c8b727b31361e5bf2 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 8 Mar 2023 11:54:06 +0200 Subject: [PATCH 426/958] FIX: Broken condition for impossible case --- integrationTests/vm/staking/stakingV4_test.go | 4 ++-- .../nodesCoordinator/hashValidatorShuffler.go | 23 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index ef175ff66a5..6d379d45f00 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -986,12 +986,12 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { EpochEnable: 0, - MaxNumNodes: 10, + MaxNumNodes: 12, NodesToShufflePerShard: 1, }, { EpochEnable: stakingV4Step3EnableEpoch, - MaxNumNodes: 8, + MaxNumNodes: 10, NodesToShufflePerShard: 1, }, }, diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 7cc0acd8914..635de1f0a6e 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -293,9 +293,10 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { totalNewWaiting := numNewWaiting + numSelectedAuction totalNodes := totalNewWaiting + numNewEligible + numShuffled + maxNumNodes := arg.maxNumNodes - distributeShuffledToWaiting := false - if totalNodes <= arg.maxNumNodes || (numNewEligible+numShuffled) <= arg.maxNumNodes { + distributeShuffledToWaitingInStakingV4 := false + if totalNodes <= maxNumNodes { log.Warn("num of total nodes in waiting is too low after shuffling; will distribute "+ "shuffled out nodes directly in waiting and skip sending them to auction", "numShuffled", numShuffled, @@ -303,14 +304,10 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { "numSelectedAuction", numSelectedAuction, "totalNewWaiting", totalNewWaiting, "totalNodes", totalNodes, - "maxNumNodes", arg.maxNumNodes) + "maxNumNodes", maxNumNodes) - distributeShuffledToWaiting = arg.flagStakingV4Step2 + distributeShuffledToWaitingInStakingV4 = arg.flagStakingV4Step2 } - // Here check that if allNodes(waitingList/newWaiting) < allNodes(shuffledOutMap) then select nodes from auction - // Compute numNodesToFillWaiting = allNodes(shuffledOutMap) - allNodes(waitingList) - // Easy case If: numNodesToFillWaiting > allNodes(auction) => move all auction list to waiting - // Else: select best nodes from auction to fill waiting list err = moveMaxNumNodesToMap(newEligible, newWaiting, arg.nodesMeta, arg.nodesPerShard) if err != nil { @@ -322,8 +319,9 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - if arg.flagStakingV4Step3 && !distributeShuffledToWaiting { - log.Debug("distributing selected nodes from auction to waiting") + if arg.flagStakingV4Step3 && !distributeShuffledToWaitingInStakingV4 { + log.Debug("distributing selected nodes from auction to waiting", + "num auction nodes", len(arg.auction), "num waiting nodes", numNewWaiting) // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) @@ -332,8 +330,9 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { } } - if distributeShuffledToWaiting { - log.Debug("distributing shuffled out nodes to waiting in staking V4") + if distributeShuffledToWaitingInStakingV4 { + log.Debug("distributing shuffled out nodes to waiting in staking V4", + "num shuffled nodes", numShuffled, "num waiting nodes", numNewWaiting) // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) From c68293a7494be7af7c1bcfd5e4463a272972cfb5 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 8 Mar 2023 17:33:58 +0200 Subject: [PATCH 427/958] FEAT: Continue integration edge case testing --- integrationTests/vm/staking/stakingV4_test.go | 211 +++++++++++------- .../nodesCoordinator/hashValidatorShuffler.go | 12 +- .../hashValidatorShufflerWithAuction.go | 11 - 3 files changed, 136 insertions(+), 98 deletions(-) delete mode 100644 sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 6d379d45f00..7864de8974f 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -902,8 +902,7 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { require.Empty(t, node.NodesConfig.queue) } -// This is an edge case with exactly 1 in waiting -func TestStakingV4_ExactlyOneNodeInWaitingEveryEpoch(t *testing.T) { +func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T) { pubKeys := generateAddresses(0, 20) owner1 := "owner1" @@ -913,8 +912,8 @@ func TestStakingV4_ExactlyOneNodeInWaitingEveryEpoch(t *testing.T) { 0: pubKeys[4:8], }, WaitingBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[8:10], - 0: pubKeys[10:12], + core.MetachainShardId: pubKeys[8:9], + 0: pubKeys[9:10], }, TotalStake: big.NewInt(20 * nodePrice), } @@ -935,63 +934,18 @@ func TestStakingV4_ExactlyOneNodeInWaitingEveryEpoch(t *testing.T) { NodesToShufflePerShard: 1, }, { - EpochEnable: stakingV4Step3EnableEpoch, + EpochEnable: stakingV4Step3EnableEpoch, // epoch 3 MaxNumNodes: 10, NodesToShufflePerShard: 1, }, - }, - } - node := NewTestMetaProcessorWithCustomNodes(cfg) - node.EpochStartTrigger.SetRoundsPerEpoch(4) - - // 1. Check initial config is correct - currNodesConfig := node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 2) - require.Empty(t, currNodesConfig.shuffledOut) - require.Empty(t, currNodesConfig.auction) - - node.Process(t, 7*4+2) -} - -func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T) { - pubKeys := generateAddresses(0, 20) - - owner1 := "owner1" - owner1Stats := &OwnerStats{ - EligibleBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[:4], - 0: pubKeys[4:8], - }, - WaitingBlsKeys: map[uint32][][]byte{ - core.MetachainShardId: pubKeys[8:9], - 0: pubKeys[9:10], - }, - TotalStake: big.NewInt(20 * nodePrice), - } - - cfg := &InitialNodesConfig{ - MetaConsensusGroupSize: 2, - ShardConsensusGroupSize: 2, - MinNumberOfEligibleShardNodes: 4, - MinNumberOfEligibleMetaNodes: 4, - NumOfShards: 1, - Owners: map[string]*OwnerStats{ - owner1: owner1Stats, - }, - MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ { - EpochEnable: 0, + EpochEnable: 6, MaxNumNodes: 12, NodesToShufflePerShard: 1, }, { - EpochEnable: stakingV4Step3EnableEpoch, - MaxNumNodes: 10, + EpochEnable: 9, + MaxNumNodes: 12, NodesToShufflePerShard: 1, }, }, @@ -1001,7 +955,6 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T // 1. Check initial config is correct currNodesConfig := node.NodesConfig - prevNodesConfig := currNodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) @@ -1011,8 +964,39 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - // 2. Epoch = StakingV4Step1, configuration should be the same, nodes from eligible should be shuffled - node.Process(t, 6) + prevNodesConfig := currNodesConfig + epochs := uint32(0) + for epochs < 9 { + node.Process(t, 5) + + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 1) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + + prevNodesConfig = currNodesConfig + epochs++ + } + + require.Equal(t, epochs, node.EpochStartTrigger.Epoch()) + + owner2Nodes := pubKeys[10:12] + node.ProcessStake(t, map[string]*NodesRegisterData{ + "owner2": { + BLSKeys: owner2Nodes, + TotalStake: big.NewInt(5 * nodePrice), + }, + }) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) @@ -1021,51 +1005,106 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T require.Len(t, currNodesConfig.eligible[0], 4) require.Len(t, currNodesConfig.waiting[0], 1) require.Empty(t, currNodesConfig.shuffledOut) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner2Nodes) + + node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), owner2Nodes) prevNodesConfig = currNodesConfig + epochs = 10 + require.Equal(t, epochs, node.EpochStartTrigger.Epoch()) + for epochs < 13 { + node.Process(t, 5) - // 3. Epoch = StakingV4Step2, shuffled nodes from eligible are sent to auction, waiting list remains empty - node.Process(t, 5) - //currNodesConfig = node.NodesConfig - //require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - //require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) - //require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - //require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) - //require.Len(t, currNodesConfig.eligible[0], 4) - //require.Len(t, currNodesConfig.waiting[0], 0) - //require.Len(t, currNodesConfig.auction, 2) - //requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) - // - //// Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes - //requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) - //requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) - // - //prevNodesConfig = currNodesConfig - - // 4. Epoch = StakingV4Step3, auction nodes from previous epoch should be sent directly to waiting list, since waiting list was empty - node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + + prevNodesConfig = currNodesConfig + epochs++ + } - /*Test fails from here, should work with fix + owner3Nodes := pubKeys[12:14] + node.ProcessStake(t, map[string]*NodesRegisterData{ + "owner3": { + BLSKeys: owner3Nodes, + TotalStake: big.NewInt(5 * nodePrice), + }, + }) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 0) - require.Len(t, currNodesConfig.auction, 2) - requireSameSliceDifferentOrder(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Empty(t, currNodesConfig.shuffledOut) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner3Nodes) - // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), prevNodesConfig.auction, 2) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) - */ + node.Process(t, 5) + prevNodesConfig = node.NodesConfig + epochs = 14 + require.Equal(t, epochs, node.EpochStartTrigger.Epoch()) + for epochs < 18 { + + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.waiting[0], 2) + require.Len(t, currNodesConfig.auction, 2) + + node.Process(t, 5) + + currNodesConfig = node.NodesConfig + // Nodes which are now in eligible are from previous waiting list + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + // New auction list does not contain nodes from previous auction list, since all of them have been distributed to waiting + requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, 0) + + // All shuffled out are from previous eligible config + requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) + + // All shuffled out are now in auction + requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + + // All nodes which have been selected from previous auction list are now in waiting + requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction) + + prevNodesConfig = currNodesConfig + epochs++ + } + + node.ProcessUnStake(t, map[string][][]byte{ + "owner3": {owner3Nodes[0]}, + }) + node.Process(t, 5) node.Process(t, 5) } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 635de1f0a6e..e3f97970077 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -319,7 +319,7 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } - if arg.flagStakingV4Step3 && !distributeShuffledToWaitingInStakingV4 { + if arg.flagStakingV4Step3 { log.Debug("distributing selected nodes from auction to waiting", "num auction nodes", len(arg.auction), "num waiting nodes", numNewWaiting) @@ -655,6 +655,16 @@ func moveNodesToMap(destination map[uint32][]Validator, source map[uint32][]Vali return nil } +func getNumPubKeys(shardValidatorsMap map[uint32][]Validator) uint32 { + numPubKeys := uint32(0) + + for _, validatorsInShard := range shardValidatorsMap { + numPubKeys += uint32(len(validatorsInShard)) + } + + return numPubKeys +} + // moveMaxNumNodesToMap moves the validators in the source list to the corresponding destination list // but adding just enough nodes so that at most the number of nodes is kept in the destination list // The parameter maxNodesToMove is a limiting factor and should limit the number of nodes diff --git a/sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go b/sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go deleted file mode 100644 index 77edafcc52a..00000000000 --- a/sharding/nodesCoordinator/hashValidatorShufflerWithAuction.go +++ /dev/null @@ -1,11 +0,0 @@ -package nodesCoordinator - -func getNumPubKeys(shardValidatorsMap map[uint32][]Validator) uint32 { - numPubKeys := uint32(0) - - for _, validatorsInShard := range shardValidatorsMap { - numPubKeys += uint32(len(validatorsInShard)) - } - - return numPubKeys -} From 9f27284c615dbd8d7ad3a707049f70ef8b7dad27 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 8 Mar 2023 18:19:07 +0200 Subject: [PATCH 428/958] FEAT: Extend edge case testing --- integrationTests/vm/staking/stakingV4_test.go | 112 +++++++++++++++--- 1 file changed, 93 insertions(+), 19 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 7864de8974f..8e85b110fc9 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -902,7 +902,7 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { require.Empty(t, node.NodesConfig.queue) } -func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T) { +func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffledToToWaiting(t *testing.T) { pubKeys := generateAddresses(0, 20) owner1 := "owner1" @@ -943,11 +943,6 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T MaxNumNodes: 12, NodesToShufflePerShard: 1, }, - { - EpochEnable: 9, - MaxNumNodes: 12, - NodesToShufflePerShard: 1, - }, }, } node := NewTestMetaProcessorWithCustomNodes(cfg) @@ -965,8 +960,15 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T require.Empty(t, currNodesConfig.auction) prevNodesConfig := currNodesConfig - epochs := uint32(0) - for epochs < 9 { + epoch := uint32(0) + + // During these 9 epochs, we will always have: + // - 10 activeNodes (8 eligible + 2 waiting) + // - 1 node to shuffle out per shard + // Meanwhile, maxNumNodes changes from 12-10-12 + // Since activeNodes <= maxNumNodes, shuffled out nodes will always be sent directly to waiting list, + // instead of auction(there is no reason to send them to auction, they will be selected anyway) + for epoch < 9 { node.Process(t, 5) currNodesConfig = node.NodesConfig @@ -985,11 +987,15 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) prevNodesConfig = currNodesConfig - epochs++ + epoch++ } - require.Equal(t, epochs, node.EpochStartTrigger.Epoch()) + require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) + // Epoch = 9 with: + // - activeNodes = 10 + // - maxNumNodes = 12 + // Owner2 stakes 2 nodes, which should be initially sent to auction list owner2Nodes := pubKeys[10:12] node.ProcessStake(t, map[string]*NodesRegisterData{ "owner2": { @@ -1007,6 +1013,10 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T require.Empty(t, currNodesConfig.shuffledOut) requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner2Nodes) + // Epoch = 10 with: + // - activeNodes = 12 + // - maxNumNodes = 12 + // Owner2's new nodes are selected from auction and distributed to waiting list node.Process(t, 5) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) @@ -1024,10 +1034,14 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), owner2Nodes) + // During epochs 10-13, we will have: + // - activeNodes = 12 + // - maxNumNodes = 12 + // Since activeNodes == maxNumNodes, shuffled out nodes will always be sent directly to waiting list, instead of auction + epoch = 10 + require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) prevNodesConfig = currNodesConfig - epochs = 10 - require.Equal(t, epochs, node.EpochStartTrigger.Epoch()) - for epochs < 13 { + for epoch < 13 { node.Process(t, 5) currNodesConfig = node.NodesConfig @@ -1046,9 +1060,13 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) prevNodesConfig = currNodesConfig - epochs++ + epoch++ } + // Epoch = 13 with: + // - activeNodes = 12 + // - maxNumNodes = 12 + // Owner3 stakes 2 nodes, which should be initially sent to auction list owner3Nodes := pubKeys[12:14] node.ProcessStake(t, map[string]*NodesRegisterData{ "owner3": { @@ -1066,11 +1084,15 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T require.Empty(t, currNodesConfig.shuffledOut) requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner3Nodes) + // During epochs 14-18, we will have: + // - activeNodes = 14 + // - maxNumNodes = 12 + // Since activeNodes > maxNumNodes, shuffled out nodes (2) will be sent to auction list node.Process(t, 5) prevNodesConfig = node.NodesConfig - epochs = 14 - require.Equal(t, epochs, node.EpochStartTrigger.Epoch()) - for epochs < 18 { + epoch = 14 + require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) + for epoch < 18 { require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) @@ -1099,12 +1121,64 @@ func TestStakingV4_NotEnoughNodesShouldSendAuctionDirectlyToWaiting(t *testing.T requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction) prevNodesConfig = currNodesConfig - epochs++ + epoch++ } + // Epoch = 18, with: + // - activeNodes = 14 + // - maxNumNodes = 12 + // Owner3 unStakes one of his nodes node.ProcessUnStake(t, map[string][][]byte{ "owner3": {owner3Nodes[0]}, }) + + // Epoch = 19, with: + // - activeNodes = 13 + // - maxNumNodes = 12 + // Owner3's unStaked node is now leaving node.Process(t, 5) - node.Process(t, 5) + currNodesConfig = node.NodesConfig + require.Len(t, currNodesConfig.leaving, 1) + requireMapContains(t, currNodesConfig.leaving, [][]byte{owner3Nodes[0]}) + + epoch = 19 + require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) + prevNodesConfig = node.NodesConfig + require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) + + // During epochs 19-23, we will have: + // - activeNodes = 13 + // - maxNumNodes = 12 + // Since activeNodes > maxNumNodes: + // - shuffled out nodes (2) will be sent to auction list + // - waiting lists will be unbalanced (3 in total: 1 + 2 per shard) + // - no node will spend extra epochs in eligible/waiting, since waiting lists will always be refilled + for epoch < 23 { + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 3) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) + require.Len(t, currNodesConfig.eligible[0], 4) + require.Len(t, currNodesConfig.auction, 2) + + node.Process(t, 5) + + currNodesConfig = node.NodesConfig + // Nodes which are now in eligible are from previous waiting list + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + + // New auction list does not contain nodes from previous auction list, since all of them have been distributed to waiting + requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, 0) + + // All shuffled out are from previous eligible config + requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) + + // All shuffled out are now in auction + requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + + // All nodes which have been selected from previous auction list are now in waiting + requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction) + + prevNodesConfig = currNodesConfig + epoch++ + } } From 8f7f754be052a1dc27c53cbbe1e67d01ec92fa53 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 9 Mar 2023 10:33:57 +0200 Subject: [PATCH 429/958] CLN: Comments --- integrationTests/vm/staking/stakingV4_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 8e85b110fc9..9698bbe5ab1 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -981,7 +981,7 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) @@ -1028,7 +1028,7 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) @@ -1054,7 +1054,7 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - // Shuffled nodes previous eligible ones are sent to waiting and previous waiting list nodes are replacing shuffled nodes + // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) From b56b74c66a5ffcc4045cd1b2caedcfb1d4fc78bd Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 9 Mar 2023 10:48:14 +0200 Subject: [PATCH 430/958] FIX: Typo --- sharding/nodesCoordinator/hashValidatorShuffler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index e3f97970077..4b2b67f133c 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -298,7 +298,7 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { distributeShuffledToWaitingInStakingV4 := false if totalNodes <= maxNumNodes { log.Warn("num of total nodes in waiting is too low after shuffling; will distribute "+ - "shuffled out nodes directly in waiting and skip sending them to auction", + "shuffled out nodes directly to waiting and skip sending them to auction", "numShuffled", numShuffled, "numNewEligible", numNewEligible, "numSelectedAuction", numSelectedAuction, From f9a847b68188c7604436ad1bc79852c26afc814a Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 9 Mar 2023 15:26:16 +0200 Subject: [PATCH 431/958] FEAT: Code placeholder --- config/configChecker.go | 37 +++++++++++++++++++++++++++++++++++++ node/nodeRunner.go | 8 ++++++++ 2 files changed, 45 insertions(+) diff --git a/config/configChecker.go b/config/configChecker.go index 5bad41d2839..329429bfd09 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -2,6 +2,8 @@ package config import ( "fmt" + + "github.com/multiversx/mx-chain-go/update" ) // SanityCheckEnableEpochsStakingV4 checks if the enable epoch configs for stakingV4 are set correctly @@ -68,3 +70,38 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr return nil } + +func SanityCheckNodesConfig( + nodesSetup update.GenesisNodesSetupHandler, + maxNodesChange []MaxNodesChangeConfig, +) error { + if len(maxNodesChange) < 1 { + return fmt.Errorf("not enough max num nodes") + } + + maxNodesConfig := maxNodesChange[0] + + waitingListSize := maxNodesConfig.MaxNumNodes - nodesSetup.MinNumberOfNodes() + if waitingListSize <= 0 { + return fmt.Errorf("negative waiting list") + } + + if maxNodesConfig.NodesToShufflePerShard == 0 { + return fmt.Errorf("0 nodes to shuffle per shard") + } + + // todo: same for metachain + waitingListSizePerShardSize := uint32(float32(nodesSetup.MinNumberOfShardNodes()) * nodesSetup.GetHysteresis()) + if waitingListSizePerShardSize%maxNodesConfig.NodesToShufflePerShard != 0 { + return fmt.Errorf("unbalanced waiting list") + } + + numSlotsWaitingListPerShard := waitingListSizePerShardSize / nodesSetup.NumberOfShards() + + atLeastOneWaitingListSlot := numSlotsWaitingListPerShard >= 1*maxNodesConfig.NodesToShufflePerShard + if !atLeastOneWaitingListSlot { + return fmt.Errorf("invalid num of waiting list slots") + } + + return nil +} diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 65875f3650f..fe7f197e431 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -284,6 +284,14 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( return true, err } + err = config.SanityCheckNodesConfig( + managedCoreComponents.GenesisNodesSetup(), + configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, + ) + if err != nil { + return true, err + } + log.Debug("creating status core components") managedStatusCoreComponents, err := nr.CreateManagedStatusCoreComponents(managedCoreComponents) if err != nil { From 095557974803e69a3c0eecf8b7187d316121280c Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 9 Mar 2023 15:32:36 +0200 Subject: [PATCH 432/958] FIX: Import cycle --- config/configChecker.go | 4 +--- config/interface.go | 10 ++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 config/interface.go diff --git a/config/configChecker.go b/config/configChecker.go index 329429bfd09..6645d17ae71 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -2,8 +2,6 @@ package config import ( "fmt" - - "github.com/multiversx/mx-chain-go/update" ) // SanityCheckEnableEpochsStakingV4 checks if the enable epoch configs for stakingV4 are set correctly @@ -72,7 +70,7 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr } func SanityCheckNodesConfig( - nodesSetup update.GenesisNodesSetupHandler, + nodesSetup NodesSetupHandler, maxNodesChange []MaxNodesChangeConfig, ) error { if len(maxNodesChange) < 1 { diff --git a/config/interface.go b/config/interface.go new file mode 100644 index 00000000000..9b3f05b1643 --- /dev/null +++ b/config/interface.go @@ -0,0 +1,10 @@ +package config + +// NodesSetupHandler provides nodes setup information +type NodesSetupHandler interface { + MinNumberOfNodes() uint32 + MinNumberOfShardNodes() uint32 + MinNumberOfMetaNodes() uint32 + GetHysteresis() float32 + NumberOfShards() uint32 +} From 1b131abc220bdf0f66259f343d0bf076e1b4339a Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Mar 2023 10:44:59 +0200 Subject: [PATCH 433/958] FEAT: Intermediary solution --- config/configChecker.go | 54 +++++++++--- config/configChecker_test.go | 162 +++++++++++++++++++++++++++++++++++ config/interface.go | 1 + 3 files changed, 203 insertions(+), 14 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index 6645d17ae71..07142d06d0e 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -69,37 +69,63 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr return nil } +// SanityCheckNodesConfig checks if the nodes limit setup is set correctly func SanityCheckNodesConfig( nodesSetup NodesSetupHandler, maxNodesChange []MaxNodesChangeConfig, ) error { if len(maxNodesChange) < 1 { - return fmt.Errorf("not enough max num nodes") + return errNotEnoughMaxNodesChanges } - maxNodesConfig := maxNodesChange[0] - - waitingListSize := maxNodesConfig.MaxNumNodes - nodesSetup.MinNumberOfNodes() - if waitingListSize <= 0 { - return fmt.Errorf("negative waiting list") + for _, maxNodesConfig := range maxNodesChange { + err := checkMaxNodesConfig(maxNodesConfig, nodesSetup) + if err != nil { + return fmt.Errorf("%w in MaxNodesChangeConfig at EpochEnable = %d", err, maxNodesConfig.EpochEnable) + } } + return nil +} + +func checkMaxNodesConfig(maxNodesConfig MaxNodesChangeConfig, nodesSetup NodesSetupHandler) error { if maxNodesConfig.NodesToShufflePerShard == 0 { return fmt.Errorf("0 nodes to shuffle per shard") } - // todo: same for metachain - waitingListSizePerShardSize := uint32(float32(nodesSetup.MinNumberOfShardNodes()) * nodesSetup.GetHysteresis()) - if waitingListSizePerShardSize%maxNodesConfig.NodesToShufflePerShard != 0 { - return fmt.Errorf("unbalanced waiting list") + nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard + maxNumNodes := maxNodesConfig.MaxNumNodes + minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() + if maxNumNodes < minNumNodesWithHysteresis { + return fmt.Errorf("MaxNumNodes less than MinNumberOfNodesWithHysteresis") + } + + numShards := nodesSetup.NumberOfShards() + hysteresis := nodesSetup.GetHysteresis() + + minNumOfShardNodesWithHysteresis := getMinNumNodesWithHysteresis(nodesSetup.MinNumberOfShardNodes(), hysteresis) + minNumOfMetaNodesWithHysteresis := getMinNumNodesWithHysteresis(nodesSetup.MinNumberOfMetaNodes(), hysteresis) + + maxWaitingListSizePerShard := (maxNumNodes - minNumOfMetaNodesWithHysteresis) / numShards + maxWaitingListSizePerMeta := maxNumNodes - minNumOfShardNodesWithHysteresis*numShards + + waitingListPerShard := (maxNumNodes - minNumNodesWithHysteresis) / (numShards + 1) + + if maxWaitingListSizePerShard <= 0 { + return fmt.Errorf("negative waiting list") } - numSlotsWaitingListPerShard := waitingListSizePerShardSize / nodesSetup.NumberOfShards() + if maxWaitingListSizePerMeta <= 0 { + return fmt.Errorf("negative waiting list") + } - atLeastOneWaitingListSlot := numSlotsWaitingListPerShard >= 1*maxNodesConfig.NodesToShufflePerShard - if !atLeastOneWaitingListSlot { - return fmt.Errorf("invalid num of waiting list slots") + if nodesToShufflePerShard > waitingListPerShard { + return fmt.Errorf("nodes to shuffle per shard > waiting list per shard") } return nil } + +func getMinNumNodesWithHysteresis(minNumNodes uint32, hysteresis float32) uint32 { + return uint32(float32(minNumNodes) * hysteresis) +} diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 3e89dad2b94..6c3d27a2181 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -7,6 +7,138 @@ import ( "github.com/stretchr/testify/require" ) +// NodesSetupStub - +type NodesSetupStub struct { + GetRoundDurationCalled func() uint64 + GetShardConsensusGroupSizeCalled func() uint32 + GetMetaConsensusGroupSizeCalled func() uint32 + NumberOfShardsCalled func() uint32 + MinNumberOfNodesCalled func() uint32 + GetAdaptivityCalled func() bool + GetHysteresisCalled func() float32 + GetShardIDForPubKeyCalled func(pubkey []byte) (uint32, error) + InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) + InitialNodesPubKeysCalled func() map[uint32][]string + MinNumberOfMetaNodesCalled func() uint32 + MinNumberOfShardNodesCalled func() uint32 + MinNumberOfNodesWithHysteresisCalled func() uint32 +} + +// MinNumberOfNodes - +func (n *NodesSetupStub) MinNumberOfNodes() uint32 { + if n.MinNumberOfNodesCalled != nil { + return n.MinNumberOfNodesCalled() + } + return 1 +} + +// GetRoundDuration - +func (n *NodesSetupStub) GetRoundDuration() uint64 { + if n.GetRoundDurationCalled != nil { + return n.GetRoundDurationCalled() + } + return 0 +} + +// GetShardConsensusGroupSize - +func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { + if n.GetShardConsensusGroupSizeCalled != nil { + return n.GetShardConsensusGroupSizeCalled() + } + return 0 +} + +// GetMetaConsensusGroupSize - +func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { + if n.GetMetaConsensusGroupSizeCalled != nil { + return n.GetMetaConsensusGroupSizeCalled() + } + return 0 +} + +// NumberOfShards - +func (n *NodesSetupStub) NumberOfShards() uint32 { + if n.NumberOfShardsCalled != nil { + return n.NumberOfShardsCalled() + } + return 0 +} + +// GetAdaptivity - +func (n *NodesSetupStub) GetAdaptivity() bool { + if n.GetAdaptivityCalled != nil { + return n.GetAdaptivityCalled() + } + + return false +} + +// GetHysteresis - +func (n *NodesSetupStub) GetHysteresis() float32 { + if n.GetHysteresisCalled != nil { + return n.GetHysteresisCalled() + } + + return 0 +} + +// GetShardIDForPubKey - +func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { + if n.GetShardIDForPubKeyCalled != nil { + return n.GetShardIDForPubKeyCalled(pubkey) + } + return 0, nil +} + +// InitialEligibleNodesPubKeysForShard - +func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { + if n.InitialEligibleNodesPubKeysForShardCalled != nil { + return n.InitialEligibleNodesPubKeysForShardCalled(shardId) + } + + return []string{"val1", "val2"}, nil +} + +// InitialNodesPubKeys - +func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { + if n.InitialNodesPubKeysCalled != nil { + return n.InitialNodesPubKeysCalled() + } + + return map[uint32][]string{0: {"val1", "val2"}} +} + +// MinNumberOfMetaNodes - +func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { + if n.MinNumberOfMetaNodesCalled != nil { + return n.MinNumberOfMetaNodesCalled() + } + + return 1 +} + +// MinNumberOfShardNodes - +func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { + if n.MinNumberOfShardNodesCalled != nil { + return n.MinNumberOfShardNodesCalled() + } + + return 1 +} + +// MinNumberOfNodesWithHysteresis - +func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { + if n.MinNumberOfNodesWithHysteresisCalled != nil { + return n.MinNumberOfNodesWithHysteresisCalled() + } + return n.MinNumberOfNodes() +} + +// IsInterfaceNil - +func (n *NodesSetupStub) IsInterfaceNil() bool { + return n == nil +} + func generateCorrectConfig() *Configs { return &Configs{ EpochConfig: &EpochConfig{ @@ -178,3 +310,33 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { require.True(t, strings.Contains(err.Error(), "56")) }) } + +func TestSanityCheckNodesConfig(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + cfg := generateCorrectConfig() + err := SanityCheckNodesConfig(&NodesSetupStub{ + + NumberOfShardsCalled: func() uint32 { + return 3 + }, + MinNumberOfMetaNodesCalled: func() uint32 { + return 5 + }, + MinNumberOfShardNodesCalled: func() uint32 { + return 5 + }, + GetHysteresisCalled: func() float32 { + return 0.2 + }, + MinNumberOfNodesWithHysteresisCalled: func() uint32 { + return 5*4 + uint32(float32(5)*0.2) + uint32(float32(5)*0.2*float32(3)) + }, + }, cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) + + require.Nil(t, err) + }) +} diff --git a/config/interface.go b/config/interface.go index 9b3f05b1643..f28661ee925 100644 --- a/config/interface.go +++ b/config/interface.go @@ -2,6 +2,7 @@ package config // NodesSetupHandler provides nodes setup information type NodesSetupHandler interface { + MinNumberOfNodesWithHysteresis() uint32 MinNumberOfNodes() uint32 MinNumberOfShardNodes() uint32 MinNumberOfMetaNodes() uint32 From 43aaad95329c504879b35d96e7bcef69ea4323e3 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Mar 2023 11:10:52 +0200 Subject: [PATCH 434/958] CLN: Simplify check a lot --- config/configChecker.go | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index 07142d06d0e..94bb9a50157 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -89,11 +89,11 @@ func SanityCheckNodesConfig( } func checkMaxNodesConfig(maxNodesConfig MaxNodesChangeConfig, nodesSetup NodesSetupHandler) error { - if maxNodesConfig.NodesToShufflePerShard == 0 { + nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard + if nodesToShufflePerShard == 0 { return fmt.Errorf("0 nodes to shuffle per shard") } - nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard maxNumNodes := maxNodesConfig.MaxNumNodes minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() if maxNumNodes < minNumNodesWithHysteresis { @@ -101,31 +101,11 @@ func checkMaxNodesConfig(maxNodesConfig MaxNodesChangeConfig, nodesSetup NodesSe } numShards := nodesSetup.NumberOfShards() - hysteresis := nodesSetup.GetHysteresis() - - minNumOfShardNodesWithHysteresis := getMinNumNodesWithHysteresis(nodesSetup.MinNumberOfShardNodes(), hysteresis) - minNumOfMetaNodesWithHysteresis := getMinNumNodesWithHysteresis(nodesSetup.MinNumberOfMetaNodes(), hysteresis) - - maxWaitingListSizePerShard := (maxNumNodes - minNumOfMetaNodesWithHysteresis) / numShards - maxWaitingListSizePerMeta := maxNumNodes - minNumOfShardNodesWithHysteresis*numShards - waitingListPerShard := (maxNumNodes - minNumNodesWithHysteresis) / (numShards + 1) - if maxWaitingListSizePerShard <= 0 { - return fmt.Errorf("negative waiting list") - } - - if maxWaitingListSizePerMeta <= 0 { - return fmt.Errorf("negative waiting list") - } - if nodesToShufflePerShard > waitingListPerShard { return fmt.Errorf("nodes to shuffle per shard > waiting list per shard") } return nil } - -func getMinNumNodesWithHysteresis(minNumNodes uint32, hysteresis float32) uint32 { - return uint32(float32(minNumNodes) * hysteresis) -} From ca9842633b7c537765062fc4800f46e3c4e8e873 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Mar 2023 11:22:46 +0200 Subject: [PATCH 435/958] CLN: Simplify more, remove interface, use values --- config/configChecker.go | 14 ++-- config/configChecker_test.go | 154 +---------------------------------- config/interface.go | 11 --- node/nodeRunner.go | 3 +- 4 files changed, 14 insertions(+), 168 deletions(-) delete mode 100644 config/interface.go diff --git a/config/configChecker.go b/config/configChecker.go index 94bb9a50157..c48b34db97e 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -71,7 +71,8 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr // SanityCheckNodesConfig checks if the nodes limit setup is set correctly func SanityCheckNodesConfig( - nodesSetup NodesSetupHandler, + numShards uint32, + minNumNodesWithHysteresis uint32, maxNodesChange []MaxNodesChangeConfig, ) error { if len(maxNodesChange) < 1 { @@ -79,7 +80,7 @@ func SanityCheckNodesConfig( } for _, maxNodesConfig := range maxNodesChange { - err := checkMaxNodesConfig(maxNodesConfig, nodesSetup) + err := checkMaxNodesConfig(numShards, minNumNodesWithHysteresis, maxNodesConfig) if err != nil { return fmt.Errorf("%w in MaxNodesChangeConfig at EpochEnable = %d", err, maxNodesConfig.EpochEnable) } @@ -88,21 +89,22 @@ func SanityCheckNodesConfig( return nil } -func checkMaxNodesConfig(maxNodesConfig MaxNodesChangeConfig, nodesSetup NodesSetupHandler) error { +func checkMaxNodesConfig( + numShards uint32, + minNumNodesWithHysteresis uint32, + maxNodesConfig MaxNodesChangeConfig, +) error { nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard if nodesToShufflePerShard == 0 { return fmt.Errorf("0 nodes to shuffle per shard") } maxNumNodes := maxNodesConfig.MaxNumNodes - minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() if maxNumNodes < minNumNodesWithHysteresis { return fmt.Errorf("MaxNumNodes less than MinNumberOfNodesWithHysteresis") } - numShards := nodesSetup.NumberOfShards() waitingListPerShard := (maxNumNodes - minNumNodesWithHysteresis) / (numShards + 1) - if nodesToShufflePerShard > waitingListPerShard { return fmt.Errorf("nodes to shuffle per shard > waiting list per shard") } diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 6c3d27a2181..5f712d8722c 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -7,138 +7,6 @@ import ( "github.com/stretchr/testify/require" ) -// NodesSetupStub - -type NodesSetupStub struct { - GetRoundDurationCalled func() uint64 - GetShardConsensusGroupSizeCalled func() uint32 - GetMetaConsensusGroupSizeCalled func() uint32 - NumberOfShardsCalled func() uint32 - MinNumberOfNodesCalled func() uint32 - GetAdaptivityCalled func() bool - GetHysteresisCalled func() float32 - GetShardIDForPubKeyCalled func(pubkey []byte) (uint32, error) - InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) - InitialNodesPubKeysCalled func() map[uint32][]string - MinNumberOfMetaNodesCalled func() uint32 - MinNumberOfShardNodesCalled func() uint32 - MinNumberOfNodesWithHysteresisCalled func() uint32 -} - -// MinNumberOfNodes - -func (n *NodesSetupStub) MinNumberOfNodes() uint32 { - if n.MinNumberOfNodesCalled != nil { - return n.MinNumberOfNodesCalled() - } - return 1 -} - -// GetRoundDuration - -func (n *NodesSetupStub) GetRoundDuration() uint64 { - if n.GetRoundDurationCalled != nil { - return n.GetRoundDurationCalled() - } - return 0 -} - -// GetShardConsensusGroupSize - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetShardConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() - } - return 0 -} - -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() - } - return 0 -} - -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() - } - return 0 -} - -// GetAdaptivity - -func (n *NodesSetupStub) GetAdaptivity() bool { - if n.GetAdaptivityCalled != nil { - return n.GetAdaptivityCalled() - } - - return false -} - -// GetHysteresis - -func (n *NodesSetupStub) GetHysteresis() float32 { - if n.GetHysteresisCalled != nil { - return n.GetHysteresisCalled() - } - - return 0 -} - -// GetShardIDForPubKey - -func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { - if n.GetShardIDForPubKeyCalled != nil { - return n.GetShardIDForPubKeyCalled(pubkey) - } - return 0, nil -} - -// InitialEligibleNodesPubKeysForShard - -func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { - if n.InitialEligibleNodesPubKeysForShardCalled != nil { - return n.InitialEligibleNodesPubKeysForShardCalled(shardId) - } - - return []string{"val1", "val2"}, nil -} - -// InitialNodesPubKeys - -func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { - if n.InitialNodesPubKeysCalled != nil { - return n.InitialNodesPubKeysCalled() - } - - return map[uint32][]string{0: {"val1", "val2"}} -} - -// MinNumberOfMetaNodes - -func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { - if n.MinNumberOfMetaNodesCalled != nil { - return n.MinNumberOfMetaNodesCalled() - } - - return 1 -} - -// MinNumberOfShardNodes - -func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { - if n.MinNumberOfShardNodesCalled != nil { - return n.MinNumberOfShardNodesCalled() - } - - return 1 -} - -// MinNumberOfNodesWithHysteresis - -func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { - if n.MinNumberOfNodesWithHysteresisCalled != nil { - return n.MinNumberOfNodesWithHysteresisCalled() - } - return n.MinNumberOfNodes() -} - -// IsInterfaceNil - -func (n *NodesSetupStub) IsInterfaceNil() bool { - return n == nil -} - func generateCorrectConfig() *Configs { return &Configs{ EpochConfig: &EpochConfig{ @@ -318,24 +186,10 @@ func TestSanityCheckNodesConfig(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - err := SanityCheckNodesConfig(&NodesSetupStub{ - - NumberOfShardsCalled: func() uint32 { - return 3 - }, - MinNumberOfMetaNodesCalled: func() uint32 { - return 5 - }, - MinNumberOfShardNodesCalled: func() uint32 { - return 5 - }, - GetHysteresisCalled: func() float32 { - return 0.2 - }, - MinNumberOfNodesWithHysteresisCalled: func() uint32 { - return 5*4 + uint32(float32(5)*0.2) + uint32(float32(5)*0.2*float32(3)) - }, - }, cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) + err := SanityCheckNodesConfig( + 3, + 20, + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) require.Nil(t, err) }) diff --git a/config/interface.go b/config/interface.go deleted file mode 100644 index f28661ee925..00000000000 --- a/config/interface.go +++ /dev/null @@ -1,11 +0,0 @@ -package config - -// NodesSetupHandler provides nodes setup information -type NodesSetupHandler interface { - MinNumberOfNodesWithHysteresis() uint32 - MinNumberOfNodes() uint32 - MinNumberOfShardNodes() uint32 - MinNumberOfMetaNodes() uint32 - GetHysteresis() float32 - NumberOfShards() uint32 -} diff --git a/node/nodeRunner.go b/node/nodeRunner.go index fe7f197e431..009c73bcf04 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -285,7 +285,8 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( } err = config.SanityCheckNodesConfig( - managedCoreComponents.GenesisNodesSetup(), + managedCoreComponents.GenesisNodesSetup().NumberOfShards(), + managedCoreComponents.GenesisNodesSetup().MinNumberOfNodesWithHysteresis(), configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, ) if err != nil { From b17b6109f36c45567b1535158fd99f84a6a08e53 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Mar 2023 11:49:10 +0200 Subject: [PATCH 436/958] CLN: Simplify + tests --- config/configChecker.go | 12 +++--- config/configChecker_test.go | 82 +++++++++++++++++++++++++++++++++--- config/errors.go | 6 +++ 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index c48b34db97e..b936efad9bc 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -75,10 +75,6 @@ func SanityCheckNodesConfig( minNumNodesWithHysteresis uint32, maxNodesChange []MaxNodesChangeConfig, ) error { - if len(maxNodesChange) < 1 { - return errNotEnoughMaxNodesChanges - } - for _, maxNodesConfig := range maxNodesChange { err := checkMaxNodesConfig(numShards, minNumNodesWithHysteresis, maxNodesConfig) if err != nil { @@ -96,17 +92,19 @@ func checkMaxNodesConfig( ) error { nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard if nodesToShufflePerShard == 0 { - return fmt.Errorf("0 nodes to shuffle per shard") + return errZeroNodesToShufflePerShard } maxNumNodes := maxNodesConfig.MaxNumNodes if maxNumNodes < minNumNodesWithHysteresis { - return fmt.Errorf("MaxNumNodes less than MinNumberOfNodesWithHysteresis") + return fmt.Errorf("%w, maxNumNodes: %d, minNumNodesWithHysteresis: %d", + errMaxMinNodesInvalid, maxNumNodes, minNumNodesWithHysteresis) } waitingListPerShard := (maxNumNodes - minNumNodesWithHysteresis) / (numShards + 1) if nodesToShufflePerShard > waitingListPerShard { - return fmt.Errorf("nodes to shuffle per shard > waiting list per shard") + return fmt.Errorf("%w, nodesToShufflePerShard: %d, waitingListPerShard: %d", + errInvalidNodesToShuffle, nodesToShufflePerShard, waitingListPerShard) } return nil diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 5f712d8722c..82690b51879 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -182,15 +182,87 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { func TestSanityCheckNodesConfig(t *testing.T) { t.Parallel() + numShards := uint32(3) t.Run("should work", func(t *testing.T) { t.Parallel() - cfg := generateCorrectConfig() - err := SanityCheckNodesConfig( - 3, - 20, - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) + cfg := generateCorrectConfig().EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch + err := SanityCheckNodesConfig(numShards, 20, cfg) + require.Nil(t, err) + cfg = []MaxNodesChangeConfig{ + { + EpochEnable: 1, + MaxNumNodes: 3200, + NodesToShufflePerShard: 80, + }, + { + EpochEnable: 2, + MaxNumNodes: 2880, + NodesToShufflePerShard: 80, + }, + { + EpochEnable: 3, + MaxNumNodes: 2240, + NodesToShufflePerShard: 80, + }, + { + EpochEnable: 4, + MaxNumNodes: 2240, + NodesToShufflePerShard: 40, + }, + } + err = SanityCheckNodesConfig(numShards, 1920, cfg) require.Nil(t, err) }) + + t.Run("zero nodes to shuffle per shard, should return error", func(t *testing.T) { + t.Parallel() + + cfg := []MaxNodesChangeConfig{ + { + EpochEnable: 4, + MaxNumNodes: 3200, + NodesToShufflePerShard: 0, + }, + } + err := SanityCheckNodesConfig(numShards, 1920, cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), errZeroNodesToShufflePerShard.Error())) + require.True(t, strings.Contains(err.Error(), "at EpochEnable = 4")) + }) + + t.Run("maxNumNodes < minNumNodesWithHysteresis, should return error ", func(t *testing.T) { + t.Parallel() + + cfg := []MaxNodesChangeConfig{ + { + EpochEnable: 4, + MaxNumNodes: 1900, + NodesToShufflePerShard: 80, + }, + } + err := SanityCheckNodesConfig(numShards, 1920, cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), errMaxMinNodesInvalid.Error())) + require.True(t, strings.Contains(err.Error(), "maxNumNodes: 1900")) + require.True(t, strings.Contains(err.Error(), "minNumNodesWithHysteresis: 1920")) + }) + + t.Run("invalid nodes to shuffle per shard, should return error ", func(t *testing.T) { + t.Parallel() + + cfg := []MaxNodesChangeConfig{ + { + EpochEnable: 3, + MaxNumNodes: 2240, + NodesToShufflePerShard: 81, + }, + } + err := SanityCheckNodesConfig(numShards, 1920, cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffle.Error())) + require.True(t, strings.Contains(err.Error(), "nodesToShufflePerShard: 81")) + require.True(t, strings.Contains(err.Error(), "waitingListPerShard: 80")) + }) } diff --git a/config/errors.go b/config/errors.go index 17409d84916..34e04f950ff 100644 --- a/config/errors.go +++ b/config/errors.go @@ -11,3 +11,9 @@ var errNoMaxNodesConfigBeforeStakingV4 = errors.New("no previous config change e var errMismatchNodesToShuffle = errors.New("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard with EnableEpoch = StakingV4Step3EnableEpoch") var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch") + +var errZeroNodesToShufflePerShard = errors.New("zero nodes to shuffle per shard found in config") + +var errMaxMinNodesInvalid = errors.New("number of min nodes with hysteresis > number of max nodes") + +var errInvalidNodesToShuffle = errors.New("number of nodes to shuffle per shard > waiting list size per shard") From a960999ddd312c55d9703a77a36268dfdd9169f1 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Mar 2023 13:45:29 +0200 Subject: [PATCH 437/958] CLN: Refactor everything to use interface --- config/configChecker.go | 43 +++++++++++++++++++++++++++++++----- config/configChecker_test.go | 40 ++++++++++++++++++++++++++++----- config/errors.go | 2 ++ config/interface.go | 11 +++++++++ config/nodesSetupMock.go | 43 ++++++++++++++++++++++++++++++++++++ node/nodeRunner.go | 3 +-- 6 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 config/interface.go create mode 100644 config/nodesSetupMock.go diff --git a/config/configChecker.go b/config/configChecker.go index b936efad9bc..9f94931bc33 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -71,12 +71,11 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr // SanityCheckNodesConfig checks if the nodes limit setup is set correctly func SanityCheckNodesConfig( - numShards uint32, - minNumNodesWithHysteresis uint32, + nodesSetup NodesSetupHandler, maxNodesChange []MaxNodesChangeConfig, ) error { for _, maxNodesConfig := range maxNodesChange { - err := checkMaxNodesConfig(numShards, minNumNodesWithHysteresis, maxNodesConfig) + err := checkMaxNodesConfig(nodesSetup, maxNodesConfig) if err != nil { return fmt.Errorf("%w in MaxNodesChangeConfig at EpochEnable = %d", err, maxNodesConfig.EpochEnable) } @@ -86,8 +85,7 @@ func SanityCheckNodesConfig( } func checkMaxNodesConfig( - numShards uint32, - minNumNodesWithHysteresis uint32, + nodesSetup NodesSetupHandler, maxNodesConfig MaxNodesChangeConfig, ) error { nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard @@ -96,16 +94,51 @@ func checkMaxNodesConfig( } maxNumNodes := maxNodesConfig.MaxNumNodes + minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() if maxNumNodes < minNumNodesWithHysteresis { return fmt.Errorf("%w, maxNumNodes: %d, minNumNodesWithHysteresis: %d", errMaxMinNodesInvalid, maxNumNodes, minNumNodesWithHysteresis) } + numShards := nodesSetup.NumberOfShards() waitingListPerShard := (maxNumNodes - minNumNodesWithHysteresis) / (numShards + 1) if nodesToShufflePerShard > waitingListPerShard { return fmt.Errorf("%w, nodesToShufflePerShard: %d, waitingListPerShard: %d", errInvalidNodesToShuffle, nodesToShufflePerShard, waitingListPerShard) } + minNumNodes := nodesSetup.MinNumberOfNodes() + if minNumNodesWithHysteresis > minNumNodes { + return checkHysteresis(nodesSetup, nodesToShufflePerShard) + } + + return nil +} + +func checkHysteresis(nodesSetup NodesSetupHandler, numToShufflePerShard uint32) error { + hysteresis := nodesSetup.GetHysteresis() + + forcedWaitingListNodesInShard := calcForcedWaitingListNodes(hysteresis, nodesSetup.MinNumberOfShardNodes()) + forcedWaitingListNodesPerShard := forcedWaitingListNodesInShard / nodesSetup.NumberOfShards() + if numToShufflePerShard > forcedWaitingListNodesPerShard { + return fmt.Errorf("%w per shard for numToShufflePerShard: %d, forcedWaitingListNodesPerShard: %d", + errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesPerShard) + } + + forcedWaitingListNodesInMeta := calcForcedWaitingListNodes(hysteresis, nodesSetup.MinNumberOfMetaNodes()) + if numToShufflePerShard > forcedWaitingListNodesInMeta { + return fmt.Errorf("%w in metachain for numToShufflePerShard: %d, forcedWaitingListNodesPerShard: %d", + errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesPerShard) + } + return nil } + +func calcForcedWaitingListNodes(hysteresis float32, minNumOfNodes uint32) uint32 { + minNumOfNodesWithHysteresis := getMinNumNodesWithHysteresis(minNumOfNodes, hysteresis) + return minNumOfNodesWithHysteresis - minNumOfNodes +} + +func getMinNumNodesWithHysteresis(minNumNodes uint32, hysteresis float32) uint32 { + return uint32(float32(minNumNodes) * hysteresis) +} diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 82690b51879..c30e454884e 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -187,7 +187,13 @@ func TestSanityCheckNodesConfig(t *testing.T) { t.Parallel() cfg := generateCorrectConfig().EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch - err := SanityCheckNodesConfig(numShards, 20, cfg) + nodesSetup := &NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0, + MinNumberOfMetaNodesField: 5, + MinNumberOfShardNodesField: 5, + } + err := SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) cfg = []MaxNodesChangeConfig{ @@ -212,7 +218,13 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 40, }, } - err = SanityCheckNodesConfig(numShards, 1920, cfg) + nodesSetup = &NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 400, + MinNumberOfShardNodesField: 400, + } + err = SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) }) @@ -226,7 +238,13 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 0, }, } - err := SanityCheckNodesConfig(numShards, 1920, cfg) + nodesSetup := &NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 400, + MinNumberOfShardNodesField: 400, + } + err := SanityCheckNodesConfig(nodesSetup, cfg) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), errZeroNodesToShufflePerShard.Error())) require.True(t, strings.Contains(err.Error(), "at EpochEnable = 4")) @@ -242,7 +260,13 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 80, }, } - err := SanityCheckNodesConfig(numShards, 1920, cfg) + nodesSetup := &NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 400, + MinNumberOfShardNodesField: 400, + } + err := SanityCheckNodesConfig(nodesSetup, cfg) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), errMaxMinNodesInvalid.Error())) require.True(t, strings.Contains(err.Error(), "maxNumNodes: 1900")) @@ -259,7 +283,13 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 81, }, } - err := SanityCheckNodesConfig(numShards, 1920, cfg) + nodesSetup := &NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 400, + MinNumberOfShardNodesField: 400, + } + err := SanityCheckNodesConfig(nodesSetup, cfg) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffle.Error())) require.True(t, strings.Contains(err.Error(), "nodesToShufflePerShard: 81")) diff --git a/config/errors.go b/config/errors.go index 34e04f950ff..337ac7bd65b 100644 --- a/config/errors.go +++ b/config/errors.go @@ -17,3 +17,5 @@ var errZeroNodesToShufflePerShard = errors.New("zero nodes to shuffle per shard var errMaxMinNodesInvalid = errors.New("number of min nodes with hysteresis > number of max nodes") var errInvalidNodesToShuffle = errors.New("number of nodes to shuffle per shard > waiting list size per shard") + +var errInvalidNodesToShuffleWithHysteresis = errors.New("number of nodes to shuffle per shard > forced waiting list size per shard with hysteresis") diff --git a/config/interface.go b/config/interface.go new file mode 100644 index 00000000000..f28661ee925 --- /dev/null +++ b/config/interface.go @@ -0,0 +1,11 @@ +package config + +// NodesSetupHandler provides nodes setup information +type NodesSetupHandler interface { + MinNumberOfNodesWithHysteresis() uint32 + MinNumberOfNodes() uint32 + MinNumberOfShardNodes() uint32 + MinNumberOfMetaNodes() uint32 + GetHysteresis() float32 + NumberOfShards() uint32 +} diff --git a/config/nodesSetupMock.go b/config/nodesSetupMock.go new file mode 100644 index 00000000000..3200ad4bd45 --- /dev/null +++ b/config/nodesSetupMock.go @@ -0,0 +1,43 @@ +package config + +// NodesSetupMock - +type NodesSetupMock struct { + NumberOfShardsField uint32 + HysteresisField float32 + MinNumberOfMetaNodesField uint32 + MinNumberOfShardNodesField uint32 +} + +// NumberOfShards - +func (n *NodesSetupMock) NumberOfShards() uint32 { + return n.NumberOfShardsField +} + +// GetHysteresis - +func (n *NodesSetupMock) GetHysteresis() float32 { + return n.HysteresisField +} + +// MinNumberOfMetaNodes - +func (n *NodesSetupMock) MinNumberOfMetaNodes() uint32 { + return n.MinNumberOfMetaNodesField +} + +// MinNumberOfShardNodes - +func (n *NodesSetupMock) MinNumberOfShardNodes() uint32 { + return n.MinNumberOfShardNodesField +} + +// MinNumberOfNodes - +func (n *NodesSetupMock) MinNumberOfNodes() uint32 { + return n.NumberOfShardsField*n.MinNumberOfShardNodesField + n.MinNumberOfMetaNodesField +} + +// MinNumberOfNodesWithHysteresis - +func (n *NodesSetupMock) MinNumberOfNodesWithHysteresis() uint32 { + hystNodesMeta := getMinNumNodesWithHysteresis(n.MinNumberOfMetaNodesField, n.HysteresisField) + hystNodesShard := getMinNumNodesWithHysteresis(n.MinNumberOfShardNodesField, n.HysteresisField) + minNumberOfNodes := n.MinNumberOfNodes() + + return minNumberOfNodes + hystNodesMeta + n.NumberOfShardsField*hystNodesShard +} diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 009c73bcf04..fe7f197e431 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -285,8 +285,7 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( } err = config.SanityCheckNodesConfig( - managedCoreComponents.GenesisNodesSetup().NumberOfShards(), - managedCoreComponents.GenesisNodesSetup().MinNumberOfNodesWithHysteresis(), + managedCoreComponents.GenesisNodesSetup(), configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, ) if err != nil { From 24ed39444d9f9a08924f3b92ef8b71a24da28ebe Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 10 Mar 2023 14:35:05 +0200 Subject: [PATCH 438/958] FIX: Refactor --- config/configChecker.go | 21 +++++---------- config/configChecker_test.go | 50 +++++++++++++++++++++++++++++++++++- config/errors.go | 2 +- config/nodesSetupMock.go | 4 +-- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index 9f94931bc33..a438957e9e0 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -97,7 +97,7 @@ func checkMaxNodesConfig( minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() if maxNumNodes < minNumNodesWithHysteresis { return fmt.Errorf("%w, maxNumNodes: %d, minNumNodesWithHysteresis: %d", - errMaxMinNodesInvalid, maxNumNodes, minNumNodesWithHysteresis) + errInvalidMaxMinNodes, maxNumNodes, minNumNodesWithHysteresis) } numShards := nodesSetup.NumberOfShards() @@ -107,8 +107,7 @@ func checkMaxNodesConfig( errInvalidNodesToShuffle, nodesToShufflePerShard, waitingListPerShard) } - minNumNodes := nodesSetup.MinNumberOfNodes() - if minNumNodesWithHysteresis > minNumNodes { + if minNumNodesWithHysteresis > nodesSetup.MinNumberOfNodes() { return checkHysteresis(nodesSetup, nodesToShufflePerShard) } @@ -118,27 +117,21 @@ func checkMaxNodesConfig( func checkHysteresis(nodesSetup NodesSetupHandler, numToShufflePerShard uint32) error { hysteresis := nodesSetup.GetHysteresis() - forcedWaitingListNodesInShard := calcForcedWaitingListNodes(hysteresis, nodesSetup.MinNumberOfShardNodes()) - forcedWaitingListNodesPerShard := forcedWaitingListNodesInShard / nodesSetup.NumberOfShards() + forcedWaitingListNodesPerShard := getHysteresisNodes(nodesSetup.MinNumberOfShardNodes(), hysteresis) if numToShufflePerShard > forcedWaitingListNodesPerShard { return fmt.Errorf("%w per shard for numToShufflePerShard: %d, forcedWaitingListNodesPerShard: %d", errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesPerShard) } - forcedWaitingListNodesInMeta := calcForcedWaitingListNodes(hysteresis, nodesSetup.MinNumberOfMetaNodes()) + forcedWaitingListNodesInMeta := getHysteresisNodes(nodesSetup.MinNumberOfMetaNodes(), hysteresis) if numToShufflePerShard > forcedWaitingListNodesInMeta { - return fmt.Errorf("%w in metachain for numToShufflePerShard: %d, forcedWaitingListNodesPerShard: %d", - errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesPerShard) + return fmt.Errorf("%w in metachain for numToShufflePerShard: %d, forcedWaitingListNodesInMeta: %d", + errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesInMeta) } return nil } -func calcForcedWaitingListNodes(hysteresis float32, minNumOfNodes uint32) uint32 { - minNumOfNodesWithHysteresis := getMinNumNodesWithHysteresis(minNumOfNodes, hysteresis) - return minNumOfNodesWithHysteresis - minNumOfNodes -} - -func getMinNumNodesWithHysteresis(minNumNodes uint32, hysteresis float32) uint32 { +func getHysteresisNodes(minNumNodes uint32, hysteresis float32) uint32 { return uint32(float32(minNumNodes) * hysteresis) } diff --git a/config/configChecker_test.go b/config/configChecker_test.go index c30e454884e..e073429aeb6 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -268,7 +268,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { } err := SanityCheckNodesConfig(nodesSetup, cfg) require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), errMaxMinNodesInvalid.Error())) + require.True(t, strings.Contains(err.Error(), errInvalidMaxMinNodes.Error())) require.True(t, strings.Contains(err.Error(), "maxNumNodes: 1900")) require.True(t, strings.Contains(err.Error(), "minNumNodesWithHysteresis: 1920")) }) @@ -295,4 +295,52 @@ func TestSanityCheckNodesConfig(t *testing.T) { require.True(t, strings.Contains(err.Error(), "nodesToShufflePerShard: 81")) require.True(t, strings.Contains(err.Error(), "waitingListPerShard: 80")) }) + + t.Run("invalid nodes to shuffle per shard with hysteresis, should return error ", func(t *testing.T) { + t.Parallel() + + cfg := []MaxNodesChangeConfig{ + { + EpochEnable: 1, + MaxNumNodes: 1600, + NodesToShufflePerShard: 80, + }, + } + nodesSetup := &NodesSetupMock{ + NumberOfShardsField: 1, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 500, + MinNumberOfShardNodesField: 300, + } + err := SanityCheckNodesConfig(nodesSetup, cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffleWithHysteresis.Error())) + require.True(t, strings.Contains(err.Error(), "per shard")) + require.True(t, strings.Contains(err.Error(), "numToShufflePerShard: 80")) + require.True(t, strings.Contains(err.Error(), "forcedWaitingListNodesPerShard: 60")) + }) + + t.Run("invalid nodes to shuffle in metachain with hysteresis, should return error ", func(t *testing.T) { + t.Parallel() + + cfg := []MaxNodesChangeConfig{ + { + EpochEnable: 1, + MaxNumNodes: 1600, + NodesToShufflePerShard: 80, + }, + } + nodesSetup := &NodesSetupMock{ + NumberOfShardsField: 1, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 300, + MinNumberOfShardNodesField: 500, + } + err := SanityCheckNodesConfig(nodesSetup, cfg) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffleWithHysteresis.Error())) + require.True(t, strings.Contains(err.Error(), "in metachain")) + require.True(t, strings.Contains(err.Error(), "numToShufflePerShard: 80")) + require.True(t, strings.Contains(err.Error(), "forcedWaitingListNodesInMeta: 60")) + }) } diff --git a/config/errors.go b/config/errors.go index 337ac7bd65b..348f03d1a8a 100644 --- a/config/errors.go +++ b/config/errors.go @@ -14,7 +14,7 @@ var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableE var errZeroNodesToShufflePerShard = errors.New("zero nodes to shuffle per shard found in config") -var errMaxMinNodesInvalid = errors.New("number of min nodes with hysteresis > number of max nodes") +var errInvalidMaxMinNodes = errors.New("number of min nodes with hysteresis > number of max nodes") var errInvalidNodesToShuffle = errors.New("number of nodes to shuffle per shard > waiting list size per shard") diff --git a/config/nodesSetupMock.go b/config/nodesSetupMock.go index 3200ad4bd45..ef365f2af73 100644 --- a/config/nodesSetupMock.go +++ b/config/nodesSetupMock.go @@ -35,8 +35,8 @@ func (n *NodesSetupMock) MinNumberOfNodes() uint32 { // MinNumberOfNodesWithHysteresis - func (n *NodesSetupMock) MinNumberOfNodesWithHysteresis() uint32 { - hystNodesMeta := getMinNumNodesWithHysteresis(n.MinNumberOfMetaNodesField, n.HysteresisField) - hystNodesShard := getMinNumNodesWithHysteresis(n.MinNumberOfShardNodesField, n.HysteresisField) + hystNodesMeta := getHysteresisNodes(n.MinNumberOfMetaNodesField, n.HysteresisField) + hystNodesShard := getHysteresisNodes(n.MinNumberOfShardNodesField, n.HysteresisField) minNumberOfNodes := n.MinNumberOfNodes() return minNumberOfNodes + hystNodesMeta + n.NumberOfShardsField*hystNodesShard From db83ac23c6c008314390caea6cb7a253fdc335b6 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Mar 2023 11:34:41 +0200 Subject: [PATCH 439/958] FIX: Refactor integration tests --- integrationTests/vm/staking/stakingV4_test.go | 206 ++++++++---------- 1 file changed, 90 insertions(+), 116 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 9698bbe5ab1..ccf4f17a413 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -194,21 +194,7 @@ func TestStakingV4(t *testing.T) { require.Empty(t, newNodeConfig.queue) require.Empty(t, newNodeConfig.leaving) - // 320 nodes which are now in eligible are from previous waiting list - requireSliceContainsNumOfElements(t, getAllPubKeys(newNodeConfig.eligible), getAllPubKeys(prevConfig.waiting), numOfShuffledOut) - - // New auction list also contains unselected nodes from previous auction list - requireSliceContainsNumOfElements(t, newNodeConfig.auction, prevConfig.auction, numOfUnselectedNodesFromAuction) - - // All shuffled out are from previous eligible config - requireMapContains(t, prevConfig.eligible, getAllPubKeys(newNodeConfig.shuffledOut)) - - // All shuffled out are now in auction - requireSliceContains(t, newNodeConfig.auction, getAllPubKeys(newNodeConfig.shuffledOut)) - - // 320 nodes which have been selected from previous auction list are now in waiting - requireSliceContainsNumOfElements(t, getAllPubKeys(newNodeConfig.waiting), prevConfig.auction, numOfSelectedNodesFromAuction) - + checkStakingV4EpochChangeFlow(t, newNodeConfig, prevConfig, numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction) prevConfig = newNodeConfig epochs++ } @@ -949,18 +935,18 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl node.EpochStartTrigger.SetRoundsPerEpoch(4) // 1. Check initial config is correct + expectedNodesNum := &configNum{ + eligible: map[uint32]int{ + core.MetachainShardId: 4, + 0: 4, + }, + waiting: map[uint32]int{ + core.MetachainShardId: 1, + 0: 1, + }, + } currNodesConfig := node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 1) - require.Empty(t, currNodesConfig.shuffledOut) - require.Empty(t, currNodesConfig.auction) - - prevNodesConfig := currNodesConfig - epoch := uint32(0) + checkConfig(t, expectedNodesNum, currNodesConfig) // During these 9 epochs, we will always have: // - 10 activeNodes (8 eligible + 2 waiting) @@ -968,23 +954,16 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl // Meanwhile, maxNumNodes changes from 12-10-12 // Since activeNodes <= maxNumNodes, shuffled out nodes will always be sent directly to waiting list, // instead of auction(there is no reason to send them to auction, they will be selected anyway) + epoch := uint32(0) + numOfShuffledOut := 2 + numRemainingEligible := 6 + prevNodesConfig := currNodesConfig for epoch < 9 { node.Process(t, 5) currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 1) - require.Empty(t, currNodesConfig.shuffledOut) - require.Empty(t, currNodesConfig.auction) - - // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + checkConfig(t, expectedNodesNum, currNodesConfig) + checkShuffledOutNodes(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numRemainingEligible) prevNodesConfig = currNodesConfig epoch++ @@ -1004,13 +983,8 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl }, }) currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 2) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 1) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 1) - require.Empty(t, currNodesConfig.shuffledOut) + expectedNodesNum.auction = 2 + checkConfig(t, expectedNodesNum, currNodesConfig) requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner2Nodes) // Epoch = 10 with: @@ -1019,19 +993,11 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl // Owner2's new nodes are selected from auction and distributed to waiting list node.Process(t, 5) currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 2) - require.Empty(t, currNodesConfig.shuffledOut) - require.Empty(t, currNodesConfig.auction) - - // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + expectedNodesNum.waiting[core.MetachainShardId]++ + expectedNodesNum.waiting[0]++ + expectedNodesNum.auction = 0 + checkConfig(t, expectedNodesNum, currNodesConfig) + checkShuffledOutNodes(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numRemainingEligible) requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), owner2Nodes) // During epochs 10-13, we will have: @@ -1045,19 +1011,8 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl node.Process(t, 5) currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 2) - require.Empty(t, currNodesConfig.shuffledOut) - require.Empty(t, currNodesConfig.auction) - - // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), 6) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), 2) + checkConfig(t, expectedNodesNum, currNodesConfig) + checkShuffledOutNodes(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numRemainingEligible) prevNodesConfig = currNodesConfig epoch++ @@ -1075,13 +1030,8 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl }, }) currNodesConfig = node.NodesConfig - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 2) - require.Empty(t, currNodesConfig.shuffledOut) + expectedNodesNum.auction = 2 + checkConfig(t, expectedNodesNum, currNodesConfig) requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner3Nodes) // During epochs 14-18, we will have: @@ -1092,33 +1042,15 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl prevNodesConfig = node.NodesConfig epoch = 14 require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) - for epoch < 18 { - require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) - require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 4) - require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 2) - require.Len(t, currNodesConfig.eligible[0], 4) - require.Len(t, currNodesConfig.waiting[0], 2) - require.Len(t, currNodesConfig.auction, 2) + numOfUnselectedNodesFromAuction := 0 + numOfSelectedNodesFromAuction := 2 + for epoch < 18 { + checkConfig(t, expectedNodesNum, currNodesConfig) node.Process(t, 5) - currNodesConfig = node.NodesConfig - // Nodes which are now in eligible are from previous waiting list - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) - - // New auction list does not contain nodes from previous auction list, since all of them have been distributed to waiting - requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, 0) - - // All shuffled out are from previous eligible config - requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) - - // All shuffled out are now in auction - requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) - - // All nodes which have been selected from previous auction list are now in waiting - requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction) + checkStakingV4EpochChangeFlow(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction) prevNodesConfig = currNodesConfig epoch++ @@ -1143,8 +1075,6 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl epoch = 19 require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) - prevNodesConfig = node.NodesConfig - require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) // During epochs 19-23, we will have: // - activeNodes = 13 @@ -1153,6 +1083,7 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl // - shuffled out nodes (2) will be sent to auction list // - waiting lists will be unbalanced (3 in total: 1 + 2 per shard) // - no node will spend extra epochs in eligible/waiting, since waiting lists will always be refilled + prevNodesConfig = node.NodesConfig for epoch < 23 { require.Len(t, getAllPubKeys(currNodesConfig.eligible), 8) require.Len(t, getAllPubKeys(currNodesConfig.waiting), 3) @@ -1163,22 +1094,65 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl node.Process(t, 5) currNodesConfig = node.NodesConfig - // Nodes which are now in eligible are from previous waiting list - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), 2) + checkStakingV4EpochChangeFlow(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction) - // New auction list does not contain nodes from previous auction list, since all of them have been distributed to waiting - requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, 0) + prevNodesConfig = currNodesConfig + epoch++ + } +} - // All shuffled out are from previous eligible config - requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) +type configNum struct { + eligible map[uint32]int + waiting map[uint32]int + leaving map[uint32]int + shuffledOut map[uint32]int + queue int + auction int + new int +} - // All shuffled out are now in auction - requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) +func checkConfig(t *testing.T, expectedConfig *configNum, nodesConfig nodesConfig) { + checkNumNodes(t, expectedConfig.eligible, nodesConfig.eligible) + checkNumNodes(t, expectedConfig.waiting, nodesConfig.waiting) + checkNumNodes(t, expectedConfig.leaving, nodesConfig.leaving) + checkNumNodes(t, expectedConfig.shuffledOut, nodesConfig.shuffledOut) - // All nodes which have been selected from previous auction list are now in waiting - requireSliceContains(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction) + require.Equal(t, expectedConfig.queue, len(nodesConfig.queue)) + require.Equal(t, expectedConfig.auction, len(nodesConfig.auction)) + require.Equal(t, expectedConfig.new, len(nodesConfig.new)) +} - prevNodesConfig = currNodesConfig - epoch++ +func checkNumNodes(t *testing.T, expectedNumNodes map[uint32]int, actualNodes map[uint32][][]byte) { + for shardID, numNodesInShard := range expectedNumNodes { + require.Equal(t, numNodesInShard, len(actualNodes[shardID])) } } + +func checkShuffledOutNodes(t *testing.T, currNodesConfig, prevNodesConfig nodesConfig, numShuffledOutNodes int, numRemainingEligible int) { + // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), numShuffledOutNodes) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), numRemainingEligible) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), numShuffledOutNodes) +} + +func checkStakingV4EpochChangeFlow( + t *testing.T, + currNodesConfig, prevNodesConfig nodesConfig, + numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction int) { + + // Nodes which are now in eligible are from previous waiting list + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), numOfShuffledOut) + + // New auction list also contains unselected nodes from previous auction list + requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, numOfUnselectedNodesFromAuction) + + // All shuffled out are from previous eligible config + requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) + + // All shuffled out are now in auction + requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + + // Nodes which have been selected from previous auction list are now in waiting + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction, numOfSelectedNodesFromAuction) + +} From 77b331d96c3ecb9171a33fda3113849c02113086 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Mar 2023 11:37:07 +0200 Subject: [PATCH 440/958] CLN: Move test functionalities --- integrationTests/vm/staking/stakingV4_test.go | 111 +++++++++--------- 1 file changed, 55 insertions(+), 56 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index ccf4f17a413..92ab77ff24a 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -106,6 +106,61 @@ func unStake(t *testing.T, owner []byte, accountsDB state.AccountsAdapter, marsh require.Nil(t, err) } +type configNum struct { + eligible map[uint32]int + waiting map[uint32]int + leaving map[uint32]int + shuffledOut map[uint32]int + queue int + auction int + new int +} + +func checkConfig(t *testing.T, expectedConfig *configNum, nodesConfig nodesConfig) { + checkNumNodes(t, expectedConfig.eligible, nodesConfig.eligible) + checkNumNodes(t, expectedConfig.waiting, nodesConfig.waiting) + checkNumNodes(t, expectedConfig.leaving, nodesConfig.leaving) + checkNumNodes(t, expectedConfig.shuffledOut, nodesConfig.shuffledOut) + + require.Equal(t, expectedConfig.queue, len(nodesConfig.queue)) + require.Equal(t, expectedConfig.auction, len(nodesConfig.auction)) + require.Equal(t, expectedConfig.new, len(nodesConfig.new)) +} + +func checkNumNodes(t *testing.T, expectedNumNodes map[uint32]int, actualNodes map[uint32][][]byte) { + for shardID, numNodesInShard := range expectedNumNodes { + require.Equal(t, numNodesInShard, len(actualNodes[shardID])) + } +} + +func checkShuffledOutNodes(t *testing.T, currNodesConfig, prevNodesConfig nodesConfig, numShuffledOutNodes int, numRemainingEligible int) { + // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), numShuffledOutNodes) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), numRemainingEligible) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), numShuffledOutNodes) +} + +func checkStakingV4EpochChangeFlow( + t *testing.T, + currNodesConfig, prevNodesConfig nodesConfig, + numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction int) { + + // Nodes which are now in eligible are from previous waiting list + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), numOfShuffledOut) + + // New auction list also contains unselected nodes from previous auction list + requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, numOfUnselectedNodesFromAuction) + + // All shuffled out are from previous eligible config + requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) + + // All shuffled out are now in auction + requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) + + // Nodes which have been selected from previous auction list are now in waiting + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction, numOfSelectedNodesFromAuction) +} + func TestStakingV4(t *testing.T) { numOfMetaNodes := uint32(400) numOfShards := uint32(3) @@ -1100,59 +1155,3 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl epoch++ } } - -type configNum struct { - eligible map[uint32]int - waiting map[uint32]int - leaving map[uint32]int - shuffledOut map[uint32]int - queue int - auction int - new int -} - -func checkConfig(t *testing.T, expectedConfig *configNum, nodesConfig nodesConfig) { - checkNumNodes(t, expectedConfig.eligible, nodesConfig.eligible) - checkNumNodes(t, expectedConfig.waiting, nodesConfig.waiting) - checkNumNodes(t, expectedConfig.leaving, nodesConfig.leaving) - checkNumNodes(t, expectedConfig.shuffledOut, nodesConfig.shuffledOut) - - require.Equal(t, expectedConfig.queue, len(nodesConfig.queue)) - require.Equal(t, expectedConfig.auction, len(nodesConfig.auction)) - require.Equal(t, expectedConfig.new, len(nodesConfig.new)) -} - -func checkNumNodes(t *testing.T, expectedNumNodes map[uint32]int, actualNodes map[uint32][][]byte) { - for shardID, numNodesInShard := range expectedNumNodes { - require.Equal(t, numNodesInShard, len(actualNodes[shardID])) - } -} - -func checkShuffledOutNodes(t *testing.T, currNodesConfig, prevNodesConfig nodesConfig, numShuffledOutNodes int, numRemainingEligible int) { - // Shuffled nodes from previous eligible are sent to waiting and previous waiting list nodes are replacing shuffled nodes - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), numShuffledOutNodes) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.eligible), numRemainingEligible) - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), getAllPubKeys(prevNodesConfig.eligible), numShuffledOutNodes) -} - -func checkStakingV4EpochChangeFlow( - t *testing.T, - currNodesConfig, prevNodesConfig nodesConfig, - numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction int) { - - // Nodes which are now in eligible are from previous waiting list - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(prevNodesConfig.waiting), numOfShuffledOut) - - // New auction list also contains unselected nodes from previous auction list - requireSliceContainsNumOfElements(t, currNodesConfig.auction, prevNodesConfig.auction, numOfUnselectedNodesFromAuction) - - // All shuffled out are from previous eligible config - requireMapContains(t, prevNodesConfig.eligible, getAllPubKeys(currNodesConfig.shuffledOut)) - - // All shuffled out are now in auction - requireSliceContains(t, currNodesConfig.auction, getAllPubKeys(currNodesConfig.shuffledOut)) - - // Nodes which have been selected from previous auction list are now in waiting - requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), prevNodesConfig.auction, numOfSelectedNodesFromAuction) - -} From 1afecd5f8a469d8014d39bbe19362cdcdf33c303 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Mar 2023 13:24:44 +0200 Subject: [PATCH 441/958] CLN: Create new func for shouldDistributeShuffledToWaitingInStakingV4 --- .../nodesCoordinator/hashValidatorShuffler.go | 76 ++++++++++++------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 4b2b67f133c..f9fc41fa856 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -47,6 +47,15 @@ type shuffleNodesArg struct { flagStakingV4Step3 bool } +type shuffledNodesStakingV4 struct { + numShuffled uint32 + numNewEligible uint32 + numNewWaiting uint32 + numSelectedAuction uint32 + maxNumNodes uint32 + flagStakingV4Step2 bool +} + // TODO: Decide if transaction load statistics will be used for limiting the number of shards type randHashShuffler struct { // TODO: remove the references to this constant and the distributor @@ -285,30 +294,6 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { shuffledOutMap, newEligible := shuffleOutNodes(newEligible, numToRemove, arg.randomness) - numShuffled := getNumPubKeys(shuffledOutMap) - numNewEligible := getNumPubKeys(newEligible) - numNewWaiting := getNumPubKeys(newWaiting) - - numSelectedAuction := uint32(len(arg.auction)) - totalNewWaiting := numNewWaiting + numSelectedAuction - - totalNodes := totalNewWaiting + numNewEligible + numShuffled - maxNumNodes := arg.maxNumNodes - - distributeShuffledToWaitingInStakingV4 := false - if totalNodes <= maxNumNodes { - log.Warn("num of total nodes in waiting is too low after shuffling; will distribute "+ - "shuffled out nodes directly to waiting and skip sending them to auction", - "numShuffled", numShuffled, - "numNewEligible", numNewEligible, - "numSelectedAuction", numSelectedAuction, - "totalNewWaiting", totalNewWaiting, - "totalNodes", totalNodes, - "maxNumNodes", maxNumNodes) - - distributeShuffledToWaitingInStakingV4 = arg.flagStakingV4Step2 - } - err = moveMaxNumNodesToMap(newEligible, newWaiting, arg.nodesMeta, arg.nodesPerShard) if err != nil { log.Warn("moveNodesToMap failed", "error", err) @@ -319,9 +304,18 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("distributeValidators newNodes failed", "error", err) } + shuffledNodesCfg := &shuffledNodesStakingV4{ + numShuffled: getNumPubKeys(shuffledOutMap), + numNewEligible: getNumPubKeys(newEligible), + numNewWaiting: getNumPubKeys(newWaiting), + numSelectedAuction: uint32(len(arg.auction)), + maxNumNodes: arg.maxNumNodes, + flagStakingV4Step2: arg.flagStakingV4Step2, + } + if arg.flagStakingV4Step3 { log.Debug("distributing selected nodes from auction to waiting", - "num auction nodes", len(arg.auction), "num waiting nodes", numNewWaiting) + "num auction nodes", len(arg.auction), "num waiting nodes", shuffledNodesCfg.numNewWaiting) // Distribute selected validators from AUCTION -> WAITING err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) @@ -330,9 +324,9 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { } } - if distributeShuffledToWaitingInStakingV4 { + if shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg) { log.Debug("distributing shuffled out nodes to waiting in staking V4", - "num shuffled nodes", numShuffled, "num waiting nodes", numNewWaiting) + "num shuffled nodes", shuffledNodesCfg.numShuffled, "num waiting nodes", shuffledNodesCfg.numNewWaiting) // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) @@ -595,6 +589,34 @@ func removeValidatorFromList(validatorList []Validator, index int) []Validator { return validatorList[:len(validatorList)-1] } +func shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg *shuffledNodesStakingV4) bool { + if !shuffledNodesCfg.flagStakingV4Step2 { + return false + } + + totalNewWaiting := shuffledNodesCfg.numNewWaiting + shuffledNodesCfg.numSelectedAuction + totalNodes := totalNewWaiting + shuffledNodesCfg.numNewEligible + shuffledNodesCfg.numShuffled + + log.Debug("checking if should distribute shuffled out nodes to waiting in staking v4", + "numShuffled", shuffledNodesCfg.numShuffled, + "numNewEligible", shuffledNodesCfg.numNewEligible, + "numSelectedAuction", shuffledNodesCfg.numSelectedAuction, + "totalNewWaiting", totalNewWaiting, + "totalNodes", totalNodes, + "maxNumNodes", shuffledNodesCfg.maxNumNodes, + ) + + distributeShuffledToWaitingInStakingV4 := false + if totalNodes <= shuffledNodesCfg.maxNumNodes { + log.Warn("num of total nodes in waiting is too low after shuffling; will distribute " + + "shuffled out nodes directly to waiting and skip sending them to auction") + + distributeShuffledToWaitingInStakingV4 = true + } + + return distributeShuffledToWaitingInStakingV4 +} + func removeValidatorFromListKeepOrder(validatorList []Validator, index int) []Validator { indexNotOK := index > len(validatorList)-1 || index < 0 if indexNotOK { From c26f690f82d31e4d237449696853d76349c13a2d Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Mar 2023 16:31:48 +0200 Subject: [PATCH 442/958] CLN: Refactor error handling + new nodes in shuffler --- .../nodesCoordinator/hashValidatorShuffler.go | 48 +++++++++++-------- .../hashValidatorShuffler_test.go | 18 +++---- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index f9fc41fa856..dcae87c12a9 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -12,6 +12,7 @@ import ( "github.com/multiversx/mx-chain-core-go/hashing/sha256" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" ) var _ NodesShuffler = (*randHashShuffler)(nil) @@ -47,7 +48,7 @@ type shuffleNodesArg struct { flagStakingV4Step3 bool } -type shuffledNodesStakingV4 struct { +type shuffledNodesConfig struct { numShuffled uint32 numNewEligible uint32 numNewWaiting uint32 @@ -299,12 +300,12 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { log.Warn("moveNodesToMap failed", "error", err) } - err = distributeValidators(newWaiting, arg.newNodes, arg.randomness, false) + err = checkAndDistributeNewNodes(newWaiting, arg.newNodes, arg.randomness, arg.flagStakingV4Step3) if err != nil { - log.Warn("distributeValidators newNodes failed", "error", err) + return nil, fmt.Errorf("distributeValidators newNodes failed, error: %w", err) } - shuffledNodesCfg := &shuffledNodesStakingV4{ + shuffledNodesCfg := &shuffledNodesConfig{ numShuffled: getNumPubKeys(shuffledOutMap), numNewEligible: getNumPubKeys(newEligible), numNewWaiting: getNumPubKeys(newWaiting), @@ -318,28 +319,20 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { "num auction nodes", len(arg.auction), "num waiting nodes", shuffledNodesCfg.numNewWaiting) // Distribute selected validators from AUCTION -> WAITING - err = distributeValidators(newWaiting, arg.auction, arg.randomness, false) + err = distributeValidators(newWaiting, arg.auction, arg.randomness, arg.flagBalanceWaitingLists) if err != nil { - log.Warn("distributeValidators auction list failed", "error", err) + return nil, fmt.Errorf("distributeValidators auction list failed, error: %w", err) } } - if shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg) { - log.Debug("distributing shuffled out nodes to waiting in staking V4", + if shouldDistributeShuffledToWaiting(shuffledNodesCfg) { + log.Debug("distributing shuffled out nodes to waiting", "num shuffled nodes", shuffledNodesCfg.numShuffled, "num waiting nodes", shuffledNodesCfg.numNewWaiting) // Distribute validators from SHUFFLED OUT -> WAITING err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) if err != nil { - log.Warn("distributeValidators shuffledOut failed", "error", err) - } - } - - if !arg.flagStakingV4Step2 { - // Distribute validators from SHUFFLED OUT -> WAITING - err = arg.distributor.DistributeValidators(newWaiting, shuffledOutMap, arg.randomness, arg.flagBalanceWaitingLists) - if err != nil { - log.Warn("distributeValidators shuffledOut failed", "error", err) + return nil, fmt.Errorf("distributeValidators shuffled out failed, error: %w", err) } } @@ -589,9 +582,26 @@ func removeValidatorFromList(validatorList []Validator, index int) []Validator { return validatorList[:len(validatorList)-1] } -func shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg *shuffledNodesStakingV4) bool { +func checkAndDistributeNewNodes( + waiting map[uint32][]Validator, + newNodes []Validator, + randomness []byte, + flagStakingV4Step3 bool, +) error { + if !flagStakingV4Step3 { + return distributeValidators(waiting, newNodes, randomness, false) + } + + if len(newNodes) > 0 { + return epochStart.ErrReceivedNewListNodeInStakingV4 + } + + return nil +} + +func shouldDistributeShuffledToWaiting(shuffledNodesCfg *shuffledNodesConfig) bool { if !shuffledNodesCfg.flagStakingV4Step2 { - return false + return true } totalNewWaiting := shuffledNodesCfg.numNewWaiting + shuffledNodesCfg.numSelectedAuction diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index cae9ad879ce..bf53154a925 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -14,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/sharding/mock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -2429,6 +2430,7 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_NoWaiting(t *testing.T) { ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + EnableEpochs: config.EnableEpochs{StakingV4Step3EnableEpoch: stakingV4Epoch}, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) @@ -2490,6 +2492,7 @@ func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_NilOrEmptyWaiting(t *test ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, EnableEpochsHandler: &mock.EnableEpochsHandlerMock{}, + EnableEpochs: config.EnableEpochs{StakingV4Step3EnableEpoch: stakingV4Epoch}, } shuffler, err := NewHashValidatorsShuffler(shufflerArgs) require.Nil(t, err) @@ -2566,20 +2569,17 @@ func TestRandHashShuffler_UpdateNodeLists_WithStakingV4(t *testing.T) { t.Parallel() numEligiblePerShard := 100 - numNewNodesPerShard := 100 numWaitingPerShard := 30 numAuction := 40 nbShards := uint32(2) eligibleMap := generateValidatorMap(numEligiblePerShard, nbShards) waitingMap := generateValidatorMap(numWaitingPerShard, nbShards) - newNodes := generateValidatorList(numNewNodesPerShard * (int(nbShards) + 1)) auctionList := generateValidatorList(numAuction) args := ArgsUpdateNodes{ Eligible: eligibleMap, Waiting: waitingMap, - NewNodes: newNodes, UnStakeLeaving: make([]Validator, 0), AdditionalLeaving: make([]Validator, 0), Rand: generateRandomByteArray(32), @@ -2592,11 +2592,6 @@ func TestRandHashShuffler_UpdateNodeLists_WithStakingV4(t *testing.T) { resUpdateNodeList, err := shuffler.UpdateNodeLists(args) require.Nil(t, err) - for _, newNode := range args.NewNodes { - found, _ := searchInMap(resUpdateNodeList.Waiting, newNode.PubKey()) - assert.True(t, found) - } - for _, auctionNode := range args.Auction { found, _ := searchInMap(resUpdateNodeList.Waiting, auctionNode.PubKey()) assert.True(t, found) @@ -2611,9 +2606,14 @@ func TestRandHashShuffler_UpdateNodeLists_WithStakingV4(t *testing.T) { allNewEligible := getValidatorsInMap(resUpdateNodeList.Eligible) allNewWaiting := getValidatorsInMap(resUpdateNodeList.Waiting) - previousNumberOfNodes := (numEligiblePerShard+numWaitingPerShard+numNewNodesPerShard)*(int(nbShards)+1) + numAuction + previousNumberOfNodes := (numEligiblePerShard+numWaitingPerShard)*(int(nbShards)+1) + numAuction currentNumberOfNodes := len(allNewEligible) + len(allNewWaiting) + len(allShuffledOut) assert.Equal(t, previousNumberOfNodes, currentNumberOfNodes) + + args.NewNodes = generateValidatorList(100 * (int(nbShards) + 1)) + resUpdateNodeList, err = shuffler.UpdateNodeLists(args) + require.ErrorIs(t, err, epochStart.ErrReceivedNewListNodeInStakingV4) + require.Nil(t, resUpdateNodeList) } func TestRandHashShuffler_UpdateNodeLists_WithNewNodes_WithWaiting_WithLeaving(t *testing.T) { From 09be7261d448a47392211d014306b53abe6bc524 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 13 Mar 2023 16:36:12 +0200 Subject: [PATCH 443/958] FIX: Return error if moveMaxNumNodesToMap fails --- sharding/nodesCoordinator/hashValidatorShuffler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index dcae87c12a9..d2a4fc0d92b 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -297,7 +297,7 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { err = moveMaxNumNodesToMap(newEligible, newWaiting, arg.nodesMeta, arg.nodesPerShard) if err != nil { - log.Warn("moveNodesToMap failed", "error", err) + return nil, fmt.Errorf("moveNodesToMap failed, error: %w", err) } err = checkAndDistributeNewNodes(newWaiting, arg.newNodes, arg.randomness, arg.flagStakingV4Step3) From f13443ea05b3db2998e1fc9181842f2c82dd569d Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 14 Mar 2023 11:47:11 +0200 Subject: [PATCH 444/958] FEAT: Deterministic displayer --- .../vm/staking/configDisplayer.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/integrationTests/vm/staking/configDisplayer.go b/integrationTests/vm/staking/configDisplayer.go index cd25b8c0a0e..3ea2a402f7f 100644 --- a/integrationTests/vm/staking/configDisplayer.go +++ b/integrationTests/vm/staking/configDisplayer.go @@ -3,8 +3,10 @@ package staking import ( "bytes" "fmt" + "sort" "strconv" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/display" "github.com/multiversx/mx-chain-go/state" ) @@ -27,6 +29,10 @@ func getAllPubKeys(validatorsMap map[uint32][][]byte) [][]byte { func getShortPubKeysList(pubKeys [][]byte) [][]byte { pubKeysToDisplay := pubKeys + sort.SliceStable(pubKeysToDisplay, func(i, j int) bool { + return string(pubKeysToDisplay[i]) < string(pubKeysToDisplay[j]) + }) + if len(pubKeys) > maxPubKeysListLen { pubKeysToDisplay = make([][]byte, 0) pubKeysToDisplay = append(pubKeysToDisplay, pubKeys[:maxPubKeysListLen/2]...) @@ -49,7 +55,10 @@ func (tmp *TestMetaProcessor) displayConfig(config nodesConfig) { allNodes := tmp.getAllNodeKeys() _ = tmp.StakingDataProvider.PrepareStakingData(allNodes) - for shard := range config.eligible { + numShards := uint32(len(config.eligible)) + for shardId := uint32(0); shardId < numShards; shardId++ { + shard := getShardId(shardId, numShards) + lines = append(lines, tmp.getDisplayableValidatorsInShard("eligible", config.eligible[shard], shard)...) lines = append(lines, tmp.getDisplayableValidatorsInShard("waiting", config.waiting[shard], shard)...) lines = append(lines, tmp.getDisplayableValidatorsInShard("leaving", config.leaving[shard], shard)...) @@ -73,6 +82,14 @@ func (tmp *TestMetaProcessor) displayConfig(config nodesConfig) { tmp.StakingDataProvider.Clean() } +func getShardId(shardId, numShards uint32) uint32 { + if shardId == numShards-1 { + return core.MetachainShardId + } + + return shardId +} + func (tmp *TestMetaProcessor) getDisplayableValidatorsInShard(list string, pubKeys [][]byte, shardID uint32) []*display.LineData { pubKeysToDisplay := getShortPubKeysList(pubKeys) From d9a94826b339410c3f268840b2b204c5b1ea16b8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 20 Mar 2023 17:06:22 +0200 Subject: [PATCH 445/958] FIX: Remove duplicated stubs + move mock --- config/configChecker_test.go | 15 +- epochStart/bootstrap/process_test.go | 13 +- epochStart/bootstrap/storageProcess_test.go | 5 +- .../bootstrap/syncValidatorStatus_test.go | 3 +- epochStart/metachain/systemSCs_test.go | 5 +- epochStart/mock/nodesSetupStub.go | 173 --------------- .../statusCore/statusCoreComponents_test.go | 5 +- .../startInEpoch/startInEpoch_test.go | 4 +- integrationTests/testConsensusNode.go | 3 +- integrationTests/testProcessorNode.go | 6 +- .../testProcessorNodeWithCoordinator.go | 3 +- .../testProcessorNodeWithMultisigner.go | 9 +- .../testProcessorNodeWithTestWebServer.go | 2 +- .../vm/staking/systemSCCreator.go | 8 +- integrationTests/vm/testInitializer.go | 3 +- node/external/nodeApiResolver_test.go | 4 +- node/metrics/metrics_test.go | 6 +- node/node_test.go | 3 +- process/mock/nodesSetupStub.go | 170 --------------- process/peer/process_test.go | 9 +- testscommon/components/default.go | 3 +- .../genesisMocks}/nodesSetupStub.go | 201 +++++++++--------- testscommon/nodesSetupMock.go | 173 --------------- .../nodesSetupMock}/nodesSetupMock.go | 6 +- 24 files changed, 167 insertions(+), 665 deletions(-) delete mode 100644 epochStart/mock/nodesSetupStub.go delete mode 100644 process/mock/nodesSetupStub.go rename {integrationTests/mock => testscommon/genesisMocks}/nodesSetupStub.go (94%) delete mode 100644 testscommon/nodesSetupMock.go rename {config => testscommon/nodesSetupMock}/nodesSetupMock.go (89%) diff --git a/config/configChecker_test.go b/config/configChecker_test.go index e073429aeb6..c4f4724f7f3 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -4,6 +4,7 @@ import ( "strings" "testing" + "github.com/multiversx/mx-chain-go/testscommon/nodesSetupMock" "github.com/stretchr/testify/require" ) @@ -187,7 +188,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { t.Parallel() cfg := generateCorrectConfig().EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch - nodesSetup := &NodesSetupMock{ + nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, HysteresisField: 0, MinNumberOfMetaNodesField: 5, @@ -218,7 +219,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 40, }, } - nodesSetup = &NodesSetupMock{ + nodesSetup = &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, HysteresisField: 0.2, MinNumberOfMetaNodesField: 400, @@ -238,7 +239,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 0, }, } - nodesSetup := &NodesSetupMock{ + nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, HysteresisField: 0.2, MinNumberOfMetaNodesField: 400, @@ -260,7 +261,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 80, }, } - nodesSetup := &NodesSetupMock{ + nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, HysteresisField: 0.2, MinNumberOfMetaNodesField: 400, @@ -283,7 +284,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 81, }, } - nodesSetup := &NodesSetupMock{ + nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, HysteresisField: 0.2, MinNumberOfMetaNodesField: 400, @@ -306,7 +307,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 80, }, } - nodesSetup := &NodesSetupMock{ + nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: 1, HysteresisField: 0.2, MinNumberOfMetaNodesField: 500, @@ -330,7 +331,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { NodesToShufflePerShard: 80, }, } - nodesSetup := &NodesSetupMock{ + nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: 1, HysteresisField: 0.2, MinNumberOfMetaNodesField: 300, diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index c9c2e0bc068..2cecf036dbe 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -34,6 +34,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" @@ -200,7 +201,7 @@ func createMockEpochStartBootstrapArgs( return 1 }, }, - GenesisNodesConfig: &mock.NodesSetupStub{}, + GenesisNodesConfig: &genesisMocks.NodesSetupStub{}, GenesisShardCoordinator: mock.NewMultipleShardsCoordinatorMock(), Rater: &mock.RaterStub{}, DestinationShardAsObserver: 0, @@ -756,7 +757,7 @@ func TestIsStartInEpochZero(t *testing.T) { coreComp, cryptoComp := createComponentsForEpochStart() args := createMockEpochStartBootstrapArgs(coreComp, cryptoComp) - args.GenesisNodesConfig = &mock.NodesSetupStub{ + args.GenesisNodesConfig = &genesisMocks.NodesSetupStub{ GetStartTimeCalled: func() int64 { return 1000 }, @@ -790,7 +791,7 @@ func TestEpochStartBootstrap_BootstrapShouldStartBootstrapProcess(t *testing.T) roundDuration := uint64(60000) coreComp, cryptoComp := createComponentsForEpochStart() args := createMockEpochStartBootstrapArgs(coreComp, cryptoComp) - args.GenesisNodesConfig = &mock.NodesSetupStub{ + args.GenesisNodesConfig = &genesisMocks.NodesSetupStub{ GetRoundDurationCalled: func() uint64 { return roundDuration }, @@ -849,7 +850,7 @@ func TestPrepareForEpochZero_NodeInGenesisShouldNotAlterShardID(t *testing.T) { } args.DestinationShardAsObserver = uint32(7) - args.GenesisNodesConfig = &mock.NodesSetupStub{ + args.GenesisNodesConfig = &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { eligibleMap := map[uint32][]nodesCoordinator.GenesisNodeInfoHandler{ 1: {mock.NewNodeInfo([]byte("addr"), []byte("pubKey11"), 1, initRating)}, @@ -884,7 +885,7 @@ func TestPrepareForEpochZero_NodeNotInGenesisShouldAlterShardID(t *testing.T) { }, } args.DestinationShardAsObserver = desiredShardAsObserver - args.GenesisNodesConfig = &mock.NodesSetupStub{ + args.GenesisNodesConfig = &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { eligibleMap := map[uint32][]nodesCoordinator.GenesisNodeInfoHandler{ 1: {mock.NewNodeInfo([]byte("addr"), []byte("pubKey11"), 1, initRating)}, @@ -1446,7 +1447,7 @@ func getNodesConfigMock(numOfShards uint32) sharding.GenesisNodesSetupHandler { roundDurationMillis := 4000 epochDurationMillis := 50 * int64(roundDurationMillis) - nodesConfig := &mock.NodesSetupStub{ + nodesConfig := &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { oneMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) for i := uint32(0); i < numOfShards; i++ { diff --git a/epochStart/bootstrap/storageProcess_test.go b/epochStart/bootstrap/storageProcess_test.go index 78288156144..a59b0d125f2 100644 --- a/epochStart/bootstrap/storageProcess_test.go +++ b/epochStart/bootstrap/storageProcess_test.go @@ -22,6 +22,7 @@ import ( epochStartMocks "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks/epochStart" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/stretchr/testify/assert" ) @@ -92,7 +93,7 @@ func TestStorageEpochStartBootstrap_BootstrapFromGenesis(t *testing.T) { return 1 }, } - args.GenesisNodesConfig = &mock.NodesSetupStub{ + args.GenesisNodesConfig = &genesisMocks.NodesSetupStub{ GetRoundDurationCalled: func() uint64 { return roundDuration }, @@ -116,7 +117,7 @@ func TestStorageEpochStartBootstrap_BootstrapMetablockNotFound(t *testing.T) { return 1 }, } - args.GenesisNodesConfig = &mock.NodesSetupStub{ + args.GenesisNodesConfig = &genesisMocks.NodesSetupStub{ GetRoundDurationCalled: func() uint64 { return roundDuration }, diff --git a/epochStart/bootstrap/syncValidatorStatus_test.go b/epochStart/bootstrap/syncValidatorStatus_test.go index 488dbe84aeb..c282d030856 100644 --- a/epochStart/bootstrap/syncValidatorStatus_test.go +++ b/epochStart/bootstrap/syncValidatorStatus_test.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" epochStartMocks "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks/epochStart" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -263,7 +264,7 @@ func getSyncValidatorStatusArgs() ArgsNewSyncValidatorStatus { Hasher: &hashingMocks.HasherMock{}, RequestHandler: &testscommon.RequestHandlerStub{}, ChanceComputer: &shardingMocks.NodesCoordinatorStub{}, - GenesisNodesConfig: &mock.NodesSetupStub{ + GenesisNodesConfig: &genesisMocks.NodesSetupStub{ NumberOfShardsCalled: func() uint32 { return 1 }, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 5eeccd0eb68..feaea0ee836 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -44,6 +44,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" @@ -761,7 +762,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp PeerAdapter: peerAccountsDB, Rater: &mock.RaterStub{}, RewardsHandler: &mock.RewardsHandlerStub{}, - NodesSetup: &mock.NodesSetupStub{}, + NodesSetup: &genesisMocks.NodesSetupStub{}, MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, EnableEpochsHandler: enableEpochsHandler, @@ -776,7 +777,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp defaults.FillGasMapInternal(gasSchedule, 1) signVerifer, _ := disabled.NewMessageSignVerifier(&cryptoMocks.KeyGenStub{}) - nodesSetup := &mock.NodesSetupStub{} + nodesSetup := &genesisMocks.NodesSetupStub{} argsHook := hooks.ArgBlockChainHook{ Accounts: userAccountsDB, diff --git a/epochStart/mock/nodesSetupStub.go b/epochStart/mock/nodesSetupStub.go deleted file mode 100644 index 9ebb5216e74..00000000000 --- a/epochStart/mock/nodesSetupStub.go +++ /dev/null @@ -1,173 +0,0 @@ -package mock - -import ( - "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" -) - -// NodesSetupStub - -type NodesSetupStub struct { - InitialNodesInfoForShardCalled func(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) - InitialNodesInfoCalled func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - GetStartTimeCalled func() int64 - GetRoundDurationCalled func() uint64 - GetShardConsensusGroupSizeCalled func() uint32 - GetMetaConsensusGroupSizeCalled func() uint32 - NumberOfShardsCalled func() uint32 - MinNumberOfNodesCalled func() uint32 - AllInitialNodesCalled func() []nodesCoordinator.GenesisNodeInfoHandler - GetAdaptivityCalled func() bool - GetHysteresisCalled func() float32 - GetShardIDForPubKeyCalled func(pubkey []byte) (uint32, error) - InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) - InitialNodesPubKeysCalled func() map[uint32][]string - MinNumberOfMetaNodesCalled func() uint32 - MinNumberOfShardNodesCalled func() uint32 - MinNumberOfNodesWithHysteresisCalled func() uint32 -} - -// MinNumberOfNodes - -func (n *NodesSetupStub) MinNumberOfNodes() uint32 { - if n.MinNumberOfNodesCalled != nil { - return n.MinNumberOfNodesCalled() - } - return 1 -} - -// GetStartTime - -func (n *NodesSetupStub) GetStartTime() int64 { - if n.GetStartTimeCalled != nil { - return n.GetStartTimeCalled() - } - return 0 -} - -// GetRoundDuration - -func (n *NodesSetupStub) GetRoundDuration() uint64 { - if n.GetRoundDurationCalled != nil { - return n.GetRoundDurationCalled() - } - return 0 -} - -// GetShardConsensusGroupSize - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetShardConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() - } - return 0 -} - -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() - } - return 0 -} - -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() - } - return 0 -} - -// InitialNodesInfoForShard - -func (n *NodesSetupStub) InitialNodesInfoForShard(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { - if n.InitialNodesInfoForShardCalled != nil { - return n.InitialNodesInfoForShardCalled(shardId) - } - return nil, nil, nil -} - -// InitialNodesInfo - -func (n *NodesSetupStub) InitialNodesInfo() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { - if n.InitialNodesInfoCalled != nil { - return n.InitialNodesInfoCalled() - } - return nil, nil -} - -// AllInitialNodes - -func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHandler { - if n.AllInitialNodesCalled != nil { - return n.AllInitialNodesCalled() - } - return nil -} - -// GetAdaptivity - -func (n *NodesSetupStub) GetAdaptivity() bool { - if n.GetAdaptivityCalled != nil { - return n.GetAdaptivityCalled() - } - - return false -} - -// GetHysteresis - -func (n *NodesSetupStub) GetHysteresis() float32 { - if n.GetHysteresisCalled != nil { - return n.GetHysteresisCalled() - } - - return 0 -} - -// GetShardIDForPubKey - -func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { - if n.GetShardIDForPubKeyCalled != nil { - return n.GetShardIDForPubKeyCalled(pubkey) - } - return 0, nil -} - -// InitialEligibleNodesPubKeysForShard - -func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { - if n.InitialEligibleNodesPubKeysForShardCalled != nil { - return n.InitialEligibleNodesPubKeysForShardCalled(shardId) - } - - return []string{"val1", "val2"}, nil -} - -// InitialNodesPubKeys - -func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { - if n.InitialNodesPubKeysCalled != nil { - return n.InitialNodesPubKeysCalled() - } - - return map[uint32][]string{0: {"val1", "val2"}} -} - -// MinNumberOfMetaNodes - -func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { - if n.MinNumberOfMetaNodesCalled != nil { - return n.MinNumberOfMetaNodesCalled() - } - - return 1 -} - -// MinNumberOfShardNodes - -func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { - if n.MinNumberOfShardNodesCalled != nil { - return n.MinNumberOfShardNodesCalled() - } - - return 1 -} - -// MinNumberOfNodesWithHysteresis - -func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { - if n.MinNumberOfNodesWithHysteresisCalled != nil { - return n.MinNumberOfNodesWithHysteresisCalled() - } - return n.MinNumberOfNodes() -} - -// IsInterfaceNil - -func (n *NodesSetupStub) IsInterfaceNil() bool { - return n == nil -} diff --git a/factory/statusCore/statusCoreComponents_test.go b/factory/statusCore/statusCoreComponents_test.go index 66c5e6c07ea..c901b2983be 100644 --- a/factory/statusCore/statusCoreComponents_test.go +++ b/factory/statusCore/statusCoreComponents_test.go @@ -12,6 +12,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" componentsMock "github.com/multiversx/mx-chain-go/testscommon/components" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -60,7 +61,7 @@ func TestNewStatusCoreComponentsFactory(t *testing.T) { coreComp := &mock.CoreComponentsStub{ EconomicsDataField: &economicsmocks.EconomicsHandlerStub{}, - GenesisNodesSetupField: &testscommon.NodesSetupStub{}, + GenesisNodesSetupField: &genesisMocks.NodesSetupStub{}, InternalMarshalizerField: nil, } @@ -74,7 +75,7 @@ func TestNewStatusCoreComponentsFactory(t *testing.T) { coreComp := &mock.CoreComponentsStub{ EconomicsDataField: &economicsmocks.EconomicsHandlerStub{}, - GenesisNodesSetupField: &testscommon.NodesSetupStub{}, + GenesisNodesSetupField: &genesisMocks.NodesSetupStub{}, InternalMarshalizerField: &testscommon.MarshalizerStub{}, Uint64ByteSliceConverterField: nil, } diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index d962045a32d..80c6318b821 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -31,6 +31,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" epochNotifierMock "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/scheduledDataSyncer" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -148,7 +149,7 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui pksBytes := integrationTests.CreatePkBytes(uint32(numOfShards)) address := []byte("afafafafafafafafafafafafafafafaf") - nodesConfig := &mock.NodesSetupStub{ + nodesConfig := &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { oneMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) for i := uint32(0); i < uint32(numOfShards); i++ { @@ -180,7 +181,6 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui return integrationTests.MinTransactionVersion }, } - defer func() { errRemoveDir := os.RemoveAll("Epoch_0") assert.NoError(t, errRemoveDir) diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index bf359c054e3..18e054ef74f 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -40,6 +40,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" testFactory "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" @@ -239,7 +240,7 @@ func (tcn *TestConsensusNode) initNode( return string(ChainID) } coreComponents.GenesisTimeField = time.Unix(startTime, 0) - coreComponents.GenesisNodesSetupField = &testscommon.NodesSetupStub{ + coreComponents.GenesisNodesSetupField = &genesisMocks.NodesSetupStub{ GetShardConsensusGroupSizeCalled: func() uint32 { return uint32(consensusSize) }, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index d2f492c3c5b..ff415e8f45c 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -572,7 +572,7 @@ func (tpn *TestProcessorNode) initValidatorStatistics() { rater, _ := rating.NewBlockSigningRater(tpn.RatingsData) if check.IfNil(tpn.NodesSetup) { - tpn.NodesSetup = &mock.NodesSetupStub{ + tpn.NodesSetup = &genesisMocks.NodesSetupStub{ MinNumberOfNodesCalled: func() uint32 { return tpn.ShardCoordinator.NumberOfShards() * 2 }, @@ -3026,7 +3026,7 @@ func GetDefaultCoreComponents() *mock.CoreComponentsStub { EconomicsDataField: &economicsmocks.EconomicsHandlerStub{}, RatingsDataField: &testscommon.RatingsInfoMock{}, RaterField: &testscommon.RaterMock{}, - GenesisNodesSetupField: &testscommon.NodesSetupStub{}, + GenesisNodesSetupField: &genesisMocks.NodesSetupStub{}, GenesisTimeField: time.Time{}, EpochNotifierField: genericEpochNotifier, EnableRoundsHandlerField: &testscommon.EnableRoundsHandlerStub{}, @@ -3237,7 +3237,7 @@ func getDefaultVMConfig() *config.VirtualMachineConfig { } func getDefaultNodesSetup(maxShards, numNodes uint32, address []byte, pksBytes map[uint32][]byte) sharding.GenesisNodesSetupHandler { - return &mock.NodesSetupStub{ + return &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { oneMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) for i := uint32(0); i < maxShards; i++ { diff --git a/integrationTests/testProcessorNodeWithCoordinator.go b/integrationTests/testProcessorNodeWithCoordinator.go index a346f343ea3..1c2acb55101 100644 --- a/integrationTests/testProcessorNodeWithCoordinator.go +++ b/integrationTests/testProcessorNodeWithCoordinator.go @@ -14,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage/cache" "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" vic "github.com/multiversx/mx-chain-go/testscommon/validatorInfoCacher" ) @@ -47,7 +48,7 @@ func CreateProcessorNodesWithNodesCoordinator( waitingMap := GenValidatorsFromPubKeys(pubKeysWaiting, nbShards) waitingMapForNodesCoordinator, _ := nodesCoordinator.NodesInfoToValidators(waitingMap) - nodesSetup := &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + nodesSetup := &genesisMocks.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { return validatorsMap, waitingMap }} diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 70fa27d0751..65a2f09f7b1 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -30,6 +30,7 @@ import ( "github.com/multiversx/mx-chain-go/storage/storageunit" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" vic "github.com/multiversx/mx-chain-go/testscommon/validatorInfoCacher" @@ -88,7 +89,7 @@ func CreateNodesWithNodesCoordinatorAndTxKeys( } waitingMapForNodesCoordinator[core.MetachainShardId] = make([]nodesCoordinator.Validator, 0) - nodesSetup := &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + nodesSetup := &genesisMocks.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { return validatorsMap, waitingMap }} @@ -220,7 +221,7 @@ func CreateNodesWithNodesCoordinatorFactory( numNodes := nbShards*nodesPerShard + nbMetaNodes - nodesSetup := &mock.NodesSetupStub{ + nodesSetup := &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { return validatorsMap, waitingMap }, @@ -407,7 +408,7 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( epochStartSubscriber := notifier.NewEpochStartSubscriptionHandler() bootStorer := CreateMemUnit() - nodesSetup := &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + nodesSetup := &genesisMocks.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { return validatorsMap, nil }} @@ -525,7 +526,7 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( epochStartSubscriber := notifier.NewEpochStartSubscriptionHandler() nodeShuffler := &shardingMocks.NodeShufflerMock{} - nodesSetup := &mock.NodesSetupStub{ + nodesSetup := &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { return validatorsMap, waitingMap }, diff --git a/integrationTests/testProcessorNodeWithTestWebServer.go b/integrationTests/testProcessorNodeWithTestWebServer.go index 814064aead5..f3c8e588eff 100644 --- a/integrationTests/testProcessorNodeWithTestWebServer.go +++ b/integrationTests/testProcessorNodeWithTestWebServer.go @@ -260,7 +260,7 @@ func createFacadeComponents(tpn *TestProcessorNode) (nodeFacade.ApiResolver, nod APITransactionHandler: apiTransactionHandler, APIBlockHandler: blockAPIHandler, APIInternalBlockHandler: apiInternalBlockProcessor, - GenesisNodesSetupHandler: &mock.NodesSetupStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, AccountsParser: &genesisMocks.AccountsParserStub{}, GasScheduleNotifier: &testscommon.GasScheduleNotifierMock{}, diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 0e3d1920b7e..d817cdca870 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -15,7 +15,6 @@ import ( "github.com/multiversx/mx-chain-go/genesis/process/disabled" "github.com/multiversx/mx-chain-go/process" metaProcess "github.com/multiversx/mx-chain-go/process/factory/metachain" - "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/process/peer" "github.com/multiversx/mx-chain-go/process/smartContract/builtInFunctions" "github.com/multiversx/mx-chain-go/process/smartContract/hooks" @@ -25,6 +24,7 @@ import ( "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" vmcommonMock "github.com/multiversx/mx-chain-vm-common-go/mock" @@ -67,7 +67,7 @@ func createSystemSCProcessor( StakingSCAddress: vm.StakingSCAddress, ChanceComputer: &epochStartMock.ChanceComputerStub{}, EpochNotifier: coreComponents.EpochNotifier(), - GenesisNodesConfig: &mock.NodesSetupStub{}, + GenesisNodesConfig: &genesisMocks.NodesSetupStub{}, StakingDataProvider: stakingDataProvider, NodesConfigProvider: nc, ShardCoordinator: shardCoordinator, @@ -112,7 +112,7 @@ func createValidatorStatisticsProcessor( PeerAdapter: peerAccounts, Rater: coreComponents.Rater(), RewardsHandler: &epochStartMock.RewardsHandlerStub{}, - NodesSetup: &mock.NodesSetupStub{}, + NodesSetup: &genesisMocks.NodesSetupStub{}, MaxComputableRounds: 1, MaxConsecutiveRoundsOfRatingDecrease: 2000, EnableEpochsHandler: coreComponents.EnableEpochsHandler(), @@ -186,7 +186,7 @@ func createVMContainerFactory( Economics: coreComponents.EconomicsData(), MessageSignVerifier: signVerifer, GasSchedule: gasScheduleNotifier, - NodesConfigProvider: &mock.NodesSetupStub{}, + NodesConfigProvider: &genesisMocks.NodesSetupStub{}, Hasher: coreComponents.Hasher(), Marshalizer: coreComponents.InternalMarshalizer(), SystemSCConfig: &config.SystemSmartContractsConfig{ diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 8cc0d3f9278..05b370323d2 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -52,6 +52,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/integrationtests" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -637,7 +638,7 @@ func CreateVMAndBlockchainHookMeta( Economics: economicsData, MessageSignVerifier: &mock.MessageSignVerifierMock{}, GasSchedule: gasSchedule, - NodesConfigProvider: &mock.NodesSetupStub{}, + NodesConfigProvider: &genesisMocks.NodesSetupStub{}, Hasher: integrationtests.TestHasher, Marshalizer: integrationtests.TestMarshalizer, SystemSCConfig: createSystemSCConfig(), diff --git a/node/external/nodeApiResolver_test.go b/node/external/nodeApiResolver_test.go index 0f4528ba2c7..f5d4bc834e8 100644 --- a/node/external/nodeApiResolver_test.go +++ b/node/external/nodeApiResolver_test.go @@ -36,7 +36,7 @@ func createMockArgs() external.ArgNodeApiResolver { APIBlockHandler: &mock.BlockAPIHandlerStub{}, APITransactionHandler: &mock.TransactionAPIHandlerStub{}, APIInternalBlockHandler: &mock.InternalBlockApiHandlerStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, AccountsParser: &genesisMocks.AccountsParserStub{}, GasScheduleNotifier: &testscommon.GasScheduleNotifierMock{}, @@ -578,7 +578,7 @@ func TestNodeApiResolver_GetGenesisNodesPubKeys(t *testing.T) { } arg := createMockArgs() - arg.GenesisNodesSetupHandler = &testscommon.NodesSetupStub{ + arg.GenesisNodesSetupHandler = &genesisMocks.NodesSetupStub{ InitialNodesInfoCalled: func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { return eligible, waiting }, diff --git a/node/metrics/metrics_test.go b/node/metrics/metrics_test.go index 8133d10890a..828cc36af4a 100644 --- a/node/metrics/metrics_test.go +++ b/node/metrics/metrics_test.go @@ -7,7 +7,7 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" - "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -181,7 +181,7 @@ func TestInitConfigMetrics(t *testing.T) { }, } - genesisNodesConfig := &testscommon.NodesSetupStub{ + genesisNodesConfig := &genesisMocks.NodesSetupStub{ GetAdaptivityCalled: func() bool { return true }, @@ -212,7 +212,7 @@ func TestInitConfigMetrics(t *testing.T) { assert.Equal(t, v, keys[k]) } - genesisNodesConfig = &testscommon.NodesSetupStub{ + genesisNodesConfig = &genesisMocks.NodesSetupStub{ GetAdaptivityCalled: func() bool { return false }, diff --git a/node/node_test.go b/node/node_test.go index 9d223be9534..6ae3145a488 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -48,6 +48,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" factoryTests "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -3940,7 +3941,7 @@ func getDefaultCoreComponents() *nodeMockFactory.CoreComponentsMock { APIEconomicsHandler: &economicsmocks.EconomicsHandlerMock{}, RatingsConfig: &testscommon.RatingsInfoMock{}, RatingHandler: &testscommon.RaterMock{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &genesisMocks.NodesSetupStub{}, StartTime: time.Time{}, EpochChangeNotifier: &epochNotifier.EpochNotifierStub{}, TxVersionCheckHandler: versioning.NewTxVersionChecker(0), diff --git a/process/mock/nodesSetupStub.go b/process/mock/nodesSetupStub.go deleted file mode 100644 index 2df5b500755..00000000000 --- a/process/mock/nodesSetupStub.go +++ /dev/null @@ -1,170 +0,0 @@ -package mock - -import "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" - -// NodesSetupStub - -type NodesSetupStub struct { - InitialNodesInfoForShardCalled func(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) - InitialNodesInfoCalled func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - GetStartTimeCalled func() int64 - GetRoundDurationCalled func() uint64 - GetShardConsensusGroupSizeCalled func() uint32 - GetMetaConsensusGroupSizeCalled func() uint32 - NumberOfShardsCalled func() uint32 - MinNumberOfNodesCalled func() uint32 - AllInitialNodesCalled func() []nodesCoordinator.GenesisNodeInfoHandler - GetAdaptivityCalled func() bool - GetHysteresisCalled func() float32 - GetShardIDForPubKeyCalled func(pubkey []byte) (uint32, error) - InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) - InitialNodesPubKeysCalled func() map[uint32][]string - MinNumberOfMetaNodesCalled func() uint32 - MinNumberOfShardNodesCalled func() uint32 - MinNumberOfNodesWithHysteresisCalled func() uint32 -} - -// MinNumberOfNodes - -func (n *NodesSetupStub) MinNumberOfNodes() uint32 { - if n.MinNumberOfNodesCalled != nil { - return n.MinNumberOfNodesCalled() - } - return 1 -} - -// GetStartTime - -func (n *NodesSetupStub) GetStartTime() int64 { - if n.GetStartTimeCalled != nil { - return n.GetStartTimeCalled() - } - return 0 -} - -// GetRoundDuration - -func (n *NodesSetupStub) GetRoundDuration() uint64 { - if n.GetRoundDurationCalled != nil { - return n.GetRoundDurationCalled() - } - return 0 -} - -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() - } - return 0 -} - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() - } - return 0 -} - -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() - } - return 0 -} - -// InitialNodesInfoForShard - -func (n *NodesSetupStub) InitialNodesInfoForShard(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { - if n.InitialNodesInfoForShardCalled != nil { - return n.InitialNodesInfoForShardCalled(shardId) - } - return nil, nil, nil -} - -// InitialNodesInfo - -func (n *NodesSetupStub) InitialNodesInfo() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { - if n.InitialNodesInfoCalled != nil { - return n.InitialNodesInfoCalled() - } - return nil, nil -} - -// AllInitialNodes - -func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHandler { - if n.AllInitialNodesCalled != nil { - return n.AllInitialNodesCalled() - } - return nil -} - -// GetAdaptivity - -func (n *NodesSetupStub) GetAdaptivity() bool { - if n.GetAdaptivityCalled != nil { - return n.GetAdaptivityCalled() - } - - return false -} - -// GetHysteresis - -func (n *NodesSetupStub) GetHysteresis() float32 { - if n.GetHysteresisCalled != nil { - return n.GetHysteresisCalled() - } - - return 0 -} - -// GetShardIDForPubKey - -func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { - if n.GetShardIDForPubKeyCalled != nil { - return n.GetShardIDForPubKeyCalled(pubkey) - } - return 0, nil -} - -// InitialEligibleNodesPubKeysForShard - -func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { - if n.InitialEligibleNodesPubKeysForShardCalled != nil { - return n.InitialEligibleNodesPubKeysForShardCalled(shardId) - } - - return []string{"val1", "val2"}, nil -} - -// InitialNodesPubKeys - -func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { - if n.InitialNodesPubKeysCalled != nil { - return n.InitialNodesPubKeysCalled() - } - - return map[uint32][]string{0: {"val1", "val2"}} -} - -// MinNumberOfMetaNodes - -func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { - if n.MinNumberOfMetaNodesCalled != nil { - return n.MinNumberOfMetaNodesCalled() - } - - return 1 -} - -// MinNumberOfShardNodes - -func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { - if n.MinNumberOfShardNodesCalled != nil { - return n.MinNumberOfShardNodesCalled() - } - - return 1 -} - -// MinNumberOfNodesWithHysteresis - -func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { - if n.MinNumberOfNodesWithHysteresisCalled != nil { - return n.MinNumberOfNodesWithHysteresisCalled() - } - return n.MinNumberOfNodes() -} - -// IsInterfaceNil - -func (n *NodesSetupStub) IsInterfaceNil() bool { - return n == nil -} diff --git a/process/peer/process_test.go b/process/peer/process_test.go index fe4402ed3f6..78d375acf91 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -27,6 +27,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" @@ -118,7 +119,7 @@ func createMockArguments() peer.ArgValidatorStatisticsProcessor { RewardsHandler: economicsData, MaxComputableRounds: 1000, MaxConsecutiveRoundsOfRatingDecrease: 2000, - NodesSetup: &mock.NodesSetupStub{}, + NodesSetup: &genesisMocks.NodesSetupStub{}, EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ IsSwitchJailWaitingFlagEnabledField: true, IsBelowSignedThresholdFlagEnabledField: true, @@ -289,7 +290,7 @@ func TestValidatorStatisticsProcessor_SaveInitialStateErrOnGetAccountFail(t *tes arguments := createMockArguments() arguments.PeerAdapter = peerAdapters - arguments.NodesSetup = &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + arguments.NodesSetup = &genesisMocks.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { oneMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) oneMap[0] = append(oneMap[0], mock.NewNodeInfo([]byte("aaaa"), []byte("aaaa"), 0, 50)) return oneMap, oneMap @@ -311,7 +312,7 @@ func TestValidatorStatisticsProcessor_SaveInitialStateGetAccountReturnsInvalid(t arguments := createMockArguments() arguments.PeerAdapter = peerAdapter - arguments.NodesSetup = &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + arguments.NodesSetup = &genesisMocks.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { oneMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) oneMap[0] = append(oneMap[0], mock.NewNodeInfo([]byte("aaaa"), []byte("aaaa"), 0, 50)) return oneMap, oneMap @@ -336,7 +337,7 @@ func TestValidatorStatisticsProcessor_SaveInitialStateSetAddressErrors(t *testin } arguments := createMockArguments() - arguments.NodesSetup = &mock.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { + arguments.NodesSetup = &genesisMocks.NodesSetupStub{InitialNodesInfoCalled: func() (m map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, m2 map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { oneMap := make(map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) oneMap[0] = append(oneMap[0], mock.NewNodeInfo([]byte("aaaa"), []byte("aaaa"), 0, 50)) return oneMap, oneMap diff --git a/testscommon/components/default.go b/testscommon/components/default.go index ccb2003e66b..6079898e618 100644 --- a/testscommon/components/default.go +++ b/testscommon/components/default.go @@ -13,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverTests "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -47,7 +48,7 @@ func GetDefaultCoreComponents() *mock.CoreComponentsMock { EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, RatingsConfig: &testscommon.RatingsInfoMock{}, RatingHandler: &testscommon.RaterMock{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &genesisMocks.NodesSetupStub{}, StartTime: time.Time{}, NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, EnableEpochsHandlerField: &testscommon.EnableEpochsHandlerStub{}, diff --git a/integrationTests/mock/nodesSetupStub.go b/testscommon/genesisMocks/nodesSetupStub.go similarity index 94% rename from integrationTests/mock/nodesSetupStub.go rename to testscommon/genesisMocks/nodesSetupStub.go index e4afbc67c90..76d19af0aee 100644 --- a/integrationTests/mock/nodesSetupStub.go +++ b/testscommon/genesisMocks/nodesSetupStub.go @@ -1,80 +1,80 @@ -package mock +package genesisMocks -import "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" +import ( + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" +) // NodesSetupStub - type NodesSetupStub struct { - InitialNodesInfoForShardCalled func(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) - InitialNodesInfoCalled func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - GetStartTimeCalled func() int64 - GetRoundDurationCalled func() uint64 - GetChainIdCalled func() string - GetMinTransactionVersionCalled func() uint32 + InitialNodesPubKeysCalled func() map[uint32][]string + InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) + GetShardIDForPubKeyCalled func(pubKey []byte) (uint32, error) + NumberOfShardsCalled func() uint32 GetShardConsensusGroupSizeCalled func() uint32 GetMetaConsensusGroupSizeCalled func() uint32 - NumberOfShardsCalled func() uint32 - MinNumberOfNodesCalled func() uint32 - MinNumberOfShardNodesCalled func() uint32 + GetRoundDurationCalled func() uint64 MinNumberOfMetaNodesCalled func() uint32 + MinNumberOfShardNodesCalled func() uint32 GetHysteresisCalled func() float32 GetAdaptivityCalled func() bool + InitialNodesInfoForShardCalled func(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) + InitialNodesInfoCalled func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) + GetStartTimeCalled func() int64 + MinNumberOfNodesCalled func() uint32 AllInitialNodesCalled func() []nodesCoordinator.GenesisNodeInfoHandler - GetShardIDForPubKeyCalled func(pubkey []byte) (uint32, error) - InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) - InitialNodesPubKeysCalled func() map[uint32][]string MinNumberOfNodesWithHysteresisCalled func() uint32 + GetChainIdCalled func() string + GetMinTransactionVersionCalled func() uint32 } -// MinNumberOfShardNodes - -func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { - if n.MinNumberOfShardNodesCalled != nil { - return n.MinNumberOfShardNodesCalled() +// InitialNodesPubKeys - +func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { + if n.InitialNodesPubKeysCalled != nil { + return n.InitialNodesPubKeysCalled() } - return 1 + return map[uint32][]string{0: {"val1", "val2"}} } -// MinNumberOfMetaNodes - -func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { - if n.MinNumberOfMetaNodesCalled != nil { - return n.MinNumberOfMetaNodesCalled() +// InitialEligibleNodesPubKeysForShard - +func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { + if n.InitialEligibleNodesPubKeysForShardCalled != nil { + return n.InitialEligibleNodesPubKeysForShardCalled(shardId) } - return 1 + return []string{"val1", "val2"}, nil } -// GetHysteresis - -func (n *NodesSetupStub) GetHysteresis() float32 { - if n.GetHysteresisCalled != nil { - return n.GetHysteresisCalled() +// NumberOfShards - +func (n *NodesSetupStub) NumberOfShards() uint32 { + if n.NumberOfShardsCalled != nil { + return n.NumberOfShardsCalled() } - - return 0 + return 1 } -// GetAdaptivity - -func (n *NodesSetupStub) GetAdaptivity() bool { - if n.GetAdaptivityCalled != nil { - return n.GetAdaptivityCalled() +// GetShardIDForPubKey - +func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { + if n.GetShardIDForPubKeyCalled != nil { + return n.GetShardIDForPubKeyCalled(pubkey) } - - return false + return 0, nil } -// MinNumberOfNodes - -func (n *NodesSetupStub) MinNumberOfNodes() uint32 { - if n.MinNumberOfNodesCalled != nil { - return n.MinNumberOfNodesCalled() +// GetShardConsensusGroupSize - +func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { + if n.GetShardConsensusGroupSizeCalled != nil { + return n.GetShardConsensusGroupSizeCalled() } - return 0 + return 1 } -// GetStartTime - -func (n *NodesSetupStub) GetStartTime() int64 { - if n.GetStartTimeCalled != nil { - return n.GetStartTimeCalled() +// GetMetaConsensusGroupSize - +func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { + if n.GetMetaConsensusGroupSizeCalled != nil { + return n.GetMetaConsensusGroupSizeCalled() } - return 0 + return 1 } // GetRoundDuration - @@ -82,54 +82,49 @@ func (n *NodesSetupStub) GetRoundDuration() uint64 { if n.GetRoundDurationCalled != nil { return n.GetRoundDurationCalled() } - return 0 + return 4000 } -// GetChainId - -func (n *NodesSetupStub) GetChainId() string { - if n.GetChainIdCalled != nil { - return n.GetChainIdCalled() - } - return "chainID" -} - -// GetMinTransactionVersion - -func (n *NodesSetupStub) GetMinTransactionVersion() uint32 { - if n.GetMinTransactionVersionCalled != nil { - return n.GetMinTransactionVersionCalled() +// MinNumberOfMetaNodes - +func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { + if n.MinNumberOfMetaNodesCalled != nil { + return n.MinNumberOfMetaNodesCalled() } return 1 } -// GetShardConsensusGroupSize - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetShardConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() +// MinNumberOfShardNodes - +func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { + if n.MinNumberOfShardNodesCalled != nil { + return n.MinNumberOfShardNodesCalled() } - return 0 + return 1 } -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() +// GetHysteresis - +func (n *NodesSetupStub) GetHysteresis() float32 { + if n.GetHysteresisCalled != nil { + return n.GetHysteresisCalled() } return 0 } -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() +// GetAdaptivity - +func (n *NodesSetupStub) GetAdaptivity() bool { + if n.GetAdaptivityCalled != nil { + return n.GetAdaptivityCalled() } - return 0 + return false } // InitialNodesInfoForShard - -func (n *NodesSetupStub) InitialNodesInfoForShard(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { +func (n *NodesSetupStub) InitialNodesInfoForShard( + shardId uint32, +) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { if n.InitialNodesInfoForShardCalled != nil { return n.InitialNodesInfoForShardCalled(shardId) } + return nil, nil, nil } @@ -138,49 +133,55 @@ func (n *NodesSetupStub) InitialNodesInfo() (map[uint32][]nodesCoordinator.Genes if n.InitialNodesInfoCalled != nil { return n.InitialNodesInfoCalled() } + return nil, nil } -// AllInitialNodes - -func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHandler { - if n.AllInitialNodesCalled != nil { - return n.AllInitialNodesCalled() +// GetStartTime - +func (n *NodesSetupStub) GetStartTime() int64 { + if n.GetStartTimeCalled != nil { + return n.GetStartTimeCalled() } - return nil + return 0 } -// GetShardIDForPubKey - -func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { - if n.GetShardIDForPubKeyCalled != nil { - return n.GetShardIDForPubKeyCalled(pubkey) +// MinNumberOfNodes - +func (n *NodesSetupStub) MinNumberOfNodes() uint32 { + if n.MinNumberOfNodesCalled != nil { + return n.MinNumberOfNodesCalled() } - return 0, nil + return 1 } -// InitialEligibleNodesPubKeysForShard - -func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { - if n.InitialEligibleNodesPubKeysForShardCalled != nil { - return n.InitialEligibleNodesPubKeysForShardCalled(shardId) +// MinNumberOfNodesWithHysteresis - +func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { + if n.MinNumberOfNodesWithHysteresisCalled != nil { + return n.MinNumberOfNodesWithHysteresisCalled() } - - return []string{"val1", "val2"}, nil + return n.MinNumberOfNodes() } -// InitialNodesPubKeys - -func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { - if n.InitialNodesPubKeysCalled != nil { - return n.InitialNodesPubKeysCalled() +// AllInitialNodes - +func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHandler { + if n.AllInitialNodesCalled != nil { + return n.AllInitialNodesCalled() } + return nil +} - return map[uint32][]string{0: {"val1", "val2"}} +func (n *NodesSetupStub) GetChainId() string { + if n.GetChainIdCalled != nil { + return n.GetChainIdCalled() + } + return "chainID" } -// MinNumberOfNodesWithHysteresis - -func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { - if n.MinNumberOfNodesWithHysteresisCalled != nil { - return n.MinNumberOfNodesWithHysteresisCalled() +// GetMinTransactionVersion - +func (n *NodesSetupStub) GetMinTransactionVersion() uint32 { + if n.GetMinTransactionVersionCalled != nil { + return n.GetMinTransactionVersionCalled() } - return n.MinNumberOfNodes() + return 1 } // IsInterfaceNil - diff --git a/testscommon/nodesSetupMock.go b/testscommon/nodesSetupMock.go deleted file mode 100644 index 683afe7073e..00000000000 --- a/testscommon/nodesSetupMock.go +++ /dev/null @@ -1,173 +0,0 @@ -package testscommon - -import ( - "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" -) - -// NodesSetupStub - -type NodesSetupStub struct { - InitialNodesPubKeysCalled func() map[uint32][]string - InitialEligibleNodesPubKeysForShardCalled func(shardId uint32) ([]string, error) - GetShardIDForPubKeyCalled func(pubKey []byte) (uint32, error) - NumberOfShardsCalled func() uint32 - GetShardConsensusGroupSizeCalled func() uint32 - GetMetaConsensusGroupSizeCalled func() uint32 - GetRoundDurationCalled func() uint64 - MinNumberOfMetaNodesCalled func() uint32 - MinNumberOfShardNodesCalled func() uint32 - GetHysteresisCalled func() float32 - GetAdaptivityCalled func() bool - InitialNodesInfoForShardCalled func(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) - InitialNodesInfoCalled func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - GetStartTimeCalled func() int64 - MinNumberOfNodesCalled func() uint32 - AllInitialNodesCalled func() []nodesCoordinator.GenesisNodeInfoHandler - MinNumberOfNodesWithHysteresisCalled func() uint32 -} - -// InitialNodesPubKeys - -func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { - if n.InitialNodesPubKeysCalled != nil { - return n.InitialNodesPubKeysCalled() - } - - return map[uint32][]string{0: {"val1", "val2"}} -} - -// InitialEligibleNodesPubKeysForShard - -func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { - if n.InitialEligibleNodesPubKeysForShardCalled != nil { - return n.InitialEligibleNodesPubKeysForShardCalled(shardId) - } - - return []string{"val1", "val2"}, nil -} - -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() - } - return 1 -} - -// GetShardIDForPubKey - -func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { - if n.GetShardIDForPubKeyCalled != nil { - return n.GetShardIDForPubKeyCalled(pubkey) - } - return 0, nil -} - -// GetShardConsensusGroupSize - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetShardConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() - } - return 1 -} - -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() - } - return 1 -} - -// GetRoundDuration - -func (n *NodesSetupStub) GetRoundDuration() uint64 { - if n.GetRoundDurationCalled != nil { - return n.GetRoundDurationCalled() - } - return 4000 -} - -// MinNumberOfMetaNodes - -func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { - if n.MinNumberOfMetaNodesCalled != nil { - return n.MinNumberOfMetaNodesCalled() - } - return 1 -} - -// MinNumberOfShardNodes - -func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { - if n.MinNumberOfShardNodesCalled != nil { - return n.MinNumberOfShardNodesCalled() - } - return 1 -} - -// GetHysteresis - -func (n *NodesSetupStub) GetHysteresis() float32 { - if n.GetHysteresisCalled != nil { - return n.GetHysteresisCalled() - } - return 0 -} - -// GetAdaptivity - -func (n *NodesSetupStub) GetAdaptivity() bool { - if n.GetAdaptivityCalled != nil { - return n.GetAdaptivityCalled() - } - return false -} - -// InitialNodesInfoForShard - -func (n *NodesSetupStub) InitialNodesInfoForShard( - shardId uint32, -) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { - if n.InitialNodesInfoForShardCalled != nil { - return n.InitialNodesInfoForShardCalled(shardId) - } - - return nil, nil, nil -} - -// InitialNodesInfo - -func (n *NodesSetupStub) InitialNodesInfo() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { - if n.InitialNodesInfoCalled != nil { - return n.InitialNodesInfoCalled() - } - - return nil, nil -} - -// GetStartTime - -func (n *NodesSetupStub) GetStartTime() int64 { - if n.GetStartTimeCalled != nil { - return n.GetStartTimeCalled() - } - return 0 -} - -// MinNumberOfNodes - -func (n *NodesSetupStub) MinNumberOfNodes() uint32 { - if n.MinNumberOfNodesCalled != nil { - return n.MinNumberOfNodesCalled() - } - return 1 -} - -// MinNumberOfNodesWithHysteresis - -func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { - if n.MinNumberOfNodesWithHysteresisCalled != nil { - return n.MinNumberOfNodesWithHysteresisCalled() - } - return n.MinNumberOfNodes() -} - -// AllInitialNodes - -func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHandler { - if n.AllInitialNodesCalled != nil { - return n.AllInitialNodesCalled() - } - return nil -} - -// IsInterfaceNil - -func (n *NodesSetupStub) IsInterfaceNil() bool { - return n == nil -} diff --git a/config/nodesSetupMock.go b/testscommon/nodesSetupMock/nodesSetupMock.go similarity index 89% rename from config/nodesSetupMock.go rename to testscommon/nodesSetupMock/nodesSetupMock.go index ef365f2af73..392cb038719 100644 --- a/config/nodesSetupMock.go +++ b/testscommon/nodesSetupMock/nodesSetupMock.go @@ -1,4 +1,4 @@ -package config +package nodesSetupMock // NodesSetupMock - type NodesSetupMock struct { @@ -41,3 +41,7 @@ func (n *NodesSetupMock) MinNumberOfNodesWithHysteresis() uint32 { return minNumberOfNodes + hystNodesMeta + n.NumberOfShardsField*hystNodesShard } + +func getHysteresisNodes(minNumNodes uint32, hysteresis float32) uint32 { + return uint32(float32(minNumNodes) * hysteresis) +} From 98de09ab3db10251e1d8eef8f22ef3cc07bf981c Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 20 Mar 2023 17:10:41 +0200 Subject: [PATCH 446/958] FIX: Remove another stub --- factory/mock/nodesSetupStub.go | 142 --------------------- testscommon/genesisMocks/nodesSetupStub.go | 1 + 2 files changed, 1 insertion(+), 142 deletions(-) delete mode 100644 factory/mock/nodesSetupStub.go diff --git a/factory/mock/nodesSetupStub.go b/factory/mock/nodesSetupStub.go deleted file mode 100644 index 835ad9fc0d8..00000000000 --- a/factory/mock/nodesSetupStub.go +++ /dev/null @@ -1,142 +0,0 @@ -package mock - -import "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" - -// NodesSetupStub - -type NodesSetupStub struct { - InitialNodesInfoForShardCalled func(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) - InitialNodesInfoCalled func() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) - GetStartTimeCalled func() int64 - GetRoundDurationCalled func() uint64 - GetChainIdCalled func() string - GetMinTransactionVersionCalled func() uint32 - GetShardConsensusGroupSizeCalled func() uint32 - GetMetaConsensusGroupSizeCalled func() uint32 - NumberOfShardsCalled func() uint32 - MinNumberOfNodesCalled func() uint32 - MinNumberOfShardNodesCalled func() uint32 - MinNumberOfMetaNodesCalled func() uint32 - GetHysteresisCalled func() float32 - GetAdaptivityCalled func() bool -} - -// MinNumberOfShardNodes - -func (n *NodesSetupStub) MinNumberOfShardNodes() uint32 { - if n.MinNumberOfShardNodesCalled != nil { - return n.MinNumberOfShardNodesCalled() - } - - return 1 -} - -// MinNumberOfMetaNodes - -func (n *NodesSetupStub) MinNumberOfMetaNodes() uint32 { - if n.MinNumberOfMetaNodesCalled != nil { - return n.MinNumberOfMetaNodesCalled() - } - - return 1 -} - -// GetHysteresis - -func (n *NodesSetupStub) GetHysteresis() float32 { - if n.GetHysteresisCalled != nil { - return n.GetHysteresisCalled() - } - - return 0 -} - -// GetAdaptivity - -func (n *NodesSetupStub) GetAdaptivity() bool { - if n.GetAdaptivityCalled != nil { - return n.GetAdaptivityCalled() - } - - return false -} - -// MinNumberOfNodes - -func (n *NodesSetupStub) MinNumberOfNodes() uint32 { - if n.MinNumberOfNodesCalled != nil { - return n.MinNumberOfNodesCalled() - } - return 2 -} - -// GetStartTime - -func (n *NodesSetupStub) GetStartTime() int64 { - if n.GetStartTimeCalled != nil { - return n.GetStartTimeCalled() - } - return 0 -} - -// GetRoundDuration - -func (n *NodesSetupStub) GetRoundDuration() uint64 { - if n.GetRoundDurationCalled != nil { - return n.GetRoundDurationCalled() - } - return 0 -} - -// GetChainId - -func (n *NodesSetupStub) GetChainId() string { - if n.GetChainIdCalled != nil { - return n.GetChainIdCalled() - } - return "chainID" -} - -// GetMinTransactionVersion - -func (n *NodesSetupStub) GetMinTransactionVersion() uint32 { - if n.GetMinTransactionVersionCalled != nil { - return n.GetMinTransactionVersionCalled() - } - return 1 -} - -// GetShardConsensusGroupSize - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetShardConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() - } - return 0 -} - -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() - } - return 0 -} - -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() - } - return 0 -} - -// InitialNodesInfoForShard - -func (n *NodesSetupStub) InitialNodesInfoForShard(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { - if n.InitialNodesInfoForShardCalled != nil { - return n.InitialNodesInfoForShardCalled(shardId) - } - return nil, nil, nil -} - -// InitialNodesInfo - -func (n *NodesSetupStub) InitialNodesInfo() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { - if n.InitialNodesInfoCalled != nil { - return n.InitialNodesInfoCalled() - } - return nil, nil -} - -// IsInterfaceNil - -func (n *NodesSetupStub) IsInterfaceNil() bool { - return n == nil -} diff --git a/testscommon/genesisMocks/nodesSetupStub.go b/testscommon/genesisMocks/nodesSetupStub.go index 76d19af0aee..424fa54abe4 100644 --- a/testscommon/genesisMocks/nodesSetupStub.go +++ b/testscommon/genesisMocks/nodesSetupStub.go @@ -169,6 +169,7 @@ func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHan return nil } +// GetChainId - func (n *NodesSetupStub) GetChainId() string { if n.GetChainIdCalled != nil { return n.GetChainIdCalled() From 3819a876e9e98021cfcc563ffe416f37569a0e33 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 21 Mar 2023 12:33:16 +0200 Subject: [PATCH 447/958] FIX: Low waiting list edge case in stakingV4Step2 --- integrationTests/vm/staking/stakingV4_test.go | 137 ++++++++++++++++++ .../nodesCoordinator/hashValidatorShuffler.go | 9 +- 2 files changed, 142 insertions(+), 4 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 92ab77ff24a..9d0b6d911e0 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1155,3 +1155,140 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl epoch++ } } + +func TestStakingV4_NewlyStakedNodesInStakingV4Step2ShouldBeSentToWaitingIfListIsTooLow(t *testing.T) { + pubKeys := generateAddresses(0, 20) + + owner1 := "owner1" + owner1Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:4], + 0: pubKeys[4:8], + }, + WaitingBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[8:9], + 0: pubKeys[9:10], + }, + TotalStake: big.NewInt(20 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 2, + ShardConsensusGroupSize: 2, + MinNumberOfEligibleShardNodes: 4, + MinNumberOfEligibleMetaNodes: 4, + NumOfShards: 1, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 20, + NodesToShufflePerShard: 1, + }, + { + EpochEnable: stakingV4Step3EnableEpoch, + MaxNumNodes: 18, + NodesToShufflePerShard: 1, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + expectedNodesNum := &configNum{ + eligible: map[uint32]int{ + core.MetachainShardId: 4, + 0: 4, + }, + waiting: map[uint32]int{ + core.MetachainShardId: 1, + 0: 1, + }, + } + currNodesConfig := node.NodesConfig + checkConfig(t, expectedNodesNum, currNodesConfig) + + // Epoch = 0, before staking v4, owner2 stakes 2 nodes + // - maxNumNodes = 20 + // - activeNumNodes = 10 + // Newly staked nodes should be sent tu new list + owner2Nodes := pubKeys[12:14] + node.ProcessStake(t, map[string]*NodesRegisterData{ + "owner2": { + BLSKeys: owner2Nodes, + TotalStake: big.NewInt(2 * nodePrice), + }, + }) + currNodesConfig = node.NodesConfig + expectedNodesNum.new = 2 + checkConfig(t, expectedNodesNum, currNodesConfig) + requireSameSliceDifferentOrder(t, currNodesConfig.new, owner2Nodes) + + // Epoch = 1, staking v4 step 1 + // - maxNumNodes = 20 + // - activeNumNodes = 12 + // Owner2's new nodes should have been sent to waiting + node.Process(t, 5) + currNodesConfig = node.NodesConfig + expectedNodesNum.new = 0 + expectedNodesNum.waiting[0]++ + expectedNodesNum.waiting[core.MetachainShardId]++ + checkConfig(t, expectedNodesNum, currNodesConfig) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), owner2Nodes, 2) + + // Epoch = 1, before staking v4, owner3 stakes 2 nodes + // - maxNumNodes = 20 + // - activeNumNodes = 12 + // Newly staked nodes should be sent to auction list + owner3Nodes := pubKeys[15:17] + node.ProcessStake(t, map[string]*NodesRegisterData{ + "owner3": { + BLSKeys: owner3Nodes, + TotalStake: big.NewInt(2 * nodePrice), + }, + }) + currNodesConfig = node.NodesConfig + expectedNodesNum.auction = 2 + checkConfig(t, expectedNodesNum, currNodesConfig) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, owner3Nodes) + + // Epoch = 2, staking v4 step 2 + // - maxNumNodes = 20 + // - activeNumNodes = 14 + // Owner3's auction nodes should have been sent to waiting + node.Process(t, 5) + currNodesConfig = node.NodesConfig + expectedNodesNum.auction = 0 + expectedNodesNum.waiting[0]++ + expectedNodesNum.waiting[core.MetachainShardId]++ + checkConfig(t, expectedNodesNum, currNodesConfig) + requireSliceContainsNumOfElements(t, getAllPubKeys(currNodesConfig.waiting), owner3Nodes, 2) + + // During epochs 2-6, we will have: + // - activeNodes = 14 + // - maxNumNodes = 18-20 + // Since activeNodes < maxNumNodes, shuffled out nodes will always be sent directly to waiting list, instead of auction + epoch := uint32(2) + require.Equal(t, epoch, node.EpochStartTrigger.Epoch()) + + numOfShuffledOut := 2 + numRemainingEligible := 6 + numOfUnselectedNodesFromAuction := 0 + numOfSelectedNodesFromAuction := 0 + + prevNodesConfig := currNodesConfig + for epoch < 6 { + node.Process(t, 5) + + currNodesConfig = node.NodesConfig + checkConfig(t, expectedNodesNum, currNodesConfig) + checkShuffledOutNodes(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numRemainingEligible) + checkStakingV4EpochChangeFlow(t, currNodesConfig, prevNodesConfig, numOfShuffledOut, numOfUnselectedNodesFromAuction, numOfSelectedNodesFromAuction) + + prevNodesConfig = currNodesConfig + epoch++ + } +} diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index d2a4fc0d92b..98ab9d10e9e 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -314,7 +314,8 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { flagStakingV4Step2: arg.flagStakingV4Step2, } - if arg.flagStakingV4Step3 { + lowWaitingList := shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg) + if arg.flagStakingV4Step3 || lowWaitingList { log.Debug("distributing selected nodes from auction to waiting", "num auction nodes", len(arg.auction), "num waiting nodes", shuffledNodesCfg.numNewWaiting) @@ -325,7 +326,7 @@ func shuffleNodes(arg shuffleNodesArg) (*ResUpdateNodes, error) { } } - if shouldDistributeShuffledToWaiting(shuffledNodesCfg) { + if !arg.flagStakingV4Step2 || lowWaitingList { log.Debug("distributing shuffled out nodes to waiting", "num shuffled nodes", shuffledNodesCfg.numShuffled, "num waiting nodes", shuffledNodesCfg.numNewWaiting) @@ -599,9 +600,9 @@ func checkAndDistributeNewNodes( return nil } -func shouldDistributeShuffledToWaiting(shuffledNodesCfg *shuffledNodesConfig) bool { +func shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg *shuffledNodesConfig) bool { if !shuffledNodesCfg.flagStakingV4Step2 { - return true + return false } totalNewWaiting := shuffledNodesCfg.numNewWaiting + shuffledNodesCfg.numSelectedAuction From 91c3ad366a4ff2c35f6c3bdaa406d580b33f91c6 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 21 Mar 2023 14:56:08 +0200 Subject: [PATCH 448/958] FIX: After merge --- epochStart/bootstrap/baseStorageHandler.go | 2 + epochStart/bootstrap/metaStorageHandler.go | 4 +- .../bootstrap/metaStorageHandler_test.go | 2 +- epochStart/bootstrap/process.go | 8 +-- epochStart/bootstrap/shardStorageHandler.go | 4 +- .../bootstrap/shardStorageHandler_test.go | 5 -- go.mod | 2 +- go.sum | 3 +- integrationTests/testConsensusNode.go | 40 ++++++----- process/peer/validatorsProvider.go | 4 +- process/peer/validatorsProviderAuction.go | 4 +- process/peer/validatorsProvider_test.go | 67 ++++++++++--------- 12 files changed, 71 insertions(+), 74 deletions(-) diff --git a/epochStart/bootstrap/baseStorageHandler.go b/epochStart/bootstrap/baseStorageHandler.go index b2f6ee01b5a..91a9e2c2230 100644 --- a/epochStart/bootstrap/baseStorageHandler.go +++ b/epochStart/bootstrap/baseStorageHandler.go @@ -32,6 +32,8 @@ type StorageHandlerArgs struct { Uint64Converter typeConverters.Uint64ByteSliceConverter NodeTypeProvider NodeTypeProviderHandler NodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory + SnapshotsEnabled bool + ManagedPeersHolder common.ManagedPeersHolder } func checkNilArgs(args StorageHandlerArgs) error { diff --git a/epochStart/bootstrap/metaStorageHandler.go b/epochStart/bootstrap/metaStorageHandler.go index 4494106a52b..e575d035df2 100644 --- a/epochStart/bootstrap/metaStorageHandler.go +++ b/epochStart/bootstrap/metaStorageHandler.go @@ -38,8 +38,8 @@ func NewMetaStorageHandler(args StorageHandlerArgs) (*metaStorageHandler, error) CurrentEpoch: args.CurrentEpoch, StorageType: factory.BootstrapStorageService, CreateTrieEpochRootHashStorer: false, - SnapshotsEnabled: arg.SnapshotsEnabled, - ManagedPeersHolder: arg.ManagedPeersHolder, + SnapshotsEnabled: args.SnapshotsEnabled, + ManagedPeersHolder: args.ManagedPeersHolder, }, ) if err != nil { diff --git a/epochStart/bootstrap/metaStorageHandler_test.go b/epochStart/bootstrap/metaStorageHandler_test.go index a8762938a79..46a5e4a12d2 100644 --- a/epochStart/bootstrap/metaStorageHandler_test.go +++ b/epochStart/bootstrap/metaStorageHandler_test.go @@ -36,7 +36,7 @@ func createStorageHandlerArgs() StorageHandlerArgs { Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, - //managedPeersHolder := &testscommon.ManagedPeersHolderStub{} + ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, } } diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index 4dbdf73f854..10d49ce194b 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -769,8 +769,8 @@ func (e *epochStartBootstrap) requestAndProcessForMeta(peerMiniBlocks []*block.M Uint64Converter: e.coreComponentsHolder.Uint64ByteSliceConverter(), NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, - e.flagsConfig.SnapshotsEnabled, - e.cryptoComponentsHolder.ManagedPeersHolder(), + SnapshotsEnabled: e.flagsConfig.SnapshotsEnabled, + ManagedPeersHolder: e.cryptoComponentsHolder.ManagedPeersHolder(), } storageHandlerComponent, err := NewMetaStorageHandler(argsStorageHandler) if err != nil { @@ -940,8 +940,8 @@ func (e *epochStartBootstrap) requestAndProcessForShard(peerMiniBlocks []*block. Uint64Converter: e.coreComponentsHolder.Uint64ByteSliceConverter(), NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, - e.flagsConfig.SnapshotsEnabled, - e.cryptoComponentsHolder.ManagedPeersHolder(), + SnapshotsEnabled: e.flagsConfig.SnapshotsEnabled, + ManagedPeersHolder: e.cryptoComponentsHolder.ManagedPeersHolder(), } storageHandlerComponent, err := NewShardStorageHandler(argsStorageHandler) if err != nil { diff --git a/epochStart/bootstrap/shardStorageHandler.go b/epochStart/bootstrap/shardStorageHandler.go index 2319fd4d280..149cc14a20b 100644 --- a/epochStart/bootstrap/shardStorageHandler.go +++ b/epochStart/bootstrap/shardStorageHandler.go @@ -42,8 +42,8 @@ func NewShardStorageHandler(args StorageHandlerArgs) (*shardStorageHandler, erro CurrentEpoch: args.CurrentEpoch, StorageType: factory.BootstrapStorageService, CreateTrieEpochRootHashStorer: false, - SnapshotsEnabled: snapshotsEnabled, - ManagedPeersHolder: managedPeersHolder, + SnapshotsEnabled: args.SnapshotsEnabled, + ManagedPeersHolder: args.ManagedPeersHolder, }, ) if err != nil { diff --git a/epochStart/bootstrap/shardStorageHandler_test.go b/epochStart/bootstrap/shardStorageHandler_test.go index 2420b101187..f3ec11b4244 100644 --- a/epochStart/bootstrap/shardStorageHandler_test.go +++ b/epochStart/bootstrap/shardStorageHandler_test.go @@ -13,11 +13,6 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-core-go/data/typeConverters" - "github.com/multiversx/mx-chain-core-go/hashing" - "github.com/multiversx/mx-chain-core-go/marshal" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" diff --git a/go.mod b/go.mod index f3642ab5b86..c83a38ac1ef 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.11 github.com/multiversx/mx-chain-p2p-go v1.0.13 github.com/multiversx/mx-chain-storage-go v1.0.7 - github.com/multiversx/mx-chain-vm-common-go v1.3.37-0.20230207142116-40f047630376 + github.com/multiversx/mx-chain-vm-common-go v1.4.1-0.20230321123200-7ad640c0bb4b github.com/multiversx/mx-chain-vm-v1_2-go v1.2.50 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.51 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.77 diff --git a/go.sum b/go.sum index 04d06edd375..be90130e3f3 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,9 @@ github.com/multiversx/mx-chain-storage-go v1.0.7 h1:UqLo/OLTD3IHiE/TB/SEdNRV1GG2 github.com/multiversx/mx-chain-storage-go v1.0.7/go.mod h1:gtKoV32Cg2Uy8deHzF8Ud0qAl0zv92FvWgPSYIP0Zmg= github.com/multiversx/mx-chain-vm-common-go v1.3.36/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= github.com/multiversx/mx-chain-vm-common-go v1.3.37/go.mod h1:sZ2COLCxvf2GxAAJHGmGqWybObLtFuk2tZUyGqnMXE8= -github.com/multiversx/mx-chain-vm-common-go v1.4.0 h1:0i0cJZJOXGzqYzwtKFHSr2yGmnFAdizOuISK8HgsnYo= github.com/multiversx/mx-chain-vm-common-go v1.4.0/go.mod h1:odBJC92ANA8zLtPh/wwajUUGJOaS88F5QYGf0t8Wgzw= +github.com/multiversx/mx-chain-vm-common-go v1.4.1-0.20230321123200-7ad640c0bb4b h1:CpiZVqd/25eN0aLrbO3EjzVMMNhhE/scApP3mqdPsRs= +github.com/multiversx/mx-chain-vm-common-go v1.4.1-0.20230321123200-7ad640c0bb4b/go.mod h1:odBJC92ANA8zLtPh/wwajUUGJOaS88F5QYGf0t8Wgzw= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.50 h1:ScUq7/wq78vthMTQ6v5Ux1DvSMQMHxQ2Sl7aPP26q1w= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.50/go.mod h1:e3uYdgoKzs3puaznbmSjDcRisJc5Do4tpg7VqyYwoek= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.51 h1:axtp5/mpA+xYJ1cu4KtAGETV4t6v6/tNfQh0HCclBYY= diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 377bc74d112..b03f0eaad57 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -363,28 +363,26 @@ func (tcn *TestConsensusNode) initNodesCoordinator( cache storage.Cacher, ) { argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: consensusSize, - MetaConsensusGroupSize: consensusSize, - Marshalizer: TestMarshalizer, - Hasher: hasher, - Shuffler: &shardingMocks.NodeShufflerMock{}, - EpochStartNotifier: epochStartRegistrationHandler, - BootStorer: CreateMemUnit(), - NbShards: maxShards, - EligibleNodes: eligibleMap, - WaitingNodes: waitingMap, - SelfPublicKey: pkBytes, - ConsensusGroupCache: cache, - ShuffledOutHandler: &chainShardingMocks.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ - IsWaitingListFixFlagEnabledField: true, - }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ShardConsensusGroupSize: consensusSize, + MetaConsensusGroupSize: consensusSize, + Marshalizer: TestMarshalizer, + Hasher: hasher, + Shuffler: &shardingMocks.NodeShufflerMock{}, + EpochStartNotifier: epochStartRegistrationHandler, + BootStorer: CreateMemUnit(), + NbShards: maxShards, + EligibleNodes: eligibleMap, + WaitingNodes: waitingMap, + SelfPublicKey: pkBytes, + ConsensusGroupCache: cache, + ShuffledOutHandler: &chainShardingMocks.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, - ShardIDAsObserver: tcn.ShardCoordinator.SelfId(), + ShardIDAsObserver: tcn.ShardCoordinator.SelfId(), StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 14af4243ebf..056ccfa6ba7 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -253,7 +253,7 @@ func (vp *validatorsProvider) createValidatorApiResponseMapFromValidatorInfoMap( newCache := make(map[string]*state.ValidatorApiResponse) for _, validatorInfo := range allNodes.GetAllValidatorsInfo() { - strKey := vp.validatorPubKeyConverter.Encode(validatorInfo.GetPublicKey()) + strKey := vp.validatorPubKeyConverter.SilentEncode(validatorInfo.GetPublicKey(), log) newCache[strKey] = &state.ValidatorApiResponse{ NumLeaderSuccess: validatorInfo.GetLeaderSuccess(), NumLeaderFailure: validatorInfo.GetLeaderFailure(), @@ -283,7 +283,7 @@ func (vp *validatorsProvider) aggregateLists( ) { for shardID, shardValidators := range validatorsMap { for _, val := range shardValidators { - encodedKey := vp.validatorPubKeyConverter.Encode(val) + encodedKey := vp.validatorPubKeyConverter.SilentEncode(val, log) foundInTrieValidator, ok := newCache[encodedKey] peerType := string(currentList) diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index 6234a22cfef..b7df20f12bc 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -163,7 +163,7 @@ func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse( for ownerPubKey, ownerData := range vp.stakingDataProvider.GetOwnersData() { numAuctionNodes := len(ownerData.AuctionList) if numAuctionNodes > 0 { - ownerEncodedPubKey := vp.addressPubKeyConverter.Encode([]byte(ownerPubKey)) + ownerEncodedPubKey := vp.addressPubKeyConverter.SilentEncode([]byte(ownerPubKey), log) auctionValidator := &common.AuctionListValidatorAPIResponse{ Owner: ownerEncodedPubKey, NumStakedNodes: ownerData.NumStakedNodes, @@ -191,7 +191,7 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( numOwnerQualifiedNodes := int64(0) for _, nodeInAuction := range ownerData.AuctionList { auctionNode := &common.AuctionNode{ - BlsKey: vp.validatorPubKeyConverter.Encode(nodeInAuction.GetPublicKey()), + BlsKey: vp.validatorPubKeyConverter.SilentEncode(nodeInAuction.GetPublicKey(), log), Qualified: false, } if ownerData.Qualified && contains(selectedNodes, nodeInAuction) { diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 40679a94d6b..b92f8979f45 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -21,6 +21,7 @@ import ( "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/pkg/errors" @@ -243,7 +244,7 @@ func TestValidatorsProvider_UpdateCache_WithError(t *testing.T) { cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, refreshCache: nil, lock: sync.RWMutex{}, - validatorPubKeyConverter: mock.NewPubkeyConverterMock(32), + validatorPubKeyConverter: testscommon.NewPubkeyConverterMock(32), } vsp.updateCache() @@ -319,7 +320,7 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { cache: nil, cacheRefreshIntervalDuration: arg.CacheRefreshIntervalDurationInSec, refreshCache: nil, - validatorPubKeyConverter: mock.NewPubkeyConverterMock(32), + validatorPubKeyConverter: testscommon.NewPubkeyConverterMock(32), lock: sync.RWMutex{}, } @@ -327,14 +328,14 @@ func TestValidatorsProvider_UpdateCache(t *testing.T) { assert.NotNil(t, vsp.cache) assert.Equal(t, len(validatorsMap.GetShardValidatorsInfoMap()[initialShardId]), len(vsp.cache)) - encodedKey := arg.ValidatorPubKeyConverter.Encode(pk) + encodedKey, _ := arg.ValidatorPubKeyConverter.Encode(pk) assert.NotNil(t, vsp.cache[encodedKey]) assert.Equal(t, initialList, vsp.cache[encodedKey].ValidatorStatus) assert.Equal(t, initialShardId, vsp.cache[encodedKey].ShardId) } func TestValidatorsProvider_aggregatePType_equal(t *testing.T) { - pubKeyConverter := mock.NewPubkeyConverterMock(32) + pubKeyConverter := testscommon.NewPubkeyConverterMock(32) pkInactive := []byte("pk1") trieInctiveShardId := uint32(0) inactiveList := string(common.InactiveList) @@ -345,9 +346,9 @@ func TestValidatorsProvider_aggregatePType_equal(t *testing.T) { trieLeavingShardId := uint32(2) leavingList := string(common.LeavingList) - encodedEligible := pubKeyConverter.Encode(pkEligible) - encondedInactive := pubKeyConverter.Encode(pkInactive) - encodedLeaving := pubKeyConverter.Encode(pkLeaving) + encodedEligible, _ := pubKeyConverter.Encode(pkEligible) + encondedInactive, _ := pubKeyConverter.Encode(pkInactive) + encodedLeaving, _ := pubKeyConverter.Encode(pkLeaving) cache := make(map[string]*state.ValidatorApiResponse) cache[encondedInactive] = &state.ValidatorApiResponse{ValidatorStatus: inactiveList, ShardId: trieInctiveShardId} cache[encodedEligible] = &state.ValidatorApiResponse{ValidatorStatus: eligibleList, ShardId: trieEligibleShardId} @@ -426,7 +427,7 @@ func TestValidatorsProvider_createCache(t *testing.T) { List: newList, }) arg := createDefaultValidatorsProviderArg() - pubKeyConverter := mock.NewPubkeyConverterMock(32) + pubKeyConverter := testscommon.NewPubkeyConverterMock(32) vsp := validatorsProvider{ nodesCoordinator: arg.NodesCoordinator, validatorStatistics: arg.ValidatorStatistics, @@ -440,22 +441,22 @@ func TestValidatorsProvider_createCache(t *testing.T) { assert.NotNil(t, cache) - encodedPkEligible := pubKeyConverter.Encode(pkEligible) + encodedPkEligible, _ := pubKeyConverter.Encode(pkEligible) assert.NotNil(t, cache[encodedPkEligible]) assert.Equal(t, eligibleList, cache[encodedPkEligible].ValidatorStatus) assert.Equal(t, eligibleShardId, cache[encodedPkEligible].ShardId) - encodedPkWaiting := pubKeyConverter.Encode(pkWaiting) + encodedPkWaiting, _ := pubKeyConverter.Encode(pkWaiting) assert.NotNil(t, cache[encodedPkWaiting]) assert.Equal(t, waitingList, cache[encodedPkWaiting].ValidatorStatus) assert.Equal(t, waitingShardId, cache[encodedPkWaiting].ShardId) - encodedPkLeaving := pubKeyConverter.Encode(pkLeaving) + encodedPkLeaving, _ := pubKeyConverter.Encode(pkLeaving) assert.NotNil(t, cache[encodedPkLeaving]) assert.Equal(t, leavingList, cache[encodedPkLeaving].ValidatorStatus) assert.Equal(t, leavingShardId, cache[encodedPkLeaving].ShardId) - encodedPkNew := pubKeyConverter.Encode(pkNew) + encodedPkNew, _ := pubKeyConverter.Encode(pkNew) assert.NotNil(t, cache[encodedPkNew]) assert.Equal(t, newList, cache[encodedPkNew].ValidatorStatus) assert.Equal(t, newShardId, cache[encodedPkNew].ShardId) @@ -510,12 +511,12 @@ func TestValidatorsProvider_createCache_combined(t *testing.T) { cache := vsp.createNewCache(0, validatorsMap) - encodedPkEligible := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) + encodedPkEligible, _ := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) assert.NotNil(t, cache[encodedPkEligible]) assert.Equal(t, eligibleList, cache[encodedPkEligible].ValidatorStatus) assert.Equal(t, nodesCoordinatorEligibleShardId, cache[encodedPkEligible].ShardId) - encodedPkLeavingInTrie := arg.ValidatorPubKeyConverter.Encode(pkLeavingInTrie) + encodedPkLeavingInTrie, _ := arg.ValidatorPubKeyConverter.Encode(pkLeavingInTrie) computedPeerType := fmt.Sprintf(common.CombinedPeerType, common.EligibleList, common.LeavingList) assert.NotNil(t, cache[encodedPkLeavingInTrie]) assert.Equal(t, computedPeerType, cache[encodedPkLeavingInTrie].ValidatorStatus) @@ -591,7 +592,7 @@ func TestValidatorsProvider_CallsUpdateCacheOnEpochChange(t *testing.T) { arg.ValidatorStatistics = validatorStatisticsProcessor vsp, _ := NewValidatorsProvider(arg) - encodedEligible := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) + encodedEligible, _ := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) assert.Equal(t, 0, len(vsp.GetCache())) // nothing in cache epochStartNotifier.NotifyAll(&block.Header{Nonce: 1, ShardID: 2, Round: 3}) time.Sleep(arg.CacheRefreshIntervalDurationInSec) @@ -629,7 +630,7 @@ func TestValidatorsProvider_DoesntCallUpdateUpdateCacheWithoutRequests(t *testin arg.ValidatorStatistics = validatorStatisticsProcessor vsp, _ := NewValidatorsProvider(arg) - encodedEligible := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) + encodedEligible, _ := arg.ValidatorPubKeyConverter.Encode(pkEligibleInTrie) assert.Equal(t, 0, len(vsp.GetCache())) // nothing in cache time.Sleep(arg.CacheRefreshIntervalDurationInSec) assert.Equal(t, 0, len(vsp.GetCache())) // nothing in cache @@ -946,91 +947,91 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { expectedList := []*common.AuctionListValidatorAPIResponse{ { - Owner: args.AddressPubKeyConverter.Encode([]byte(owner3)), + Owner: args.AddressPubKeyConverter.SilentEncode([]byte(owner3), log), NumStakedNodes: 2, TotalTopUp: "4000", TopUpPerNode: "2000", QualifiedTopUp: "4000", AuctionList: []*common.AuctionNode{ { - BlsKey: args.ValidatorPubKeyConverter.Encode(v5.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v5.PublicKey, log), Qualified: true, }, { - BlsKey: args.ValidatorPubKeyConverter.Encode(v6.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v6.PublicKey, log), Qualified: false, }, }, }, { - Owner: args.AddressPubKeyConverter.Encode([]byte(owner1)), + Owner: args.AddressPubKeyConverter.SilentEncode([]byte(owner1), log), NumStakedNodes: 3, TotalTopUp: "7500", TopUpPerNode: "2500", QualifiedTopUp: "2500", AuctionList: []*common.AuctionNode{ { - BlsKey: args.ValidatorPubKeyConverter.Encode(v1.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v1.PublicKey, log), Qualified: true, }, { - BlsKey: args.ValidatorPubKeyConverter.Encode(v2.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v2.PublicKey, log), Qualified: true, }, }, }, { - Owner: args.AddressPubKeyConverter.Encode([]byte(owner2)), + Owner: args.AddressPubKeyConverter.SilentEncode([]byte(owner2), log), NumStakedNodes: 3, TotalTopUp: "3000", TopUpPerNode: "1000", QualifiedTopUp: "1500", AuctionList: []*common.AuctionNode{ { - BlsKey: args.ValidatorPubKeyConverter.Encode(v3.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v3.PublicKey, log), Qualified: true, }, { - BlsKey: args.ValidatorPubKeyConverter.Encode(v4.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v4.PublicKey, log), Qualified: false, }, }, }, { - Owner: args.AddressPubKeyConverter.Encode([]byte(owner7)), + Owner: args.AddressPubKeyConverter.SilentEncode([]byte(owner7), log), NumStakedNodes: 1, TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", AuctionList: []*common.AuctionNode{ { - BlsKey: args.ValidatorPubKeyConverter.Encode(v12.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v12.PublicKey, log), Qualified: true, }, }, }, { - Owner: args.AddressPubKeyConverter.Encode([]byte(owner6)), + Owner: args.AddressPubKeyConverter.SilentEncode([]byte(owner6), log), NumStakedNodes: 1, TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", AuctionList: []*common.AuctionNode{ { - BlsKey: args.ValidatorPubKeyConverter.Encode(v11.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v11.PublicKey, log), Qualified: false, }, }, }, { - Owner: args.AddressPubKeyConverter.Encode([]byte(owner4)), + Owner: args.AddressPubKeyConverter.SilentEncode([]byte(owner4), log), NumStakedNodes: 3, TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", AuctionList: []*common.AuctionNode{ { - BlsKey: args.ValidatorPubKeyConverter.Encode(v7.PublicKey), + BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v7.PublicKey, log), Qualified: false, }, }, @@ -1091,8 +1092,8 @@ func createDefaultValidatorsProviderArg() ArgValidatorsProvider { }, }, MaxRating: 100, - ValidatorPubKeyConverter: mock.NewPubkeyConverterMock(32), - AddressPubKeyConverter: mock.NewPubkeyConverterMock(32), + ValidatorPubKeyConverter: testscommon.NewPubkeyConverterMock(32), + AddressPubKeyConverter: testscommon.NewPubkeyConverterMock(32), AuctionListSelector: &stakingcommon.AuctionListSelectorStub{}, } } From 26f52496c177e67f11687ff4b517a03cbed2c787 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 3 Apr 2023 15:40:33 +0300 Subject: [PATCH 449/958] FIX: Typo --- integrationTests/vm/staking/stakingV4_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 9d0b6d911e0..aca81f1eca1 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1214,7 +1214,7 @@ func TestStakingV4_NewlyStakedNodesInStakingV4Step2ShouldBeSentToWaitingIfListIs // Epoch = 0, before staking v4, owner2 stakes 2 nodes // - maxNumNodes = 20 // - activeNumNodes = 10 - // Newly staked nodes should be sent tu new list + // Newly staked nodes should be sent to new list owner2Nodes := pubKeys[12:14] node.ProcessStake(t, map[string]*NodesRegisterData{ "owner2": { From 2834cda55b8286ecce59654181e92ff95d724e91 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 31 Aug 2023 18:08:11 +0300 Subject: [PATCH 450/958] - started work on the testOnlyProcessingNode --- .../testOnlyProcessingNode.go | 45 +++++++++++++++++++ .../testOnlyProcessingNode_test.go | 36 +++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 node/processingOnlyNode/testOnlyProcessingNode.go create mode 100644 node/processingOnlyNode/testOnlyProcessingNode_test.go diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go new file mode 100644 index 00000000000..560aed4df86 --- /dev/null +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -0,0 +1,45 @@ +package processingOnlyNode + +import ( + coreData "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/hashing/blake2b" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/sharding" +) + +// ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function +type ArgsTestOnlyProcessingNode struct { + NumShards uint32 + ShardID uint32 +} + +type testOnlyProcessingNode struct { + Marshaller coreData.Marshaller + Hasher coreData.Hasher + ShardCoordinator sharding.Coordinator +} + +// NewTestOnlyProcessingNode creates a new instance of a node that is able to only process transactions +func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProcessingNode, error) { + instance := &testOnlyProcessingNode{} + + err := instance.addBasicComponents(args) + if err != nil { + return nil, err + } + + return instance, nil +} + +func (node *testOnlyProcessingNode) addBasicComponents(args ArgsTestOnlyProcessingNode) error { + node.Marshaller = &marshal.GogoProtoMarshalizer{} + node.Hasher = blake2b.NewBlake2b() + + var err error + node.ShardCoordinator, err = sharding.NewMultiShardCoordinator(args.ShardID, args.NumShards) + if err != nil { + return err + } + + return nil +} diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/processingOnlyNode/testOnlyProcessingNode_test.go new file mode 100644 index 00000000000..f31eb876e6e --- /dev/null +++ b/node/processingOnlyNode/testOnlyProcessingNode_test.go @@ -0,0 +1,36 @@ +package processingOnlyNode + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func createMockArgsTestOnlyProcessingNode() ArgsTestOnlyProcessingNode { + return ArgsTestOnlyProcessingNode{ + NumShards: 0, + ShardID: 3, + } +} + +func TestNewTestOnlyProcessingNode(t *testing.T) { + t.Parallel() + + t.Run("invalid shard configuration should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode() + args.ShardID = args.NumShards + node, err := NewTestOnlyProcessingNode(args) + assert.NotNil(t, err) + assert.Nil(t, node) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode() + node, err := NewTestOnlyProcessingNode(args) + assert.Nil(t, err) + assert.NotNil(t, node) + }) +} From 1dea5602b243449fb661b27482b1e4260c57044a Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 1 Sep 2023 02:33:11 +0300 Subject: [PATCH 451/958] - added more components --- node/processingOnlyNode/configLoaders.go | 60 ++++++ node/processingOnlyNode/memoryComponents.go | 19 ++ .../testOnlyProcessingNode.go | 193 ++++++++++++++++-- .../testOnlyProcessingNode_test.go | 30 ++- 4 files changed, 285 insertions(+), 17 deletions(-) create mode 100644 node/processingOnlyNode/configLoaders.go create mode 100644 node/processingOnlyNode/memoryComponents.go diff --git a/node/processingOnlyNode/configLoaders.go b/node/processingOnlyNode/configLoaders.go new file mode 100644 index 00000000000..3de9d7569ed --- /dev/null +++ b/node/processingOnlyNode/configLoaders.go @@ -0,0 +1,60 @@ +package processingOnlyNode + +import ( + "os" + "path" + "strconv" + "strings" + + "github.com/pelletier/go-toml" +) + +// LoadConfigFromFile will try to load the config from the specified file +func LoadConfigFromFile(filename string, config interface{}) error { + data, err := os.ReadFile(filename) + if err != nil { + return err + } + + err = toml.Unmarshal(data, config) + + return err +} + +// GetLatestGasScheduleFilename will parse the provided path and get the latest gas schedule filename +func GetLatestGasScheduleFilename(directory string) (string, error) { + entries, err := os.ReadDir(directory) + if err != nil { + return "", err + } + + extension := ".toml" + versionMarker := "V" + + highestVersion := 0 + filename := "" + for _, entry := range entries { + if entry.IsDir() { + continue + } + + name := entry.Name() + splt := strings.Split(name, versionMarker) + if len(splt) != 2 { + continue + } + + versionAsString := splt[1][:len(splt[1])-len(extension)] + number, errConversion := strconv.Atoi(versionAsString) + if errConversion != nil { + continue + } + + if number > highestVersion { + highestVersion = number + filename = name + } + } + + return path.Join(directory, filename), nil +} diff --git a/node/processingOnlyNode/memoryComponents.go b/node/processingOnlyNode/memoryComponents.go new file mode 100644 index 00000000000..7dd8d43a3e6 --- /dev/null +++ b/node/processingOnlyNode/memoryComponents.go @@ -0,0 +1,19 @@ +package processingOnlyNode + +import ( + "github.com/multiversx/mx-chain-go/storage" + "github.com/multiversx/mx-chain-go/storage/database" + "github.com/multiversx/mx-chain-go/storage/storageunit" +) + +// CreateMemUnit creates a new in-memory storage unit +func CreateMemUnit() storage.Storer { + capacity := uint32(10) + shards := uint32(1) + sizeInBytes := uint64(0) + cache, _ := storageunit.NewCache(storageunit.CacheConfig{Type: storageunit.LRUCache, Capacity: capacity, Shards: shards, SizeInBytes: sizeInBytes}) + persist, _ := database.NewlruDB(100000) + unit, _ := storageunit.NewStorageUnit(cache, persist) + + return unit +} diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index 560aed4df86..e5ef25123d8 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -1,29 +1,94 @@ package processingOnlyNode import ( + "sync" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/versioning" coreData "github.com/multiversx/mx-chain-core-go/data" - "github.com/multiversx/mx-chain-core-go/hashing/blake2b" + hashingFactory "github.com/multiversx/mx-chain-core-go/hashing/factory" "github.com/multiversx/mx-chain-core-go/marshal" + marshalFactory "github.com/multiversx/mx-chain-core-go/marshal/factory" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/enablers" + "github.com/multiversx/mx-chain-go/common/factory" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever" + dataRetrieverFactory "github.com/multiversx/mx-chain-go/dataRetriever/factory" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/process/block/postprocess" + "github.com/multiversx/mx-chain-go/process/economics" + "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/storage" + storageFactory "github.com/multiversx/mx-chain-go/storage/factory" ) // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function type ArgsTestOnlyProcessingNode struct { - NumShards uint32 - ShardID uint32 + Config config.Config + EnableEpochsConfig config.EnableEpochs + EconomicsConfig config.EconomicsConfig + GasScheduleFilename string + WorkingDir string + NumShards uint32 + ShardID uint32 } type testOnlyProcessingNode struct { - Marshaller coreData.Marshaller - Hasher coreData.Hasher - ShardCoordinator sharding.Coordinator + RoundNotifier process.RoundNotifier + EpochNotifier process.EpochNotifier + WasmerChangeLocker common.Locker + ArgumentsParser process.ArgumentsParser + TxVersionChecker process.TxVersionCheckerHandler + + Marshaller marshal.Marshalizer + Hasher coreData.Hasher + ShardCoordinator sharding.Coordinator + TransactionFeeHandler process.TransactionFeeHandler + AddressPubKeyConverter core.PubkeyConverter + ValidatorPubKeyConverter core.PubkeyConverter + EnableEpochsHandler common.EnableEpochsHandler + PathHandler storage.PathManagerHandler + + GasScheduleNotifier core.GasScheduleNotifier + BuiltinFunctionsCostHandler economics.BuiltInFunctionsCostHandler + EconomicsData process.EconomicsDataHandler + DataPool dataRetriever.PoolsHolder } // NewTestOnlyProcessingNode creates a new instance of a node that is able to only process transactions func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProcessingNode, error) { - instance := &testOnlyProcessingNode{} + instance := &testOnlyProcessingNode{ + RoundNotifier: forking.NewGenericRoundNotifier(), + EpochNotifier: forking.NewGenericEpochNotifier(), + WasmerChangeLocker: &sync.RWMutex{}, + ArgumentsParser: smartContract.NewArgumentParser(), + TxVersionChecker: versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion), + } + + err := instance.createBasicComponents(args) + if err != nil { + return nil, err + } + + err = instance.createGasScheduleNotifier(args) + if err != nil { + return nil, err + } + + err = instance.createBuiltinFunctionsCostHandler() + if err != nil { + return nil, err + } + + err = instance.createEconomicsHandler(args) + if err != nil { + return nil, err + } - err := instance.addBasicComponents(args) + err = instance.createDataPool(args) if err != nil { return nil, err } @@ -31,15 +96,119 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return instance, nil } -func (node *testOnlyProcessingNode) addBasicComponents(args ArgsTestOnlyProcessingNode) error { - node.Marshaller = &marshal.GogoProtoMarshalizer{} - node.Hasher = blake2b.NewBlake2b() - +func (node *testOnlyProcessingNode) createBasicComponents(args ArgsTestOnlyProcessingNode) error { var err error + + node.Marshaller, err = marshalFactory.NewMarshalizer(args.Config.Marshalizer.Type) + if err != nil { + return err + } + + node.Hasher, err = hashingFactory.NewHasher(args.Config.Hasher.Type) + if err != nil { + return err + } + node.ShardCoordinator, err = sharding.NewMultiShardCoordinator(args.ShardID, args.NumShards) if err != nil { return err } + node.TransactionFeeHandler, err = postprocess.NewFeeAccumulator() + if err != nil { + return err + } + + node.ValidatorPubKeyConverter, err = factory.NewPubkeyConverter(args.Config.ValidatorPubkeyConverter) + if err != nil { + return err + } + + node.AddressPubKeyConverter, err = factory.NewPubkeyConverter(args.Config.AddressPubkeyConverter) + if err != nil { + return err + } + + node.EnableEpochsHandler, err = enablers.NewEnableEpochsHandler(args.EnableEpochsConfig, node.EpochNotifier) + if err != nil { + return err + } + + node.PathHandler, err = storageFactory.CreatePathManager( + storageFactory.ArgCreatePathManager{ + WorkingDir: args.WorkingDir, + ChainID: args.Config.GeneralSettings.ChainID, + }, + ) + if err != nil { + return err + } + return nil } + +func (node *testOnlyProcessingNode) createGasScheduleNotifier(args ArgsTestOnlyProcessingNode) error { + var err error + + argsGasSchedule := forking.ArgsNewGasScheduleNotifier{ + GasScheduleConfig: config.GasScheduleConfig{ + GasScheduleByEpochs: []config.GasScheduleByEpochs{ + { + StartEpoch: 0, + FileName: args.GasScheduleFilename, + }, + }, + }, + ConfigDir: "", + EpochNotifier: node.EpochNotifier, + WasmVMChangeLocker: node.WasmerChangeLocker, + } + node.GasScheduleNotifier, err = forking.NewGasScheduleNotifier(argsGasSchedule) + + return err +} + +func (node *testOnlyProcessingNode) createBuiltinFunctionsCostHandler() error { + var err error + + args := &economics.ArgsBuiltInFunctionCost{ + GasSchedule: node.GasScheduleNotifier, + ArgsParser: node.ArgumentsParser, + } + + node.BuiltinFunctionsCostHandler, err = economics.NewBuiltInFunctionsCost(args) + + return err +} + +func (node *testOnlyProcessingNode) createEconomicsHandler(args ArgsTestOnlyProcessingNode) error { + var err error + + argsEconomicsHandler := economics.ArgsNewEconomicsData{ + TxVersionChecker: node.TxVersionChecker, + BuiltInFunctionsCostHandler: node.BuiltinFunctionsCostHandler, + Economics: &args.EconomicsConfig, + EpochNotifier: node.EpochNotifier, + EnableEpochsHandler: node.EnableEpochsHandler, + } + + node.EconomicsData, err = economics.NewEconomicsData(argsEconomicsHandler) + + return err +} + +func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNode) error { + var err error + + argsDataPool := dataRetrieverFactory.ArgsDataPool{ + Config: &args.Config, + EconomicsData: node.EconomicsData, + ShardCoordinator: node.ShardCoordinator, + Marshalizer: node.Marshaller, + PathManager: node.PathHandler, + } + + node.DataPool, err = dataRetrieverFactory.NewDataPoolFromConfig(argsDataPool) + + return err +} diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/processingOnlyNode/testOnlyProcessingNode_test.go index f31eb876e6e..b22f4e0bdeb 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode_test.go +++ b/node/processingOnlyNode/testOnlyProcessingNode_test.go @@ -3,13 +3,33 @@ package processingOnlyNode import ( "testing" + "github.com/multiversx/mx-chain-go/config" "github.com/stretchr/testify/assert" ) -func createMockArgsTestOnlyProcessingNode() ArgsTestOnlyProcessingNode { +const pathForMainConfig = "../../cmd/node/config/config.toml" +const pathForEconomicsConfig = "../../cmd/node/config/economics.toml" +const pathForGasSchedules = "../../cmd/node/config/gasSchedules" + +func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { + mainConfig := config.Config{} + err := LoadConfigFromFile(pathForMainConfig, &mainConfig) + assert.Nil(t, err) + + economicsConfig := config.EconomicsConfig{} + err = LoadConfigFromFile(pathForEconomicsConfig, &economicsConfig) + assert.Nil(t, err) + + gasScheduleName, err := GetLatestGasScheduleFilename(pathForGasSchedules) + assert.Nil(t, err) + return ArgsTestOnlyProcessingNode{ - NumShards: 0, - ShardID: 3, + Config: mainConfig, + EnableEpochsConfig: config.EnableEpochs{}, + EconomicsConfig: economicsConfig, + GasScheduleFilename: gasScheduleName, + NumShards: 0, + ShardID: 3, } } @@ -19,7 +39,7 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { t.Run("invalid shard configuration should error", func(t *testing.T) { t.Parallel() - args := createMockArgsTestOnlyProcessingNode() + args := createMockArgsTestOnlyProcessingNode(t) args.ShardID = args.NumShards node, err := NewTestOnlyProcessingNode(args) assert.NotNil(t, err) @@ -28,7 +48,7 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { t.Run("should work", func(t *testing.T) { t.Parallel() - args := createMockArgsTestOnlyProcessingNode() + args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) assert.Nil(t, err) assert.NotNil(t, node) From 48f6e6ba8b5ce02210f4461b1aaacf317ff18034 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 5 Sep 2023 16:09:52 +0300 Subject: [PATCH 452/958] initialize core components --- node/processingOnlyNode/coreComponents.go | 377 ++++++++++++++++++ node/processingOnlyNode/storageService.go | 31 ++ .../testOnlyProcessingNode.go | 185 +++------ .../testOnlyProcessingNode_test.go | 4 +- 4 files changed, 456 insertions(+), 141 deletions(-) create mode 100644 node/processingOnlyNode/coreComponents.go create mode 100644 node/processingOnlyNode/storageService.go diff --git a/node/processingOnlyNode/coreComponents.go b/node/processingOnlyNode/coreComponents.go new file mode 100644 index 00000000000..345b5587b14 --- /dev/null +++ b/node/processingOnlyNode/coreComponents.go @@ -0,0 +1,377 @@ +package processingOnlyNode + +import ( + "bytes" + "sync" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/alarm" + "github.com/multiversx/mx-chain-core-go/core/nodetype" + "github.com/multiversx/mx-chain-core-go/core/versioning" + "github.com/multiversx/mx-chain-core-go/core/watchdog" + "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-core-go/data/typeConverters" + "github.com/multiversx/mx-chain-core-go/data/typeConverters/uint64ByteSlice" + "github.com/multiversx/mx-chain-core-go/hashing" + hashingFactory "github.com/multiversx/mx-chain-core-go/hashing/factory" + "github.com/multiversx/mx-chain-core-go/marshal" + marshalFactory "github.com/multiversx/mx-chain-core-go/marshal/factory" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/enablers" + factoryPubKey "github.com/multiversx/mx-chain-go/common/factory" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/epochStart/notifier" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/ntp" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/process/economics" + "github.com/multiversx/mx-chain-go/process/smartContract" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/statusHandler" + "github.com/multiversx/mx-chain-go/storage" + storageFactory "github.com/multiversx/mx-chain-go/storage/factory" +) + +type coreComponentsHolder struct { + internalMarshaller marshal.Marshalizer + txMarshaller marshal.Marshalizer + vmMarshaller marshal.Marshalizer + hasher hashing.Hasher + txSignHasher hashing.Hasher + uint64SliceConverter typeConverters.Uint64ByteSliceConverter + addressPubKeyConverter core.PubkeyConverter + validatorPubKeyConverter core.PubkeyConverter + pathHandler storage.PathManagerHandler + watchdog core.WatchdogTimer + alarmScheduler core.TimersScheduler + syncTimer ntp.SyncTimer + roundHandler consensus.RoundHandler + economicsData process.EconomicsDataHandler + apiEconomicsData process.EconomicsDataHandler + ratingsData process.RatingsInfoHandler + rater sharding.PeerAccountListAndRatingHandler + genesisNodesSetup sharding.GenesisNodesSetupHandler + nodesShuffler nodesCoordinator.NodesShuffler + epochNotifier process.EpochNotifier + enableRoundsHandler process.EnableRoundsHandler + roundNotifier process.RoundNotifier + epochStartNotifierWithConfirm factory.EpochStartNotifierWithConfirm + chanStopNodeProcess chan endProcess.ArgEndProcess + genesisTime time.Time + chainID string + minTransactionVersion uint32 + txVersionChecker process.TxVersionCheckerHandler + encodedAddressLen uint32 + nodeTypeProvider core.NodeTypeProviderHandler + wasmVMChangeLocker common.Locker + processStatusHandler common.ProcessStatusHandler + hardforkTriggerPubKey []byte + enableEpochsHandler common.EnableEpochsHandler +} + +type ArgsCoreComponentsHolder struct { + Cfg config.Config + EnableEpochsConfig config.EnableEpochs + RoundsConfig config.RoundConfig + EconomicsConfig config.EconomicsConfig + ChanStopNodeProcess chan endProcess.ArgEndProcess + GasScheduleFilename string + NumShards uint32 + WorkingDir string +} + +func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComponentsHolder, error) { + var err error + instance := &coreComponentsHolder{} + + instance.internalMarshaller, err = marshalFactory.NewMarshalizer(args.Cfg.Marshalizer.Type) + if err != nil { + return nil, err + } + instance.txMarshaller, err = marshalFactory.NewMarshalizer(args.Cfg.TxSignMarshalizer.Type) + if err != nil { + return nil, err + } + instance.vmMarshaller, err = marshalFactory.NewMarshalizer(args.Cfg.VmMarshalizer.Type) + if err != nil { + return nil, err + } + instance.hasher, err = hashingFactory.NewHasher(args.Cfg.Hasher.Type) + if err != nil { + return nil, err + } + instance.txSignHasher, err = hashingFactory.NewHasher(args.Cfg.TxSignHasher.Type) + if err != nil { + return nil, err + } + instance.uint64SliceConverter = uint64ByteSlice.NewBigEndianConverter() + instance.addressPubKeyConverter, err = factoryPubKey.NewPubkeyConverter(args.Cfg.AddressPubkeyConverter) + if err != nil { + return nil, err + } + instance.validatorPubKeyConverter, err = factoryPubKey.NewPubkeyConverter(args.Cfg.ValidatorPubkeyConverter) + if err != nil { + return nil, err + } + + instance.pathHandler, err = storageFactory.CreatePathManager( + storageFactory.ArgCreatePathManager{ + WorkingDir: args.WorkingDir, + ChainID: args.Cfg.GeneralSettings.ChainID, + }, + ) + + // TODO check if we need the real watchdog + instance.watchdog = &watchdog.DisabledWatchdog{} + // TODO check if we need the real alarm scheduler + instance.alarmScheduler = alarm.NewAlarmScheduler() + // TODO check if we need the real sync time also this component need to be started + instance.syncTimer = ntp.NewSyncTime(args.Cfg.NTPConfig, nil) + // TODO discuss with Iulian about the round handler + //instance.roundHandler + + instance.wasmVMChangeLocker = &sync.RWMutex{} + instance.txVersionChecker = versioning.NewTxVersionChecker(args.Cfg.GeneralSettings.MinTransactionVersion) + instance.epochNotifier = forking.NewGenericEpochNotifier() + instance.enableEpochsHandler, err = enablers.NewEnableEpochsHandler(args.EnableEpochsConfig, instance.epochNotifier) + if err != nil { + return nil, err + } + + argsGasSchedule := forking.ArgsNewGasScheduleNotifier{ + GasScheduleConfig: config.GasScheduleConfig{ + GasScheduleByEpochs: []config.GasScheduleByEpochs{ + { + StartEpoch: 0, + FileName: args.GasScheduleFilename, + }, + }, + }, + ConfigDir: "", + EpochNotifier: instance.epochNotifier, + WasmVMChangeLocker: instance.wasmVMChangeLocker, + } + gasScheduleNotifier, err := forking.NewGasScheduleNotifier(argsGasSchedule) + if err != nil { + return nil, err + } + + builtInCostHandler, err := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ + ArgsParser: smartContract.NewArgumentParser(), + GasSchedule: gasScheduleNotifier, + }) + if err != nil { + return nil, err + } + + argsEconomicsHandler := economics.ArgsNewEconomicsData{ + TxVersionChecker: instance.txVersionChecker, + BuiltInFunctionsCostHandler: builtInCostHandler, + Economics: &args.EconomicsConfig, + EpochNotifier: instance.epochNotifier, + EnableEpochsHandler: instance.enableEpochsHandler, + } + + instance.economicsData, err = economics.NewEconomicsData(argsEconomicsHandler) + if err != nil { + return nil, err + } + instance.apiEconomicsData = instance.economicsData + + // TODO check if we need this + instance.ratingsData = nil + instance.rater = nil + + instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.WorkingDir, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) + if err != nil { + return nil, err + } + // TODO check if we need nodes shuffler + instance.nodesShuffler = nil + + instance.roundNotifier = forking.NewGenericRoundNotifier() + instance.enableRoundsHandler, err = enablers.NewEnableRoundsHandler(args.RoundsConfig, instance.roundNotifier) + if err != nil { + return nil, err + } + + instance.epochStartNotifierWithConfirm = notifier.NewEpochStartSubscriptionHandler() + instance.chanStopNodeProcess = args.ChanStopNodeProcess + instance.genesisTime = time.Unix(instance.genesisNodesSetup.GetStartTime(), 0) + instance.chainID = args.Cfg.GeneralSettings.ChainID + instance.minTransactionVersion = args.Cfg.GeneralSettings.MinTransactionVersion + instance.encodedAddressLen, err = computeEncodedAddressLen(instance.addressPubKeyConverter) + if err != nil { + return nil, err + } + + instance.nodeTypeProvider = nodetype.NewNodeTypeProvider(core.NodeTypeObserver) + instance.processStatusHandler = statusHandler.NewProcessStatusHandler() + + pubKeyBytes, err := instance.validatorPubKeyConverter.Decode(args.Cfg.Hardfork.PublicKeyToListenFrom) + if err != nil { + return nil, err + } + instance.hardforkTriggerPubKey = pubKeyBytes + + return instance, nil +} + +func computeEncodedAddressLen(converter core.PubkeyConverter) (uint32, error) { + emptyAddress := bytes.Repeat([]byte{0}, converter.Len()) + encodedEmptyAddress, err := converter.Encode(emptyAddress) + if err != nil { + return 0, err + } + + return uint32(len(encodedEmptyAddress)), nil +} + +func (c *coreComponentsHolder) InternalMarshalizer() marshal.Marshalizer { + return c.internalMarshaller +} + +func (c *coreComponentsHolder) SetInternalMarshalizer(marshalizer marshal.Marshalizer) error { + c.internalMarshaller = marshalizer + return nil +} + +func (c *coreComponentsHolder) TxMarshalizer() marshal.Marshalizer { + return c.txMarshaller +} + +func (c *coreComponentsHolder) VmMarshalizer() marshal.Marshalizer { + return c.vmMarshaller +} + +func (c *coreComponentsHolder) Hasher() hashing.Hasher { + return c.hasher +} + +func (c *coreComponentsHolder) TxSignHasher() hashing.Hasher { + return c.txSignHasher +} + +func (c *coreComponentsHolder) Uint64ByteSliceConverter() typeConverters.Uint64ByteSliceConverter { + return c.uint64SliceConverter +} + +func (c *coreComponentsHolder) AddressPubKeyConverter() core.PubkeyConverter { + return c.addressPubKeyConverter +} + +func (c *coreComponentsHolder) ValidatorPubKeyConverter() core.PubkeyConverter { + return c.validatorPubKeyConverter +} + +func (c *coreComponentsHolder) PathHandler() storage.PathManagerHandler { + return c.pathHandler +} + +func (c *coreComponentsHolder) Watchdog() core.WatchdogTimer { + return c.watchdog +} + +func (c *coreComponentsHolder) AlarmScheduler() core.TimersScheduler { + return c.alarmScheduler +} + +func (c *coreComponentsHolder) SyncTimer() ntp.SyncTimer { + return c.syncTimer +} + +func (c *coreComponentsHolder) RoundHandler() consensus.RoundHandler { + return c.roundHandler +} + +func (c *coreComponentsHolder) EconomicsData() process.EconomicsDataHandler { + return c.economicsData +} + +func (c *coreComponentsHolder) APIEconomicsData() process.EconomicsDataHandler { + return c.apiEconomicsData +} + +func (c *coreComponentsHolder) RatingsData() process.RatingsInfoHandler { + return c.ratingsData +} + +func (c *coreComponentsHolder) Rater() sharding.PeerAccountListAndRatingHandler { + return c.rater +} + +func (c *coreComponentsHolder) GenesisNodesSetup() sharding.GenesisNodesSetupHandler { + return c.genesisNodesSetup +} + +func (c *coreComponentsHolder) NodesShuffler() nodesCoordinator.NodesShuffler { + return c.nodesShuffler +} + +func (c *coreComponentsHolder) EpochNotifier() process.EpochNotifier { + return c.epochNotifier +} + +func (c *coreComponentsHolder) EnableRoundsHandler() process.EnableRoundsHandler { + return c.enableRoundsHandler +} + +func (c *coreComponentsHolder) RoundNotifier() process.RoundNotifier { + return c.roundNotifier +} + +func (c *coreComponentsHolder) EpochStartNotifierWithConfirm() factory.EpochStartNotifierWithConfirm { + return c.epochStartNotifierWithConfirm +} + +func (c *coreComponentsHolder) ChanStopNodeProcess() chan endProcess.ArgEndProcess { + return c.chanStopNodeProcess +} + +func (c *coreComponentsHolder) GenesisTime() time.Time { + return c.genesisTime +} + +func (c *coreComponentsHolder) ChainID() string { + return c.chainID +} + +func (c *coreComponentsHolder) MinTransactionVersion() uint32 { + return c.minTransactionVersion +} + +func (c *coreComponentsHolder) TxVersionChecker() process.TxVersionCheckerHandler { + return c.txVersionChecker +} + +func (c *coreComponentsHolder) EncodedAddressLen() uint32 { + return c.encodedAddressLen +} + +func (c *coreComponentsHolder) NodeTypeProvider() core.NodeTypeProviderHandler { + return c.nodeTypeProvider +} + +func (c *coreComponentsHolder) WasmVMChangeLocker() common.Locker { + return c.wasmVMChangeLocker +} + +func (c *coreComponentsHolder) ProcessStatusHandler() common.ProcessStatusHandler { + return c.processStatusHandler +} + +func (c *coreComponentsHolder) HardforkTriggerPubKey() []byte { + return c.hardforkTriggerPubKey +} + +func (c *coreComponentsHolder) EnableEpochsHandler() common.EnableEpochsHandler { + return c.enableEpochsHandler +} + +func (c *coreComponentsHolder) IsInterfaceNil() bool { + return c == nil +} diff --git a/node/processingOnlyNode/storageService.go b/node/processingOnlyNode/storageService.go new file mode 100644 index 00000000000..73b1a8677a7 --- /dev/null +++ b/node/processingOnlyNode/storageService.go @@ -0,0 +1,31 @@ +package processingOnlyNode + +import ( + "github.com/multiversx/mx-chain-go/dataRetriever" +) + +// CreateStore creates a storage service for shard nodes +func CreateStore(numOfShards uint32) dataRetriever.StorageService { + store := dataRetriever.NewChainStorer() + store.AddStorer(dataRetriever.TransactionUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.MiniBlockUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.MetaBlockUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.PeerChangesUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.BlockHeaderUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.UnsignedTransactionUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.RewardTransactionUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.MetaHdrNonceHashDataUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.BootstrapUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.StatusMetricsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.ReceiptsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.ScheduledSCRsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.TxLogsUnit, CreateMemUnit()) + // TODO add the rest of units + + for i := uint32(0); i < numOfShards; i++ { + hdrNonceHashDataUnit := dataRetriever.ShardHdrNonceHashDataUnit + dataRetriever.UnitType(i) + store.AddStorer(hdrNonceHashDataUnit, CreateMemUnit()) + } + + return store +} diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index e5ef25123d8..a67099a82a2 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -1,28 +1,17 @@ package processingOnlyNode import ( - "sync" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/versioning" - coreData "github.com/multiversx/mx-chain-core-go/data" - hashingFactory "github.com/multiversx/mx-chain-core-go/hashing/factory" - "github.com/multiversx/mx-chain-core-go/marshal" - marshalFactory "github.com/multiversx/mx-chain-core-go/marshal/factory" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/common/enablers" - "github.com/multiversx/mx-chain-go/common/factory" - "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" dataRetrieverFactory "github.com/multiversx/mx-chain-go/dataRetriever/factory" + "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/postprocess" "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/smartContract" + "github.com/multiversx/mx-chain-go/process/transactionLog" "github.com/multiversx/mx-chain-go/sharding" - "github.com/multiversx/mx-chain-go/storage" - storageFactory "github.com/multiversx/mx-chain-go/storage/factory" ) // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function @@ -30,6 +19,8 @@ type ArgsTestOnlyProcessingNode struct { Config config.Config EnableEpochsConfig config.EnableEpochs EconomicsConfig config.EconomicsConfig + RoundsConfig config.RoundConfig + ChanStopNodeProcess chan endProcess.ArgEndProcess GasScheduleFilename string WorkingDir string NumShards uint32 @@ -37,58 +28,47 @@ type ArgsTestOnlyProcessingNode struct { } type testOnlyProcessingNode struct { - RoundNotifier process.RoundNotifier - EpochNotifier process.EpochNotifier - WasmerChangeLocker common.Locker - ArgumentsParser process.ArgumentsParser - TxVersionChecker process.TxVersionCheckerHandler - - Marshaller marshal.Marshalizer - Hasher coreData.Hasher - ShardCoordinator sharding.Coordinator - TransactionFeeHandler process.TransactionFeeHandler - AddressPubKeyConverter core.PubkeyConverter - ValidatorPubKeyConverter core.PubkeyConverter - EnableEpochsHandler common.EnableEpochsHandler - PathHandler storage.PathManagerHandler - - GasScheduleNotifier core.GasScheduleNotifier + CoreComponentsHolder factory.CoreComponentsHolder + + ShardCoordinator sharding.Coordinator + ArgumentsParser process.ArgumentsParser + TransactionFeeHandler process.TransactionFeeHandler + StoreService dataRetriever.StorageService BuiltinFunctionsCostHandler economics.BuiltInFunctionsCostHandler - EconomicsData process.EconomicsDataHandler DataPool dataRetriever.PoolsHolder + TxLogsProcessor process.TransactionLogProcessor } // NewTestOnlyProcessingNode creates a new instance of a node that is able to only process transactions func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProcessingNode, error) { instance := &testOnlyProcessingNode{ - RoundNotifier: forking.NewGenericRoundNotifier(), - EpochNotifier: forking.NewGenericEpochNotifier(), - WasmerChangeLocker: &sync.RWMutex{}, - ArgumentsParser: smartContract.NewArgumentParser(), - TxVersionChecker: versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion), + ArgumentsParser: smartContract.NewArgumentParser(), + StoreService: CreateStore(args.NumShards), } - - err := instance.createBasicComponents(args) + err := instance.createBasicComponents(args.NumShards, args.ShardID) if err != nil { return nil, err } - err = instance.createGasScheduleNotifier(args) + instance.CoreComponentsHolder, err = CreateCoreComponentsHolder(ArgsCoreComponentsHolder{ + Cfg: args.Config, + EnableEpochsConfig: args.EnableEpochsConfig, + RoundsConfig: args.RoundsConfig, + EconomicsConfig: args.EconomicsConfig, + ChanStopNodeProcess: args.ChanStopNodeProcess, + NumShards: args.NumShards, + WorkingDir: args.WorkingDir, + GasScheduleFilename: args.GasScheduleFilename, + }) if err != nil { return nil, err } - err = instance.createBuiltinFunctionsCostHandler() - if err != nil { - return nil, err - } - - err = instance.createEconomicsHandler(args) + err = instance.createDataPool(args) if err != nil { return nil, err } - - err = instance.createDataPool(args) + err = instance.createTransactionLogProcessor() if err != nil { return nil, err } @@ -96,119 +76,46 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return instance, nil } -func (node *testOnlyProcessingNode) createBasicComponents(args ArgsTestOnlyProcessingNode) error { +func (node *testOnlyProcessingNode) createBasicComponents(numShards, selfShardID uint32) error { var err error - node.Marshaller, err = marshalFactory.NewMarshalizer(args.Config.Marshalizer.Type) - if err != nil { - return err - } - - node.Hasher, err = hashingFactory.NewHasher(args.Config.Hasher.Type) - if err != nil { - return err - } - - node.ShardCoordinator, err = sharding.NewMultiShardCoordinator(args.ShardID, args.NumShards) - if err != nil { - return err - } - node.TransactionFeeHandler, err = postprocess.NewFeeAccumulator() if err != nil { return err } - - node.ValidatorPubKeyConverter, err = factory.NewPubkeyConverter(args.Config.ValidatorPubkeyConverter) - if err != nil { - return err - } - - node.AddressPubKeyConverter, err = factory.NewPubkeyConverter(args.Config.AddressPubkeyConverter) - if err != nil { - return err - } - - node.EnableEpochsHandler, err = enablers.NewEnableEpochsHandler(args.EnableEpochsConfig, node.EpochNotifier) - if err != nil { - return err - } - - node.PathHandler, err = storageFactory.CreatePathManager( - storageFactory.ArgCreatePathManager{ - WorkingDir: args.WorkingDir, - ChainID: args.Config.GeneralSettings.ChainID, - }, - ) - if err != nil { - return err - } + node.ShardCoordinator, err = sharding.NewMultiShardCoordinator(numShards, selfShardID) return nil } -func (node *testOnlyProcessingNode) createGasScheduleNotifier(args ArgsTestOnlyProcessingNode) error { - var err error - - argsGasSchedule := forking.ArgsNewGasScheduleNotifier{ - GasScheduleConfig: config.GasScheduleConfig{ - GasScheduleByEpochs: []config.GasScheduleByEpochs{ - { - StartEpoch: 0, - FileName: args.GasScheduleFilename, - }, - }, - }, - ConfigDir: "", - EpochNotifier: node.EpochNotifier, - WasmVMChangeLocker: node.WasmerChangeLocker, - } - node.GasScheduleNotifier, err = forking.NewGasScheduleNotifier(argsGasSchedule) - - return err -} - -func (node *testOnlyProcessingNode) createBuiltinFunctionsCostHandler() error { +func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNode) error { var err error - args := &economics.ArgsBuiltInFunctionCost{ - GasSchedule: node.GasScheduleNotifier, - ArgsParser: node.ArgumentsParser, + argsDataPool := dataRetrieverFactory.ArgsDataPool{ + Config: &args.Config, + EconomicsData: node.CoreComponentsHolder.EconomicsData(), + ShardCoordinator: node.ShardCoordinator, + Marshalizer: node.CoreComponentsHolder.InternalMarshalizer(), + PathManager: node.CoreComponentsHolder.PathHandler(), } - node.BuiltinFunctionsCostHandler, err = economics.NewBuiltInFunctionsCost(args) + node.DataPool, err = dataRetrieverFactory.NewDataPoolFromConfig(argsDataPool) return err } -func (node *testOnlyProcessingNode) createEconomicsHandler(args ArgsTestOnlyProcessingNode) error { - var err error - - argsEconomicsHandler := economics.ArgsNewEconomicsData{ - TxVersionChecker: node.TxVersionChecker, - BuiltInFunctionsCostHandler: node.BuiltinFunctionsCostHandler, - Economics: &args.EconomicsConfig, - EpochNotifier: node.EpochNotifier, - EnableEpochsHandler: node.EnableEpochsHandler, +func (node *testOnlyProcessingNode) createTransactionLogProcessor() error { + logsStorer, err := node.StoreService.GetStorer(dataRetriever.TxLogsUnit) + if err != nil { + return err } - - node.EconomicsData, err = economics.NewEconomicsData(argsEconomicsHandler) - - return err -} - -func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNode) error { - var err error - - argsDataPool := dataRetrieverFactory.ArgsDataPool{ - Config: &args.Config, - EconomicsData: node.EconomicsData, - ShardCoordinator: node.ShardCoordinator, - Marshalizer: node.Marshaller, - PathManager: node.PathHandler, + argsTxLogProcessor := transactionLog.ArgTxLogProcessor{ + Storer: logsStorer, + Marshalizer: node.CoreComponentsHolder.InternalMarshalizer(), + SaveInStorageEnabled: true, } - node.DataPool, err = dataRetrieverFactory.NewDataPoolFromConfig(argsDataPool) + node.TxLogsProcessor, err = transactionLog.NewTxLogProcessor(argsTxLogProcessor) return err } diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/processingOnlyNode/testOnlyProcessingNode_test.go index b22f4e0bdeb..639ddd76c21 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode_test.go +++ b/node/processingOnlyNode/testOnlyProcessingNode_test.go @@ -28,8 +28,8 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo EnableEpochsConfig: config.EnableEpochs{}, EconomicsConfig: economicsConfig, GasScheduleFilename: gasScheduleName, - NumShards: 0, - ShardID: 3, + NumShards: 3, + ShardID: 0, } } From e13cc2b53ce6d0e8b88fc08addb1e1ac2164ed21 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 5 Sep 2023 16:29:10 +0300 Subject: [PATCH 453/958] fix linter and test --- node/processingOnlyNode/coreComponents.go | 6 +++++- node/processingOnlyNode/testOnlyProcessingNode.go | 5 +++++ .../testOnlyProcessingNode_test.go | 13 +++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/node/processingOnlyNode/coreComponents.go b/node/processingOnlyNode/coreComponents.go index 345b5587b14..ed3fa73c1e4 100644 --- a/node/processingOnlyNode/coreComponents.go +++ b/node/processingOnlyNode/coreComponents.go @@ -79,6 +79,7 @@ type ArgsCoreComponentsHolder struct { RoundsConfig config.RoundConfig EconomicsConfig config.EconomicsConfig ChanStopNodeProcess chan endProcess.ArgEndProcess + NodesSetupPath string GasScheduleFilename string NumShards uint32 WorkingDir string @@ -124,6 +125,9 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp ChainID: args.Cfg.GeneralSettings.ChainID, }, ) + if err != nil { + return nil, err + } // TODO check if we need the real watchdog instance.watchdog = &watchdog.DisabledWatchdog{} @@ -186,7 +190,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.ratingsData = nil instance.rater = nil - instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.WorkingDir, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) + instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.NodesSetupPath, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) if err != nil { return nil, err } diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index a67099a82a2..2ff89c09ab3 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -23,6 +23,7 @@ type ArgsTestOnlyProcessingNode struct { ChanStopNodeProcess chan endProcess.ArgEndProcess GasScheduleFilename string WorkingDir string + NodesSetupPath string NumShards uint32 ShardID uint32 } @@ -59,6 +60,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces NumShards: args.NumShards, WorkingDir: args.WorkingDir, GasScheduleFilename: args.GasScheduleFilename, + NodesSetupPath: args.NodesSetupPath, }) if err != nil { return nil, err @@ -84,6 +86,9 @@ func (node *testOnlyProcessingNode) createBasicComponents(numShards, selfShardID return err } node.ShardCoordinator, err = sharding.NewMultiShardCoordinator(numShards, selfShardID) + if err != nil { + return err + } return nil } diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/processingOnlyNode/testOnlyProcessingNode_test.go index 639ddd76c21..e23b4d389a6 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode_test.go +++ b/node/processingOnlyNode/testOnlyProcessingNode_test.go @@ -10,6 +10,7 @@ import ( const pathForMainConfig = "../../cmd/node/config/config.toml" const pathForEconomicsConfig = "../../cmd/node/config/economics.toml" const pathForGasSchedules = "../../cmd/node/config/gasSchedules" +const nodesSetupConfig = "../../cmd/node/config/nodesSetup.json" func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { mainConfig := config.Config{} @@ -24,10 +25,18 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo assert.Nil(t, err) return ArgsTestOnlyProcessingNode{ - Config: mainConfig, - EnableEpochsConfig: config.EnableEpochs{}, + Config: mainConfig, + EnableEpochsConfig: config.EnableEpochs{}, + RoundsConfig: config.RoundConfig{ + RoundActivations: map[string]config.ActivationRoundByName{ + "DisableAsyncCallV1": { + Round: "18446744073709551614", + }, + }, + }, EconomicsConfig: economicsConfig, GasScheduleFilename: gasScheduleName, + NodesSetupPath: nodesSetupConfig, NumShards: 3, ShardID: 0, } From 76099d7f2e7c6ff371c414424823757de026f973 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 7 Sep 2023 09:09:30 +0300 Subject: [PATCH 454/958] fixes after review --- node/processingOnlyNode/coreComponents.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/node/processingOnlyNode/coreComponents.go b/node/processingOnlyNode/coreComponents.go index ed3fa73c1e4..421b5f42f10 100644 --- a/node/processingOnlyNode/coreComponents.go +++ b/node/processingOnlyNode/coreComponents.go @@ -6,7 +6,6 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/alarm" "github.com/multiversx/mx-chain-core-go/core/nodetype" "github.com/multiversx/mx-chain-core-go/core/versioning" "github.com/multiversx/mx-chain-core-go/core/watchdog" @@ -23,6 +22,7 @@ import ( "github.com/multiversx/mx-chain-go/common/forking" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/epochStart/notifier" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/ntp" @@ -34,6 +34,7 @@ import ( "github.com/multiversx/mx-chain-go/statusHandler" "github.com/multiversx/mx-chain-go/storage" storageFactory "github.com/multiversx/mx-chain-go/storage/factory" + "github.com/multiversx/mx-chain-go/testscommon" ) type coreComponentsHolder struct { @@ -73,6 +74,7 @@ type coreComponentsHolder struct { enableEpochsHandler common.EnableEpochsHandler } +// ArgsCoreComponentsHolder will hold arguments needed for the core components holder type ArgsCoreComponentsHolder struct { Cfg config.Config EnableEpochsConfig config.EnableEpochs @@ -85,6 +87,7 @@ type ArgsCoreComponentsHolder struct { WorkingDir string } +// CreateCoreComponentsHolder will create a new instance of factory.CoreComponentsHolder func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComponentsHolder, error) { var err error instance := &coreComponentsHolder{} @@ -129,12 +132,9 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp return nil, err } - // TODO check if we need the real watchdog instance.watchdog = &watchdog.DisabledWatchdog{} - // TODO check if we need the real alarm scheduler - instance.alarmScheduler = alarm.NewAlarmScheduler() - // TODO check if we need the real sync time also this component need to be started - instance.syncTimer = ntp.NewSyncTime(args.Cfg.NTPConfig, nil) + instance.alarmScheduler = &mock.AlarmSchedulerStub{} + instance.syncTimer = &testscommon.SyncTimerStub{} // TODO discuss with Iulian about the round handler //instance.roundHandler From 43041971fe2d088dbe403a2c2dcc757e20448798 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 7 Sep 2023 11:41:26 +0300 Subject: [PATCH 455/958] comments --- node/processingOnlyNode/coreComponents.go | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/node/processingOnlyNode/coreComponents.go b/node/processingOnlyNode/coreComponents.go index 421b5f42f10..abaf2f888e4 100644 --- a/node/processingOnlyNode/coreComponents.go +++ b/node/processingOnlyNode/coreComponents.go @@ -235,147 +235,183 @@ func computeEncodedAddressLen(converter core.PubkeyConverter) (uint32, error) { return uint32(len(encodedEmptyAddress)), nil } +// InternalMarshalizer will return the internal marshaller func (c *coreComponentsHolder) InternalMarshalizer() marshal.Marshalizer { return c.internalMarshaller } +// SetInternalMarshalizer will set the internal marshaller func (c *coreComponentsHolder) SetInternalMarshalizer(marshalizer marshal.Marshalizer) error { c.internalMarshaller = marshalizer return nil } +// TxMarshalizer will return the transaction marshaller func (c *coreComponentsHolder) TxMarshalizer() marshal.Marshalizer { return c.txMarshaller } +// VmMarshalizer will return the vm marshaller func (c *coreComponentsHolder) VmMarshalizer() marshal.Marshalizer { return c.vmMarshaller } +// Hasher will return the hasher func (c *coreComponentsHolder) Hasher() hashing.Hasher { return c.hasher } +// TxSignHasher will return the transaction sign hasher func (c *coreComponentsHolder) TxSignHasher() hashing.Hasher { return c.txSignHasher } +// Uint64ByteSliceConverter will return the uint64 to slice converter func (c *coreComponentsHolder) Uint64ByteSliceConverter() typeConverters.Uint64ByteSliceConverter { return c.uint64SliceConverter } +// AddressPubKeyConverter will return the address pub key converter func (c *coreComponentsHolder) AddressPubKeyConverter() core.PubkeyConverter { return c.addressPubKeyConverter } +// ValidatorPubKeyConverter will return the validator pub key converter func (c *coreComponentsHolder) ValidatorPubKeyConverter() core.PubkeyConverter { return c.validatorPubKeyConverter } +// PathHandler will return the path handler func (c *coreComponentsHolder) PathHandler() storage.PathManagerHandler { return c.pathHandler } +// Watchdog will return the watch dog func (c *coreComponentsHolder) Watchdog() core.WatchdogTimer { return c.watchdog } +// AlarmScheduler will return the alarm scheduler func (c *coreComponentsHolder) AlarmScheduler() core.TimersScheduler { return c.alarmScheduler } +// SyncTimer will return the sync timer func (c *coreComponentsHolder) SyncTimer() ntp.SyncTimer { return c.syncTimer } +// RoundHandler will return the round handler func (c *coreComponentsHolder) RoundHandler() consensus.RoundHandler { return c.roundHandler } +// EconomicsData will return the economics data handler func (c *coreComponentsHolder) EconomicsData() process.EconomicsDataHandler { return c.economicsData } +// APIEconomicsData will return the api economics data handler func (c *coreComponentsHolder) APIEconomicsData() process.EconomicsDataHandler { return c.apiEconomicsData } +// RatingsData will return the ratings data handler func (c *coreComponentsHolder) RatingsData() process.RatingsInfoHandler { return c.ratingsData } +// Rater will return the rater handler func (c *coreComponentsHolder) Rater() sharding.PeerAccountListAndRatingHandler { return c.rater } +// GenesisNodesSetup will return the genesis nodes setup handler func (c *coreComponentsHolder) GenesisNodesSetup() sharding.GenesisNodesSetupHandler { return c.genesisNodesSetup } +// NodesShuffler will return the nodes shuffler func (c *coreComponentsHolder) NodesShuffler() nodesCoordinator.NodesShuffler { return c.nodesShuffler } +// EpochNotifier will return the epoch notifier func (c *coreComponentsHolder) EpochNotifier() process.EpochNotifier { return c.epochNotifier } +// EnableRoundsHandler will return the enable rounds handler func (c *coreComponentsHolder) EnableRoundsHandler() process.EnableRoundsHandler { return c.enableRoundsHandler } +// RoundNotifier will return the round notifier func (c *coreComponentsHolder) RoundNotifier() process.RoundNotifier { return c.roundNotifier } +// EpochStartNotifierWithConfirm will return the epoch start notifier with confirm func (c *coreComponentsHolder) EpochStartNotifierWithConfirm() factory.EpochStartNotifierWithConfirm { return c.epochStartNotifierWithConfirm } +// ChanStopNodeProcess will return the channel for stop node process func (c *coreComponentsHolder) ChanStopNodeProcess() chan endProcess.ArgEndProcess { return c.chanStopNodeProcess } +// GenesisTime will return the genesis time func (c *coreComponentsHolder) GenesisTime() time.Time { return c.genesisTime } +// ChainID will return the chain id func (c *coreComponentsHolder) ChainID() string { return c.chainID } +// MinTransactionVersion will return the min transaction version func (c *coreComponentsHolder) MinTransactionVersion() uint32 { return c.minTransactionVersion } +// TxVersionChecker will return the tx version checker func (c *coreComponentsHolder) TxVersionChecker() process.TxVersionCheckerHandler { return c.txVersionChecker } +// EncodedAddressLen will return the len of encoded address func (c *coreComponentsHolder) EncodedAddressLen() uint32 { return c.encodedAddressLen } +// NodeTypeProvider will return the node type provider func (c *coreComponentsHolder) NodeTypeProvider() core.NodeTypeProviderHandler { return c.nodeTypeProvider } +// WasmVMChangeLocker will return the wasm vm change locker func (c *coreComponentsHolder) WasmVMChangeLocker() common.Locker { return c.wasmVMChangeLocker } +// ProcessStatusHandler will return the process status handler func (c *coreComponentsHolder) ProcessStatusHandler() common.ProcessStatusHandler { return c.processStatusHandler } +// HardforkTriggerPubKey will return the pub key for the hard fork trigger func (c *coreComponentsHolder) HardforkTriggerPubKey() []byte { return c.hardforkTriggerPubKey } +// EnableEpochsHandler will return the enable epoch handler func (c *coreComponentsHolder) EnableEpochsHandler() common.EnableEpochsHandler { return c.enableEpochsHandler } +// IsInterfaceNil returns true if there is no value under the interface func (c *coreComponentsHolder) IsInterfaceNil() bool { return c == nil } From a1a60e8dbea9cddea8bdaa684b60d10435cd7275 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 11 Sep 2023 12:21:55 +0300 Subject: [PATCH 456/958] more components --- node/processingOnlyNode/cryptoComponents.go | 3 + node/processingOnlyNode/stateComponents.go | 119 ++++++++++++++++++ node/processingOnlyNode/statusComponents.go | 3 + .../statusCoreComponents.go | 80 ++++++++++++ node/processingOnlyNode/storageService.go | 4 + .../testOnlyProcessingNode.go | 40 +++++- 6 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 node/processingOnlyNode/cryptoComponents.go create mode 100644 node/processingOnlyNode/stateComponents.go create mode 100644 node/processingOnlyNode/statusComponents.go create mode 100644 node/processingOnlyNode/statusCoreComponents.go diff --git a/node/processingOnlyNode/cryptoComponents.go b/node/processingOnlyNode/cryptoComponents.go new file mode 100644 index 00000000000..fa747bb0127 --- /dev/null +++ b/node/processingOnlyNode/cryptoComponents.go @@ -0,0 +1,3 @@ +package processingOnlyNode + +// TODO implement in next PR diff --git a/node/processingOnlyNode/stateComponents.go b/node/processingOnlyNode/stateComponents.go new file mode 100644 index 00000000000..8e57f0a6fe4 --- /dev/null +++ b/node/processingOnlyNode/stateComponents.go @@ -0,0 +1,119 @@ +package processingOnlyNode + +import ( + chainData "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/factory" + factoryState "github.com/multiversx/mx-chain-go/factory/state" + "github.com/multiversx/mx-chain-go/state" +) + +// ArgsStateComponents will hold the components needed for state components +type ArgsStateComponents struct { + Cfg config.Config + CoreComponents factory.CoreComponentsHolder + StatusCore factory.StatusCoreComponentsHolder + StoreService dataRetriever.StorageService + ChainHandler chainData.ChainHandler +} + +type stateComponentsHolder struct { + peerAccount state.AccountsAdapter + accountsAdapter state.AccountsAdapter + accountsAdapterAPI state.AccountsAdapter + accountsRepository state.AccountsRepository + triesContainer common.TriesHolder + triesStorageManager map[string]common.StorageManager + missingTrieNodesNotifier common.MissingTrieNodesNotifier + closeFunc func() error +} + +// CreateStateComponents will create the state components holder +func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHolder, error) { + stateComponentsFactory, err := factoryState.NewStateComponentsFactory(factoryState.StateComponentsFactoryArgs{ + Config: args.Cfg, + Core: args.CoreComponents, + StatusCore: args.StatusCore, + StorageService: args.StoreService, + ProcessingMode: 0, + ShouldSerializeSnapshots: false, + ChainHandler: args.ChainHandler, + }) + if err != nil { + return nil, err + } + + stateComp, err := factoryState.NewManagedStateComponents(stateComponentsFactory) + if err != nil { + return nil, err + } + + err = stateComp.Create() + if err != nil { + return nil, err + } + + // TODO should call this + err = stateComp.CheckSubcomponents() + if err != nil { + return nil, err + } + + return &stateComponentsHolder{ + peerAccount: stateComp.PeerAccounts(), + accountsAdapter: stateComp.AccountsAdapter(), + accountsAdapterAPI: stateComp.AccountsAdapterAPI(), + accountsRepository: stateComp.AccountsRepository(), + triesContainer: stateComp.TriesContainer(), + triesStorageManager: stateComp.TrieStorageManagers(), + missingTrieNodesNotifier: stateComp.MissingTrieNodesNotifier(), + closeFunc: stateComp.Close, + }, nil +} + +// PeerAccounts will return peer accounts +func (s *stateComponentsHolder) PeerAccounts() state.AccountsAdapter { + return s.peerAccount +} + +// AccountsAdapter will return accounts adapter +func (s *stateComponentsHolder) AccountsAdapter() state.AccountsAdapter { + return s.accountsAdapter +} + +// AccountsAdapterAPI will return accounts adapter api +func (s *stateComponentsHolder) AccountsAdapterAPI() state.AccountsAdapter { + return s.accountsAdapterAPI +} + +// AccountsRepository will return accounts repository +func (s *stateComponentsHolder) AccountsRepository() state.AccountsRepository { + return s.accountsRepository +} + +// TriesContainer will return tries container +func (s *stateComponentsHolder) TriesContainer() common.TriesHolder { + return s.triesContainer +} + +// TrieStorageManagers will return trie storage managers +func (s *stateComponentsHolder) TrieStorageManagers() map[string]common.StorageManager { + return s.triesStorageManager +} + +// MissingTrieNodesNotifier will return missing trie nodes notifier +func (s *stateComponentsHolder) MissingTrieNodesNotifier() common.MissingTrieNodesNotifier { + return s.missingTrieNodesNotifier +} + +// Close will close the state components +func (s *stateComponentsHolder) Close() error { + return s.closeFunc() +} + +// IsInterfaceNil returns true if there is no value under the interface +func (s *stateComponentsHolder) IsInterfaceNil() bool { + return s == nil +} diff --git a/node/processingOnlyNode/statusComponents.go b/node/processingOnlyNode/statusComponents.go new file mode 100644 index 00000000000..fa747bb0127 --- /dev/null +++ b/node/processingOnlyNode/statusComponents.go @@ -0,0 +1,3 @@ +package processingOnlyNode + +// TODO implement in next PR diff --git a/node/processingOnlyNode/statusCoreComponents.go b/node/processingOnlyNode/statusCoreComponents.go new file mode 100644 index 00000000000..7d425ee155b --- /dev/null +++ b/node/processingOnlyNode/statusCoreComponents.go @@ -0,0 +1,80 @@ +package processingOnlyNode + +import ( + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/cmd/termui/presenter" + "github.com/multiversx/mx-chain-go/common/statistics" + "github.com/multiversx/mx-chain-go/common/statistics/machine" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/node/external" + "github.com/multiversx/mx-chain-go/statusHandler" + "github.com/multiversx/mx-chain-go/statusHandler/persister" + statisticsTrie "github.com/multiversx/mx-chain-go/trie/statistics" +) + +type statusCoreComponentsHolder struct { + resourceMonitor factory.ResourceMonitor + networkStatisticsProvider factory.NetworkStatisticsProvider + trieSyncStatisticsProvider factory.TrieSyncStatisticsProvider + statusHandler core.AppStatusHandler + statusMetrics external.StatusMetricsHandler + persistentStatusHandler factory.PersistentStatusHandler +} + +// CreateStatusCoreComponentsHolder will create a new instance of factory.StatusCoreComponentsHolder +func CreateStatusCoreComponentsHolder(cfg config.Config, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHolder, error) { + var err error + instance := &statusCoreComponentsHolder{ + networkStatisticsProvider: machine.NewNetStatistics(), + trieSyncStatisticsProvider: statisticsTrie.NewTrieSyncStatistics(), + statusHandler: presenter.NewPresenterStatusHandler(), + statusMetrics: statusHandler.NewStatusMetrics(), + } + + instance.resourceMonitor, err = statistics.NewResourceMonitor(cfg, instance.networkStatisticsProvider) + if err != nil { + return nil, err + } + instance.persistentStatusHandler, err = persister.NewPersistentStatusHandler(coreComponents.InternalMarshalizer(), coreComponents.Uint64ByteSliceConverter()) + if err != nil { + return nil, err + } + + return instance, nil +} + +// ResourceMonitor will return the resource monitor +func (s *statusCoreComponentsHolder) ResourceMonitor() factory.ResourceMonitor { + return s.resourceMonitor +} + +// NetworkStatistics will return the network statistics provider +func (s *statusCoreComponentsHolder) NetworkStatistics() factory.NetworkStatisticsProvider { + return s.networkStatisticsProvider +} + +// TrieSyncStatistics will return trie sync statistics provider +func (s *statusCoreComponentsHolder) TrieSyncStatistics() factory.TrieSyncStatisticsProvider { + return s.trieSyncStatisticsProvider +} + +// AppStatusHandler will return the status handler +func (s *statusCoreComponentsHolder) AppStatusHandler() core.AppStatusHandler { + return s.statusHandler +} + +// StatusMetrics will return the status metrics handler +func (s *statusCoreComponentsHolder) StatusMetrics() external.StatusMetricsHandler { + return s.statusMetrics +} + +// PersistentStatusHandler will return the persistent status handler +func (s *statusCoreComponentsHolder) PersistentStatusHandler() factory.PersistentStatusHandler { + return s.persistentStatusHandler +} + +// IsInterfaceNil returns true if there is no value under the interface +func (s *statusCoreComponentsHolder) IsInterfaceNil() bool { + return s == nil +} diff --git a/node/processingOnlyNode/storageService.go b/node/processingOnlyNode/storageService.go index 73b1a8677a7..e7d9462afed 100644 --- a/node/processingOnlyNode/storageService.go +++ b/node/processingOnlyNode/storageService.go @@ -20,6 +20,10 @@ func CreateStore(numOfShards uint32) dataRetriever.StorageService { store.AddStorer(dataRetriever.ReceiptsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.ScheduledSCRsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.TxLogsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.UserAccountsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.UserAccountsCheckpointsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.PeerAccountsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.PeerAccountsCheckpointsUnit, CreateMemUnit()) // TODO add the rest of units for i := uint32(0); i < numOfShards; i++ { diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index 2ff89c09ab3..3ee63d4d8f6 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -1,9 +1,12 @@ package processingOnlyNode import ( + "github.com/multiversx/mx-chain-core-go/core" + chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" dataRetrieverFactory "github.com/multiversx/mx-chain-go/dataRetriever/factory" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/process" @@ -29,8 +32,11 @@ type ArgsTestOnlyProcessingNode struct { } type testOnlyProcessingNode struct { - CoreComponentsHolder factory.CoreComponentsHolder + CoreComponentsHolder factory.CoreComponentsHolder + StatusCoreComponents factory.StatusCoreComponentsHolder + StateComponentsHolder factory.StateComponentsHolder + ChainHandler chainData.ChainHandler ShardCoordinator sharding.Coordinator ArgumentsParser process.ArgumentsParser TransactionFeeHandler process.TransactionFeeHandler @@ -66,6 +72,27 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + instance.StatusCoreComponents, err = CreateStatusCoreComponentsHolder(args.Config, instance.CoreComponentsHolder) + if err != nil { + return nil, err + } + + err = instance.createBlockChain(args.ShardID) + if err != nil { + return nil, err + } + + instance.StateComponentsHolder, err = CreateStateComponents(ArgsStateComponents{ + Cfg: args.Config, + CoreComponents: instance.CoreComponentsHolder, + StatusCore: instance.StatusCoreComponents, + StoreService: instance.StoreService, + ChainHandler: instance.ChainHandler, + }) + if err != nil { + return nil, err + } + err = instance.createDataPool(args) if err != nil { return nil, err @@ -93,6 +120,17 @@ func (node *testOnlyProcessingNode) createBasicComponents(numShards, selfShardID return nil } +func (node *testOnlyProcessingNode) createBlockChain(selfShardID uint32) error { + var err error + if selfShardID == core.MetachainShardId { + node.ChainHandler, err = blockchain.NewMetaChain(node.StatusCoreComponents.AppStatusHandler()) + } else { + node.ChainHandler, err = blockchain.NewBlockChain(node.StatusCoreComponents.AppStatusHandler()) + } + + return err +} + func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNode) error { var err error From 31c09aeb33d4b9aad5124f7612e8a993616bf90e Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 11 Sep 2023 12:43:07 +0300 Subject: [PATCH 457/958] status components --- node/processingOnlyNode/statusComponents.go | 52 ++++++++++++++++++- .../testOnlyProcessingNode.go | 11 ++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/node/processingOnlyNode/statusComponents.go b/node/processingOnlyNode/statusComponents.go index fa747bb0127..2ba77f3fb4c 100644 --- a/node/processingOnlyNode/statusComponents.go +++ b/node/processingOnlyNode/statusComponents.go @@ -1,3 +1,53 @@ package processingOnlyNode -// TODO implement in next PR +import ( + "time" + + outportCfg "github.com/multiversx/mx-chain-core-go/data/outport" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/statistics" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/outport" + "github.com/multiversx/mx-chain-go/testscommon" +) + +type statusComponentsHolder struct { + outportHandler outport.OutportHandler + softwareVersionChecker statistics.SoftwareVersionChecker + managedPeerMonitor common.ManagedPeersMonitor +} + +func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHolder, error) { + var err error + instance := &statusComponentsHolder{} + + // TODO add drivers to index data + instance.outportHandler, err = outport.NewOutport(100*time.Millisecond, outportCfg.OutportConfig{ + ShardID: shardID, + }) + if err != nil { + return nil, err + } + instance.softwareVersionChecker = &mock.SoftwareVersionCheckerMock{} + instance.managedPeerMonitor = &testscommon.ManagedPeersMonitorStub{} + + return instance, nil +} + +func (s *statusComponentsHolder) OutportHandler() outport.OutportHandler { + return s.outportHandler +} + +func (s *statusComponentsHolder) SoftwareVersionChecker() statistics.SoftwareVersionChecker { + return s.softwareVersionChecker +} + +func (s *statusComponentsHolder) ManagedPeersMonitor() common.ManagedPeersMonitor { + return s.managedPeerMonitor +} + +// IsInterfaceNil returns true if there is no value under the interface +func (s *statusComponentsHolder) IsInterfaceNil() bool { + return s == nil +} diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index 3ee63d4d8f6..af80e2e6ec8 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -32,9 +32,10 @@ type ArgsTestOnlyProcessingNode struct { } type testOnlyProcessingNode struct { - CoreComponentsHolder factory.CoreComponentsHolder - StatusCoreComponents factory.StatusCoreComponentsHolder - StateComponentsHolder factory.StateComponentsHolder + CoreComponentsHolder factory.CoreComponentsHolder + StatusCoreComponents factory.StatusCoreComponentsHolder + StateComponentsHolder factory.StateComponentsHolder + StatusComponentsHolder factory.StatusComponentsHolder ChainHandler chainData.ChainHandler ShardCoordinator sharding.Coordinator @@ -92,6 +93,10 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces if err != nil { return nil, err } + instance.StatusComponentsHolder, err = CreateStatusComponentsHolder(args.ShardID) + if err != nil { + return nil, err + } err = instance.createDataPool(args) if err != nil { From 9a535a5a00f48a749ad3890a2f8e15ffcc469402 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 11 Sep 2023 15:10:29 +0300 Subject: [PATCH 458/958] fixes --- node/processingOnlyNode/stateComponents.go | 1 - node/processingOnlyNode/statusComponents.go | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/node/processingOnlyNode/stateComponents.go b/node/processingOnlyNode/stateComponents.go index 8e57f0a6fe4..cb5e56b85d7 100644 --- a/node/processingOnlyNode/stateComponents.go +++ b/node/processingOnlyNode/stateComponents.go @@ -55,7 +55,6 @@ func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHol return nil, err } - // TODO should call this err = stateComp.CheckSubcomponents() if err != nil { return nil, err diff --git a/node/processingOnlyNode/statusComponents.go b/node/processingOnlyNode/statusComponents.go index 2ba77f3fb4c..b05bc82824f 100644 --- a/node/processingOnlyNode/statusComponents.go +++ b/node/processingOnlyNode/statusComponents.go @@ -18,6 +18,7 @@ type statusComponentsHolder struct { managedPeerMonitor common.ManagedPeersMonitor } +// CreateStatusComponentsHolder will create a new instance of status components holder func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHolder, error) { var err error instance := &statusComponentsHolder{} @@ -35,14 +36,17 @@ func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHolde return instance, nil } +// OutportHandler will return the outport handler func (s *statusComponentsHolder) OutportHandler() outport.OutportHandler { return s.outportHandler } +// SoftwareVersionChecker will return the software version checker func (s *statusComponentsHolder) SoftwareVersionChecker() statistics.SoftwareVersionChecker { return s.softwareVersionChecker } +// ManagedPeersMonitor will return the managed peers monitor func (s *statusComponentsHolder) ManagedPeersMonitor() common.ManagedPeersMonitor { return s.managedPeerMonitor } From 6140ea1fa2db00fbb8ba70db4f475a4e299a1031 Mon Sep 17 00:00:00 2001 From: jules01 Date: Mon, 11 Sep 2023 18:40:43 +0300 Subject: [PATCH 459/958] - added synced network messenger --- .../syncedBroadcastNetwork.go | 126 +++++++ .../syncedBroadcastNetwork_test.go | 222 +++++++++++ node/processingOnlyNode/syncedMessenger.go | 354 ++++++++++++++++++ testscommon/p2pmocks/messageProcessorStub.go | 25 ++ 4 files changed, 727 insertions(+) create mode 100644 node/processingOnlyNode/syncedBroadcastNetwork.go create mode 100644 node/processingOnlyNode/syncedBroadcastNetwork_test.go create mode 100644 node/processingOnlyNode/syncedMessenger.go create mode 100644 testscommon/p2pmocks/messageProcessorStub.go diff --git a/node/processingOnlyNode/syncedBroadcastNetwork.go b/node/processingOnlyNode/syncedBroadcastNetwork.go new file mode 100644 index 00000000000..c6fef5c1d1f --- /dev/null +++ b/node/processingOnlyNode/syncedBroadcastNetwork.go @@ -0,0 +1,126 @@ +package processingOnlyNode + +import ( + "fmt" + "sync" + + "github.com/multiversx/mx-chain-communication-go/p2p" + p2pMessage "github.com/multiversx/mx-chain-communication-go/p2p/message" + "github.com/multiversx/mx-chain-core-go/core" +) + +type messageReceiver interface { + receive(fromConnectedPeer core.PeerID, message p2p.MessageP2P) + HasTopic(name string) bool +} + +type syncedBroadcastNetwork struct { + mutOperation sync.RWMutex + peers map[core.PeerID]messageReceiver +} + +// NewSyncedBroadcastNetwork creates a new synced broadcast network +func NewSyncedBroadcastNetwork() *syncedBroadcastNetwork { + return &syncedBroadcastNetwork{ + peers: make(map[core.PeerID]messageReceiver), + } +} + +// RegisterMessageReceiver registers the message receiver +func (network *syncedBroadcastNetwork) RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) { + if handler == nil { + log.Error("programming error in syncedBroadcastNetwork.RegisterMessageReceiver: nil handler") + return + } + + network.mutOperation.Lock() + defer network.mutOperation.Unlock() + + _, found := network.peers[pid] + if found { + log.Error("programming error in syncedBroadcastNetwork.RegisterMessageReceiver: handler already exists", "pid", pid.Pretty()) + return + } + + network.peers[pid] = handler +} + +// Broadcast will iterate through peers and send the message +func (network *syncedBroadcastNetwork) Broadcast(pid core.PeerID, topic string, buff []byte) { + _, handlers := network.getPeersAndHandlers() + + for _, handler := range handlers { + message := &p2pMessage.Message{ + FromField: pid.Bytes(), + DataField: buff, + TopicField: topic, + BroadcastMethodField: p2p.Broadcast, + } + + handler.receive(pid, message) + } +} + +// SendDirectly will try to send directly to the provided peer +func (network *syncedBroadcastNetwork) SendDirectly(from core.PeerID, topic string, buff []byte, to core.PeerID) error { + network.mutOperation.RLock() + handler, found := network.peers[to] + if !found { + network.mutOperation.RUnlock() + + return fmt.Errorf("syncedBroadcastNetwork.SendDirectly: trying to send to an unknwon peer, pid %s", to.Pretty()) + } + network.mutOperation.RUnlock() + + message := &p2pMessage.Message{ + FromField: from.Bytes(), + DataField: buff, + TopicField: topic, + BroadcastMethodField: p2p.Direct, + } + + handler.receive(from, message) + + return nil +} + +// GetConnectedPeers returns all connected peers +func (network *syncedBroadcastNetwork) GetConnectedPeers() []core.PeerID { + peers, _ := network.getPeersAndHandlers() + + return peers +} + +func (network *syncedBroadcastNetwork) getPeersAndHandlers() ([]core.PeerID, []messageReceiver) { + network.mutOperation.RLock() + defer network.mutOperation.RUnlock() + + peers := make([]core.PeerID, 0, len(network.peers)) + handlers := make([]messageReceiver, 0, len(network.peers)) + + for p, handler := range network.peers { + peers = append(peers, p) + handlers = append(handlers, handler) + } + + return peers, handlers +} + +// GetConnectedPeersOnTopic will find suitable peers connected on the provided topic +func (network *syncedBroadcastNetwork) GetConnectedPeersOnTopic(topic string) []core.PeerID { + peers, handlers := network.getPeersAndHandlers() + + peersOnTopic := make([]core.PeerID, 0, len(peers)) + for idx, p := range peers { + if handlers[idx].HasTopic(topic) { + peersOnTopic = append(peersOnTopic, p) + } + } + + return peersOnTopic +} + +// IsInterfaceNil returns true if there is no value under the interface +func (network *syncedBroadcastNetwork) IsInterfaceNil() bool { + return network == nil +} diff --git a/node/processingOnlyNode/syncedBroadcastNetwork_test.go b/node/processingOnlyNode/syncedBroadcastNetwork_test.go new file mode 100644 index 00000000000..67fcaa8b2b2 --- /dev/null +++ b/node/processingOnlyNode/syncedBroadcastNetwork_test.go @@ -0,0 +1,222 @@ +package processingOnlyNode + +import ( + "testing" + + "github.com/multiversx/mx-chain-communication-go/p2p" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" + "github.com/stretchr/testify/assert" +) + +func TestSyncedBroadcastNetwork_BroadcastShouldWorkOn3Peers(t *testing.T) { + t.Parallel() + + network := NewSyncedBroadcastNetwork() + messages := make(map[core.PeerID]map[string][]byte) + + globalTopic := "global" + oneTwoTopic := "topic_1_2" + oneThreeTopic := "topic_1_3" + twoThreeTopic := "topic_2_3" + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor1 := createMessageProcessor(messages, peer1.ID()) + _ = peer1.CreateTopic(globalTopic, true) + _ = peer1.RegisterMessageProcessor(globalTopic, "", processor1) + _ = peer1.CreateTopic(oneTwoTopic, true) + _ = peer1.RegisterMessageProcessor(oneTwoTopic, "", processor1) + _ = peer1.CreateTopic(oneThreeTopic, true) + _ = peer1.RegisterMessageProcessor(oneThreeTopic, "", processor1) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor2 := createMessageProcessor(messages, peer2.ID()) + _ = peer2.CreateTopic(globalTopic, true) + _ = peer2.RegisterMessageProcessor(globalTopic, "", processor2) + _ = peer2.CreateTopic(oneTwoTopic, true) + _ = peer2.RegisterMessageProcessor(oneTwoTopic, "", processor2) + _ = peer2.CreateTopic(twoThreeTopic, true) + _ = peer2.RegisterMessageProcessor(twoThreeTopic, "", processor2) + + peer3, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor3 := createMessageProcessor(messages, peer3.ID()) + _ = peer3.CreateTopic(globalTopic, true) + _ = peer3.RegisterMessageProcessor(globalTopic, "", processor3) + _ = peer3.CreateTopic(oneThreeTopic, true) + _ = peer3.RegisterMessageProcessor(oneThreeTopic, "", processor3) + _ = peer3.CreateTopic(twoThreeTopic, true) + _ = peer3.RegisterMessageProcessor(twoThreeTopic, "", processor3) + + globalMessage := []byte("global message") + oneTwoMessage := []byte("1-2 message") + oneThreeMessage := []byte("1-3 message") + twoThreeMessage := []byte("2-3 message") + + peer1.Broadcast(globalTopic, globalMessage) + assert.Equal(t, globalMessage, messages[peer1.ID()][globalTopic]) + assert.Equal(t, globalMessage, messages[peer2.ID()][globalTopic]) + assert.Equal(t, globalMessage, messages[peer3.ID()][globalTopic]) + + peer1.Broadcast(oneTwoTopic, oneTwoMessage) + assert.Equal(t, oneTwoMessage, messages[peer1.ID()][oneTwoTopic]) + assert.Equal(t, oneTwoMessage, messages[peer2.ID()][oneTwoTopic]) + assert.Nil(t, messages[peer3.ID()][oneTwoTopic]) + + peer1.Broadcast(oneThreeTopic, oneThreeMessage) + assert.Equal(t, oneThreeMessage, messages[peer1.ID()][oneThreeTopic]) + assert.Nil(t, messages[peer2.ID()][oneThreeTopic]) + assert.Equal(t, oneThreeMessage, messages[peer3.ID()][oneThreeTopic]) + + peer2.Broadcast(twoThreeTopic, twoThreeMessage) + assert.Nil(t, messages[peer1.ID()][twoThreeTopic]) + assert.Equal(t, twoThreeMessage, messages[peer2.ID()][twoThreeTopic]) + assert.Equal(t, twoThreeMessage, messages[peer3.ID()][twoThreeTopic]) +} + +func TestSyncedBroadcastNetwork_BroadcastOnAnUnjoinedTopicShouldDiscardMessage(t *testing.T) { + t.Parallel() + + network := NewSyncedBroadcastNetwork() + messages := make(map[core.PeerID]map[string][]byte) + + globalTopic := "global" + twoThreeTopic := "topic_2_3" + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor1 := createMessageProcessor(messages, peer1.ID()) + _ = peer1.CreateTopic(globalTopic, true) + _ = peer1.RegisterMessageProcessor(globalTopic, "", processor1) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor2 := createMessageProcessor(messages, peer2.ID()) + _ = peer2.CreateTopic(globalTopic, true) + _ = peer2.RegisterMessageProcessor(globalTopic, "", processor2) + _ = peer2.CreateTopic(twoThreeTopic, true) + _ = peer2.RegisterMessageProcessor(twoThreeTopic, "", processor2) + + peer3, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor3 := createMessageProcessor(messages, peer3.ID()) + _ = peer3.CreateTopic(globalTopic, true) + _ = peer3.RegisterMessageProcessor(globalTopic, "", processor3) + _ = peer3.CreateTopic(twoThreeTopic, true) + _ = peer3.RegisterMessageProcessor(twoThreeTopic, "", processor3) + + testMessage := []byte("test message") + + peer1.Broadcast(twoThreeTopic, testMessage) + + assert.Nil(t, messages[peer1.ID()][twoThreeTopic]) + assert.Nil(t, messages[peer2.ID()][twoThreeTopic]) + assert.Nil(t, messages[peer3.ID()][twoThreeTopic]) +} + +func TestSyncedBroadcastNetwork_SendDirectlyShouldWorkBetween2peers(t *testing.T) { + t.Parallel() + + network := NewSyncedBroadcastNetwork() + messages := make(map[core.PeerID]map[string][]byte) + + topic := "topic" + testMessage := []byte("test message") + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor1 := createMessageProcessor(messages, peer1.ID()) + _ = peer1.CreateTopic(topic, true) + _ = peer1.RegisterMessageProcessor(topic, "", processor1) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor2 := createMessageProcessor(messages, peer2.ID()) + _ = peer2.CreateTopic(topic, true) + _ = peer2.RegisterMessageProcessor(topic, "", processor2) + + err = peer1.SendToConnectedPeer(topic, testMessage, peer2.ID()) + assert.Nil(t, err) + + assert.Nil(t, messages[peer1.ID()][topic]) + assert.Equal(t, testMessage, messages[peer2.ID()][topic]) +} + +func TestSyncedBroadcastNetwork_SendDirectlyToSelfShouldWork(t *testing.T) { + t.Parallel() + + network := NewSyncedBroadcastNetwork() + messages := make(map[core.PeerID]map[string][]byte) + + topic := "topic" + testMessage := []byte("test message") + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor1 := createMessageProcessor(messages, peer1.ID()) + _ = peer1.CreateTopic(topic, true) + _ = peer1.RegisterMessageProcessor(topic, "", processor1) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor2 := createMessageProcessor(messages, peer2.ID()) + _ = peer2.CreateTopic(topic, true) + _ = peer2.RegisterMessageProcessor(topic, "", processor2) + + err = peer1.SendToConnectedPeer(topic, testMessage, peer1.ID()) + assert.Nil(t, err) + + assert.Equal(t, testMessage, messages[peer1.ID()][topic]) + assert.Nil(t, messages[peer2.ID()][topic]) +} + +func TestSyncedBroadcastNetwork_SendDirectlyShouldNotDeadlock(t *testing.T) { + t.Parallel() + + network := NewSyncedBroadcastNetwork() + messages := make(map[core.PeerID]map[string][]byte) + + topic := "topic" + testMessage := []byte("test message") + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor1 := createMessageProcessor(messages, peer1.ID()) + _ = peer1.CreateTopic(topic, true) + _ = peer1.RegisterMessageProcessor(topic, "", processor1) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + processor2 := &p2pmocks.MessageProcessorStub{ + ProcessReceivedMessageCalled: func(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error { + log.Debug("sending message back to", "pid", fromConnectedPeer.Pretty()) + return source.SendToConnectedPeer(message.Topic(), []byte("reply: "+string(message.Data())), fromConnectedPeer) + }, + } + _ = peer2.CreateTopic(topic, true) + _ = peer2.RegisterMessageProcessor(topic, "", processor2) + + err = peer1.SendToConnectedPeer(topic, testMessage, peer2.ID()) + assert.Nil(t, err) + + assert.Equal(t, "reply: "+string(testMessage), string(messages[peer1.ID()][topic])) + assert.Nil(t, messages[peer2.ID()][topic]) +} + +func createMessageProcessor(dataMap map[core.PeerID]map[string][]byte, pid core.PeerID) p2p.MessageProcessor { + return &p2pmocks.MessageProcessorStub{ + ProcessReceivedMessageCalled: func(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error { + m, found := dataMap[pid] + if !found { + m = make(map[string][]byte) + dataMap[pid] = m + } + + m[message.Topic()] = message.Data() + + return nil + }, + } +} diff --git a/node/processingOnlyNode/syncedMessenger.go b/node/processingOnlyNode/syncedMessenger.go new file mode 100644 index 00000000000..48c0e4df65b --- /dev/null +++ b/node/processingOnlyNode/syncedMessenger.go @@ -0,0 +1,354 @@ +package processingOnlyNode + +import ( + "bytes" + "errors" + "fmt" + "sync" + "time" + + "github.com/multiversx/mx-chain-communication-go/p2p" + "github.com/multiversx/mx-chain-communication-go/p2p/libp2p/crypto" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/hashing/blake2b" + logger "github.com/multiversx/mx-chain-logger-go" +) + +const virtualAddressTemplate = "/virtual/p2p/%s" + +var log = logger.GetOrCreate("node/chainSimulator") +var p2pInstanceCreator, _ = crypto.NewIdentityGenerator(log) +var hasher = blake2b.NewBlake2b() + +type syncedBroadcastNetworkHandler interface { + RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) + Broadcast(pid core.PeerID, topic string, buff []byte) + SendDirectly(from core.PeerID, topic string, buff []byte, to core.PeerID) error + GetConnectedPeers() []core.PeerID + GetConnectedPeersOnTopic(topic string) []core.PeerID + IsInterfaceNil() bool +} + +type syncedMessenger struct { + mutOperation sync.RWMutex + topics map[string]map[string]p2p.MessageProcessor + network syncedBroadcastNetworkHandler + pid core.PeerID +} + +// NewSyncedMessenger creates a new synced network messenger +func NewSyncedMessenger(network syncedBroadcastNetworkHandler) (*syncedMessenger, error) { + if check.IfNil(network) { + return nil, fmt.Errorf("nil network") + } + + _, pid, err := p2pInstanceCreator.CreateRandomP2PIdentity() + if err != nil { + return nil, err + } + + messenger := &syncedMessenger{ + network: network, + topics: make(map[string]map[string]p2p.MessageProcessor), + pid: pid, + } + + log.Debug("created syncedMessenger", "pid", pid.Pretty()) + + network.RegisterMessageReceiver(messenger, pid) + + return messenger, nil +} + +func (messenger *syncedMessenger) receive(fromConnectedPeer core.PeerID, message p2p.MessageP2P) { + if check.IfNil(message) { + return + } + + messenger.mutOperation.RLock() + handlers := messenger.topics[message.Topic()] + messenger.mutOperation.RUnlock() + + for _, handler := range handlers { + err := handler.ProcessReceivedMessage(message, fromConnectedPeer, messenger) + if err != nil { + log.Trace("received message syncedMessenger", + "error", err, "topic", message.Topic(), "from connected peer", fromConnectedPeer.Pretty()) + } + } +} + +// ProcessReceivedMessage does nothing and returns nil +func (messenger *syncedMessenger) ProcessReceivedMessage(_ p2p.MessageP2P, _ core.PeerID, _ p2p.MessageHandler) error { + return nil +} + +// CreateTopic will create a topic for receiving data +func (messenger *syncedMessenger) CreateTopic(name string, _ bool) error { + messenger.mutOperation.Lock() + defer messenger.mutOperation.Unlock() + + _, found := messenger.topics[name] + if found { + return fmt.Errorf("programming error in syncedMessenger.CreateTopic, topic already created, topic %s", name) + } + + messenger.topics[name] = make(map[string]p2p.MessageProcessor, 0) + + return nil +} + +// HasTopic returns true if the topic was registered +func (messenger *syncedMessenger) HasTopic(name string) bool { + messenger.mutOperation.RLock() + defer messenger.mutOperation.RUnlock() + + _, found := messenger.topics[name] + + return found +} + +// RegisterMessageProcessor will try to register a message processor on the provided topic & identifier +func (messenger *syncedMessenger) RegisterMessageProcessor(topic string, identifier string, handler p2p.MessageProcessor) error { + if handler.IsInterfaceNil() { + return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, "+ + "provided handler is nil for topic %s and identifier %s", topic, identifier) + } + + messenger.mutOperation.Lock() + defer messenger.mutOperation.Unlock() + + handlers, found := messenger.topics[topic] + if !found { + return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, topic %s does not exists", topic) + } + + _, found = handlers[identifier] + if found { + return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, topic %s already "+ + "contains a registered processor for identifier %s", topic, identifier) + } + + handlers[identifier] = handler + + return nil +} + +// UnregisterAllMessageProcessors will unregister all message processors +func (messenger *syncedMessenger) UnregisterAllMessageProcessors() error { + messenger.mutOperation.Lock() + defer messenger.mutOperation.Unlock() + + for topic := range messenger.topics { + messenger.topics[topic] = make(map[string]p2p.MessageProcessor) + } + + return nil +} + +// UnregisterMessageProcessor will unregister the message processor for the provided topic and identifier +func (messenger *syncedMessenger) UnregisterMessageProcessor(topic string, identifier string) error { + messenger.mutOperation.Lock() + defer messenger.mutOperation.Unlock() + + handlers, found := messenger.topics[topic] + if !found { + return fmt.Errorf("programming error in syncedMessenger.UnregisterMessageProcessor, topic %s does not exists", topic) + } + + delete(handlers, identifier) + + return nil +} + +// Broadcast will broadcast the provided buffer on the topic in a synchronous manner +func (messenger *syncedMessenger) Broadcast(topic string, buff []byte) { + if !messenger.HasTopic(topic) { + return + } + + messenger.network.Broadcast(messenger.pid, topic, buff) +} + +// BroadcastOnChannel calls the Broadcast method +func (messenger *syncedMessenger) BroadcastOnChannel(_ string, topic string, buff []byte) { + messenger.Broadcast(topic, buff) +} + +// BroadcastUsingPrivateKey calls the Broadcast method +func (messenger *syncedMessenger) BroadcastUsingPrivateKey(topic string, buff []byte, _ core.PeerID, _ []byte) { + messenger.Broadcast(topic, buff) +} + +// BroadcastOnChannelUsingPrivateKey calls the Broadcast method +func (messenger *syncedMessenger) BroadcastOnChannelUsingPrivateKey(_ string, topic string, buff []byte, _ core.PeerID, _ []byte) { + messenger.Broadcast(topic, buff) +} + +// SendToConnectedPeer will send the message to the peer +func (messenger *syncedMessenger) SendToConnectedPeer(topic string, buff []byte, peerID core.PeerID) error { + if !messenger.HasTopic(topic) { + return nil + } + + log.Trace("syncedMessenger.SendToConnectedPeer", + "from", messenger.pid.Pretty(), + "to", peerID.Pretty(), + "data", buff) + + return messenger.network.SendDirectly(messenger.pid, topic, buff, peerID) +} + +// UnJoinAllTopics will unjoin all topics +func (messenger *syncedMessenger) UnJoinAllTopics() error { + messenger.mutOperation.Lock() + defer messenger.mutOperation.Unlock() + + messenger.topics = make(map[string]map[string]p2p.MessageProcessor) + + return nil +} + +// Bootstrap does nothing and returns nil +func (messenger *syncedMessenger) Bootstrap() error { + return nil +} + +// Peers returns the network's peer ID +func (messenger *syncedMessenger) Peers() []core.PeerID { + return messenger.network.GetConnectedPeers() +} + +// Addresses returns the addresses this messenger was bound to. It returns a virtual address +func (messenger *syncedMessenger) Addresses() []string { + return []string{fmt.Sprintf(virtualAddressTemplate, messenger.pid.Pretty())} +} + +// ConnectToPeer does nothing and returns nil +func (messenger *syncedMessenger) ConnectToPeer(_ string) error { + return nil +} + +// IsConnected returns true if the peer ID is found on the network +func (messenger *syncedMessenger) IsConnected(peerID core.PeerID) bool { + peers := messenger.network.GetConnectedPeers() + for _, peer := range peers { + if peer == peerID { + return true + } + } + + return false +} + +// ConnectedPeers returns the same list as the function Peers +func (messenger *syncedMessenger) ConnectedPeers() []core.PeerID { + return messenger.Peers() +} + +// ConnectedAddresses returns all connected addresses +func (messenger *syncedMessenger) ConnectedAddresses() []string { + peers := messenger.network.GetConnectedPeers() + addresses := make([]string, 0, len(peers)) + for _, peer := range peers { + addresses = append(addresses, fmt.Sprintf(virtualAddressTemplate, peer.Pretty())) + } + + return addresses +} + +// PeerAddresses returns the virtual peer address +func (messenger *syncedMessenger) PeerAddresses(pid core.PeerID) []string { + return []string{fmt.Sprintf(virtualAddressTemplate, pid.Pretty())} +} + +// ConnectedPeersOnTopic returns the connected peers on the provided topic +func (messenger *syncedMessenger) ConnectedPeersOnTopic(topic string) []core.PeerID { + return messenger.network.GetConnectedPeersOnTopic(topic) +} + +// SetPeerShardResolver does nothing and returns nil +func (messenger *syncedMessenger) SetPeerShardResolver(_ p2p.PeerShardResolver) error { + return nil +} + +// GetConnectedPeersInfo return current connected peers info +func (messenger *syncedMessenger) GetConnectedPeersInfo() *p2p.ConnectedPeersInfo { + peersInfo := &p2p.ConnectedPeersInfo{} + peers := messenger.network.GetConnectedPeers() + for _, peer := range peers { + peersInfo.UnknownPeers = append(peersInfo.UnknownPeers, peer.Pretty()) + } + + return peersInfo +} + +// WaitForConnections does nothing +func (messenger *syncedMessenger) WaitForConnections(_ time.Duration, _ uint32) { +} + +// IsConnectedToTheNetwork returns true +func (messenger *syncedMessenger) IsConnectedToTheNetwork() bool { + return true +} + +// ThresholdMinConnectedPeers returns 0 +func (messenger *syncedMessenger) ThresholdMinConnectedPeers() int { + return 0 +} + +// SetThresholdMinConnectedPeers does nothing and returns nil +func (messenger *syncedMessenger) SetThresholdMinConnectedPeers(_ int) error { + return nil +} + +// SetPeerDenialEvaluator does nothing and returns nil +func (messenger *syncedMessenger) SetPeerDenialEvaluator(_ p2p.PeerDenialEvaluator) error { + return nil +} + +// ID returns the peer ID +func (messenger *syncedMessenger) ID() core.PeerID { + return messenger.pid +} + +// Port returns 0 +func (messenger *syncedMessenger) Port() int { + return 0 +} + +// Sign will return the hash(messenger.ID + payload) +func (messenger *syncedMessenger) Sign(payload []byte) ([]byte, error) { + return hasher.Compute(messenger.pid.Pretty() + string(payload)), nil +} + +// Verify will check if the provided signature === hash(pid + payload) +func (messenger *syncedMessenger) Verify(payload []byte, pid core.PeerID, signature []byte) error { + sig := hasher.Compute(pid.Pretty() + string(payload)) + if bytes.Equal(sig, signature) { + return nil + } + + return errors.New("invalid signature") +} + +// SignUsingPrivateKey will return an empty byte slice +func (messenger *syncedMessenger) SignUsingPrivateKey(_ []byte, _ []byte) ([]byte, error) { + return make([]byte, 0), nil +} + +// AddPeerTopicNotifier does nothing and returns nil +func (messenger *syncedMessenger) AddPeerTopicNotifier(_ p2p.PeerTopicNotifier) error { + return nil +} + +// Close does nothing and returns nil +func (messenger *syncedMessenger) Close() error { + return nil +} + +// IsInterfaceNil returns true if there is no value under the interface +func (messenger *syncedMessenger) IsInterfaceNil() bool { + return messenger == nil +} diff --git a/testscommon/p2pmocks/messageProcessorStub.go b/testscommon/p2pmocks/messageProcessorStub.go new file mode 100644 index 00000000000..5802dcc6785 --- /dev/null +++ b/testscommon/p2pmocks/messageProcessorStub.go @@ -0,0 +1,25 @@ +package p2pmocks + +import ( + "github.com/multiversx/mx-chain-communication-go/p2p" + "github.com/multiversx/mx-chain-core-go/core" +) + +// MessageProcessorStub - +type MessageProcessorStub struct { + ProcessReceivedMessageCalled func(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error +} + +// ProcessReceivedMessage - +func (stub *MessageProcessorStub) ProcessReceivedMessage(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error { + if stub.ProcessReceivedMessageCalled != nil { + return stub.ProcessReceivedMessageCalled(message, fromConnectedPeer, source) + } + + return nil +} + +// IsInterfaceNil - +func (stub *MessageProcessorStub) IsInterfaceNil() bool { + return stub == nil +} From b4685db55359c99695af57b07675ffdb2b6a2c7b Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 12:05:31 +0300 Subject: [PATCH 460/958] fixes after second review --- node/processingOnlyNode/coreComponents.go | 26 +++++++++---------- node/processingOnlyNode/stateComponents.go | 8 +++--- .../testOnlyProcessingNode.go | 4 +-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/node/processingOnlyNode/coreComponents.go b/node/processingOnlyNode/coreComponents.go index abaf2f888e4..be99c71edda 100644 --- a/node/processingOnlyNode/coreComponents.go +++ b/node/processingOnlyNode/coreComponents.go @@ -76,7 +76,7 @@ type coreComponentsHolder struct { // ArgsCoreComponentsHolder will hold arguments needed for the core components holder type ArgsCoreComponentsHolder struct { - Cfg config.Config + Config config.Config EnableEpochsConfig config.EnableEpochs RoundsConfig config.RoundConfig EconomicsConfig config.EconomicsConfig @@ -92,32 +92,32 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp var err error instance := &coreComponentsHolder{} - instance.internalMarshaller, err = marshalFactory.NewMarshalizer(args.Cfg.Marshalizer.Type) + instance.internalMarshaller, err = marshalFactory.NewMarshalizer(args.Config.Marshalizer.Type) if err != nil { return nil, err } - instance.txMarshaller, err = marshalFactory.NewMarshalizer(args.Cfg.TxSignMarshalizer.Type) + instance.txMarshaller, err = marshalFactory.NewMarshalizer(args.Config.TxSignMarshalizer.Type) if err != nil { return nil, err } - instance.vmMarshaller, err = marshalFactory.NewMarshalizer(args.Cfg.VmMarshalizer.Type) + instance.vmMarshaller, err = marshalFactory.NewMarshalizer(args.Config.VmMarshalizer.Type) if err != nil { return nil, err } - instance.hasher, err = hashingFactory.NewHasher(args.Cfg.Hasher.Type) + instance.hasher, err = hashingFactory.NewHasher(args.Config.Hasher.Type) if err != nil { return nil, err } - instance.txSignHasher, err = hashingFactory.NewHasher(args.Cfg.TxSignHasher.Type) + instance.txSignHasher, err = hashingFactory.NewHasher(args.Config.TxSignHasher.Type) if err != nil { return nil, err } instance.uint64SliceConverter = uint64ByteSlice.NewBigEndianConverter() - instance.addressPubKeyConverter, err = factoryPubKey.NewPubkeyConverter(args.Cfg.AddressPubkeyConverter) + instance.addressPubKeyConverter, err = factoryPubKey.NewPubkeyConverter(args.Config.AddressPubkeyConverter) if err != nil { return nil, err } - instance.validatorPubKeyConverter, err = factoryPubKey.NewPubkeyConverter(args.Cfg.ValidatorPubkeyConverter) + instance.validatorPubKeyConverter, err = factoryPubKey.NewPubkeyConverter(args.Config.ValidatorPubkeyConverter) if err != nil { return nil, err } @@ -125,7 +125,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.pathHandler, err = storageFactory.CreatePathManager( storageFactory.ArgCreatePathManager{ WorkingDir: args.WorkingDir, - ChainID: args.Cfg.GeneralSettings.ChainID, + ChainID: args.Config.GeneralSettings.ChainID, }, ) if err != nil { @@ -139,7 +139,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp //instance.roundHandler instance.wasmVMChangeLocker = &sync.RWMutex{} - instance.txVersionChecker = versioning.NewTxVersionChecker(args.Cfg.GeneralSettings.MinTransactionVersion) + instance.txVersionChecker = versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion) instance.epochNotifier = forking.NewGenericEpochNotifier() instance.enableEpochsHandler, err = enablers.NewEnableEpochsHandler(args.EnableEpochsConfig, instance.epochNotifier) if err != nil { @@ -206,8 +206,8 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.epochStartNotifierWithConfirm = notifier.NewEpochStartSubscriptionHandler() instance.chanStopNodeProcess = args.ChanStopNodeProcess instance.genesisTime = time.Unix(instance.genesisNodesSetup.GetStartTime(), 0) - instance.chainID = args.Cfg.GeneralSettings.ChainID - instance.minTransactionVersion = args.Cfg.GeneralSettings.MinTransactionVersion + instance.chainID = args.Config.GeneralSettings.ChainID + instance.minTransactionVersion = args.Config.GeneralSettings.MinTransactionVersion instance.encodedAddressLen, err = computeEncodedAddressLen(instance.addressPubKeyConverter) if err != nil { return nil, err @@ -216,7 +216,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.nodeTypeProvider = nodetype.NewNodeTypeProvider(core.NodeTypeObserver) instance.processStatusHandler = statusHandler.NewProcessStatusHandler() - pubKeyBytes, err := instance.validatorPubKeyConverter.Decode(args.Cfg.Hardfork.PublicKeyToListenFrom) + pubKeyBytes, err := instance.validatorPubKeyConverter.Decode(args.Config.Hardfork.PublicKeyToListenFrom) if err != nil { return nil, err } diff --git a/node/processingOnlyNode/stateComponents.go b/node/processingOnlyNode/stateComponents.go index cb5e56b85d7..66587f36f77 100644 --- a/node/processingOnlyNode/stateComponents.go +++ b/node/processingOnlyNode/stateComponents.go @@ -10,9 +10,11 @@ import ( "github.com/multiversx/mx-chain-go/state" ) +const NormalProcessingMode = 0 + // ArgsStateComponents will hold the components needed for state components type ArgsStateComponents struct { - Cfg config.Config + Config config.Config CoreComponents factory.CoreComponentsHolder StatusCore factory.StatusCoreComponentsHolder StoreService dataRetriever.StorageService @@ -33,11 +35,11 @@ type stateComponentsHolder struct { // CreateStateComponents will create the state components holder func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHolder, error) { stateComponentsFactory, err := factoryState.NewStateComponentsFactory(factoryState.StateComponentsFactoryArgs{ - Config: args.Cfg, + Config: args.Config, Core: args.CoreComponents, StatusCore: args.StatusCore, StorageService: args.StoreService, - ProcessingMode: 0, + ProcessingMode: NormalProcessingMode, ShouldSerializeSnapshots: false, ChainHandler: args.ChainHandler, }) diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index af80e2e6ec8..9c461a089b6 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -59,7 +59,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } instance.CoreComponentsHolder, err = CreateCoreComponentsHolder(ArgsCoreComponentsHolder{ - Cfg: args.Config, + Config: args.Config, EnableEpochsConfig: args.EnableEpochsConfig, RoundsConfig: args.RoundsConfig, EconomicsConfig: args.EconomicsConfig, @@ -84,7 +84,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } instance.StateComponentsHolder, err = CreateStateComponents(ArgsStateComponents{ - Cfg: args.Config, + Config: args.Config, CoreComponents: instance.CoreComponentsHolder, StatusCore: instance.StatusCoreComponents, StoreService: instance.StoreService, From 8fc962e64ab7e2fa3f5d26657deda685e2401183 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 12:06:52 +0300 Subject: [PATCH 461/958] small fix --- node/processingOnlyNode/stateComponents.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/node/processingOnlyNode/stateComponents.go b/node/processingOnlyNode/stateComponents.go index 66587f36f77..307e7079a7c 100644 --- a/node/processingOnlyNode/stateComponents.go +++ b/node/processingOnlyNode/stateComponents.go @@ -10,8 +10,6 @@ import ( "github.com/multiversx/mx-chain-go/state" ) -const NormalProcessingMode = 0 - // ArgsStateComponents will hold the components needed for state components type ArgsStateComponents struct { Config config.Config @@ -39,7 +37,7 @@ func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHol Core: args.CoreComponents, StatusCore: args.StatusCore, StorageService: args.StoreService, - ProcessingMode: NormalProcessingMode, + ProcessingMode: common.Normal, ShouldSerializeSnapshots: false, ChainHandler: args.ChainHandler, }) From 91163908535cb1e4f9bfd6e78ddb5e5e655f151b Mon Sep 17 00:00:00 2001 From: jules01 Date: Tue, 12 Sep 2023 12:33:09 +0300 Subject: [PATCH 462/958] - added more unit tests --- .../syncedBroadcastNetwork_test.go | 79 +++++ node/processingOnlyNode/syncedMessenger.go | 2 +- .../syncedMessenger_test.go | 274 ++++++++++++++++++ 3 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 node/processingOnlyNode/syncedMessenger_test.go diff --git a/node/processingOnlyNode/syncedBroadcastNetwork_test.go b/node/processingOnlyNode/syncedBroadcastNetwork_test.go index 67fcaa8b2b2..3eb7688c844 100644 --- a/node/processingOnlyNode/syncedBroadcastNetwork_test.go +++ b/node/processingOnlyNode/syncedBroadcastNetwork_test.go @@ -1,6 +1,7 @@ package processingOnlyNode import ( + "fmt" "testing" "github.com/multiversx/mx-chain-communication-go/p2p" @@ -205,6 +206,84 @@ func TestSyncedBroadcastNetwork_SendDirectlyShouldNotDeadlock(t *testing.T) { assert.Nil(t, messages[peer2.ID()][topic]) } +func TestSyncedBroadcastNetwork_ConnectedPeersAndAddresses(t *testing.T) { + t.Parallel() + + network := NewSyncedBroadcastNetwork() + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + + peers := peer1.ConnectedPeers() + assert.Equal(t, 2, len(peers)) + + assert.Contains(t, peers, peer1.ID()) + assert.Contains(t, peers, peer2.ID()) + + assert.True(t, peer1.IsConnected(peer2.ID())) + assert.True(t, peer2.IsConnected(peer1.ID())) + assert.False(t, peer1.IsConnected("no connection")) + + addresses := peer1.ConnectedAddresses() + assert.Equal(t, 2, len(addresses)) + fmt.Println(addresses) + assert.Contains(t, addresses, fmt.Sprintf(virtualAddressTemplate, peer1.ID().Pretty())) + assert.Contains(t, addresses, peer1.Addresses()[0]) + assert.Contains(t, addresses, fmt.Sprintf(virtualAddressTemplate, peer2.ID().Pretty())) + assert.Contains(t, addresses, peer2.Addresses()[0]) +} + +func TestSyncedBroadcastNetwork_GetConnectedPeersOnTopic(t *testing.T) { + t.Parallel() + + globalTopic := "global" + oneTwoTopic := "topic_1_2" + oneThreeTopic := "topic_1_3" + twoThreeTopic := "topic_2_3" + + network := NewSyncedBroadcastNetwork() + + peer1, err := NewSyncedMessenger(network) + assert.Nil(t, err) + _ = peer1.CreateTopic(globalTopic, false) + _ = peer1.CreateTopic(oneTwoTopic, false) + _ = peer1.CreateTopic(oneThreeTopic, false) + + peer2, err := NewSyncedMessenger(network) + assert.Nil(t, err) + _ = peer2.CreateTopic(globalTopic, false) + _ = peer2.CreateTopic(oneTwoTopic, false) + _ = peer2.CreateTopic(twoThreeTopic, false) + + peer3, err := NewSyncedMessenger(network) + assert.Nil(t, err) + _ = peer3.CreateTopic(globalTopic, false) + _ = peer3.CreateTopic(oneThreeTopic, false) + _ = peer3.CreateTopic(twoThreeTopic, false) + + peers := peer1.ConnectedPeersOnTopic(globalTopic) + assert.Equal(t, 3, len(peers)) + assert.Contains(t, peers, peer1.ID()) + assert.Contains(t, peers, peer2.ID()) + assert.Contains(t, peers, peer3.ID()) + + peers = peer1.ConnectedPeersOnTopic(oneTwoTopic) + assert.Equal(t, 2, len(peers)) + assert.Contains(t, peers, peer1.ID()) + assert.Contains(t, peers, peer2.ID()) + + peers = peer3.ConnectedPeersOnTopic(oneThreeTopic) + assert.Equal(t, 2, len(peers)) + assert.Contains(t, peers, peer1.ID()) + assert.Contains(t, peers, peer3.ID()) + + peersInfo := peer1.GetConnectedPeersInfo() + assert.Equal(t, 3, len(peersInfo.UnknownPeers)) +} + func createMessageProcessor(dataMap map[core.PeerID]map[string][]byte, pid core.PeerID) p2p.MessageProcessor { return &p2pmocks.MessageProcessorStub{ ProcessReceivedMessageCalled: func(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error { diff --git a/node/processingOnlyNode/syncedMessenger.go b/node/processingOnlyNode/syncedMessenger.go index 48c0e4df65b..8aba125f995 100644 --- a/node/processingOnlyNode/syncedMessenger.go +++ b/node/processingOnlyNode/syncedMessenger.go @@ -111,7 +111,7 @@ func (messenger *syncedMessenger) HasTopic(name string) bool { // RegisterMessageProcessor will try to register a message processor on the provided topic & identifier func (messenger *syncedMessenger) RegisterMessageProcessor(topic string, identifier string, handler p2p.MessageProcessor) error { - if handler.IsInterfaceNil() { + if check.IfNil(handler) { return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, "+ "provided handler is nil for topic %s and identifier %s", topic, identifier) } diff --git a/node/processingOnlyNode/syncedMessenger_test.go b/node/processingOnlyNode/syncedMessenger_test.go new file mode 100644 index 00000000000..6e16fb7dcdb --- /dev/null +++ b/node/processingOnlyNode/syncedMessenger_test.go @@ -0,0 +1,274 @@ +package processingOnlyNode + +import ( + "fmt" + "testing" + + "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" + "github.com/stretchr/testify/assert" +) + +func TestNewSyncedMessenger(t *testing.T) { + t.Parallel() + + t.Run("nil network should error", func(t *testing.T) { + t.Parallel() + + messenger, err := NewSyncedMessenger(nil) + assert.Nil(t, messenger) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "nil network") + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + messenger, err := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + assert.NotNil(t, messenger) + assert.Nil(t, err) + }) +} + +func TestSyncedMessenger_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var messenger *syncedMessenger + assert.True(t, messenger.IsInterfaceNil()) + + messenger, _ = NewSyncedMessenger(NewSyncedBroadcastNetwork()) + assert.False(t, messenger.IsInterfaceNil()) +} + +func TestSyncedMessenger_DisabledMethodsShouldNotPanic(t *testing.T) { + t.Parallel() + + defer func() { + r := recover() + if r != nil { + assert.Fail(t, fmt.Sprintf("should have not panicked: %v", r)) + } + }() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + assert.Nil(t, messenger.Close()) + assert.Nil(t, messenger.AddPeerTopicNotifier(nil)) + assert.Zero(t, messenger.Port()) + assert.Nil(t, messenger.SetPeerDenialEvaluator(nil)) + assert.Nil(t, messenger.SetThresholdMinConnectedPeers(0)) + assert.Zero(t, messenger.ThresholdMinConnectedPeers()) + assert.True(t, messenger.IsConnectedToTheNetwork()) + assert.Nil(t, messenger.SetPeerShardResolver(nil)) + assert.Nil(t, messenger.ConnectToPeer("")) + assert.Nil(t, messenger.Bootstrap()) + assert.Nil(t, messenger.ProcessReceivedMessage(nil, "", nil)) + + messenger.WaitForConnections(0, 0) + + buff, err := messenger.SignUsingPrivateKey(nil, nil) + assert.Empty(t, buff) + assert.Nil(t, err) +} + +func TestSyncedMessenger_RegisterMessageProcessor(t *testing.T) { + t.Parallel() + + t.Run("nil message processor should error", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + err := messenger.RegisterMessageProcessor("", "", nil) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "provided handler is nil for topic") + }) + t.Run("topic not created should error", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + err := messenger.RegisterMessageProcessor("t", "", &p2pmocks.MessageProcessorStub{}) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "topic t does not exists") + }) + t.Run("processor exists, should error", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + err := messenger.CreateTopic("t", false) + assert.Nil(t, err) + + processor1 := &p2pmocks.MessageProcessorStub{} + err = messenger.RegisterMessageProcessor("t", "i", processor1) + assert.Nil(t, err) + + processor2 := &p2pmocks.MessageProcessorStub{} + err = messenger.RegisterMessageProcessor("t", "i", processor2) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "topic t already contains a registered processor for identifier i") + + messenger.mutOperation.RLock() + defer messenger.mutOperation.RUnlock() + + assert.True(t, messenger.topics["t"]["i"] == processor1) // pointer testing + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + err := messenger.CreateTopic("t", false) + assert.Nil(t, err) + + processor := &p2pmocks.MessageProcessorStub{} + err = messenger.RegisterMessageProcessor("t", "i", processor) + assert.Nil(t, err) + + messenger.mutOperation.RLock() + defer messenger.mutOperation.RUnlock() + + assert.True(t, messenger.topics["t"]["i"] == processor) // pointer testing + }) +} + +func TestSyncedMessenger_UnregisterAllMessageProcessors(t *testing.T) { + t.Parallel() + + t.Run("no topics should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics) + messenger.mutOperation.RUnlock() + + err := messenger.UnregisterAllMessageProcessors() + assert.Nil(t, err) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics) + messenger.mutOperation.RUnlock() + }) + t.Run("one topic but no processor should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + topic := "topic" + _ = messenger.CreateTopic(topic, true) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics[topic]) + messenger.mutOperation.RUnlock() + + err := messenger.UnregisterAllMessageProcessors() + assert.Nil(t, err) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics[topic]) + messenger.mutOperation.RUnlock() + }) + t.Run("one topic with processor should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + topic := "topic" + identifier := "identifier" + _ = messenger.CreateTopic(topic, true) + _ = messenger.RegisterMessageProcessor(topic, identifier, &p2pmocks.MessageProcessorStub{}) + + messenger.mutOperation.RLock() + assert.NotNil(t, messenger.topics[topic][identifier]) + messenger.mutOperation.RUnlock() + + err := messenger.UnregisterAllMessageProcessors() + assert.Nil(t, err) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics[topic]) + messenger.mutOperation.RUnlock() + }) +} + +func TestSyncedMessenger_UnregisterMessageProcessor(t *testing.T) { + t.Parallel() + + t.Run("topic not found should error", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + topic := "topic" + identifier := "identifier" + err := messenger.UnregisterMessageProcessor(topic, identifier) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "syncedMessenger.UnregisterMessageProcessor, topic topic does not exists") + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + topic := "topic" + identifier1 := "identifier1" + identifier2 := "identifier2" + + _ = messenger.CreateTopic(topic, true) + _ = messenger.RegisterMessageProcessor(topic, identifier1, &p2pmocks.MessageProcessorStub{}) + _ = messenger.RegisterMessageProcessor(topic, identifier2, &p2pmocks.MessageProcessorStub{}) + + messenger.mutOperation.RLock() + assert.Equal(t, 2, len(messenger.topics[topic])) + assert.NotNil(t, messenger.topics[topic][identifier1]) + assert.NotNil(t, messenger.topics[topic][identifier2]) + messenger.mutOperation.RUnlock() + + err := messenger.UnregisterMessageProcessor(topic, identifier1) + assert.Nil(t, err) + + messenger.mutOperation.RLock() + assert.Equal(t, 1, len(messenger.topics[topic])) + assert.NotNil(t, messenger.topics[topic][identifier2]) + messenger.mutOperation.RUnlock() + }) +} + +func TestSyncedMessenger_UnJoinAllTopics(t *testing.T) { + t.Parallel() + + t.Run("no topics registered should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics) + messenger.mutOperation.RUnlock() + + err := messenger.UnJoinAllTopics() + assert.Nil(t, err) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics) + messenger.mutOperation.RUnlock() + }) + t.Run("one registered topic should work", func(t *testing.T) { + t.Parallel() + + messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) + topic := "topic" + _ = messenger.CreateTopic(topic, true) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics[topic]) + messenger.mutOperation.RUnlock() + + err := messenger.UnJoinAllTopics() + assert.Nil(t, err) + + messenger.mutOperation.RLock() + assert.Empty(t, messenger.topics) + messenger.mutOperation.RUnlock() + }) +} From 63e10acbcf71ee89290e3b73eaee3a04b2292c9f Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 14:12:31 +0300 Subject: [PATCH 463/958] crypto components --- node/processingOnlyNode/cryptoComponents.go | 234 +++++++++++++++++- .../testOnlyProcessingNode.go | 13 + 2 files changed, 246 insertions(+), 1 deletion(-) diff --git a/node/processingOnlyNode/cryptoComponents.go b/node/processingOnlyNode/cryptoComponents.go index fa747bb0127..23212f80773 100644 --- a/node/processingOnlyNode/cryptoComponents.go +++ b/node/processingOnlyNode/cryptoComponents.go @@ -1,3 +1,235 @@ package processingOnlyNode -// TODO implement in next PR +import ( + "fmt" + + "github.com/multiversx/mx-chain-core-go/core" + crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-go/common" + cryptoCommon "github.com/multiversx/mx-chain-go/common/crypto" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/factory" + cryptoComp "github.com/multiversx/mx-chain-go/factory/crypto" + "github.com/multiversx/mx-chain-go/vm" +) + +type ArgsCryptoComponentsHolder struct { + Config config.Config + EnableEpochsConfig config.EnableEpochs + Preferences config.Preferences + CoreComponentsHolder factory.CoreComponentsHolder + ValidatorKeyPemFileName string +} + +type cryptoComponentsHolder struct { + publicKey crypto.PublicKey + privateKey crypto.PrivateKey + p2pPublicKey crypto.PublicKey + p2pPrivateKey crypto.PrivateKey + p2pSingleSigner crypto.SingleSigner + txSingleSigner crypto.SingleSigner + blockSigner crypto.SingleSigner + multiSignerContainer cryptoCommon.MultiSignerContainer + peerSignatureHandler crypto.PeerSignatureHandler + blockSignKeyGen crypto.KeyGenerator + txSignKeyGen crypto.KeyGenerator + p2pKeyGen crypto.KeyGenerator + messageSignVerifier vm.MessageSignVerifier + consensusSigningHandler consensus.SigningHandler + managedPeersHolder common.ManagedPeersHolder + keysHandler consensus.KeysHandler + publicKeyBytes []byte + publicKeyString string +} + +func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHolder, error) { + instance := &cryptoComponentsHolder{} + + cryptoComponentsHandlerArgs := cryptoComp.CryptoComponentsFactoryArgs{ + Config: args.Config, + EnableEpochs: args.EnableEpochsConfig, + PrefsConfig: args.Preferences, + CoreComponentsHolder: args.CoreComponentsHolder, + KeyLoader: core.NewKeyLoader(), + ActivateBLSPubKeyMessageVerification: true, + IsInImportMode: false, + ImportModeNoSigCheck: false, + NoKeyProvided: false, + + P2pKeyPemFileName: "", + ValidatorKeyPemFileName: args.ValidatorKeyPemFileName, + AllValidatorKeysPemFileName: "", + SkIndex: 0, + } + + cryptoComponentsFactory, err := cryptoComp.NewCryptoComponentsFactory(cryptoComponentsHandlerArgs) + if err != nil { + return nil, fmt.Errorf("NewCryptoComponentsFactory failed: %w", err) + } + + managedCryptoComponents, err := cryptoComp.NewManagedCryptoComponents(cryptoComponentsFactory) + if err != nil { + return nil, err + } + + err = managedCryptoComponents.Create() + if err != nil { + return nil, err + } + + instance.publicKey = managedCryptoComponents.PublicKey() + instance.privateKey = managedCryptoComponents.PrivateKey() + instance.publicKeyBytes, err = instance.publicKey.ToByteArray() + instance.publicKeyString, err = args.CoreComponentsHolder.ValidatorPubKeyConverter().Encode(instance.publicKeyBytes) + if err != nil { + return nil, err + } + + instance.p2pPublicKey = managedCryptoComponents.P2pPublicKey() + instance.p2pPrivateKey = managedCryptoComponents.P2pPrivateKey() + instance.p2pSingleSigner = managedCryptoComponents.P2pSingleSigner() + instance.blockSigner = managedCryptoComponents.BlockSigner() + instance.txSingleSigner = managedCryptoComponents.TxSingleSigner() + instance.multiSignerContainer = managedCryptoComponents.MultiSignerContainer() + instance.peerSignatureHandler = managedCryptoComponents.PeerSignatureHandler() + instance.blockSignKeyGen = managedCryptoComponents.BlockSignKeyGen() + instance.txSignKeyGen = managedCryptoComponents.TxSignKeyGen() + instance.p2pKeyGen = managedCryptoComponents.P2pKeyGen() + instance.messageSignVerifier = managedCryptoComponents.MessageSignVerifier() + instance.consensusSigningHandler = managedCryptoComponents.ConsensusSigningHandler() + instance.managedPeersHolder = managedCryptoComponents.ManagedPeersHolder() + instance.keysHandler = managedCryptoComponents.KeysHandler() + + return instance, nil +} + +// PublicKey will return the public key +func (c *cryptoComponentsHolder) PublicKey() crypto.PublicKey { + return c.publicKey +} + +// PrivateKey will return the private key +func (c *cryptoComponentsHolder) PrivateKey() crypto.PrivateKey { + return c.privateKey +} + +// PublicKeyString will return the private key string +func (c *cryptoComponentsHolder) PublicKeyString() string { + return c.publicKeyString +} + +// PublicKeyBytes will return the public key bytes +func (c *cryptoComponentsHolder) PublicKeyBytes() []byte { + return c.publicKeyBytes +} + +// P2pPublicKey will return the p2p public key +func (c *cryptoComponentsHolder) P2pPublicKey() crypto.PublicKey { + return c.p2pPublicKey +} + +// P2pPrivateKey will return the p2p private key +func (c *cryptoComponentsHolder) P2pPrivateKey() crypto.PrivateKey { + return c.p2pPrivateKey +} + +// P2pSingleSigner will return the p2p single signer +func (c *cryptoComponentsHolder) P2pSingleSigner() crypto.SingleSigner { + return c.p2pSingleSigner +} + +// TxSingleSigner will return the transaction single signer +func (c *cryptoComponentsHolder) TxSingleSigner() crypto.SingleSigner { + return c.txSingleSigner +} + +// BlockSigner will return the block signer +func (c *cryptoComponentsHolder) BlockSigner() crypto.SingleSigner { + return c.blockSigner +} + +// SetMultiSignerContainer will set the multi signer container +func (c *cryptoComponentsHolder) SetMultiSignerContainer(container cryptoCommon.MultiSignerContainer) error { + c.multiSignerContainer = container + + return nil +} + +// MultiSignerContainer will return the multi signer container +func (c *cryptoComponentsHolder) MultiSignerContainer() cryptoCommon.MultiSignerContainer { + return c.multiSignerContainer +} + +// GetMultiSigner will return the multi signer by epoch +func (c *cryptoComponentsHolder) GetMultiSigner(epoch uint32) (crypto.MultiSigner, error) { + return c.MultiSignerContainer().GetMultiSigner(epoch) +} + +// PeerSignatureHandler will return the peer signature handler +func (c *cryptoComponentsHolder) PeerSignatureHandler() crypto.PeerSignatureHandler { + return c.peerSignatureHandler +} + +// BlockSignKeyGen will return the block signer key generator +func (c *cryptoComponentsHolder) BlockSignKeyGen() crypto.KeyGenerator { + return c.blockSignKeyGen +} + +// TxSignKeyGen will return the transaction sign key generator +func (c *cryptoComponentsHolder) TxSignKeyGen() crypto.KeyGenerator { + return c.txSignKeyGen +} + +// P2pKeyGen will return the p2p key generator +func (c *cryptoComponentsHolder) P2pKeyGen() crypto.KeyGenerator { + return c.p2pKeyGen +} + +// MessageSignVerifier will return the message signature verifier +func (c *cryptoComponentsHolder) MessageSignVerifier() vm.MessageSignVerifier { + return c.messageSignVerifier +} + +// ConsensusSigningHandler will return the consensus signing handler +func (c *cryptoComponentsHolder) ConsensusSigningHandler() consensus.SigningHandler { + return c.consensusSigningHandler +} + +// ManagedPeersHolder will return the managed peer holder +func (c *cryptoComponentsHolder) ManagedPeersHolder() common.ManagedPeersHolder { + return c.managedPeersHolder +} + +// KeysHandler will return the keys handler +func (c *cryptoComponentsHolder) KeysHandler() consensus.KeysHandler { + return c.keysHandler +} + +// Clone will clone the cryptoComponentsHolder +func (c *cryptoComponentsHolder) Clone() interface{} { + return &cryptoComponentsHolder{ + publicKey: c.PublicKey(), + privateKey: c.PrivateKey(), + p2pPublicKey: c.P2pPublicKey(), + p2pPrivateKey: c.P2pPrivateKey(), + p2pSingleSigner: c.P2pSingleSigner(), + txSingleSigner: c.TxSingleSigner(), + blockSigner: c.BlockSigner(), + multiSignerContainer: c.MultiSignerContainer(), + peerSignatureHandler: c.PeerSignatureHandler(), + blockSignKeyGen: c.BlockSignKeyGen(), + txSignKeyGen: c.TxSignKeyGen(), + p2pKeyGen: c.P2pKeyGen(), + messageSignVerifier: c.MessageSignVerifier(), + consensusSigningHandler: c.ConsensusSigningHandler(), + managedPeersHolder: c.ManagedPeersHolder(), + keysHandler: c.KeysHandler(), + publicKeyBytes: c.PublicKeyBytes(), + publicKeyString: c.PublicKeyString(), + } +} + +func (c *cryptoComponentsHolder) IsInterfaceNil() bool { + return c == nil +} diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/processingOnlyNode/testOnlyProcessingNode.go index 9c461a089b6..b34d6da447d 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/processingOnlyNode/testOnlyProcessingNode.go @@ -23,8 +23,10 @@ type ArgsTestOnlyProcessingNode struct { EnableEpochsConfig config.EnableEpochs EconomicsConfig config.EconomicsConfig RoundsConfig config.RoundConfig + PreferencesConfig config.Preferences ChanStopNodeProcess chan endProcess.ArgEndProcess GasScheduleFilename string + ValidatorPemFile string WorkingDir string NodesSetupPath string NumShards uint32 @@ -36,6 +38,7 @@ type testOnlyProcessingNode struct { StatusCoreComponents factory.StatusCoreComponentsHolder StateComponentsHolder factory.StateComponentsHolder StatusComponentsHolder factory.StatusComponentsHolder + CryptoComponentsHolder factory.CryptoComponentsHolder ChainHandler chainData.ChainHandler ShardCoordinator sharding.Coordinator @@ -97,6 +100,16 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces if err != nil { return nil, err } + instance.CryptoComponentsHolder, err = CreateCryptoComponentsHolder(ArgsCryptoComponentsHolder{ + Config: args.Config, + EnableEpochsConfig: args.EnableEpochsConfig, + Preferences: args.PreferencesConfig, + CoreComponentsHolder: instance.CoreComponentsHolder, + ValidatorKeyPemFileName: args.ValidatorPemFile, + }) + if err != nil { + return nil, err + } err = instance.createDataPool(args) if err != nil { From 968118eb792923efc3a72a2f15715450300e4a94 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 14:24:47 +0300 Subject: [PATCH 464/958] fix test --- cmd/node/config/testKeys/validatorKey.pem | 4 ++++ node/processingOnlyNode/testOnlyProcessingNode_test.go | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 cmd/node/config/testKeys/validatorKey.pem diff --git a/cmd/node/config/testKeys/validatorKey.pem b/cmd/node/config/testKeys/validatorKey.pem new file mode 100644 index 00000000000..e4e7ec71328 --- /dev/null +++ b/cmd/node/config/testKeys/validatorKey.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY for 75907bf66c64949f8d1dd003ed8fd815e8dec189a9e50e4bfd7e2592cfdc92641baf500e3533820e0f58c4ed3f39c01750f0017726731fe5bc66a0ab6fc9a7b5661d163e72f099fe29df16fd59ded198dc1423575be1b6e2160e0d84a5ece08a----- +MmVkOGZmZDRmNWQ5NjIyMjU5YjRiYjE2OGQ5ZTk2YjYxMjIyMmMwOGU5NTM4MTcz +MGVkMzI3ODY4Y2I2NDUwNA== +-----END PRIVATE KEY for 75907bf66c64949f8d1dd003ed8fd815e8dec189a9e50e4bfd7e2592cfdc92641baf500e3533820e0f58c4ed3f39c01750f0017726731fe5bc66a0ab6fc9a7b5661d163e72f099fe29df16fd59ded198dc1423575be1b6e2160e0d84a5ece08a----- diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/processingOnlyNode/testOnlyProcessingNode_test.go index e23b4d389a6..3a293c4c69b 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode_test.go +++ b/node/processingOnlyNode/testOnlyProcessingNode_test.go @@ -11,6 +11,8 @@ const pathForMainConfig = "../../cmd/node/config/config.toml" const pathForEconomicsConfig = "../../cmd/node/config/economics.toml" const pathForGasSchedules = "../../cmd/node/config/gasSchedules" const nodesSetupConfig = "../../cmd/node/config/nodesSetup.json" +const pathForPrefsConfig = "../../cmd/node/config/prefs.toml" +const validatorPemFile = "../../cmd/node/config/testKeys/validatorKey.pem" func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { mainConfig := config.Config{} @@ -24,6 +26,10 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo gasScheduleName, err := GetLatestGasScheduleFilename(pathForGasSchedules) assert.Nil(t, err) + prefsConfig := config.Preferences{} + err = LoadConfigFromFile(pathForPrefsConfig, &prefsConfig) + assert.Nil(t, err) + return ArgsTestOnlyProcessingNode{ Config: mainConfig, EnableEpochsConfig: config.EnableEpochs{}, @@ -39,6 +45,8 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo NodesSetupPath: nodesSetupConfig, NumShards: 3, ShardID: 0, + ValidatorPemFile: validatorPemFile, + PreferencesConfig: prefsConfig, } } From 4ad9950627501a8a309e310c436edd6ea3df35a6 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 14:34:25 +0300 Subject: [PATCH 465/958] fix test 2 --- node/processingOnlyNode/testOnlyProcessingNode_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/processingOnlyNode/testOnlyProcessingNode_test.go index 3a293c4c69b..3407b80eb52 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode_test.go +++ b/node/processingOnlyNode/testOnlyProcessingNode_test.go @@ -31,8 +31,12 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo assert.Nil(t, err) return ArgsTestOnlyProcessingNode{ - Config: mainConfig, - EnableEpochsConfig: config.EnableEpochs{}, + Config: mainConfig, + EnableEpochsConfig: config.EnableEpochs{ + BLSMultiSignerEnableEpoch: []config.MultiSignerConfig{ + {EnableEpoch: 0, Type: "KOSK"}, + }, + }, RoundsConfig: config.RoundConfig{ RoundActivations: map[string]config.ActivationRoundByName{ "DisableAsyncCallV1": { From 09ed57627aa955a13373e2cde6e7ad7b28479e65 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 14:39:36 +0300 Subject: [PATCH 466/958] error check --- node/processingOnlyNode/cryptoComponents.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/processingOnlyNode/cryptoComponents.go b/node/processingOnlyNode/cryptoComponents.go index 23212f80773..52d214ddc1e 100644 --- a/node/processingOnlyNode/cryptoComponents.go +++ b/node/processingOnlyNode/cryptoComponents.go @@ -81,6 +81,9 @@ func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.Cryp instance.publicKey = managedCryptoComponents.PublicKey() instance.privateKey = managedCryptoComponents.PrivateKey() instance.publicKeyBytes, err = instance.publicKey.ToByteArray() + if err != nil { + return nil, err + } instance.publicKeyString, err = args.CoreComponentsHolder.ValidatorPubKeyConverter().Encode(instance.publicKeyBytes) if err != nil { return nil, err From 4600d241f16ad9d7faa98f5b5efad842917f3199 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Sep 2023 15:28:51 +0300 Subject: [PATCH 467/958] fixes --- node/processingOnlyNode/cryptoComponents.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/processingOnlyNode/cryptoComponents.go b/node/processingOnlyNode/cryptoComponents.go index 52d214ddc1e..82c8e26979a 100644 --- a/node/processingOnlyNode/cryptoComponents.go +++ b/node/processingOnlyNode/cryptoComponents.go @@ -14,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-go/vm" ) +// ArgsCryptoComponentsHolder holds all arguments needed to create a crypto components holder type ArgsCryptoComponentsHolder struct { Config config.Config EnableEpochsConfig config.EnableEpochs @@ -43,6 +44,7 @@ type cryptoComponentsHolder struct { publicKeyString string } +// CreateCryptoComponentsHolder will create a new instance of cryptoComponentsHolder func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHolder, error) { instance := &cryptoComponentsHolder{} From 77b84b85da6f1c8b303899be5ba7b2571ed96429 Mon Sep 17 00:00:00 2001 From: jules01 Date: Tue, 12 Sep 2023 15:31:01 +0300 Subject: [PATCH 468/958] - fixes after review --- .../syncedBroadcastNetwork.go | 13 ++++++-- .../syncedBroadcastNetwork_test.go | 1 - node/processingOnlyNode/syncedMessenger.go | 32 ++++++++++++------- .../syncedMessenger_test.go | 15 +++------ 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/node/processingOnlyNode/syncedBroadcastNetwork.go b/node/processingOnlyNode/syncedBroadcastNetwork.go index c6fef5c1d1f..23ae2a2e211 100644 --- a/node/processingOnlyNode/syncedBroadcastNetwork.go +++ b/node/processingOnlyNode/syncedBroadcastNetwork.go @@ -1,6 +1,7 @@ package processingOnlyNode import ( + "errors" "fmt" "sync" @@ -9,6 +10,12 @@ import ( "github.com/multiversx/mx-chain-core-go/core" ) +var ( + errNilHandler = errors.New("nil handler") + errHandlerAlreadyExists = errors.New("handler already exists") + errUnknownPeer = errors.New("unknown peer") +) + type messageReceiver interface { receive(fromConnectedPeer core.PeerID, message p2p.MessageP2P) HasTopic(name string) bool @@ -29,7 +36,7 @@ func NewSyncedBroadcastNetwork() *syncedBroadcastNetwork { // RegisterMessageReceiver registers the message receiver func (network *syncedBroadcastNetwork) RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) { if handler == nil { - log.Error("programming error in syncedBroadcastNetwork.RegisterMessageReceiver: nil handler") + log.Error("programming error in syncedBroadcastNetwork.RegisterMessageReceiver: %w", errNilHandler) return } @@ -38,7 +45,7 @@ func (network *syncedBroadcastNetwork) RegisterMessageReceiver(handler messageRe _, found := network.peers[pid] if found { - log.Error("programming error in syncedBroadcastNetwork.RegisterMessageReceiver: handler already exists", "pid", pid.Pretty()) + log.Error("programming error in syncedBroadcastNetwork.RegisterMessageReceiver", "pid", pid.Pretty(), "error", errHandlerAlreadyExists) return } @@ -68,7 +75,7 @@ func (network *syncedBroadcastNetwork) SendDirectly(from core.PeerID, topic stri if !found { network.mutOperation.RUnlock() - return fmt.Errorf("syncedBroadcastNetwork.SendDirectly: trying to send to an unknwon peer, pid %s", to.Pretty()) + return fmt.Errorf("syncedBroadcastNetwork.SendDirectly: %w, pid %s", errUnknownPeer, to.Pretty()) } network.mutOperation.RUnlock() diff --git a/node/processingOnlyNode/syncedBroadcastNetwork_test.go b/node/processingOnlyNode/syncedBroadcastNetwork_test.go index 3eb7688c844..29b97340b17 100644 --- a/node/processingOnlyNode/syncedBroadcastNetwork_test.go +++ b/node/processingOnlyNode/syncedBroadcastNetwork_test.go @@ -229,7 +229,6 @@ func TestSyncedBroadcastNetwork_ConnectedPeersAndAddresses(t *testing.T) { addresses := peer1.ConnectedAddresses() assert.Equal(t, 2, len(addresses)) - fmt.Println(addresses) assert.Contains(t, addresses, fmt.Sprintf(virtualAddressTemplate, peer1.ID().Pretty())) assert.Contains(t, addresses, peer1.Addresses()[0]) assert.Contains(t, addresses, fmt.Sprintf(virtualAddressTemplate, peer2.ID().Pretty())) diff --git a/node/processingOnlyNode/syncedMessenger.go b/node/processingOnlyNode/syncedMessenger.go index 8aba125f995..9b2375225e3 100644 --- a/node/processingOnlyNode/syncedMessenger.go +++ b/node/processingOnlyNode/syncedMessenger.go @@ -17,9 +17,17 @@ import ( const virtualAddressTemplate = "/virtual/p2p/%s" -var log = logger.GetOrCreate("node/chainSimulator") -var p2pInstanceCreator, _ = crypto.NewIdentityGenerator(log) -var hasher = blake2b.NewBlake2b() +var ( + log = logger.GetOrCreate("node/chainSimulator") + p2pInstanceCreator, _ = crypto.NewIdentityGenerator(log) + hasher = blake2b.NewBlake2b() + errNilNetwork = errors.New("nil network") + errTopicAlreadyCreated = errors.New("topic already created") + errNilMessageProcessor = errors.New("nil message processor") + errTopicNotCreated = errors.New("topic not created") + errTopicHasProcessor = errors.New("there is already a message processor for provided topic and identifier") + errInvalidSignature = errors.New("invalid signature") +) type syncedBroadcastNetworkHandler interface { RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) @@ -40,7 +48,7 @@ type syncedMessenger struct { // NewSyncedMessenger creates a new synced network messenger func NewSyncedMessenger(network syncedBroadcastNetworkHandler) (*syncedMessenger, error) { if check.IfNil(network) { - return nil, fmt.Errorf("nil network") + return nil, errNilNetwork } _, pid, err := p2pInstanceCreator.CreateRandomP2PIdentity() @@ -91,7 +99,7 @@ func (messenger *syncedMessenger) CreateTopic(name string, _ bool) error { _, found := messenger.topics[name] if found { - return fmt.Errorf("programming error in syncedMessenger.CreateTopic, topic already created, topic %s", name) + return fmt.Errorf("programming error in syncedMessenger.CreateTopic, %w for topic %s", errTopicAlreadyCreated, name) } messenger.topics[name] = make(map[string]p2p.MessageProcessor, 0) @@ -113,7 +121,7 @@ func (messenger *syncedMessenger) HasTopic(name string) bool { func (messenger *syncedMessenger) RegisterMessageProcessor(topic string, identifier string, handler p2p.MessageProcessor) error { if check.IfNil(handler) { return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, "+ - "provided handler is nil for topic %s and identifier %s", topic, identifier) + "%w for topic %s and identifier %s", errNilMessageProcessor, topic, identifier) } messenger.mutOperation.Lock() @@ -121,13 +129,14 @@ func (messenger *syncedMessenger) RegisterMessageProcessor(topic string, identif handlers, found := messenger.topics[topic] if !found { - return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, topic %s does not exists", topic) + return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, %w for topic %s", + errTopicNotCreated, topic) } _, found = handlers[identifier] if found { - return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, topic %s already "+ - "contains a registered processor for identifier %s", topic, identifier) + return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, %w, topic %s, identifier %s", + errTopicHasProcessor, topic, identifier) } handlers[identifier] = handler @@ -154,7 +163,8 @@ func (messenger *syncedMessenger) UnregisterMessageProcessor(topic string, ident handlers, found := messenger.topics[topic] if !found { - return fmt.Errorf("programming error in syncedMessenger.UnregisterMessageProcessor, topic %s does not exists", topic) + return fmt.Errorf("programming error in syncedMessenger.UnregisterMessageProcessor, %w for topic %s", + errTopicNotCreated, topic) } delete(handlers, identifier) @@ -330,7 +340,7 @@ func (messenger *syncedMessenger) Verify(payload []byte, pid core.PeerID, signat return nil } - return errors.New("invalid signature") + return errInvalidSignature } // SignUsingPrivateKey will return an empty byte slice diff --git a/node/processingOnlyNode/syncedMessenger_test.go b/node/processingOnlyNode/syncedMessenger_test.go index 6e16fb7dcdb..7d3eba84b00 100644 --- a/node/processingOnlyNode/syncedMessenger_test.go +++ b/node/processingOnlyNode/syncedMessenger_test.go @@ -16,8 +16,7 @@ func TestNewSyncedMessenger(t *testing.T) { messenger, err := NewSyncedMessenger(nil) assert.Nil(t, messenger) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "nil network") + assert.Equal(t, errNilNetwork, err) }) t.Run("should work", func(t *testing.T) { t.Parallel() @@ -78,8 +77,7 @@ func TestSyncedMessenger_RegisterMessageProcessor(t *testing.T) { messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) err := messenger.RegisterMessageProcessor("", "", nil) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "provided handler is nil for topic") + assert.ErrorIs(t, err, errNilMessageProcessor) }) t.Run("topic not created should error", func(t *testing.T) { t.Parallel() @@ -87,8 +85,7 @@ func TestSyncedMessenger_RegisterMessageProcessor(t *testing.T) { messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) err := messenger.RegisterMessageProcessor("t", "", &p2pmocks.MessageProcessorStub{}) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "topic t does not exists") + assert.ErrorIs(t, err, errTopicNotCreated) }) t.Run("processor exists, should error", func(t *testing.T) { t.Parallel() @@ -104,8 +101,7 @@ func TestSyncedMessenger_RegisterMessageProcessor(t *testing.T) { processor2 := &p2pmocks.MessageProcessorStub{} err = messenger.RegisterMessageProcessor("t", "i", processor2) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "topic t already contains a registered processor for identifier i") + assert.ErrorIs(t, err, errTopicHasProcessor) messenger.mutOperation.RLock() defer messenger.mutOperation.RUnlock() @@ -202,8 +198,7 @@ func TestSyncedMessenger_UnregisterMessageProcessor(t *testing.T) { topic := "topic" identifier := "identifier" err := messenger.UnregisterMessageProcessor(topic, identifier) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "syncedMessenger.UnregisterMessageProcessor, topic topic does not exists") + assert.ErrorIs(t, err, errTopicNotCreated) }) t.Run("should work", func(t *testing.T) { t.Parallel() From 6dd5b7b8c2fbac3cb33548ad08b62b165c1f21b9 Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 13 Sep 2023 10:43:03 +0300 Subject: [PATCH 469/958] - renamed the package - added networkComponents --- .../configLoaders.go | 2 +- .../coreComponents.go | 2 +- .../cryptoComponents.go | 2 +- node/chainSimulator/disabled/antiflooder.go | 72 ++++++++++++ node/chainSimulator/disabled/peerHonesty.go | 23 ++++ .../disabled/peersRatingMonitor.go | 21 ++++ node/chainSimulator/interface.go | 13 +++ .../memoryComponents.go | 2 +- node/chainSimulator/networkComponents.go | 108 ++++++++++++++++++ .../stateComponents.go | 2 +- .../statusComponents.go | 2 +- .../statusCoreComponents.go | 2 +- .../storageService.go | 2 +- .../syncedBroadcastNetwork.go | 2 +- .../syncedBroadcastNetwork_test.go | 2 +- .../syncedMessenger.go | 15 +-- .../syncedMessenger_test.go | 2 +- .../testOnlyProcessingNode.go | 43 ++++--- .../testOnlyProcessingNode_test.go | 17 +-- 19 files changed, 285 insertions(+), 49 deletions(-) rename node/{processingOnlyNode => chainSimulator}/configLoaders.go (97%) rename node/{processingOnlyNode => chainSimulator}/coreComponents.go (99%) rename node/{processingOnlyNode => chainSimulator}/cryptoComponents.go (99%) create mode 100644 node/chainSimulator/disabled/antiflooder.go create mode 100644 node/chainSimulator/disabled/peerHonesty.go create mode 100644 node/chainSimulator/disabled/peersRatingMonitor.go create mode 100644 node/chainSimulator/interface.go rename node/{processingOnlyNode => chainSimulator}/memoryComponents.go (95%) create mode 100644 node/chainSimulator/networkComponents.go rename node/{processingOnlyNode => chainSimulator}/stateComponents.go (99%) rename node/{processingOnlyNode => chainSimulator}/statusComponents.go (98%) rename node/{processingOnlyNode => chainSimulator}/statusCoreComponents.go (99%) rename node/{processingOnlyNode => chainSimulator}/storageService.go (98%) rename node/{processingOnlyNode => chainSimulator}/syncedBroadcastNetwork.go (99%) rename node/{processingOnlyNode => chainSimulator}/syncedBroadcastNetwork_test.go (99%) rename node/{processingOnlyNode => chainSimulator}/syncedMessenger.go (95%) rename node/{processingOnlyNode => chainSimulator}/syncedMessenger_test.go (99%) rename node/{processingOnlyNode => chainSimulator}/testOnlyProcessingNode.go (84%) rename node/{processingOnlyNode => chainSimulator}/testOnlyProcessingNode_test.go (85%) diff --git a/node/processingOnlyNode/configLoaders.go b/node/chainSimulator/configLoaders.go similarity index 97% rename from node/processingOnlyNode/configLoaders.go rename to node/chainSimulator/configLoaders.go index 3de9d7569ed..7e1334d88cd 100644 --- a/node/processingOnlyNode/configLoaders.go +++ b/node/chainSimulator/configLoaders.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "os" diff --git a/node/processingOnlyNode/coreComponents.go b/node/chainSimulator/coreComponents.go similarity index 99% rename from node/processingOnlyNode/coreComponents.go rename to node/chainSimulator/coreComponents.go index be99c71edda..4fd8ba9d9e1 100644 --- a/node/processingOnlyNode/coreComponents.go +++ b/node/chainSimulator/coreComponents.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "bytes" diff --git a/node/processingOnlyNode/cryptoComponents.go b/node/chainSimulator/cryptoComponents.go similarity index 99% rename from node/processingOnlyNode/cryptoComponents.go rename to node/chainSimulator/cryptoComponents.go index 82c8e26979a..4907f94818b 100644 --- a/node/processingOnlyNode/cryptoComponents.go +++ b/node/chainSimulator/cryptoComponents.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "fmt" diff --git a/node/chainSimulator/disabled/antiflooder.go b/node/chainSimulator/disabled/antiflooder.go new file mode 100644 index 00000000000..0d4c45fd0e3 --- /dev/null +++ b/node/chainSimulator/disabled/antiflooder.go @@ -0,0 +1,72 @@ +package disabled + +import ( + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/p2p" + "github.com/multiversx/mx-chain-go/process" +) + +type antiFlooder struct { +} + +// NewAntiFlooder creates a new instance of disabled antiflooder +func NewAntiFlooder() *antiFlooder { + return &antiFlooder{} +} + +// CanProcessMessage returns nil +func (a *antiFlooder) CanProcessMessage(_ p2p.MessageP2P, _ core.PeerID) error { + return nil +} + +// IsOriginatorEligibleForTopic does nothing and returns nil +func (a *antiFlooder) IsOriginatorEligibleForTopic(_ core.PeerID, _ string) error { + return nil +} + +// CanProcessMessagesOnTopic does nothing and returns nil +func (a *antiFlooder) CanProcessMessagesOnTopic(_ core.PeerID, _ string, _ uint32, _ uint64, _ []byte) error { + return nil +} + +// ApplyConsensusSize does nothing +func (a *antiFlooder) ApplyConsensusSize(_ int) { +} + +// SetDebugger does nothing and returns nil +func (a *antiFlooder) SetDebugger(_ process.AntifloodDebugger) error { + return nil +} + +// BlacklistPeer does nothing +func (a *antiFlooder) BlacklistPeer(_ core.PeerID, _ string, _ time.Duration) { +} + +// ResetForTopic does nothing +func (a *antiFlooder) ResetForTopic(_ string) { +} + +// SetMaxMessagesForTopic does nothing +func (a *antiFlooder) SetMaxMessagesForTopic(_ string, _ uint32) { +} + +// SetPeerValidatorMapper does nothing and returns nil +func (a *antiFlooder) SetPeerValidatorMapper(_ process.PeerValidatorMapper) error { + return nil +} + +// SetTopicsForAll does nothing +func (a *antiFlooder) SetTopicsForAll(_ ...string) { +} + +// Close does nothing and returns nil +func (a *antiFlooder) Close() error { + return nil +} + +// IsInterfaceNil returns true if there is no value under the interface +func (a *antiFlooder) IsInterfaceNil() bool { + return a == nil +} diff --git a/node/chainSimulator/disabled/peerHonesty.go b/node/chainSimulator/disabled/peerHonesty.go new file mode 100644 index 00000000000..87552b29e43 --- /dev/null +++ b/node/chainSimulator/disabled/peerHonesty.go @@ -0,0 +1,23 @@ +package disabled + +type peerHonesty struct { +} + +// NewPeerHonesty creates a new instance of disabled peer honesty +func NewPeerHonesty() *peerHonesty { + return &peerHonesty{} +} + +// ChangeScore does nothing +func (p *peerHonesty) ChangeScore(_ string, _ string, _ int) { +} + +// Close does nothing and returns nil +func (p *peerHonesty) Close() error { + return nil +} + +// IsInterfaceNil returns true if there is no value under the interface +func (p *peerHonesty) IsInterfaceNil() bool { + return p == nil +} diff --git a/node/chainSimulator/disabled/peersRatingMonitor.go b/node/chainSimulator/disabled/peersRatingMonitor.go new file mode 100644 index 00000000000..425b63fdc8c --- /dev/null +++ b/node/chainSimulator/disabled/peersRatingMonitor.go @@ -0,0 +1,21 @@ +package disabled + +import "github.com/multiversx/mx-chain-go/p2p" + +type peersRatingMonitor struct { +} + +// NewPeersRatingMonitor will create a new disabled peersRatingMonitor instance +func NewPeersRatingMonitor() *peersRatingMonitor { + return &peersRatingMonitor{} +} + +// GetConnectedPeersRatings returns an empty string since it is a disabled component +func (monitor *peersRatingMonitor) GetConnectedPeersRatings(_ p2p.ConnectionsHandler) (string, error) { + return "", nil +} + +// IsInterfaceNil returns true if there is no value under the interface +func (monitor *peersRatingMonitor) IsInterfaceNil() bool { + return monitor == nil +} diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go new file mode 100644 index 00000000000..911c24449a0 --- /dev/null +++ b/node/chainSimulator/interface.go @@ -0,0 +1,13 @@ +package chainSimulator + +import "github.com/multiversx/mx-chain-core-go/core" + +// SyncedBroadcastNetworkHandler defines the synced network interface +type SyncedBroadcastNetworkHandler interface { + RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) + Broadcast(pid core.PeerID, topic string, buff []byte) + SendDirectly(from core.PeerID, topic string, buff []byte, to core.PeerID) error + GetConnectedPeers() []core.PeerID + GetConnectedPeersOnTopic(topic string) []core.PeerID + IsInterfaceNil() bool +} diff --git a/node/processingOnlyNode/memoryComponents.go b/node/chainSimulator/memoryComponents.go similarity index 95% rename from node/processingOnlyNode/memoryComponents.go rename to node/chainSimulator/memoryComponents.go index 7dd8d43a3e6..3d44fae7508 100644 --- a/node/processingOnlyNode/memoryComponents.go +++ b/node/chainSimulator/memoryComponents.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "github.com/multiversx/mx-chain-go/storage" diff --git a/node/chainSimulator/networkComponents.go b/node/chainSimulator/networkComponents.go new file mode 100644 index 00000000000..c52fea16697 --- /dev/null +++ b/node/chainSimulator/networkComponents.go @@ -0,0 +1,108 @@ +package chainSimulator + +import ( + disabledBootstrap "github.com/multiversx/mx-chain-go/epochStart/bootstrap/disabled" + "github.com/multiversx/mx-chain-go/factory" + disabledFactory "github.com/multiversx/mx-chain-go/factory/disabled" + "github.com/multiversx/mx-chain-go/node/chainSimulator/disabled" + "github.com/multiversx/mx-chain-go/p2p" + disabledP2P "github.com/multiversx/mx-chain-go/p2p/disabled" + "github.com/multiversx/mx-chain-go/process" + disabledAntiflood "github.com/multiversx/mx-chain-go/process/throttle/antiflood/disabled" +) + +type networkComponentsHolder struct { + networkMessenger p2p.Messenger + inputAntiFloodHandler factory.P2PAntifloodHandler + outputAntiFloodHandler factory.P2PAntifloodHandler + pubKeyCacher process.TimeCacher + peerBlackListHandler process.PeerBlackListCacher + peerHonestyHandler factory.PeerHonestyHandler + preferredPeersHolderHandler factory.PreferredPeersHolderHandler + peersRatingHandler p2p.PeersRatingHandler + peersRatingMonitor p2p.PeersRatingMonitor + fullArchiveNetworkMessenger p2p.Messenger + fullArchivePreferredPeersHolderHandler factory.PreferredPeersHolderHandler +} + +// CreateNetworkComponentsHolder creates a new networkComponentsHolder instance +func CreateNetworkComponentsHolder(network SyncedBroadcastNetworkHandler) (*networkComponentsHolder, error) { + messenger, err := NewSyncedMessenger(network) + if err != nil { + return nil, err + } + + return &networkComponentsHolder{ + networkMessenger: messenger, + inputAntiFloodHandler: disabled.NewAntiFlooder(), + outputAntiFloodHandler: disabled.NewAntiFlooder(), + pubKeyCacher: &disabledAntiflood.TimeCache{}, + peerBlackListHandler: &disabledAntiflood.PeerBlacklistCacher{}, + peerHonestyHandler: disabled.NewPeerHonesty(), + preferredPeersHolderHandler: disabledFactory.NewPreferredPeersHolder(), + peersRatingHandler: disabledBootstrap.NewDisabledPeersRatingHandler(), + peersRatingMonitor: disabled.NewPeersRatingMonitor(), + fullArchiveNetworkMessenger: disabledP2P.NewNetworkMessenger(), + fullArchivePreferredPeersHolderHandler: disabledFactory.NewPreferredPeersHolder(), + }, nil +} + +// NetworkMessenger returns the network messenger +func (holder *networkComponentsHolder) NetworkMessenger() p2p.Messenger { + return holder.networkMessenger +} + +// InputAntiFloodHandler returns the input antiflooder +func (holder *networkComponentsHolder) InputAntiFloodHandler() factory.P2PAntifloodHandler { + return holder.inputAntiFloodHandler +} + +// OutputAntiFloodHandler returns the output antiflooder +func (holder *networkComponentsHolder) OutputAntiFloodHandler() factory.P2PAntifloodHandler { + return holder.outputAntiFloodHandler +} + +// PubKeyCacher returns the public key cacher +func (holder *networkComponentsHolder) PubKeyCacher() process.TimeCacher { + return holder.pubKeyCacher +} + +// PeerBlackListHandler returns the peer blacklist handler +func (holder *networkComponentsHolder) PeerBlackListHandler() process.PeerBlackListCacher { + return holder.peerBlackListHandler +} + +// PeerHonestyHandler returns the peer honesty handler +func (holder *networkComponentsHolder) PeerHonestyHandler() factory.PeerHonestyHandler { + return holder.peerHonestyHandler +} + +// PreferredPeersHolderHandler returns the preferred peers holder +func (holder *networkComponentsHolder) PreferredPeersHolderHandler() factory.PreferredPeersHolderHandler { + return holder.preferredPeersHolderHandler +} + +// PeersRatingHandler returns the peers rating handler +func (holder *networkComponentsHolder) PeersRatingHandler() p2p.PeersRatingHandler { + return holder.peersRatingHandler +} + +// PeersRatingMonitor returns the peers rating monitor +func (holder *networkComponentsHolder) PeersRatingMonitor() p2p.PeersRatingMonitor { + return holder.peersRatingMonitor +} + +// FullArchiveNetworkMessenger returns the full archive network messenger +func (holder *networkComponentsHolder) FullArchiveNetworkMessenger() p2p.Messenger { + return holder.fullArchiveNetworkMessenger +} + +// FullArchivePreferredPeersHolderHandler returns the full archive preferred peers holder +func (holder *networkComponentsHolder) FullArchivePreferredPeersHolderHandler() factory.PreferredPeersHolderHandler { + return holder.fullArchivePreferredPeersHolderHandler +} + +// IsInterfaceNil returns true if there is no value under the interface +func (holder *networkComponentsHolder) IsInterfaceNil() bool { + return holder == nil +} diff --git a/node/processingOnlyNode/stateComponents.go b/node/chainSimulator/stateComponents.go similarity index 99% rename from node/processingOnlyNode/stateComponents.go rename to node/chainSimulator/stateComponents.go index 307e7079a7c..8837ac251e5 100644 --- a/node/processingOnlyNode/stateComponents.go +++ b/node/chainSimulator/stateComponents.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( chainData "github.com/multiversx/mx-chain-core-go/data" diff --git a/node/processingOnlyNode/statusComponents.go b/node/chainSimulator/statusComponents.go similarity index 98% rename from node/processingOnlyNode/statusComponents.go rename to node/chainSimulator/statusComponents.go index b05bc82824f..6c8a141499f 100644 --- a/node/processingOnlyNode/statusComponents.go +++ b/node/chainSimulator/statusComponents.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "time" diff --git a/node/processingOnlyNode/statusCoreComponents.go b/node/chainSimulator/statusCoreComponents.go similarity index 99% rename from node/processingOnlyNode/statusCoreComponents.go rename to node/chainSimulator/statusCoreComponents.go index 7d425ee155b..dd02c1460bb 100644 --- a/node/processingOnlyNode/statusCoreComponents.go +++ b/node/chainSimulator/statusCoreComponents.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "github.com/multiversx/mx-chain-core-go/core" diff --git a/node/processingOnlyNode/storageService.go b/node/chainSimulator/storageService.go similarity index 98% rename from node/processingOnlyNode/storageService.go rename to node/chainSimulator/storageService.go index e7d9462afed..c7a566105f2 100644 --- a/node/processingOnlyNode/storageService.go +++ b/node/chainSimulator/storageService.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "github.com/multiversx/mx-chain-go/dataRetriever" diff --git a/node/processingOnlyNode/syncedBroadcastNetwork.go b/node/chainSimulator/syncedBroadcastNetwork.go similarity index 99% rename from node/processingOnlyNode/syncedBroadcastNetwork.go rename to node/chainSimulator/syncedBroadcastNetwork.go index 23ae2a2e211..67f6e85c197 100644 --- a/node/processingOnlyNode/syncedBroadcastNetwork.go +++ b/node/chainSimulator/syncedBroadcastNetwork.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "errors" diff --git a/node/processingOnlyNode/syncedBroadcastNetwork_test.go b/node/chainSimulator/syncedBroadcastNetwork_test.go similarity index 99% rename from node/processingOnlyNode/syncedBroadcastNetwork_test.go rename to node/chainSimulator/syncedBroadcastNetwork_test.go index 29b97340b17..eaaf6a96f00 100644 --- a/node/processingOnlyNode/syncedBroadcastNetwork_test.go +++ b/node/chainSimulator/syncedBroadcastNetwork_test.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "fmt" diff --git a/node/processingOnlyNode/syncedMessenger.go b/node/chainSimulator/syncedMessenger.go similarity index 95% rename from node/processingOnlyNode/syncedMessenger.go rename to node/chainSimulator/syncedMessenger.go index 9b2375225e3..0948774bddb 100644 --- a/node/processingOnlyNode/syncedMessenger.go +++ b/node/chainSimulator/syncedMessenger.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "bytes" @@ -29,24 +29,15 @@ var ( errInvalidSignature = errors.New("invalid signature") ) -type syncedBroadcastNetworkHandler interface { - RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) - Broadcast(pid core.PeerID, topic string, buff []byte) - SendDirectly(from core.PeerID, topic string, buff []byte, to core.PeerID) error - GetConnectedPeers() []core.PeerID - GetConnectedPeersOnTopic(topic string) []core.PeerID - IsInterfaceNil() bool -} - type syncedMessenger struct { mutOperation sync.RWMutex topics map[string]map[string]p2p.MessageProcessor - network syncedBroadcastNetworkHandler + network SyncedBroadcastNetworkHandler pid core.PeerID } // NewSyncedMessenger creates a new synced network messenger -func NewSyncedMessenger(network syncedBroadcastNetworkHandler) (*syncedMessenger, error) { +func NewSyncedMessenger(network SyncedBroadcastNetworkHandler) (*syncedMessenger, error) { if check.IfNil(network) { return nil, errNilNetwork } diff --git a/node/processingOnlyNode/syncedMessenger_test.go b/node/chainSimulator/syncedMessenger_test.go similarity index 99% rename from node/processingOnlyNode/syncedMessenger_test.go rename to node/chainSimulator/syncedMessenger_test.go index 7d3eba84b00..82901c07af8 100644 --- a/node/processingOnlyNode/syncedMessenger_test.go +++ b/node/chainSimulator/syncedMessenger_test.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "fmt" diff --git a/node/processingOnlyNode/testOnlyProcessingNode.go b/node/chainSimulator/testOnlyProcessingNode.go similarity index 84% rename from node/processingOnlyNode/testOnlyProcessingNode.go rename to node/chainSimulator/testOnlyProcessingNode.go index b34d6da447d..93920b6d4bd 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode.go +++ b/node/chainSimulator/testOnlyProcessingNode.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "github.com/multiversx/mx-chain-core-go/core" @@ -19,26 +19,28 @@ import ( // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function type ArgsTestOnlyProcessingNode struct { - Config config.Config - EnableEpochsConfig config.EnableEpochs - EconomicsConfig config.EconomicsConfig - RoundsConfig config.RoundConfig - PreferencesConfig config.Preferences - ChanStopNodeProcess chan endProcess.ArgEndProcess - GasScheduleFilename string - ValidatorPemFile string - WorkingDir string - NodesSetupPath string - NumShards uint32 - ShardID uint32 + Config config.Config + EnableEpochsConfig config.EnableEpochs + EconomicsConfig config.EconomicsConfig + RoundsConfig config.RoundConfig + PreferencesConfig config.Preferences + ChanStopNodeProcess chan endProcess.ArgEndProcess + SyncedBroadcastNetwork SyncedBroadcastNetworkHandler + GasScheduleFilename string + ValidatorPemFile string + WorkingDir string + NodesSetupPath string + NumShards uint32 + ShardID uint32 } type testOnlyProcessingNode struct { - CoreComponentsHolder factory.CoreComponentsHolder - StatusCoreComponents factory.StatusCoreComponentsHolder - StateComponentsHolder factory.StateComponentsHolder - StatusComponentsHolder factory.StatusComponentsHolder - CryptoComponentsHolder factory.CryptoComponentsHolder + CoreComponentsHolder factory.CoreComponentsHolder + StatusCoreComponents factory.StatusCoreComponentsHolder + StateComponentsHolder factory.StateComponentsHolder + StatusComponentsHolder factory.StatusComponentsHolder + CryptoComponentsHolder factory.CryptoComponentsHolder + NetworkComponentsHolder factory.NetworkComponentsHolder ChainHandler chainData.ChainHandler ShardCoordinator sharding.Coordinator @@ -111,6 +113,11 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + instance.NetworkComponentsHolder, err = CreateNetworkComponentsHolder(args.SyncedBroadcastNetwork) + if err != nil { + return nil, err + } + err = instance.createDataPool(args) if err != nil { return nil, err diff --git a/node/processingOnlyNode/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go similarity index 85% rename from node/processingOnlyNode/testOnlyProcessingNode_test.go rename to node/chainSimulator/testOnlyProcessingNode_test.go index 3407b80eb52..d9114cb1ca6 100644 --- a/node/processingOnlyNode/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -1,4 +1,4 @@ -package processingOnlyNode +package chainSimulator import ( "testing" @@ -44,13 +44,14 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo }, }, }, - EconomicsConfig: economicsConfig, - GasScheduleFilename: gasScheduleName, - NodesSetupPath: nodesSetupConfig, - NumShards: 3, - ShardID: 0, - ValidatorPemFile: validatorPemFile, - PreferencesConfig: prefsConfig, + EconomicsConfig: economicsConfig, + GasScheduleFilename: gasScheduleName, + NodesSetupPath: nodesSetupConfig, + NumShards: 3, + ShardID: 0, + ValidatorPemFile: validatorPemFile, + PreferencesConfig: prefsConfig, + SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), } } From 6d2094936d69aa2d0f8b159da2ea6901e366a027 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 15 Sep 2023 16:15:25 +0300 Subject: [PATCH 470/958] bootstrap components --- node/chainSimulator/bootstrapComponents.go | 124 ++++++++++++++++++ node/chainSimulator/coreComponents.go | 7 +- node/chainSimulator/testOnlyProcessingNode.go | 30 ++++- .../testOnlyProcessingNode_test.go | 11 +- 4 files changed, 162 insertions(+), 10 deletions(-) create mode 100644 node/chainSimulator/bootstrapComponents.go diff --git a/node/chainSimulator/bootstrapComponents.go b/node/chainSimulator/bootstrapComponents.go new file mode 100644 index 00000000000..c9f8bdcce08 --- /dev/null +++ b/node/chainSimulator/bootstrapComponents.go @@ -0,0 +1,124 @@ +package chainSimulator + +import ( + "fmt" + + "github.com/multiversx/mx-chain-core-go/core" + nodeFactory "github.com/multiversx/mx-chain-go/cmd/node/factory" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/factory" + bootstrapComp "github.com/multiversx/mx-chain-go/factory/bootstrap" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding" +) + +type ArgsBootstrapComponentsHolder struct { + CoreComponents factory.CoreComponentsHolder + CryptoComponents factory.CryptoComponentsHolder + NetworkComponents factory.NetworkComponentsHolder + StatusCoreComponents factory.StatusCoreComponentsHolder + WorkingDir string + FlagsConfig config.ContextFlagsConfig + ImportDBConfig config.ImportDbConfig + PrefsConfig config.Preferences + Config config.Config +} + +type bootstrapComponentsHolder struct { + epochStartBootstrapper factory.EpochStartBootstrapper + epochBootstrapParams factory.BootstrapParamsHolder + nodeType core.NodeType + shardCoordinator sharding.Coordinator + versionedHeaderFactory nodeFactory.VersionedHeaderFactory + headerVersionHandler nodeFactory.HeaderVersionHandler + headerIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler + guardedAccountHandler process.GuardedAccountHandler +} + +// CreateBootstrapComponentHolder will create a new instance of bootstrap components holder +func CreateBootstrapComponentHolder(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHolder, error) { + instance := &bootstrapComponentsHolder{} + + bootstrapComponentsFactoryArgs := bootstrapComp.BootstrapComponentsFactoryArgs{ + Config: args.Config, + PrefConfig: args.PrefsConfig, + ImportDbConfig: args.ImportDBConfig, + FlagsConfig: args.FlagsConfig, + WorkingDir: args.WorkingDir, + CoreComponents: args.CoreComponents, + CryptoComponents: args.CryptoComponents, + NetworkComponents: args.NetworkComponents, + StatusCoreComponents: args.StatusCoreComponents, + } + + bootstrapComponentsFactory, err := bootstrapComp.NewBootstrapComponentsFactory(bootstrapComponentsFactoryArgs) + if err != nil { + return nil, fmt.Errorf("NewBootstrapComponentsFactory failed: %w", err) + } + + managedBootstrapComponents, err := bootstrapComp.NewManagedBootstrapComponents(bootstrapComponentsFactory) + if err != nil { + return nil, err + } + + err = managedBootstrapComponents.Create() + if err != nil { + return nil, err + } + + instance.epochStartBootstrapper = managedBootstrapComponents.EpochStartBootstrapper() + instance.epochBootstrapParams = managedBootstrapComponents.EpochBootstrapParams() + instance.nodeType = managedBootstrapComponents.NodeType() + instance.shardCoordinator = managedBootstrapComponents.ShardCoordinator() + instance.versionedHeaderFactory = managedBootstrapComponents.VersionedHeaderFactory() + instance.headerVersionHandler = managedBootstrapComponents.HeaderVersionHandler() + instance.headerIntegrityVerifier = managedBootstrapComponents.HeaderIntegrityVerifier() + instance.guardedAccountHandler = managedBootstrapComponents.GuardedAccountHandler() + + return instance, nil +} + +// EpochStartBootstrapper will return the epoch start bootstrapper +func (b *bootstrapComponentsHolder) EpochStartBootstrapper() factory.EpochStartBootstrapper { + return b.epochStartBootstrapper +} + +// EpochBootstrapParams will return the epoch bootstrap params +func (b *bootstrapComponentsHolder) EpochBootstrapParams() factory.BootstrapParamsHolder { + return b.epochBootstrapParams +} + +// NodeType will return the node type +func (b *bootstrapComponentsHolder) NodeType() core.NodeType { + return b.nodeType +} + +// ShardCoordinator will return the shardCoordinator +func (b *bootstrapComponentsHolder) ShardCoordinator() sharding.Coordinator { + return b.shardCoordinator +} + +// VersionedHeaderFactory will return the versioned header factory +func (b *bootstrapComponentsHolder) VersionedHeaderFactory() nodeFactory.VersionedHeaderFactory { + return b.versionedHeaderFactory +} + +// HeaderVersionHandler will return header version handler +func (b *bootstrapComponentsHolder) HeaderVersionHandler() nodeFactory.HeaderVersionHandler { + return b.headerVersionHandler +} + +// HeaderIntegrityVerifier will return header integrity verifier +func (b *bootstrapComponentsHolder) HeaderIntegrityVerifier() nodeFactory.HeaderIntegrityVerifierHandler { + return b.headerIntegrityVerifier +} + +// GuardedAccountHandler will return guarded account handler +func (b *bootstrapComponentsHolder) GuardedAccountHandler() process.GuardedAccountHandler { + return b.guardedAccountHandler +} + +// IsInterfaceNil returns true if there is no value under the interface +func (b *bootstrapComponentsHolder) IsInterfaceNil() bool { + return b == nil +} diff --git a/node/chainSimulator/coreComponents.go b/node/chainSimulator/coreComponents.go index 4fd8ba9d9e1..339ae33d666 100644 --- a/node/chainSimulator/coreComponents.go +++ b/node/chainSimulator/coreComponents.go @@ -35,6 +35,7 @@ import ( "github.com/multiversx/mx-chain-go/storage" storageFactory "github.com/multiversx/mx-chain-go/storage/factory" "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" ) type coreComponentsHolder struct { @@ -136,7 +137,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.alarmScheduler = &mock.AlarmSchedulerStub{} instance.syncTimer = &testscommon.SyncTimerStub{} // TODO discuss with Iulian about the round handler - //instance.roundHandler + instance.roundHandler = &testscommon.RoundHandlerMock{} instance.wasmVMChangeLocker = &sync.RWMutex{} instance.txVersionChecker = versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion) @@ -188,14 +189,14 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp // TODO check if we need this instance.ratingsData = nil - instance.rater = nil + instance.rater = &testscommon.RaterMock{} instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.NodesSetupPath, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) if err != nil { return nil, err } // TODO check if we need nodes shuffler - instance.nodesShuffler = nil + instance.nodesShuffler = &shardingMocks.NodeShufflerMock{} instance.roundNotifier = forking.NewGenericRoundNotifier() instance.enableRoundsHandler, err = enablers.NewEnableRoundsHandler(args.RoundsConfig, instance.roundNotifier) diff --git a/node/chainSimulator/testOnlyProcessingNode.go b/node/chainSimulator/testOnlyProcessingNode.go index 93920b6d4bd..fb31cd7b048 100644 --- a/node/chainSimulator/testOnlyProcessingNode.go +++ b/node/chainSimulator/testOnlyProcessingNode.go @@ -24,6 +24,8 @@ type ArgsTestOnlyProcessingNode struct { EconomicsConfig config.EconomicsConfig RoundsConfig config.RoundConfig PreferencesConfig config.Preferences + ImportDBConfig config.ImportDbConfig + ContextFlagsConfig config.ContextFlagsConfig ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler GasScheduleFilename string @@ -35,12 +37,13 @@ type ArgsTestOnlyProcessingNode struct { } type testOnlyProcessingNode struct { - CoreComponentsHolder factory.CoreComponentsHolder - StatusCoreComponents factory.StatusCoreComponentsHolder - StateComponentsHolder factory.StateComponentsHolder - StatusComponentsHolder factory.StatusComponentsHolder - CryptoComponentsHolder factory.CryptoComponentsHolder - NetworkComponentsHolder factory.NetworkComponentsHolder + CoreComponentsHolder factory.CoreComponentsHolder + StatusCoreComponents factory.StatusCoreComponentsHolder + StateComponentsHolder factory.StateComponentsHolder + StatusComponentsHolder factory.StatusComponentsHolder + CryptoComponentsHolder factory.CryptoComponentsHolder + NetworkComponentsHolder factory.NetworkComponentsHolder + BootstrapComponentsHolder factory.BootstrapComponentsHolder ChainHandler chainData.ChainHandler ShardCoordinator sharding.Coordinator @@ -118,6 +121,21 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + instance.BootstrapComponentsHolder, err = CreateBootstrapComponentHolder(ArgsBootstrapComponentsHolder{ + CoreComponents: instance.CoreComponentsHolder, + CryptoComponents: instance.CryptoComponentsHolder, + NetworkComponents: instance.NetworkComponentsHolder, + StatusCoreComponents: instance.StatusCoreComponents, + WorkingDir: args.WorkingDir, + FlagsConfig: args.ContextFlagsConfig, + ImportDBConfig: args.ImportDBConfig, + PrefsConfig: args.PreferencesConfig, + Config: args.Config, + }) + if err != nil { + return nil, err + } + err = instance.createDataPool(args) if err != nil { return nil, err diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index d9114cb1ca6..1fdad961c81 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -1,6 +1,7 @@ package chainSimulator import ( + "os" "testing" "github.com/multiversx/mx-chain-go/config" @@ -30,8 +31,12 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo err = LoadConfigFromFile(pathForPrefsConfig, &prefsConfig) assert.Nil(t, err) + workingDir, err := os.Getwd() + assert.Nil(t, err) + return ArgsTestOnlyProcessingNode{ - Config: mainConfig, + Config: mainConfig, + WorkingDir: workingDir, EnableEpochsConfig: config.EnableEpochs{ BLSMultiSignerEnableEpoch: []config.MultiSignerConfig{ {EnableEpoch: 0, Type: "KOSK"}, @@ -52,6 +57,10 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo ValidatorPemFile: validatorPemFile, PreferencesConfig: prefsConfig, SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), + ImportDBConfig: config.ImportDbConfig{}, + ContextFlagsConfig: config.ContextFlagsConfig{ + WorkingDir: workingDir, + }, } } From 7701a262c28a3a12a130f3426c236c85351d5a8e Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 19 Sep 2023 09:00:13 +0300 Subject: [PATCH 471/958] fixes after review --- node/chainSimulator/bootstrapComponents.go | 1 + node/chainSimulator/testOnlyProcessingNode_test.go | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/bootstrapComponents.go b/node/chainSimulator/bootstrapComponents.go index c9f8bdcce08..3cbd144dc50 100644 --- a/node/chainSimulator/bootstrapComponents.go +++ b/node/chainSimulator/bootstrapComponents.go @@ -12,6 +12,7 @@ import ( "github.com/multiversx/mx-chain-go/sharding" ) +// ArgsBootstrapComponentsHolder will hold the components needed for the bootstrap components holders type ArgsBootstrapComponentsHolder struct { CoreComponents factory.CoreComponentsHolder CryptoComponents factory.CryptoComponentsHolder diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index 1fdad961c81..829d6fb681a 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -1,7 +1,6 @@ package chainSimulator import ( - "os" "testing" "github.com/multiversx/mx-chain-go/config" @@ -31,8 +30,7 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo err = LoadConfigFromFile(pathForPrefsConfig, &prefsConfig) assert.Nil(t, err) - workingDir, err := os.Getwd() - assert.Nil(t, err) + workingDir := t.TempDir() return ArgsTestOnlyProcessingNode{ Config: mainConfig, From 8b68faa183049d0762ed937a15319b9c4d435693 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 3 Oct 2023 10:46:31 +0300 Subject: [PATCH 472/958] fixes after update --- node/chainSimulator/cryptoComponents.go | 1 - node/chainSimulator/syncedMessenger.go | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/cryptoComponents.go b/node/chainSimulator/cryptoComponents.go index 4907f94818b..307d0647cd5 100644 --- a/node/chainSimulator/cryptoComponents.go +++ b/node/chainSimulator/cryptoComponents.go @@ -57,7 +57,6 @@ func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.Cryp ActivateBLSPubKeyMessageVerification: true, IsInImportMode: false, ImportModeNoSigCheck: false, - NoKeyProvided: false, P2pKeyPemFileName: "", ValidatorKeyPemFileName: args.ValidatorKeyPemFileName, diff --git a/node/chainSimulator/syncedMessenger.go b/node/chainSimulator/syncedMessenger.go index 0948774bddb..30c52c413fe 100644 --- a/node/chainSimulator/syncedMessenger.go +++ b/node/chainSimulator/syncedMessenger.go @@ -344,6 +344,11 @@ func (messenger *syncedMessenger) AddPeerTopicNotifier(_ p2p.PeerTopicNotifier) return nil } +// SetDebugger will set the provided debugger +func (messenger *syncedMessenger) SetDebugger(_ p2p.Debugger) error { + return nil +} + // Close does nothing and returns nil func (messenger *syncedMessenger) Close() error { return nil From 64fa09eef4cc4d562c1000bba5d3237e016b5d37 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 10:56:38 +0300 Subject: [PATCH 473/958] data components and process components --- node/chainSimulator/dataComponents.go | 94 ++++ node/chainSimulator/processComponents.go | 485 ++++++++++++++++++ node/chainSimulator/testOnlyProcessingNode.go | 106 +++- 3 files changed, 676 insertions(+), 9 deletions(-) create mode 100644 node/chainSimulator/dataComponents.go create mode 100644 node/chainSimulator/processComponents.go diff --git a/node/chainSimulator/dataComponents.go b/node/chainSimulator/dataComponents.go new file mode 100644 index 00000000000..3b1607397f0 --- /dev/null +++ b/node/chainSimulator/dataComponents.go @@ -0,0 +1,94 @@ +package chainSimulator + +import ( + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/dataRetriever/provider" + "github.com/multiversx/mx-chain-go/factory" +) + +// ArgsDataComponentsHolder will hold the components needed for data components +type ArgsDataComponentsHolder struct { + Chain data.ChainHandler + StorageService dataRetriever.StorageService + DataPool dataRetriever.PoolsHolder + InternalMarshaller marshal.Marshalizer +} + +type dataComponentsHolder struct { + chain data.ChainHandler + storageService dataRetriever.StorageService + dataPool dataRetriever.PoolsHolder + miniBlockProvider factory.MiniBlockProvider +} + +// CreateDataComponentsHolder will create the data components holder +func CreateDataComponentsHolder(args ArgsDataComponentsHolder) (factory.DataComponentsHolder, error) { + miniBlockStorer, err := args.StorageService.GetStorer(dataRetriever.MiniBlockUnit) + if err != nil { + return nil, err + } + + arg := provider.ArgMiniBlockProvider{ + MiniBlockPool: args.DataPool.MiniBlocks(), + MiniBlockStorage: miniBlockStorer, + Marshalizer: args.InternalMarshaller, + } + + miniBlocksProvider, err := provider.NewMiniBlockProvider(arg) + if err != nil { + return nil, err + } + + instance := &dataComponentsHolder{ + chain: args.Chain, + storageService: args.StorageService, + dataPool: args.DataPool, + miniBlockProvider: miniBlocksProvider, + } + + return instance, nil +} + +// Blockchain will return the blockchain handler +func (d *dataComponentsHolder) Blockchain() data.ChainHandler { + return d.chain +} + +// SetBlockchain will set the blockchain handler +func (d *dataComponentsHolder) SetBlockchain(chain data.ChainHandler) error { + d.chain = chain + + return nil +} + +// StorageService will return the storage service +func (d *dataComponentsHolder) StorageService() dataRetriever.StorageService { + return d.storageService +} + +// Datapool will return the data pool +func (d *dataComponentsHolder) Datapool() dataRetriever.PoolsHolder { + return d.dataPool +} + +// MiniBlocksProvider will return the mini blocks provider +func (d *dataComponentsHolder) MiniBlocksProvider() factory.MiniBlockProvider { + return d.miniBlockProvider +} + +// Clone will clone the data components holder +func (d *dataComponentsHolder) Clone() interface{} { + return &dataComponentsHolder{ + chain: d.chain, + storageService: d.storageService, + dataPool: d.dataPool, + miniBlockProvider: d.miniBlockProvider, + } +} + +// IsInterfaceNil returns true if there is no value under the interface +func (d *dataComponentsHolder) IsInterfaceNil() bool { + return d == nil +} diff --git a/node/chainSimulator/processComponents.go b/node/chainSimulator/processComponents.go new file mode 100644 index 00000000000..16769518282 --- /dev/null +++ b/node/chainSimulator/processComponents.go @@ -0,0 +1,485 @@ +package chainSimulator + +import ( + "fmt" + "math/big" + "path/filepath" + "time" + + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/common/ordering" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/dblookupext" + dbLookupFactory "github.com/multiversx/mx-chain-go/dblookupext/factory" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/factory" + processComp "github.com/multiversx/mx-chain-go/factory/processing" + "github.com/multiversx/mx-chain-go/genesis" + "github.com/multiversx/mx-chain-go/genesis/parsing" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/process/interceptors" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/storage/cache" + storageFactory "github.com/multiversx/mx-chain-go/storage/factory" + "github.com/multiversx/mx-chain-go/storage/storageunit" + "github.com/multiversx/mx-chain-go/update" + "github.com/multiversx/mx-chain-go/update/trigger" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" +) + +// ArgsProcessComponentsHolder will hold the components needed for process components +type ArgsProcessComponentsHolder struct { + CoreComponents factory.CoreComponentsHolder + CryptoComponents factory.CryptoComponentsHolder + NetworkComponents factory.NetworkComponentsHolder + BootstrapComponents factory.BootstrapComponentsHolder + StateComponents factory.StateComponentsHolder + DataComponents factory.DataComponentsHolder + StatusComponents factory.StatusComponentsHolder + StatusCoreComponents factory.StatusCoreComponentsHolder + NodesCoordinator nodesCoordinator.NodesCoordinator + + EpochConfig config.EpochConfig + ConfigurationPathsHolder config.ConfigurationPathsHolder + FlagsConfig config.ContextFlagsConfig + ImportDBConfig config.ImportDbConfig + PrefsConfig config.Preferences + Config config.Config + EconomicsConfig config.EconomicsConfig + SystemSCConfig config.SystemSmartContractsConfig +} + +type processComponentsHolder struct { + receiptsRepository factory.ReceiptsRepository + nodesCoordinator nodesCoordinator.NodesCoordinator + shardCoordinator sharding.Coordinator + interceptorsContainer process.InterceptorsContainer + fullArchiveInterceptorsContainer process.InterceptorsContainer + resolversContainer dataRetriever.ResolversContainer + requestersFinder dataRetriever.RequestersFinder + roundHandler consensus.RoundHandler + epochStartTrigger epochStart.TriggerHandler + epochStartNotifier factory.EpochStartNotifier + forkDetector process.ForkDetector + blockProcessor process.BlockProcessor + blackListHandler process.TimeCacher + bootStorer process.BootStorer + headerSigVerifier process.InterceptedHeaderSigVerifier + headerIntegrityVerifier process.HeaderIntegrityVerifier + validatorsStatistics process.ValidatorStatisticsProcessor + validatorsProvider process.ValidatorsProvider + blockTracker process.BlockTracker + pendingMiniBlocksHandler process.PendingMiniBlocksHandler + requestHandler process.RequestHandler + txLogsProcessor process.TransactionLogProcessorDatabase + headerConstructionValidator process.HeaderConstructionValidator + peerShardMapper process.NetworkShardingCollector + fullArchivePeerShardMapper process.NetworkShardingCollector + fallbackHeaderValidator process.FallbackHeaderValidator + apiTransactionEvaluator factory.TransactionEvaluator + whiteListHandler process.WhiteListHandler + whiteListerVerifiedTxs process.WhiteListHandler + historyRepository dblookupext.HistoryRepository + importStartHandler update.ImportStartHandler + requestedItemsHandler dataRetriever.RequestedItemsHandler + nodeRedundancyHandler consensus.NodeRedundancyHandler + currentEpochProvider process.CurrentNetworkEpochProviderHandler + scheduledTxsExecutionHandler process.ScheduledTxsExecutionHandler + txsSenderHandler process.TxsSenderHandler + hardforkTrigger factory.HardforkTrigger + processedMiniBlocksTracker process.ProcessedMiniBlocksTracker + esdtDataStorageHandlerForAPI vmcommon.ESDTNFTStorageHandler + accountsParser genesis.AccountsParser +} + +// CreateProcessComponentsHolder will create the process components holder +func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.ProcessComponentsHolder, error) { + importStartHandler, err := trigger.NewImportStartHandler(filepath.Join(args.FlagsConfig.DbDir, common.DefaultDBPath), args.FlagsConfig.Version) + if err != nil { + return nil, err + } + totalSupply, ok := big.NewInt(0).SetString(args.EconomicsConfig.GlobalSettings.GenesisTotalSupply, 10) + if !ok { + return nil, fmt.Errorf("can not parse total suply from economics.toml, %s is not a valid value", + args.EconomicsConfig.GlobalSettings.GenesisTotalSupply) + } + + mintingSenderAddress := args.EconomicsConfig.GlobalSettings.GenesisMintingSenderAddress + argsAccountsParser := genesis.AccountsParserArgs{ + GenesisFilePath: args.ConfigurationPathsHolder.Genesis, + EntireSupply: totalSupply, + MinterAddress: mintingSenderAddress, + PubkeyConverter: args.CoreComponents.AddressPubKeyConverter(), + KeyGenerator: args.CryptoComponents.TxSignKeyGen(), + Hasher: args.CoreComponents.Hasher(), + Marshalizer: args.CoreComponents.InternalMarshalizer(), + } + + accountsParser, err := parsing.NewAccountsParser(argsAccountsParser) + if err != nil { + return nil, err + } + + smartContractParser, err := parsing.NewSmartContractsParser( + args.ConfigurationPathsHolder.SmartContracts, + args.CoreComponents.AddressPubKeyConverter(), + args.CryptoComponents.TxSignKeyGen(), + ) + if err != nil { + return nil, err + } + + historyRepoFactoryArgs := &dbLookupFactory.ArgsHistoryRepositoryFactory{ + SelfShardID: args.BootstrapComponents.ShardCoordinator().SelfId(), + Config: args.Config.DbLookupExtensions, + Hasher: args.CoreComponents.Hasher(), + Marshalizer: args.CoreComponents.InternalMarshalizer(), + Store: args.DataComponents.StorageService(), + Uint64ByteSliceConverter: args.CoreComponents.Uint64ByteSliceConverter(), + } + historyRepositoryFactory, err := dbLookupFactory.NewHistoryRepositoryFactory(historyRepoFactoryArgs) + if err != nil { + return nil, err + } + + whiteListCache, err := storageunit.NewCache(storageFactory.GetCacherFromConfig(args.Config.WhiteListPool)) + if err != nil { + return nil, err + } + // TODO check if this is needed + whiteListRequest, err := interceptors.NewWhiteListDataVerifier(whiteListCache) + if err != nil { + return nil, err + } + + // TODO check if this is needed + whiteListerVerifiedTxs, err := createWhiteListerVerifiedTxs(&args.Config) + if err != nil { + return nil, err + } + + historyRepository, err := historyRepositoryFactory.Create() + if err != nil { + return nil, err + } + + requestedItemsHandler := cache.NewTimeCache( + time.Duration(uint64(time.Millisecond) * args.CoreComponents.GenesisNodesSetup().GetRoundDuration())) + + txExecutionOrderHandler := ordering.NewOrderedCollection() + + argsGasScheduleNotifier := forking.ArgsNewGasScheduleNotifier{ + GasScheduleConfig: args.EpochConfig.GasSchedule, + ConfigDir: args.ConfigurationPathsHolder.GasScheduleDirectoryName, + EpochNotifier: args.CoreComponents.EpochNotifier(), + WasmVMChangeLocker: args.CoreComponents.WasmVMChangeLocker(), + } + gasScheduleNotifier, err := forking.NewGasScheduleNotifier(argsGasScheduleNotifier) + if err != nil { + return nil, err + } + + processArgs := processComp.ProcessComponentsFactoryArgs{ + Config: args.Config, + EpochConfig: args.EpochConfig, + PrefConfigs: args.PrefsConfig, + ImportDBConfig: args.ImportDBConfig, + AccountsParser: accountsParser, + SmartContractParser: smartContractParser, + GasSchedule: gasScheduleNotifier, + NodesCoordinator: args.NodesCoordinator, + Data: args.DataComponents, + CoreData: args.CoreComponents, + Crypto: args.CryptoComponents, + State: args.StateComponents, + Network: args.NetworkComponents, + BootstrapComponents: args.BootstrapComponents, + StatusComponents: args.StatusComponents, + StatusCoreComponents: args.StatusCoreComponents, + RequestedItemsHandler: requestedItemsHandler, + WhiteListHandler: whiteListRequest, + WhiteListerVerifiedTxs: whiteListerVerifiedTxs, + MaxRating: 50, + SystemSCConfig: &args.SystemSCConfig, + ImportStartHandler: importStartHandler, + HistoryRepo: historyRepository, + FlagsConfig: args.FlagsConfig, + TxExecutionOrderHandler: txExecutionOrderHandler, + } + processComponentsFactory, err := processComp.NewProcessComponentsFactory(processArgs) + if err != nil { + return nil, fmt.Errorf("NewProcessComponentsFactory failed: %w", err) + } + + managedProcessComponents, err := processComp.NewManagedProcessComponents(processComponentsFactory) + if err != nil { + return nil, err + } + + err = managedProcessComponents.Create() + if err != nil { + return nil, err + } + + instance := &processComponentsHolder{ + receiptsRepository: managedProcessComponents.ReceiptsRepository(), + nodesCoordinator: managedProcessComponents.NodesCoordinator(), + shardCoordinator: managedProcessComponents.ShardCoordinator(), + interceptorsContainer: managedProcessComponents.InterceptorsContainer(), + fullArchiveInterceptorsContainer: managedProcessComponents.FullArchiveInterceptorsContainer(), + resolversContainer: managedProcessComponents.ResolversContainer(), + requestersFinder: managedProcessComponents.RequestersFinder(), + roundHandler: managedProcessComponents.RoundHandler(), + epochStartTrigger: managedProcessComponents.EpochStartTrigger(), + epochStartNotifier: managedProcessComponents.EpochStartNotifier(), + forkDetector: managedProcessComponents.ForkDetector(), + blockProcessor: managedProcessComponents.BlockProcessor(), + blackListHandler: managedProcessComponents.BlackListHandler(), + bootStorer: managedProcessComponents.BootStorer(), + headerSigVerifier: managedProcessComponents.HeaderSigVerifier(), + headerIntegrityVerifier: managedProcessComponents.HeaderIntegrityVerifier(), + validatorsStatistics: managedProcessComponents.ValidatorsStatistics(), + validatorsProvider: managedProcessComponents.ValidatorsProvider(), + blockTracker: managedProcessComponents.BlockTracker(), + pendingMiniBlocksHandler: managedProcessComponents.PendingMiniBlocksHandler(), + requestHandler: managedProcessComponents.RequestHandler(), + txLogsProcessor: managedProcessComponents.TxLogsProcessor(), + headerConstructionValidator: managedProcessComponents.HeaderConstructionValidator(), + peerShardMapper: managedProcessComponents.PeerShardMapper(), + fullArchivePeerShardMapper: managedProcessComponents.FullArchivePeerShardMapper(), + fallbackHeaderValidator: managedProcessComponents.FallbackHeaderValidator(), + apiTransactionEvaluator: managedProcessComponents.APITransactionEvaluator(), + whiteListHandler: managedProcessComponents.WhiteListHandler(), + whiteListerVerifiedTxs: managedProcessComponents.WhiteListerVerifiedTxs(), + historyRepository: managedProcessComponents.HistoryRepository(), + importStartHandler: managedProcessComponents.ImportStartHandler(), + requestedItemsHandler: managedProcessComponents.RequestedItemsHandler(), + nodeRedundancyHandler: managedProcessComponents.NodeRedundancyHandler(), + currentEpochProvider: managedProcessComponents.CurrentEpochProvider(), + scheduledTxsExecutionHandler: managedProcessComponents.ScheduledTxsExecutionHandler(), + txsSenderHandler: managedProcessComponents.TxsSenderHandler(), + hardforkTrigger: managedProcessComponents.HardforkTrigger(), + processedMiniBlocksTracker: managedProcessComponents.ProcessedMiniBlocksTracker(), + esdtDataStorageHandlerForAPI: managedProcessComponents.ESDTDataStorageHandlerForAPI(), + accountsParser: managedProcessComponents.AccountsParser(), + } + + return instance, nil +} + +func createWhiteListerVerifiedTxs(generalConfig *config.Config) (process.WhiteListHandler, error) { + whiteListCacheVerified, err := storageunit.NewCache(storageFactory.GetCacherFromConfig(generalConfig.WhiteListerVerifiedTxs)) + if err != nil { + return nil, err + } + return interceptors.NewWhiteListDataVerifier(whiteListCacheVerified) +} + +// NodesCoordinator will return the nodes coordinator +func (p *processComponentsHolder) NodesCoordinator() nodesCoordinator.NodesCoordinator { + return p.nodesCoordinator +} + +// ShardCoordinator will return the shard coordinator +func (p *processComponentsHolder) ShardCoordinator() sharding.Coordinator { + return p.shardCoordinator +} + +// InterceptorsContainer will return the interceptors container +func (p *processComponentsHolder) InterceptorsContainer() process.InterceptorsContainer { + return p.interceptorsContainer +} + +// FullArchiveInterceptorsContainer will return the full archive interceptor container +func (p *processComponentsHolder) FullArchiveInterceptorsContainer() process.InterceptorsContainer { + return p.fullArchiveInterceptorsContainer +} + +// ResolversContainer will return the resolvers container +func (p *processComponentsHolder) ResolversContainer() dataRetriever.ResolversContainer { + return p.resolversContainer +} + +// RequestersFinder will return the requesters finder +func (p *processComponentsHolder) RequestersFinder() dataRetriever.RequestersFinder { + return p.requestersFinder +} + +// RoundHandler will return the round handler +func (p *processComponentsHolder) RoundHandler() consensus.RoundHandler { + return p.roundHandler +} + +// EpochStartTrigger will return the epoch start trigger +func (p *processComponentsHolder) EpochStartTrigger() epochStart.TriggerHandler { + return p.epochStartTrigger +} + +// EpochStartNotifier will return the epoch start notifier +func (p *processComponentsHolder) EpochStartNotifier() factory.EpochStartNotifier { + return p.epochStartNotifier +} + +// ForkDetector will return the fork detector +func (p *processComponentsHolder) ForkDetector() process.ForkDetector { + return p.forkDetector +} + +// BlockProcessor will return the block processor +func (p *processComponentsHolder) BlockProcessor() process.BlockProcessor { + return p.blockProcessor +} + +// BlackListHandler will return the black list handler +func (p *processComponentsHolder) BlackListHandler() process.TimeCacher { + return p.blackListHandler +} + +// BootStorer will return the boot storer +func (p *processComponentsHolder) BootStorer() process.BootStorer { + return p.bootStorer +} + +// HeaderSigVerifier will return the header sign verifier +func (p *processComponentsHolder) HeaderSigVerifier() process.InterceptedHeaderSigVerifier { + return p.headerSigVerifier +} + +// HeaderIntegrityVerifier will return the header integrity verifier +func (p *processComponentsHolder) HeaderIntegrityVerifier() process.HeaderIntegrityVerifier { + return p.headerIntegrityVerifier +} + +// ValidatorsStatistics will return the validators statistics +func (p *processComponentsHolder) ValidatorsStatistics() process.ValidatorStatisticsProcessor { + return p.validatorsStatistics +} + +// ValidatorsProvider will return the validators provider +func (p *processComponentsHolder) ValidatorsProvider() process.ValidatorsProvider { + return p.validatorsProvider +} + +// BlockTracker will return the block tracker +func (p *processComponentsHolder) BlockTracker() process.BlockTracker { + return p.blockTracker +} + +// PendingMiniBlocksHandler will return the pending miniblocks handler +func (p *processComponentsHolder) PendingMiniBlocksHandler() process.PendingMiniBlocksHandler { + return p.pendingMiniBlocksHandler +} + +// RequestHandler will return the request handler +func (p *processComponentsHolder) RequestHandler() process.RequestHandler { + return p.requestHandler +} + +// TxLogsProcessor will return the transaction log processor +func (p *processComponentsHolder) TxLogsProcessor() process.TransactionLogProcessorDatabase { + return p.txLogsProcessor +} + +// HeaderConstructionValidator will return the header construction validator +func (p *processComponentsHolder) HeaderConstructionValidator() process.HeaderConstructionValidator { + return p.headerConstructionValidator +} + +// PeerShardMapper will return the peer shard mapper +func (p *processComponentsHolder) PeerShardMapper() process.NetworkShardingCollector { + return p.peerShardMapper +} + +// FullArchivePeerShardMapper will return the full archive peer shard mapper +func (p *processComponentsHolder) FullArchivePeerShardMapper() process.NetworkShardingCollector { + return p.fullArchivePeerShardMapper +} + +// FallbackHeaderValidator will return the fallback header validator +func (p *processComponentsHolder) FallbackHeaderValidator() process.FallbackHeaderValidator { + return p.fallbackHeaderValidator +} + +// APITransactionEvaluator will return the api transaction evaluator +func (p *processComponentsHolder) APITransactionEvaluator() factory.TransactionEvaluator { + return p.apiTransactionEvaluator +} + +// WhiteListHandler will return the white list handler +func (p *processComponentsHolder) WhiteListHandler() process.WhiteListHandler { + return p.whiteListHandler +} + +// WhiteListerVerifiedTxs will return the white lister verifier +func (p *processComponentsHolder) WhiteListerVerifiedTxs() process.WhiteListHandler { + return p.whiteListerVerifiedTxs +} + +// HistoryRepository will return the history repository +func (p *processComponentsHolder) HistoryRepository() dblookupext.HistoryRepository { + return p.historyRepository +} + +// ImportStartHandler will return the import start handler +func (p *processComponentsHolder) ImportStartHandler() update.ImportStartHandler { + return p.importStartHandler +} + +// RequestedItemsHandler will return the requested item handler +func (p *processComponentsHolder) RequestedItemsHandler() dataRetriever.RequestedItemsHandler { + return p.requestedItemsHandler +} + +// NodeRedundancyHandler will return the node redundancy handler +func (p *processComponentsHolder) NodeRedundancyHandler() consensus.NodeRedundancyHandler { + return p.nodeRedundancyHandler +} + +// CurrentEpochProvider will return the current epoch provider +func (p *processComponentsHolder) CurrentEpochProvider() process.CurrentNetworkEpochProviderHandler { + return p.currentEpochProvider +} + +// ScheduledTxsExecutionHandler will return the scheduled transactions execution handler +func (p *processComponentsHolder) ScheduledTxsExecutionHandler() process.ScheduledTxsExecutionHandler { + return p.scheduledTxsExecutionHandler +} + +// TxsSenderHandler will return the transactions sender handler +func (p *processComponentsHolder) TxsSenderHandler() process.TxsSenderHandler { + return p.txsSenderHandler +} + +// HardforkTrigger will return the hardfork trigger +func (p *processComponentsHolder) HardforkTrigger() factory.HardforkTrigger { + return p.hardforkTrigger +} + +// ProcessedMiniBlocksTracker will return the processed miniblocks tracker +func (p *processComponentsHolder) ProcessedMiniBlocksTracker() process.ProcessedMiniBlocksTracker { + return p.processedMiniBlocksTracker +} + +// ESDTDataStorageHandlerForAPI will return the esdt data storage handler for api +func (p *processComponentsHolder) ESDTDataStorageHandlerForAPI() vmcommon.ESDTNFTStorageHandler { + return p.esdtDataStorageHandlerForAPI +} + +// AccountsParser will return the accounts parser +func (p *processComponentsHolder) AccountsParser() genesis.AccountsParser { + return p.accountsParser +} + +// ReceiptsRepository returns the receipts repository +func (p *processComponentsHolder) ReceiptsRepository() factory.ReceiptsRepository { + return p.receiptsRepository +} + +// IsInterfaceNil returns true if there is no value under the interface +func (p *processComponentsHolder) IsInterfaceNil() bool { + return p == nil +} diff --git a/node/chainSimulator/testOnlyProcessingNode.go b/node/chainSimulator/testOnlyProcessingNode.go index fb31cd7b048..5bac7fab4bf 100644 --- a/node/chainSimulator/testOnlyProcessingNode.go +++ b/node/chainSimulator/testOnlyProcessingNode.go @@ -9,23 +9,28 @@ import ( "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" dataRetrieverFactory "github.com/multiversx/mx-chain-go/dataRetriever/factory" "github.com/multiversx/mx-chain-go/factory" + bootstrapComp "github.com/multiversx/mx-chain-go/factory/bootstrap" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/postprocess" "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/process/transactionLog" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" ) // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function type ArgsTestOnlyProcessingNode struct { - Config config.Config - EnableEpochsConfig config.EnableEpochs - EconomicsConfig config.EconomicsConfig - RoundsConfig config.RoundConfig - PreferencesConfig config.Preferences - ImportDBConfig config.ImportDbConfig - ContextFlagsConfig config.ContextFlagsConfig + Config config.Config + EpochConfig config.EpochConfig + EconomicsConfig config.EconomicsConfig + RoundsConfig config.RoundConfig + PreferencesConfig config.Preferences + ImportDBConfig config.ImportDbConfig + ContextFlagsConfig config.ContextFlagsConfig + SystemSCConfig config.SystemSmartContractsConfig + ConfigurationPathsHolder config.ConfigurationPathsHolder + ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler GasScheduleFilename string @@ -44,7 +49,10 @@ type testOnlyProcessingNode struct { CryptoComponentsHolder factory.CryptoComponentsHolder NetworkComponentsHolder factory.NetworkComponentsHolder BootstrapComponentsHolder factory.BootstrapComponentsHolder + ProcessComponentsHolder factory.ProcessComponentsHolder + DataComponentsHolder factory.DataComponentsHolder + NodesCoordinator nodesCoordinator.NodesCoordinator ChainHandler chainData.ChainHandler ShardCoordinator sharding.Coordinator ArgumentsParser process.ArgumentsParser @@ -68,7 +76,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces instance.CoreComponentsHolder, err = CreateCoreComponentsHolder(ArgsCoreComponentsHolder{ Config: args.Config, - EnableEpochsConfig: args.EnableEpochsConfig, + EnableEpochsConfig: args.EpochConfig.EnableEpochs, RoundsConfig: args.RoundsConfig, EconomicsConfig: args.EconomicsConfig, ChanStopNodeProcess: args.ChanStopNodeProcess, @@ -107,7 +115,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } instance.CryptoComponentsHolder, err = CreateCryptoComponentsHolder(ArgsCryptoComponentsHolder{ Config: args.Config, - EnableEpochsConfig: args.EnableEpochsConfig, + EnableEpochsConfig: args.EpochConfig.EnableEpochs, Preferences: args.PreferencesConfig, CoreComponentsHolder: instance.CoreComponentsHolder, ValidatorKeyPemFileName: args.ValidatorPemFile, @@ -145,6 +153,45 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + err = instance.createNodesCoordinator(args.PreferencesConfig.Preferences, args.Config) + if err != nil { + return nil, err + } + + instance.DataComponentsHolder, err = CreateDataComponentsHolder(ArgsDataComponentsHolder{ + Chain: instance.ChainHandler, + StorageService: instance.StoreService, + DataPool: instance.DataPool, + InternalMarshaller: instance.CoreComponentsHolder.InternalMarshalizer(), + }) + if err != nil { + return nil, err + } + + instance.ProcessComponentsHolder, err = CreateProcessComponentsHolder(ArgsProcessComponentsHolder{ + CoreComponents: instance.CoreComponentsHolder, + CryptoComponents: instance.CryptoComponentsHolder, + NetworkComponents: instance.NetworkComponentsHolder, + BootstrapComponents: instance.BootstrapComponentsHolder, + StateComponents: instance.StateComponentsHolder, + StatusComponents: instance.StatusComponentsHolder, + StatusCoreComponents: instance.StatusCoreComponents, + FlagsConfig: args.ContextFlagsConfig, + ImportDBConfig: args.ImportDBConfig, + PrefsConfig: args.PreferencesConfig, + Config: args.Config, + EconomicsConfig: args.EconomicsConfig, + SystemSCConfig: args.SystemSCConfig, + EpochConfig: args.EpochConfig, + ConfigurationPathsHolder: args.ConfigurationPathsHolder, + NodesCoordinator: instance.NodesCoordinator, + + DataComponents: nil, + }) + if err != nil { + return nil, err + } + return instance, nil } @@ -205,3 +252,44 @@ func (node *testOnlyProcessingNode) createTransactionLogProcessor() error { return err } + +func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.PreferencesConfig, generalConfig config.Config) error { + nodesShufflerOut, err := bootstrapComp.CreateNodesShuffleOut( + node.CoreComponentsHolder.GenesisNodesSetup(), + generalConfig.EpochStartConfig, + node.CoreComponentsHolder.ChanStopNodeProcess(), + ) + if err != nil { + return err + } + + bootstrapStorer, err := node.StoreService.GetStorer(dataRetriever.BootstrapUnit) + if err != nil { + return err + } + + node.NodesCoordinator, err = bootstrapComp.CreateNodesCoordinator( + nodesShufflerOut, + node.CoreComponentsHolder.GenesisNodesSetup(), + pref, + node.CoreComponentsHolder.EpochStartNotifierWithConfirm(), + node.CryptoComponentsHolder.PublicKey(), + node.CoreComponentsHolder.InternalMarshalizer(), + node.CoreComponentsHolder.Hasher(), + node.CoreComponentsHolder.Rater(), + bootstrapStorer, + node.CoreComponentsHolder.NodesShuffler(), + node.ShardCoordinator.SelfId(), + node.BootstrapComponentsHolder.EpochBootstrapParams(), + node.BootstrapComponentsHolder.EpochBootstrapParams().Epoch(), + node.CoreComponentsHolder.ChanStopNodeProcess(), + node.CoreComponentsHolder.NodeTypeProvider(), + node.CoreComponentsHolder.EnableEpochsHandler(), + node.DataPool.CurrentEpochValidatorInfo(), + ) + if err != nil { + return err + } + + return nil +} From f5aa7ff5fb4b8afc165023b88559436cab56f1c5 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 13:31:30 +0300 Subject: [PATCH 474/958] fix tests --- node/chainSimulator/syncedMessenger.go | 6 +-- node/chainSimulator/syncedMessenger_test.go | 8 ---- node/chainSimulator/testOnlyProcessingNode.go | 3 +- .../testOnlyProcessingNode_test.go | 43 +++++++++++++------ .../testdata/genesisSmartContracts.json | 18 ++++++++ 5 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 node/chainSimulator/testdata/genesisSmartContracts.json diff --git a/node/chainSimulator/syncedMessenger.go b/node/chainSimulator/syncedMessenger.go index 30c52c413fe..dd84ebe3da1 100644 --- a/node/chainSimulator/syncedMessenger.go +++ b/node/chainSimulator/syncedMessenger.go @@ -93,7 +93,7 @@ func (messenger *syncedMessenger) CreateTopic(name string, _ bool) error { return fmt.Errorf("programming error in syncedMessenger.CreateTopic, %w for topic %s", errTopicAlreadyCreated, name) } - messenger.topics[name] = make(map[string]p2p.MessageProcessor, 0) + messenger.topics[name] = make(map[string]p2p.MessageProcessor) return nil } @@ -120,8 +120,8 @@ func (messenger *syncedMessenger) RegisterMessageProcessor(topic string, identif handlers, found := messenger.topics[topic] if !found { - return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, %w for topic %s", - errTopicNotCreated, topic) + handlers = make(map[string]p2p.MessageProcessor) + messenger.topics[topic] = handlers } _, found = handlers[identifier] diff --git a/node/chainSimulator/syncedMessenger_test.go b/node/chainSimulator/syncedMessenger_test.go index 82901c07af8..85ca22f8a18 100644 --- a/node/chainSimulator/syncedMessenger_test.go +++ b/node/chainSimulator/syncedMessenger_test.go @@ -79,14 +79,6 @@ func TestSyncedMessenger_RegisterMessageProcessor(t *testing.T) { err := messenger.RegisterMessageProcessor("", "", nil) assert.ErrorIs(t, err, errNilMessageProcessor) }) - t.Run("topic not created should error", func(t *testing.T) { - t.Parallel() - - messenger, _ := NewSyncedMessenger(NewSyncedBroadcastNetwork()) - - err := messenger.RegisterMessageProcessor("t", "", &p2pmocks.MessageProcessorStub{}) - assert.ErrorIs(t, err, errTopicNotCreated) - }) t.Run("processor exists, should error", func(t *testing.T) { t.Parallel() diff --git a/node/chainSimulator/testOnlyProcessingNode.go b/node/chainSimulator/testOnlyProcessingNode.go index 5bac7fab4bf..6fad1c5ff89 100644 --- a/node/chainSimulator/testOnlyProcessingNode.go +++ b/node/chainSimulator/testOnlyProcessingNode.go @@ -185,8 +185,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces EpochConfig: args.EpochConfig, ConfigurationPathsHolder: args.ConfigurationPathsHolder, NodesCoordinator: instance.NodesCoordinator, - - DataComponents: nil, + DataComponents: instance.DataComponentsHolder, }) if err != nil { return nil, err diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index 829d6fb681a..5deeba6f58f 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -3,16 +3,22 @@ package chainSimulator import ( "testing" + "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/stretchr/testify/assert" ) -const pathForMainConfig = "../../cmd/node/config/config.toml" -const pathForEconomicsConfig = "../../cmd/node/config/economics.toml" -const pathForGasSchedules = "../../cmd/node/config/gasSchedules" -const nodesSetupConfig = "../../cmd/node/config/nodesSetup.json" -const pathForPrefsConfig = "../../cmd/node/config/prefs.toml" -const validatorPemFile = "../../cmd/node/config/testKeys/validatorKey.pem" +const ( + pathTestData = "./testdata/" + pathToConfigFolder = "../../cmd/node/config/" + pathForMainConfig = "../../cmd/node/config/config.toml" + pathForEconomicsConfig = "../../cmd/node/config/economics.toml" + pathForGasSchedules = "../../cmd/node/config/gasSchedules" + nodesSetupConfig = "../../cmd/node/config/nodesSetup.json" + pathForPrefsConfig = "../../cmd/node/config/prefs.toml" + validatorPemFile = "../../cmd/node/config/testKeys/validatorKey.pem" + pathSystemSCConfig = "../../cmd/node/config/systemSmartContractsConfig.toml" +) func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { mainConfig := config.Config{} @@ -30,16 +36,19 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo err = LoadConfigFromFile(pathForPrefsConfig, &prefsConfig) assert.Nil(t, err) + systemSCConfig := config.SystemSmartContractsConfig{} + err = LoadConfigFromFile(pathSystemSCConfig, &systemSCConfig) + assert.Nil(t, err) + workingDir := t.TempDir() + epochConfig := config.EpochConfig{} + err = LoadConfigFromFile(pathToConfigFolder+"enableEpochs.toml", &epochConfig) + return ArgsTestOnlyProcessingNode{ - Config: mainConfig, - WorkingDir: workingDir, - EnableEpochsConfig: config.EnableEpochs{ - BLSMultiSignerEnableEpoch: []config.MultiSignerConfig{ - {EnableEpoch: 0, Type: "KOSK"}, - }, - }, + Config: mainConfig, + WorkingDir: workingDir, + EpochConfig: epochConfig, RoundsConfig: config.RoundConfig{ RoundActivations: map[string]config.ActivationRoundByName{ "DisableAsyncCallV1": { @@ -58,7 +67,15 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo ImportDBConfig: config.ImportDbConfig{}, ContextFlagsConfig: config.ContextFlagsConfig{ WorkingDir: workingDir, + Version: "1", + }, + ConfigurationPathsHolder: config.ConfigurationPathsHolder{ + GasScheduleDirectoryName: pathToConfigFolder + "gasSchedules", + Genesis: pathToConfigFolder + "genesis.json", + SmartContracts: pathTestData + "genesisSmartContracts.json", }, + SystemSCConfig: systemSCConfig, + ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), } } diff --git a/node/chainSimulator/testdata/genesisSmartContracts.json b/node/chainSimulator/testdata/genesisSmartContracts.json new file mode 100644 index 00000000000..be68c4fec51 --- /dev/null +++ b/node/chainSimulator/testdata/genesisSmartContracts.json @@ -0,0 +1,18 @@ +[ + { + "owner": "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80", + "filename": "../../cmd/node/config/genesisContracts/delegation.wasm", + "vm-type": "0500", + "init-parameters": "%validator_sc_address%@03E8@00@030D40@030D40", + "type": "delegation", + "version": "0.4.*" + }, + { + "owner": "erd188anxz35atlef7cucszypmvx88lhz4m7a7t7lhcwt6sfphpsqlkswfhcx2", + "filename": "../../cmd/node/config/genesisContracts/dns.wasm", + "vm-type": "0500", + "init-parameters": "056bc75e2d63100000", + "type": "dns", + "version": "0.2.*" + } +] From a683ba1a57742fd74590826b5b1aecbec627aa3a Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 13:37:11 +0300 Subject: [PATCH 475/958] fix linter issues --- node/chainSimulator/testOnlyProcessingNode_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index 5deeba6f58f..1ae60e28507 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -44,6 +44,7 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo epochConfig := config.EpochConfig{} err = LoadConfigFromFile(pathToConfigFolder+"enableEpochs.toml", &epochConfig) + assert.Nil(t, err) return ArgsTestOnlyProcessingNode{ Config: mainConfig, From 2444a5564d5aa61229090d8117a46856113fc21f Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 14:11:28 +0300 Subject: [PATCH 476/958] commit block --- .../testOnlyProcessingNode_test.go | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index 1ae60e28507..30dff534efa 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -2,10 +2,12 @@ package chainSimulator import ( "testing" + "time" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ( @@ -100,4 +102,37 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, node) }) + + t.Run("try commit a block", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + node, err := NewTestOnlyProcessingNode(args) + assert.Nil(t, err) + assert.NotNil(t, node) + + genesis, err := node.ProcessComponentsHolder.BlockProcessor().CreateNewHeader(0, 0) + assert.Nil(t, err) + err = node.ChainHandler.SetGenesisHeader(genesis) + assert.Nil(t, err) + err = node.ChainHandler.SetCurrentBlockHeaderAndRootHash(genesis, []byte("root")) + assert.Nil(t, err) + + newHeader, err := node.ProcessComponentsHolder.BlockProcessor().CreateNewHeader(1, 1) + assert.Nil(t, err) + + header, block, err := node.ProcessComponentsHolder.BlockProcessor().CreateBlock(newHeader, func() bool { + return true + }) + require.NotNil(t, header) + require.NotNil(t, block) + + err = node.ProcessComponentsHolder.BlockProcessor().ProcessBlock(header, block, func() time.Duration { + return time.Hour + }) + assert.Nil(t, err) + + err = node.ProcessComponentsHolder.BlockProcessor().CommitBlock(header, block) + assert.Nil(t, err) + }) } From ecab5da0156234b21540dcb381fe98271950ed54 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 14:19:25 +0300 Subject: [PATCH 477/958] fixes --- node/chainSimulator/testOnlyProcessingNode_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index 30dff534efa..e343c959320 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -113,8 +113,10 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { genesis, err := node.ProcessComponentsHolder.BlockProcessor().CreateNewHeader(0, 0) assert.Nil(t, err) + err = node.ChainHandler.SetGenesisHeader(genesis) assert.Nil(t, err) + err = node.ChainHandler.SetCurrentBlockHeaderAndRootHash(genesis, []byte("root")) assert.Nil(t, err) @@ -124,6 +126,7 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { header, block, err := node.ProcessComponentsHolder.BlockProcessor().CreateBlock(newHeader, func() bool { return true }) + assert.Nil(t, err) require.NotNil(t, header) require.NotNil(t, block) From 39f2f5f087a3f8dd65b5ec5d0c171aa87ca21503 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 16:38:56 +0300 Subject: [PATCH 478/958] fixes --- .../testOnlyProcessingNode_test.go | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index e343c959320..c143fd0fa17 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -95,6 +95,10 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { assert.Nil(t, node) }) t.Run("should work", func(t *testing.T) { + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() args := createMockArgsTestOnlyProcessingNode(t) @@ -104,6 +108,10 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { }) t.Run("try commit a block", func(t *testing.T) { + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() args := createMockArgsTestOnlyProcessingNode(t) @@ -111,29 +119,18 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, node) - genesis, err := node.ProcessComponentsHolder.BlockProcessor().CreateNewHeader(0, 0) - assert.Nil(t, err) - - err = node.ChainHandler.SetGenesisHeader(genesis) - assert.Nil(t, err) - - err = node.ChainHandler.SetCurrentBlockHeaderAndRootHash(genesis, []byte("root")) - assert.Nil(t, err) - newHeader, err := node.ProcessComponentsHolder.BlockProcessor().CreateNewHeader(1, 1) assert.Nil(t, err) header, block, err := node.ProcessComponentsHolder.BlockProcessor().CreateBlock(newHeader, func() bool { return true }) - assert.Nil(t, err) require.NotNil(t, header) require.NotNil(t, block) err = node.ProcessComponentsHolder.BlockProcessor().ProcessBlock(header, block, func() time.Duration { - return time.Hour + return 1000 }) - assert.Nil(t, err) err = node.ProcessComponentsHolder.BlockProcessor().CommitBlock(header, block) assert.Nil(t, err) From beb9c30a197bcc8b3a542b9aa17f3e92bc566685 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 4 Oct 2023 16:44:43 +0300 Subject: [PATCH 479/958] fix linter --- node/chainSimulator/testOnlyProcessingNode_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/testOnlyProcessingNode_test.go index c143fd0fa17..9f1e6bd383f 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/testOnlyProcessingNode_test.go @@ -125,12 +125,14 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { header, block, err := node.ProcessComponentsHolder.BlockProcessor().CreateBlock(newHeader, func() bool { return true }) + assert.Nil(t, err) require.NotNil(t, header) require.NotNil(t, block) err = node.ProcessComponentsHolder.BlockProcessor().ProcessBlock(header, block, func() time.Duration { return 1000 }) + assert.Nil(t, err) err = node.ProcessComponentsHolder.BlockProcessor().CommitBlock(header, block) assert.Nil(t, err) From 7b84d9f38c59ff9e4aefebe0196379cebdef8a99 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 5 Oct 2023 13:16:26 +0300 Subject: [PATCH 480/958] fixes --- node/chainSimulator/processComponents.go | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/node/chainSimulator/processComponents.go b/node/chainSimulator/processComponents.go index 16769518282..92af5b77062 100644 --- a/node/chainSimulator/processComponents.go +++ b/node/chainSimulator/processComponents.go @@ -20,12 +20,10 @@ import ( "github.com/multiversx/mx-chain-go/genesis" "github.com/multiversx/mx-chain-go/genesis/parsing" "github.com/multiversx/mx-chain-go/process" - "github.com/multiversx/mx-chain-go/process/interceptors" + "github.com/multiversx/mx-chain-go/process/interceptors/disabled" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage/cache" - storageFactory "github.com/multiversx/mx-chain-go/storage/factory" - "github.com/multiversx/mx-chain-go/storage/storageunit" "github.com/multiversx/mx-chain-go/update" "github.com/multiversx/mx-chain-go/update/trigger" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -146,18 +144,12 @@ func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.Pr return nil, err } - whiteListCache, err := storageunit.NewCache(storageFactory.GetCacherFromConfig(args.Config.WhiteListPool)) - if err != nil { - return nil, err - } - // TODO check if this is needed - whiteListRequest, err := interceptors.NewWhiteListDataVerifier(whiteListCache) + whiteListRequest, err := disabled.NewDisabledWhiteListDataVerifier() if err != nil { return nil, err } - // TODO check if this is needed - whiteListerVerifiedTxs, err := createWhiteListerVerifiedTxs(&args.Config) + whiteListerVerifiedTxs, err := disabled.NewDisabledWhiteListDataVerifier() if err != nil { return nil, err } @@ -271,14 +263,6 @@ func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.Pr return instance, nil } -func createWhiteListerVerifiedTxs(generalConfig *config.Config) (process.WhiteListHandler, error) { - whiteListCacheVerified, err := storageunit.NewCache(storageFactory.GetCacherFromConfig(generalConfig.WhiteListerVerifiedTxs)) - if err != nil { - return nil, err - } - return interceptors.NewWhiteListDataVerifier(whiteListCacheVerified) -} - // NodesCoordinator will return the nodes coordinator func (p *processComponentsHolder) NodesCoordinator() nodesCoordinator.NodesCoordinator { return p.nodesCoordinator From e20b348ff701678d1f9105aa084203636601d3d0 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 30 Oct 2023 16:39:25 +0200 Subject: [PATCH 481/958] create configs --- node/chainSimulator/chainSimulator.go | 64 +++++++ node/chainSimulator/chainSimulator_test.go | 1 + .../{ => components}/bootstrapComponents.go | 2 +- .../{ => components}/configLoaders.go | 2 +- .../{ => components}/coreComponents.go | 2 +- .../{ => components}/cryptoComponents.go | 2 +- .../{ => components}/dataComponents.go | 2 +- node/chainSimulator/components/interface.go | 13 ++ .../{ => components}/memoryComponents.go | 2 +- .../{ => components}/networkComponents.go | 2 +- .../{ => components}/processComponents.go | 2 +- .../{ => components}/stateComponents.go | 2 +- .../{ => components}/statusComponents.go | 2 +- .../{ => components}/statusCoreComponents.go | 2 +- .../{ => components}/storageService.go | 2 +- .../syncedBroadcastNetwork.go | 2 +- .../syncedBroadcastNetwork_test.go | 2 +- .../{ => components}/syncedMessenger.go | 2 +- .../{ => components}/syncedMessenger_test.go | 2 +- .../testOnlyProcessingNode.go | 52 +++++- .../testOnlyProcessingNode_test.go | 20 +-- node/chainSimulator/configs/configs.go | 161 ++++++++++++++++++ node/chainSimulator/configs/configs_test.go | 23 +++ node/chainSimulator/interface.go | 11 +- .../testdata/genesisSmartContracts.json | 4 +- 25 files changed, 343 insertions(+), 38 deletions(-) create mode 100644 node/chainSimulator/chainSimulator.go create mode 100644 node/chainSimulator/chainSimulator_test.go rename node/chainSimulator/{ => components}/bootstrapComponents.go (99%) rename node/chainSimulator/{ => components}/configLoaders.go (98%) rename node/chainSimulator/{ => components}/coreComponents.go (99%) rename node/chainSimulator/{ => components}/cryptoComponents.go (99%) rename node/chainSimulator/{ => components}/dataComponents.go (99%) create mode 100644 node/chainSimulator/components/interface.go rename node/chainSimulator/{ => components}/memoryComponents.go (96%) rename node/chainSimulator/{ => components}/networkComponents.go (99%) rename node/chainSimulator/{ => components}/processComponents.go (99%) rename node/chainSimulator/{ => components}/stateComponents.go (99%) rename node/chainSimulator/{ => components}/statusComponents.go (98%) rename node/chainSimulator/{ => components}/statusCoreComponents.go (99%) rename node/chainSimulator/{ => components}/storageService.go (98%) rename node/chainSimulator/{ => components}/syncedBroadcastNetwork.go (99%) rename node/chainSimulator/{ => components}/syncedBroadcastNetwork_test.go (99%) rename node/chainSimulator/{ => components}/syncedMessenger.go (99%) rename node/chainSimulator/{ => components}/syncedMessenger_test.go (99%) rename node/chainSimulator/{ => components}/testOnlyProcessingNode.go (90%) rename node/chainSimulator/{ => components}/testOnlyProcessingNode_test.go (86%) create mode 100644 node/chainSimulator/configs/configs.go create mode 100644 node/chainSimulator/configs/configs_test.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go new file mode 100644 index 00000000000..aabecae66eb --- /dev/null +++ b/node/chainSimulator/chainSimulator.go @@ -0,0 +1,64 @@ +package chainSimulator + +import ( + "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components" + "github.com/multiversx/mx-chain-go/testscommon" +) + +const ( + NumOfShards = 3 +) + +type simulator struct { + chanStopNodeProcess chan endProcess.ArgEndProcess + syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler + nodes []ChainHandler +} + +func NewChainSimulator() (*simulator, error) { + syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() + + return &simulator{ + syncedBroadcastNetwork: syncedBroadcastNetwork, + }, nil +} + +func (s *simulator) createChanHandler(shardID uint32) (ChainHandler, error) { + generalConfig := testscommon.GetGeneralConfig() + + args := components.ArgsTestOnlyProcessingNode{ + Config: generalConfig, + EpochConfig: config.EpochConfig{}, + EconomicsConfig: config.EconomicsConfig{}, + RoundsConfig: config.RoundConfig{}, + PreferencesConfig: config.Preferences{}, + ImportDBConfig: config.ImportDbConfig{}, + ContextFlagsConfig: config.ContextFlagsConfig{}, + SystemSCConfig: config.SystemSmartContractsConfig{}, + ConfigurationPathsHolder: config.ConfigurationPathsHolder{}, + ChanStopNodeProcess: nil, + SyncedBroadcastNetwork: s.syncedBroadcastNetwork, + GasScheduleFilename: "", + ValidatorPemFile: "", + WorkingDir: "", + NodesSetupPath: "", + NumShards: NumOfShards, + ShardID: shardID, + } + + return components.NewTestOnlyProcessingNode(args) +} + +func (s *simulator) GenerateBlocks(numOfBlock int) error { + return nil +} + +func (s *simulator) Stop() { +} + +// IsInterfaceNil returns true if there is no value under the interface +func (s *simulator) IsInterfaceNil() bool { + return s == nil +} diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go new file mode 100644 index 00000000000..8015b9a1580 --- /dev/null +++ b/node/chainSimulator/chainSimulator_test.go @@ -0,0 +1 @@ +package chainSimulator diff --git a/node/chainSimulator/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go similarity index 99% rename from node/chainSimulator/bootstrapComponents.go rename to node/chainSimulator/components/bootstrapComponents.go index 3cbd144dc50..e27693754f5 100644 --- a/node/chainSimulator/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "fmt" diff --git a/node/chainSimulator/configLoaders.go b/node/chainSimulator/components/configLoaders.go similarity index 98% rename from node/chainSimulator/configLoaders.go rename to node/chainSimulator/components/configLoaders.go index 7e1334d88cd..336935bbeaf 100644 --- a/node/chainSimulator/configLoaders.go +++ b/node/chainSimulator/components/configLoaders.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "os" diff --git a/node/chainSimulator/coreComponents.go b/node/chainSimulator/components/coreComponents.go similarity index 99% rename from node/chainSimulator/coreComponents.go rename to node/chainSimulator/components/coreComponents.go index 339ae33d666..29af73ba133 100644 --- a/node/chainSimulator/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "bytes" diff --git a/node/chainSimulator/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go similarity index 99% rename from node/chainSimulator/cryptoComponents.go rename to node/chainSimulator/components/cryptoComponents.go index 307d0647cd5..9e4f9de49c4 100644 --- a/node/chainSimulator/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "fmt" diff --git a/node/chainSimulator/dataComponents.go b/node/chainSimulator/components/dataComponents.go similarity index 99% rename from node/chainSimulator/dataComponents.go rename to node/chainSimulator/components/dataComponents.go index 3b1607397f0..f8a01db7697 100644 --- a/node/chainSimulator/dataComponents.go +++ b/node/chainSimulator/components/dataComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "github.com/multiversx/mx-chain-core-go/data" diff --git a/node/chainSimulator/components/interface.go b/node/chainSimulator/components/interface.go new file mode 100644 index 00000000000..0da375cdf42 --- /dev/null +++ b/node/chainSimulator/components/interface.go @@ -0,0 +1,13 @@ +package components + +import "github.com/multiversx/mx-chain-core-go/core" + +// SyncedBroadcastNetworkHandler defines the synced network interface +type SyncedBroadcastNetworkHandler interface { + RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) + Broadcast(pid core.PeerID, topic string, buff []byte) + SendDirectly(from core.PeerID, topic string, buff []byte, to core.PeerID) error + GetConnectedPeers() []core.PeerID + GetConnectedPeersOnTopic(topic string) []core.PeerID + IsInterfaceNil() bool +} diff --git a/node/chainSimulator/memoryComponents.go b/node/chainSimulator/components/memoryComponents.go similarity index 96% rename from node/chainSimulator/memoryComponents.go rename to node/chainSimulator/components/memoryComponents.go index 3d44fae7508..5384f320790 100644 --- a/node/chainSimulator/memoryComponents.go +++ b/node/chainSimulator/components/memoryComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "github.com/multiversx/mx-chain-go/storage" diff --git a/node/chainSimulator/networkComponents.go b/node/chainSimulator/components/networkComponents.go similarity index 99% rename from node/chainSimulator/networkComponents.go rename to node/chainSimulator/components/networkComponents.go index c52fea16697..1afa6037b16 100644 --- a/node/chainSimulator/networkComponents.go +++ b/node/chainSimulator/components/networkComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( disabledBootstrap "github.com/multiversx/mx-chain-go/epochStart/bootstrap/disabled" diff --git a/node/chainSimulator/processComponents.go b/node/chainSimulator/components/processComponents.go similarity index 99% rename from node/chainSimulator/processComponents.go rename to node/chainSimulator/components/processComponents.go index 92af5b77062..c55d6bbfecf 100644 --- a/node/chainSimulator/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "fmt" diff --git a/node/chainSimulator/stateComponents.go b/node/chainSimulator/components/stateComponents.go similarity index 99% rename from node/chainSimulator/stateComponents.go rename to node/chainSimulator/components/stateComponents.go index 8837ac251e5..a942087be72 100644 --- a/node/chainSimulator/stateComponents.go +++ b/node/chainSimulator/components/stateComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( chainData "github.com/multiversx/mx-chain-core-go/data" diff --git a/node/chainSimulator/statusComponents.go b/node/chainSimulator/components/statusComponents.go similarity index 98% rename from node/chainSimulator/statusComponents.go rename to node/chainSimulator/components/statusComponents.go index 6c8a141499f..f332370bf13 100644 --- a/node/chainSimulator/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "time" diff --git a/node/chainSimulator/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go similarity index 99% rename from node/chainSimulator/statusCoreComponents.go rename to node/chainSimulator/components/statusCoreComponents.go index dd02c1460bb..60e6c8f0f47 100644 --- a/node/chainSimulator/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "github.com/multiversx/mx-chain-core-go/core" diff --git a/node/chainSimulator/storageService.go b/node/chainSimulator/components/storageService.go similarity index 98% rename from node/chainSimulator/storageService.go rename to node/chainSimulator/components/storageService.go index c7a566105f2..dcbd19e5a98 100644 --- a/node/chainSimulator/storageService.go +++ b/node/chainSimulator/components/storageService.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "github.com/multiversx/mx-chain-go/dataRetriever" diff --git a/node/chainSimulator/syncedBroadcastNetwork.go b/node/chainSimulator/components/syncedBroadcastNetwork.go similarity index 99% rename from node/chainSimulator/syncedBroadcastNetwork.go rename to node/chainSimulator/components/syncedBroadcastNetwork.go index 67f6e85c197..572689b0c0a 100644 --- a/node/chainSimulator/syncedBroadcastNetwork.go +++ b/node/chainSimulator/components/syncedBroadcastNetwork.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "errors" diff --git a/node/chainSimulator/syncedBroadcastNetwork_test.go b/node/chainSimulator/components/syncedBroadcastNetwork_test.go similarity index 99% rename from node/chainSimulator/syncedBroadcastNetwork_test.go rename to node/chainSimulator/components/syncedBroadcastNetwork_test.go index eaaf6a96f00..1067e1155be 100644 --- a/node/chainSimulator/syncedBroadcastNetwork_test.go +++ b/node/chainSimulator/components/syncedBroadcastNetwork_test.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "fmt" diff --git a/node/chainSimulator/syncedMessenger.go b/node/chainSimulator/components/syncedMessenger.go similarity index 99% rename from node/chainSimulator/syncedMessenger.go rename to node/chainSimulator/components/syncedMessenger.go index dd84ebe3da1..d5cc0da5d6c 100644 --- a/node/chainSimulator/syncedMessenger.go +++ b/node/chainSimulator/components/syncedMessenger.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "bytes" diff --git a/node/chainSimulator/syncedMessenger_test.go b/node/chainSimulator/components/syncedMessenger_test.go similarity index 99% rename from node/chainSimulator/syncedMessenger_test.go rename to node/chainSimulator/components/syncedMessenger_test.go index 85ca22f8a18..c0efd6f2942 100644 --- a/node/chainSimulator/syncedMessenger_test.go +++ b/node/chainSimulator/components/syncedMessenger_test.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "fmt" diff --git a/node/chainSimulator/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go similarity index 90% rename from node/chainSimulator/testOnlyProcessingNode.go rename to node/chainSimulator/components/testOnlyProcessingNode.go index 6fad1c5ff89..7c453b3e441 100644 --- a/node/chainSimulator/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -1,6 +1,8 @@ -package chainSimulator +package components import ( + "time" + "github.com/multiversx/mx-chain-core-go/core" chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/endProcess" @@ -292,3 +294,51 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc return nil } + +func (node *testOnlyProcessingNode) ProcessBlock(nonce uint64, round uint64) error { + bp := node.ProcessComponentsHolder.BlockProcessor() + newHeader, err := node.prepareHeader(nonce, round) + if err != nil { + return err + } + + header, block, err := bp.CreateBlock(newHeader, func() bool { + return true + }) + if err != nil { + return err + } + + err = bp.ProcessBlock(header, block, func() time.Duration { + return 1000 + }) + if err != nil { + return err + } + + err = bp.CommitBlock(header, block) + if err != nil { + return err + } + + return nil +} + +func (node *testOnlyProcessingNode) prepareHeader(nonce uint64, round uint64) (chainData.HeaderHandler, error) { + bp := node.ProcessComponentsHolder.BlockProcessor() + newHeader, err := bp.CreateNewHeader(round, nonce) + if err != nil { + return nil, err + } + err = newHeader.SetShardID(node.ShardCoordinator.SelfId()) + if err != nil { + return nil, err + } + + return newHeader, nil +} + +// IsInterfaceNil returns true if there is no value under the interface +func (node *testOnlyProcessingNode) IsInterfaceNil() bool { + return node == nil +} diff --git a/node/chainSimulator/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go similarity index 86% rename from node/chainSimulator/testOnlyProcessingNode_test.go rename to node/chainSimulator/components/testOnlyProcessingNode_test.go index 9f1e6bd383f..ae5db48e64f 100644 --- a/node/chainSimulator/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -1,4 +1,4 @@ -package chainSimulator +package components import ( "testing" @@ -11,15 +11,15 @@ import ( ) const ( - pathTestData = "./testdata/" - pathToConfigFolder = "../../cmd/node/config/" - pathForMainConfig = "../../cmd/node/config/config.toml" - pathForEconomicsConfig = "../../cmd/node/config/economics.toml" - pathForGasSchedules = "../../cmd/node/config/gasSchedules" - nodesSetupConfig = "../../cmd/node/config/nodesSetup.json" - pathForPrefsConfig = "../../cmd/node/config/prefs.toml" - validatorPemFile = "../../cmd/node/config/testKeys/validatorKey.pem" - pathSystemSCConfig = "../../cmd/node/config/systemSmartContractsConfig.toml" + pathTestData = "../testdata/" + pathToConfigFolder = "../../../cmd/node/config/" + pathForMainConfig = "../../../cmd/node/config/config.toml" + pathForEconomicsConfig = "../../../cmd/node/config/economics.toml" + pathForGasSchedules = "../../../cmd/node/config/gasSchedules" + nodesSetupConfig = "../../../cmd/node/config/nodesSetup.json" + pathForPrefsConfig = "../../../cmd/node/config/prefs.toml" + validatorPemFile = "../../../cmd/node/config/testKeys/validatorKey.pem" + pathSystemSCConfig = "../../../cmd/node/config/systemSmartContractsConfig.toml" ) func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go new file mode 100644 index 00000000000..9f4d9e70842 --- /dev/null +++ b/node/chainSimulator/configs/configs.go @@ -0,0 +1,161 @@ +package configs + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "encoding/pem" + "math/big" + "os" + "path" + "testing" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/pubkeyConverter" + crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/genesis/data" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/stretchr/testify/require" +) + +type ArgsChainSimulatorConfigs struct { + NumOfShards uint32 + OriginalConfigsPath string + GenesisAddressWithStake string + GenesisAddressWithBalance string +} + +type ArgsConfigsSimulator struct { + Configs *config.Configs + ValidatorsPrivateKeys []crypto.PrivateKey +} + +func CreateChainSimulatorConfigs(tb testing.TB, args ArgsChainSimulatorConfigs) ArgsConfigsSimulator { + configs := testscommon.CreateTestConfigs(tb, args.OriginalConfigsPath) + + // empty genesis smart contracts file + modifyFile(tb, configs.ConfigurationPathsHolder.SmartContracts, func(intput []byte) []byte { + return []byte("[]") + }) + + // generate validatos key and nodesSetup.json + privateKeys, publicKeys := generateValidatorsKeyAndUpdateFiles(tb, configs, args.NumOfShards, args.GenesisAddressWithStake) + + // update genesis.json + modifyFile(tb, configs.ConfigurationPathsHolder.Genesis, func(i []byte) []byte { + addresses := make([]data.InitialAccount, 0) + + // 10_000 egld + bigValue, _ := big.NewInt(0).SetString("10000000000000000000000", 0) + addresses = append(addresses, data.InitialAccount{ + Address: args.GenesisAddressWithStake, + StakingValue: bigValue, + Supply: bigValue, + }) + + bigValueAddr, _ := big.NewInt(0).SetString("19990000000000000000000000", 10) + addresses = append(addresses, data.InitialAccount{ + Address: args.GenesisAddressWithBalance, + Balance: bigValueAddr, + Supply: bigValueAddr, + }) + + addressesBytes, err := json.Marshal(addresses) + require.Nil(tb, err) + + return addressesBytes + }) + + // generate validators.pem + configs.ConfigurationPathsHolder.ValidatorKey = path.Join(args.OriginalConfigsPath, "validatorKey.pem") + generateValidatorsPem(tb, configs.ConfigurationPathsHolder.ValidatorKey, publicKeys, privateKeys) + + return ArgsConfigsSimulator{ + Configs: configs, + ValidatorsPrivateKeys: privateKeys, + } +} + +func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, numOfShards uint32, address string) ([]crypto.PrivateKey, []crypto.PublicKey) { + blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) + + nodesSetupFile := configs.ConfigurationPathsHolder.Nodes + nodes := &sharding.NodesSetup{} + err := core.LoadJsonFile(nodes, nodesSetupFile) + require.Nil(tb, err) + + nodes.ConsensusGroupSize = 1 + nodes.MinNodesPerShard = 1 + nodes.MetaChainMinNodes = 1 + nodes.MetaChainConsensusGroupSize = 1 + nodes.InitialNodes = make([]*sharding.InitialNode, 0) + + privateKeys := make([]crypto.PrivateKey, 0, numOfShards+1) + publicKeys := make([]crypto.PublicKey, 0, numOfShards+1) + for idx := uint32(0); idx < numOfShards+1; idx++ { + sk, pk := blockSigningGenerator.GeneratePair() + privateKeys = append(privateKeys, sk) + publicKeys = append(publicKeys, pk) + + pkBytes, errB := pk.ToByteArray() + require.Nil(tb, errB) + + nodes.InitialNodes = append(nodes.InitialNodes, &sharding.InitialNode{ + PubKey: hex.EncodeToString(pkBytes), + Address: address, + }) + } + + marshaledNodes, err := json.Marshal(nodes) + require.Nil(tb, err) + + err = os.WriteFile(nodesSetupFile, marshaledNodes, 0644) + require.Nil(tb, err) + + return privateKeys, publicKeys +} + +func generateValidatorsPem(tb testing.TB, validatorsFile string, publicKeys []crypto.PublicKey, privateKey []crypto.PrivateKey) { + validatorPubKeyConverter, err := pubkeyConverter.NewHexPubkeyConverter(96) + require.Nil(tb, err) + + buff := bytes.Buffer{} + for idx := 0; idx < len(publicKeys); idx++ { + publicKeyBytes, errA := publicKeys[idx].ToByteArray() + require.Nil(tb, errA) + + pkString, errE := validatorPubKeyConverter.Encode(publicKeyBytes) + require.Nil(tb, errE) + + privateKeyBytes, errP := privateKey[idx].ToByteArray() + require.Nil(tb, errP) + + blk := pem.Block{ + Type: "PRIVATE KEY for " + pkString, + Bytes: []byte(hex.EncodeToString(privateKeyBytes)), + } + + err = pem.Encode(&buff, &blk) + require.Nil(tb, errE) + } + + err = os.WriteFile(validatorsFile, buff.Bytes(), 0644) + require.Nil(tb, err) +} + +func modifyFile(tb testing.TB, fileName string, f func(i []byte) []byte) { + input, err := os.ReadFile(fileName) + require.Nil(tb, err) + + output := input + if f != nil { + output = f(input) + } + + err = os.WriteFile(fileName, output, 0644) + require.Nil(tb, err) +} diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go new file mode 100644 index 00000000000..b157345ca84 --- /dev/null +++ b/node/chainSimulator/configs/configs_test.go @@ -0,0 +1,23 @@ +package configs + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/integrationTests/realcomponents" +) + +func TestNewProcessorRunnerChainArguments(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + outputConfig := CreateChainSimulatorConfigs(t, ArgsChainSimulatorConfigs{ + NumOfShards: 3, + OriginalConfigsPath: "../../../cmd/node/config", + GenesisAddressWithStake: "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7", + GenesisAddressWithBalance: "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz", + }) + + pr := realcomponents.NewProcessorRunner(t, *outputConfig.Configs) + pr.Close(t) +} diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go index 911c24449a0..8217ec1c77e 100644 --- a/node/chainSimulator/interface.go +++ b/node/chainSimulator/interface.go @@ -1,13 +1,6 @@ package chainSimulator -import "github.com/multiversx/mx-chain-core-go/core" - -// SyncedBroadcastNetworkHandler defines the synced network interface -type SyncedBroadcastNetworkHandler interface { - RegisterMessageReceiver(handler messageReceiver, pid core.PeerID) - Broadcast(pid core.PeerID, topic string, buff []byte) - SendDirectly(from core.PeerID, topic string, buff []byte, to core.PeerID) error - GetConnectedPeers() []core.PeerID - GetConnectedPeersOnTopic(topic string) []core.PeerID +type ChainHandler interface { + ProcessBlock(nonce uint64, round uint64) error IsInterfaceNil() bool } diff --git a/node/chainSimulator/testdata/genesisSmartContracts.json b/node/chainSimulator/testdata/genesisSmartContracts.json index be68c4fec51..c0be11c3c0f 100644 --- a/node/chainSimulator/testdata/genesisSmartContracts.json +++ b/node/chainSimulator/testdata/genesisSmartContracts.json @@ -1,7 +1,7 @@ [ { "owner": "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80", - "filename": "../../cmd/node/config/genesisContracts/delegation.wasm", + "filename": "../../../cmd/node/config/genesisContracts/delegation.wasm", "vm-type": "0500", "init-parameters": "%validator_sc_address%@03E8@00@030D40@030D40", "type": "delegation", @@ -9,7 +9,7 @@ }, { "owner": "erd188anxz35atlef7cucszypmvx88lhz4m7a7t7lhcwt6sfphpsqlkswfhcx2", - "filename": "../../cmd/node/config/genesisContracts/dns.wasm", + "filename": "../../../cmd/node/config/genesisContracts/dns.wasm", "vm-type": "0500", "init-parameters": "056bc75e2d63100000", "type": "dns", From 9a0dffbd1ee134d1fb502c22c4d4b920848fb553 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 31 Oct 2023 11:58:19 +0200 Subject: [PATCH 482/958] refactoring --- .../realcomponents/processorRunner_test.go | 5 +- .../txsimulator/componentConstruction_test.go | 10 +- node/chainSimulator/chainSimulator.go | 78 +++++++---- .../components/configLoaders.go | 41 ------ .../components/cryptoComponents.go | 10 +- .../components/testOnlyProcessingNode.go | 21 +-- .../components/testOnlyProcessingNode_test.go | 8 +- node/chainSimulator/configs/configs.go | 124 ++++++++++++++---- node/chainSimulator/configs/configs_test.go | 4 +- node/nodeRunner_test.go | 10 +- testscommon/realConfigsHandling.go | 70 ++++++---- 11 files changed, 244 insertions(+), 137 deletions(-) diff --git a/integrationTests/realcomponents/processorRunner_test.go b/integrationTests/realcomponents/processorRunner_test.go index 55951b63831..401a7259279 100644 --- a/integrationTests/realcomponents/processorRunner_test.go +++ b/integrationTests/realcomponents/processorRunner_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/testscommon" + "github.com/stretchr/testify/require" ) func TestNewProcessorRunnerAndClose(t *testing.T) { @@ -11,7 +12,9 @@ func TestNewProcessorRunnerAndClose(t *testing.T) { t.Skip("this is not a short test") } - cfg := testscommon.CreateTestConfigs(t, "../../cmd/node/config") + cfg, err := testscommon.CreateTestConfigs("../../cmd/node/config") + require.Nil(t, err) + pr := NewProcessorRunner(t, *cfg) pr.Close(t) } diff --git a/integrationTests/realcomponents/txsimulator/componentConstruction_test.go b/integrationTests/realcomponents/txsimulator/componentConstruction_test.go index 7aa899e5afa..215e1549c2c 100644 --- a/integrationTests/realcomponents/txsimulator/componentConstruction_test.go +++ b/integrationTests/realcomponents/txsimulator/componentConstruction_test.go @@ -23,7 +23,9 @@ func TestTransactionSimulationComponentConstructionOnMetachain(t *testing.T) { t.Skip("this is not a short test") } - cfg := testscommon.CreateTestConfigs(t, "../../../cmd/node/config") + cfg, err := testscommon.CreateTestConfigs("../../../cmd/node/config") + require.Nil(t, err) + cfg.EpochConfig.EnableEpochs.ESDTEnableEpoch = 0 cfg.EpochConfig.EnableEpochs.BuiltInFunctionsEnableEpoch = 0 cfg.PreferencesConfig.Preferences.DestinationShardAsObserver = "metachain" // the problem was only on the metachain @@ -72,7 +74,9 @@ func TestTransactionSimulationComponentConstructionOnShard(t *testing.T) { t.Skip("this is not a short test") } - cfg := testscommon.CreateTestConfigs(t, "../../../cmd/node/config") + cfg, err := testscommon.CreateTestConfigs("../../../cmd/node/config") + require.Nil(t, err) + cfg.EpochConfig.EnableEpochs.SCDeployEnableEpoch = 0 cfg.PreferencesConfig.Preferences.DestinationShardAsObserver = "0" cfg.GeneralConfig.VirtualMachine.Execution.WasmVMVersions = []config.WasmVMVersionByEpoch{ @@ -98,7 +102,7 @@ func TestTransactionSimulationComponentConstructionOnShard(t *testing.T) { // deploy the contract txDeploy, hash := pr.CreateDeploySCTx(t, alice, "../testdata/adder/adder.wasm", 3000000, []string{"01"}) - err := pr.ExecuteTransactionAsScheduled(t, txDeploy) + err = pr.ExecuteTransactionAsScheduled(t, txDeploy) require.Nil(t, err) // get the contract address from logs diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index aabecae66eb..98e43558218 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,51 +1,85 @@ package chainSimulator import ( + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" - "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" ) const ( - NumOfShards = 3 + genesisAddressWithStake = "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7" + genesisAddressWithStakeSK = "ZWRlZDAyNDczZTE4NjQ2MTY5NzNhZTIwY2IzYjg3NWFhM2ZmZWU1NWE2MGQ5NDgy\nMjhmMzk4ZTQ4OTk1NjA3NTc4YjUwNmRkYzkyMWU0YmUyNGZlOTUxMTMwN2JlYmYy\nNWFhNzI3NzdiMjBlMjQ4OTNlMmZjN2QwODgwYWQ1MDg=" + genesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" + genesisAddressWithBalanceSK = "YWQxMTM2YTEyNWZkM2YxY2ZiMTU0MTU5NDQyZTRiYzZhM2I1YzMwOTU5NDMwMjk5\nNThhYzQ2NGRhN2NlMTNlYjFkYzdiNTNmN2I0YTgzYzQwOGQ4OGFkZGZlNDUzZDU2\nYWI3MzY3Mjk5YTNmMDI1N2FkODU1YTFjNjIwNTg0NjU=" ) type simulator struct { chanStopNodeProcess chan endProcess.ArgEndProcess syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler nodes []ChainHandler + numOfShards uint32 } -func NewChainSimulator() (*simulator, error) { +func NewChainSimulator(numOfShards uint32) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() - return &simulator{ + instance := &simulator{ syncedBroadcastNetwork: syncedBroadcastNetwork, - }, nil + nodes: make([]ChainHandler, 0), + numOfShards: numOfShards, + } + + return instance, nil } -func (s *simulator) createChanHandler(shardID uint32) (ChainHandler, error) { - generalConfig := testscommon.GetGeneralConfig() +func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath string) error { + outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ + NumOfShards: numOfShards, + OriginalConfigsPath: originalConfigPath, + GenesisAddressWithStake: genesisAddressWithStake, + GenesisAddressWithBalance: genesisAddressWithBalance, + }) + if err != nil { + return err + } + + metaChainHandler, err := s.createChainHandler(core.MetachainShardId, outputConfigs.Configs, 0) + if err != nil { + return err + } + + s.nodes = append(s.nodes, metaChainHandler) + + for idx := uint32(0); idx < numOfShards; idx++ { + shardChainHandler, errS := s.createChainHandler(idx, outputConfigs.Configs, int(idx)+1) + if errS != nil { + return errS + } + + s.nodes = append(s.nodes, shardChainHandler) + } + + return nil +} +func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, skIndex int) (ChainHandler, error) { args := components.ArgsTestOnlyProcessingNode{ - Config: generalConfig, - EpochConfig: config.EpochConfig{}, - EconomicsConfig: config.EconomicsConfig{}, - RoundsConfig: config.RoundConfig{}, - PreferencesConfig: config.Preferences{}, - ImportDBConfig: config.ImportDbConfig{}, - ContextFlagsConfig: config.ContextFlagsConfig{}, - SystemSCConfig: config.SystemSmartContractsConfig{}, - ConfigurationPathsHolder: config.ConfigurationPathsHolder{}, - ChanStopNodeProcess: nil, + Config: *configs.GeneralConfig, + EpochConfig: *configs.EpochConfig, + EconomicsConfig: *configs.EconomicsConfig, + RoundsConfig: *configs.RoundConfig, + PreferencesConfig: *configs.PreferencesConfig, + ImportDBConfig: *configs.ImportDbConfig, + ContextFlagsConfig: *configs.FlagsConfig, + SystemSCConfig: *configs.SystemSCConfig, + ConfigurationPathsHolder: *configs.ConfigurationPathsHolder, + ChanStopNodeProcess: s.chanStopNodeProcess, SyncedBroadcastNetwork: s.syncedBroadcastNetwork, - GasScheduleFilename: "", - ValidatorPemFile: "", - WorkingDir: "", - NodesSetupPath: "", - NumShards: NumOfShards, + NumShards: s.numOfShards, ShardID: shardID, + SkKeyIndex: skIndex, } return components.NewTestOnlyProcessingNode(args) diff --git a/node/chainSimulator/components/configLoaders.go b/node/chainSimulator/components/configLoaders.go index 336935bbeaf..6e895d87724 100644 --- a/node/chainSimulator/components/configLoaders.go +++ b/node/chainSimulator/components/configLoaders.go @@ -2,9 +2,6 @@ package components import ( "os" - "path" - "strconv" - "strings" "github.com/pelletier/go-toml" ) @@ -20,41 +17,3 @@ func LoadConfigFromFile(filename string, config interface{}) error { return err } - -// GetLatestGasScheduleFilename will parse the provided path and get the latest gas schedule filename -func GetLatestGasScheduleFilename(directory string) (string, error) { - entries, err := os.ReadDir(directory) - if err != nil { - return "", err - } - - extension := ".toml" - versionMarker := "V" - - highestVersion := 0 - filename := "" - for _, entry := range entries { - if entry.IsDir() { - continue - } - - name := entry.Name() - splt := strings.Split(name, versionMarker) - if len(splt) != 2 { - continue - } - - versionAsString := splt[1][:len(splt[1])-len(extension)] - number, errConversion := strconv.Atoi(versionAsString) - if errConversion != nil { - continue - } - - if number > highestVersion { - highestVersion = number - filename = name - } - } - - return path.Join(directory, filename), nil -} diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 9e4f9de49c4..67ec1e75574 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -21,6 +21,7 @@ type ArgsCryptoComponentsHolder struct { Preferences config.Preferences CoreComponentsHolder factory.CoreComponentsHolder ValidatorKeyPemFileName string + SkKeyIndex int } type cryptoComponentsHolder struct { @@ -57,11 +58,10 @@ func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.Cryp ActivateBLSPubKeyMessageVerification: true, IsInImportMode: false, ImportModeNoSigCheck: false, - - P2pKeyPemFileName: "", - ValidatorKeyPemFileName: args.ValidatorKeyPemFileName, - AllValidatorKeysPemFileName: "", - SkIndex: 0, + P2pKeyPemFileName: "", + ValidatorKeyPemFileName: args.ValidatorKeyPemFileName, + AllValidatorKeysPemFileName: "", + SkIndex: args.SkKeyIndex, } cryptoComponentsFactory, err := cryptoComp.NewCryptoComponentsFactory(cryptoComponentsHandlerArgs) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 7c453b3e441..d6e353e7a25 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -35,12 +35,12 @@ type ArgsTestOnlyProcessingNode struct { ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler - GasScheduleFilename string - ValidatorPemFile string - WorkingDir string - NodesSetupPath string - NumShards uint32 - ShardID uint32 + + GasScheduleFilename string + + NumShards uint32 + ShardID uint32 + SkKeyIndex int } type testOnlyProcessingNode struct { @@ -83,9 +83,9 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces EconomicsConfig: args.EconomicsConfig, ChanStopNodeProcess: args.ChanStopNodeProcess, NumShards: args.NumShards, - WorkingDir: args.WorkingDir, + WorkingDir: args.ContextFlagsConfig.WorkingDir, GasScheduleFilename: args.GasScheduleFilename, - NodesSetupPath: args.NodesSetupPath, + NodesSetupPath: args.ConfigurationPathsHolder.Nodes, }) if err != nil { return nil, err @@ -120,7 +120,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces EnableEpochsConfig: args.EpochConfig.EnableEpochs, Preferences: args.PreferencesConfig, CoreComponentsHolder: instance.CoreComponentsHolder, - ValidatorKeyPemFileName: args.ValidatorPemFile, + ValidatorKeyPemFileName: args.ConfigurationPathsHolder.ValidatorKey, + SkKeyIndex: args.SkKeyIndex, }) if err != nil { return nil, err @@ -136,7 +137,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces CryptoComponents: instance.CryptoComponentsHolder, NetworkComponents: instance.NetworkComponentsHolder, StatusCoreComponents: instance.StatusCoreComponents, - WorkingDir: args.WorkingDir, + WorkingDir: args.ContextFlagsConfig.WorkingDir, FlagsConfig: args.ContextFlagsConfig, ImportDBConfig: args.ImportDBConfig, PrefsConfig: args.PreferencesConfig, diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index ae5db48e64f..3662cb8303e 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -6,6 +6,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -31,7 +32,7 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo err = LoadConfigFromFile(pathForEconomicsConfig, &economicsConfig) assert.Nil(t, err) - gasScheduleName, err := GetLatestGasScheduleFilename(pathForGasSchedules) + gasScheduleName, err := configs.GetLatestGasScheduleFilename(pathForGasSchedules) assert.Nil(t, err) prefsConfig := config.Preferences{} @@ -50,7 +51,6 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo return ArgsTestOnlyProcessingNode{ Config: mainConfig, - WorkingDir: workingDir, EpochConfig: epochConfig, RoundsConfig: config.RoundConfig{ RoundActivations: map[string]config.ActivationRoundByName{ @@ -61,10 +61,8 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo }, EconomicsConfig: economicsConfig, GasScheduleFilename: gasScheduleName, - NodesSetupPath: nodesSetupConfig, NumShards: 3, ShardID: 0, - ValidatorPemFile: validatorPemFile, PreferencesConfig: prefsConfig, SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), ImportDBConfig: config.ImportDbConfig{}, @@ -76,6 +74,8 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo GasScheduleDirectoryName: pathToConfigFolder + "gasSchedules", Genesis: pathToConfigFolder + "genesis.json", SmartContracts: pathTestData + "genesisSmartContracts.json", + Nodes: nodesSetupConfig, + ValidatorKey: validatorPemFile, }, SystemSCConfig: systemSCConfig, ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 9f4d9e70842..f2036b7e098 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -8,6 +8,8 @@ import ( "math/big" "os" "path" + "strconv" + "strings" "testing" "github.com/multiversx/mx-chain-core-go/core" @@ -30,23 +32,30 @@ type ArgsChainSimulatorConfigs struct { } type ArgsConfigsSimulator struct { + GasScheduleFilename string Configs *config.Configs ValidatorsPrivateKeys []crypto.PrivateKey } -func CreateChainSimulatorConfigs(tb testing.TB, args ArgsChainSimulatorConfigs) ArgsConfigsSimulator { - configs := testscommon.CreateTestConfigs(tb, args.OriginalConfigsPath) +func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSimulator, error) { + configs, err := testscommon.CreateTestConfigs(args.OriginalConfigsPath) + if err != nil { + return nil, err + } // empty genesis smart contracts file - modifyFile(tb, configs.ConfigurationPathsHolder.SmartContracts, func(intput []byte) []byte { - return []byte("[]") + err = modifyFile(configs.ConfigurationPathsHolder.SmartContracts, func(intput []byte) ([]byte, error) { + return []byte("[]"), nil }) + if err != nil { + return nil, err + } // generate validatos key and nodesSetup.json - privateKeys, publicKeys := generateValidatorsKeyAndUpdateFiles(tb, configs, args.NumOfShards, args.GenesisAddressWithStake) + privateKeys, publicKeys := generateValidatorsKeyAndUpdateFiles(nil, configs, args.NumOfShards, args.GenesisAddressWithStake) // update genesis.json - modifyFile(tb, configs.ConfigurationPathsHolder.Genesis, func(i []byte) []byte { + err = modifyFile(configs.ConfigurationPathsHolder.Genesis, func(i []byte) ([]byte, error) { addresses := make([]data.InitialAccount, 0) // 10_000 egld @@ -64,20 +73,34 @@ func CreateChainSimulatorConfigs(tb testing.TB, args ArgsChainSimulatorConfigs) Supply: bigValueAddr, }) - addressesBytes, err := json.Marshal(addresses) - require.Nil(tb, err) + addressesBytes, errM := json.Marshal(addresses) + if errM != nil { + return nil, errM + } - return addressesBytes + return addressesBytes, nil }) + if err != nil { + return nil, err + } // generate validators.pem configs.ConfigurationPathsHolder.ValidatorKey = path.Join(args.OriginalConfigsPath, "validatorKey.pem") - generateValidatorsPem(tb, configs.ConfigurationPathsHolder.ValidatorKey, publicKeys, privateKeys) + err = generateValidatorsPem(configs.ConfigurationPathsHolder.ValidatorKey, publicKeys, privateKeys) + if err != nil { + return nil, err + } - return ArgsConfigsSimulator{ + gasScheduleName, err := GetLatestGasScheduleFilename(configs.ConfigurationPathsHolder.GasScheduleDirectoryName) + if err != nil { + return nil, err + } + + return &ArgsConfigsSimulator{ Configs: configs, ValidatorsPrivateKeys: privateKeys, - } + GasScheduleFilename: gasScheduleName, + }, nil } func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, numOfShards uint32, address string) ([]crypto.PrivateKey, []crypto.PublicKey) { @@ -119,20 +142,28 @@ func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, return privateKeys, publicKeys } -func generateValidatorsPem(tb testing.TB, validatorsFile string, publicKeys []crypto.PublicKey, privateKey []crypto.PrivateKey) { +func generateValidatorsPem(validatorsFile string, publicKeys []crypto.PublicKey, privateKey []crypto.PrivateKey) error { validatorPubKeyConverter, err := pubkeyConverter.NewHexPubkeyConverter(96) - require.Nil(tb, err) + if err != nil { + return err + } buff := bytes.Buffer{} for idx := 0; idx < len(publicKeys); idx++ { publicKeyBytes, errA := publicKeys[idx].ToByteArray() - require.Nil(tb, errA) + if errA != nil { + return errA + } pkString, errE := validatorPubKeyConverter.Encode(publicKeyBytes) - require.Nil(tb, errE) + if errE != nil { + return errE + } privateKeyBytes, errP := privateKey[idx].ToByteArray() - require.Nil(tb, errP) + if errP != nil { + return errP + } blk := pem.Block{ Type: "PRIVATE KEY for " + pkString, @@ -140,22 +171,65 @@ func generateValidatorsPem(tb testing.TB, validatorsFile string, publicKeys []cr } err = pem.Encode(&buff, &blk) - require.Nil(tb, errE) + if err != nil { + return err + } } - err = os.WriteFile(validatorsFile, buff.Bytes(), 0644) - require.Nil(tb, err) + return os.WriteFile(validatorsFile, buff.Bytes(), 0644) } -func modifyFile(tb testing.TB, fileName string, f func(i []byte) []byte) { +func modifyFile(fileName string, f func(i []byte) ([]byte, error)) error { input, err := os.ReadFile(fileName) - require.Nil(tb, err) + if err != nil { + return err + } output := input if f != nil { - output = f(input) + output, err = f(input) + if err != nil { + return err + } } - err = os.WriteFile(fileName, output, 0644) - require.Nil(tb, err) + return os.WriteFile(fileName, output, 0644) +} + +// GetLatestGasScheduleFilename will parse the provided path and get the latest gas schedule filename +func GetLatestGasScheduleFilename(directory string) (string, error) { + entries, err := os.ReadDir(directory) + if err != nil { + return "", err + } + + extension := ".toml" + versionMarker := "V" + + highestVersion := 0 + filename := "" + for _, entry := range entries { + if entry.IsDir() { + continue + } + + name := entry.Name() + splt := strings.Split(name, versionMarker) + if len(splt) != 2 { + continue + } + + versionAsString := splt[1][:len(splt[1])-len(extension)] + number, errConversion := strconv.Atoi(versionAsString) + if errConversion != nil { + continue + } + + if number > highestVersion { + highestVersion = number + filename = name + } + } + + return path.Join(directory, filename), nil } diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index b157345ca84..c94ec49fa80 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/integrationTests/realcomponents" + "github.com/stretchr/testify/require" ) func TestNewProcessorRunnerChainArguments(t *testing.T) { @@ -11,12 +12,13 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { t.Skip("this is not a short test") } - outputConfig := CreateChainSimulatorConfigs(t, ArgsChainSimulatorConfigs{ + outputConfig, err := CreateChainSimulatorConfigs(ArgsChainSimulatorConfigs{ NumOfShards: 3, OriginalConfigsPath: "../../../cmd/node/config", GenesisAddressWithStake: "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7", GenesisAddressWithBalance: "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz", }) + require.Nil(t, err) pr := realcomponents.NewProcessorRunner(t, *outputConfig.Configs) pr.Close(t) diff --git a/node/nodeRunner_test.go b/node/nodeRunner_test.go index 6e3c61a12cd..c8afa1a17e3 100644 --- a/node/nodeRunner_test.go +++ b/node/nodeRunner_test.go @@ -35,7 +35,9 @@ func TestNewNodeRunner(t *testing.T) { t.Run("with valid configs should work", func(t *testing.T) { t.Parallel() - configs := testscommon.CreateTestConfigs(t, originalConfigsPath) + configs, err := testscommon.CreateTestConfigs(originalConfigsPath) + require.Nil(t, err) + runner, err := NewNodeRunner(configs) assert.NotNil(t, runner) assert.Nil(t, err) @@ -45,11 +47,13 @@ func TestNewNodeRunner(t *testing.T) { func TestNodeRunner_StartAndCloseNodeUsingSIGINT(t *testing.T) { t.Parallel() - configs := testscommon.CreateTestConfigs(t, originalConfigsPath) + configs, err := testscommon.CreateTestConfigs(originalConfigsPath) + require.Nil(t, err) + runner, _ := NewNodeRunner(configs) trigger := mock.NewApplicationRunningTrigger() - err := logger.AddLogObserver(trigger, &logger.PlainFormatter{}) + err = logger.AddLogObserver(trigger, &logger.PlainFormatter{}) require.Nil(t, err) // start a go routine that will send the SIGINT message after 1 second after the node has started diff --git a/testscommon/realConfigsHandling.go b/testscommon/realConfigsHandling.go index 024fe336b9f..eaccef8a75c 100644 --- a/testscommon/realConfigsHandling.go +++ b/testscommon/realConfigsHandling.go @@ -5,60 +5,85 @@ import ( "os/exec" "path" "strings" - "testing" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" - "github.com/stretchr/testify/require" ) // CreateTestConfigs will try to copy the whole configs directory to a temp directory and return the configs after load // The copying of the configs is required because minor adjustments of their contents is required for the tests to pass -func CreateTestConfigs(tb testing.TB, originalConfigsPath string) *config.Configs { - tempDir := tb.TempDir() +func CreateTestConfigs(originalConfigsPath string) (*config.Configs, error) { + tempDir := os.TempDir() newConfigsPath := path.Join(tempDir, "config") // TODO refactor this cp to work on all OSes cmd := exec.Command("cp", "-r", originalConfigsPath, newConfigsPath) err := cmd.Run() - require.Nil(tb, err) + if err != nil { + return nil, err + } newGenesisSmartContractsFilename := path.Join(newConfigsPath, "genesisSmartContracts.json") - correctTestPathInGenesisSmartContracts(tb, tempDir, newGenesisSmartContractsFilename) + err = correctTestPathInGenesisSmartContracts(tempDir, newGenesisSmartContractsFilename) + if err != nil { + return nil, err + } apiConfig, err := common.LoadApiConfig(path.Join(newConfigsPath, "api.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } generalConfig, err := common.LoadMainConfig(path.Join(newConfigsPath, "config.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } ratingsConfig, err := common.LoadRatingsConfig(path.Join(newConfigsPath, "ratings.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } economicsConfig, err := common.LoadEconomicsConfig(path.Join(newConfigsPath, "economics.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } prefsConfig, err := common.LoadPreferencesConfig(path.Join(newConfigsPath, "prefs.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } mainP2PConfig, err := common.LoadP2PConfig(path.Join(newConfigsPath, "p2p.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } fullArchiveP2PConfig, err := common.LoadP2PConfig(path.Join(newConfigsPath, "fullArchiveP2P.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } externalConfig, err := common.LoadExternalConfig(path.Join(newConfigsPath, "external.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } systemSCConfig, err := common.LoadSystemSmartContractsConfig(path.Join(newConfigsPath, "systemSmartContractsConfig.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } epochConfig, err := common.LoadEpochConfig(path.Join(newConfigsPath, "enableEpochs.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } roundConfig, err := common.LoadRoundConfig(path.Join(newConfigsPath, "enableRounds.toml")) - require.Nil(tb, err) + if err != nil { + return nil, err + } // make the node pass the network wait constraints mainP2PConfig.Node.MinNumPeersToWaitForOnBootstrap = 0 @@ -91,12 +116,14 @@ func CreateTestConfigs(tb testing.TB, originalConfigsPath string) *config.Config }, EpochConfig: epochConfig, RoundConfig: roundConfig, - } + }, nil } -func correctTestPathInGenesisSmartContracts(tb testing.TB, tempDir string, newGenesisSmartContractsFilename string) { +func correctTestPathInGenesisSmartContracts(tempDir string, newGenesisSmartContractsFilename string) error { input, err := os.ReadFile(newGenesisSmartContractsFilename) - require.Nil(tb, err) + if err != nil { + return err + } lines := strings.Split(string(input), "\n") for i, line := range lines { @@ -105,6 +132,5 @@ func correctTestPathInGenesisSmartContracts(tb testing.TB, tempDir string, newGe } } output := strings.Join(lines, "\n") - err = os.WriteFile(newGenesisSmartContractsFilename, []byte(output), 0644) - require.Nil(tb, err) + return os.WriteFile(newGenesisSmartContractsFilename, []byte(output), 0644) } From 9b8b90f13b452a95644a8c65c096496db0ef3933 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 31 Oct 2023 12:08:52 +0200 Subject: [PATCH 483/958] fix test --- node/chainSimulator/components/testOnlyProcessingNode_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 3662cb8303e..d1441971249 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -122,6 +122,9 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { newHeader, err := node.ProcessComponentsHolder.BlockProcessor().CreateNewHeader(1, 1) assert.Nil(t, err) + err = newHeader.SetPrevHash(node.ChainHandler.GetGenesisHeaderHash()) + assert.Nil(t, err) + header, block, err := node.ProcessComponentsHolder.BlockProcessor().CreateBlock(newHeader, func() bool { return true }) From c417fb890c08b18998351aee4b4ba71503c28107 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 31 Oct 2023 13:38:54 +0200 Subject: [PATCH 484/958] unit tests --- node/chainSimulator/chainSimulator.go | 31 +++++++++++++------ node/chainSimulator/chainSimulator_test.go | 16 ++++++++++ .../components/coreComponents.go | 2 +- node/chainSimulator/configs/configs.go | 5 +++ 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 98e43558218..292c45f1092 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,6 +1,8 @@ package chainSimulator import ( + "errors" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" @@ -9,10 +11,10 @@ import ( ) const ( - genesisAddressWithStake = "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7" - genesisAddressWithStakeSK = "ZWRlZDAyNDczZTE4NjQ2MTY5NzNhZTIwY2IzYjg3NWFhM2ZmZWU1NWE2MGQ5NDgy\nMjhmMzk4ZTQ4OTk1NjA3NTc4YjUwNmRkYzkyMWU0YmUyNGZlOTUxMTMwN2JlYmYy\nNWFhNzI3NzdiMjBlMjQ4OTNlMmZjN2QwODgwYWQ1MDg=" - genesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" - genesisAddressWithBalanceSK = "YWQxMTM2YTEyNWZkM2YxY2ZiMTU0MTU5NDQyZTRiYzZhM2I1YzMwOTU5NDMwMjk5\nNThhYzQ2NGRhN2NlMTNlYjFkYzdiNTNmN2I0YTgzYzQwOGQ4OGFkZGZlNDUzZDU2\nYWI3MzY3Mjk5YTNmMDI1N2FkODU1YTFjNjIwNTg0NjU=" + genesisAddressWithStake = "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7" + //genesisAddressWithStakeSK = "ZWRlZDAyNDczZTE4NjQ2MTY5NzNhZTIwY2IzYjg3NWFhM2ZmZWU1NWE2MGQ5NDgy\nMjhmMzk4ZTQ4OTk1NjA3NTc4YjUwNmRkYzkyMWU0YmUyNGZlOTUxMTMwN2JlYmYy\nNWFhNzI3NzdiMjBlMjQ4OTNlMmZjN2QwODgwYWQ1MDg=" + genesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" + //genesisAddressWithBalanceSK = "YWQxMTM2YTEyNWZkM2YxY2ZiMTU0MTU5NDQyZTRiYzZhM2I1YzMwOTU5NDMwMjk5\nNThhYzQ2NGRhN2NlMTNlYjFkYzdiNTNmN2I0YTgzYzQwOGQ4OGFkZGZlNDUzZDU2\nYWI3MzY3Mjk5YTNmMDI1N2FkODU1YTFjNjIwNTg0NjU=" ) type simulator struct { @@ -22,13 +24,23 @@ type simulator struct { numOfShards uint32 } -func NewChainSimulator(numOfShards uint32) (*simulator, error) { +func NewChainSimulator(numOfShards uint32, pathToInitialConfig string) (*simulator, error) { + if pathToInitialConfig == "" { + return nil, errors.New("invalid provided path to the initial config") + } + syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() instance := &simulator{ syncedBroadcastNetwork: syncedBroadcastNetwork, nodes: make([]ChainHandler, 0), numOfShards: numOfShards, + chanStopNodeProcess: make(chan endProcess.ArgEndProcess), + } + + err := instance.createChainHandlers(numOfShards, pathToInitialConfig) + if err != nil { + return nil, err } return instance, nil @@ -45,7 +57,7 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s return err } - metaChainHandler, err := s.createChainHandler(core.MetachainShardId, outputConfigs.Configs, 0) + metaChainHandler, err := s.createChainHandler(core.MetachainShardId, outputConfigs.Configs, 0, outputConfigs.GasScheduleFilename) if err != nil { return err } @@ -53,7 +65,7 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s s.nodes = append(s.nodes, metaChainHandler) for idx := uint32(0); idx < numOfShards; idx++ { - shardChainHandler, errS := s.createChainHandler(idx, outputConfigs.Configs, int(idx)+1) + shardChainHandler, errS := s.createChainHandler(idx, outputConfigs.Configs, int(idx)+1, outputConfigs.GasScheduleFilename) if errS != nil { return errS } @@ -64,7 +76,7 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s return nil } -func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, skIndex int) (ChainHandler, error) { +func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, skIndex int, gasScheduleFilename string) (ChainHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Config: *configs.GeneralConfig, EpochConfig: *configs.EpochConfig, @@ -78,6 +90,7 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, ChanStopNodeProcess: s.chanStopNodeProcess, SyncedBroadcastNetwork: s.syncedBroadcastNetwork, NumShards: s.numOfShards, + GasScheduleFilename: gasScheduleFilename, ShardID: shardID, SkKeyIndex: skIndex, } @@ -85,7 +98,7 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, return components.NewTestOnlyProcessingNode(args) } -func (s *simulator) GenerateBlocks(numOfBlock int) error { +func (s *simulator) GenerateBlocks(_ int) error { return nil } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 8015b9a1580..7d831828051 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -1 +1,17 @@ package chainSimulator + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +const ( + defaultPathToInitialConfig = "../../cmd/node/config/" +) + +func TestNewChainSimulator(t *testing.T) { + chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig) + require.Nil(t, err) + require.NotNil(t, chainSimulator) +} diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 29af73ba133..078309959e7 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -188,7 +188,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.apiEconomicsData = instance.economicsData // TODO check if we need this - instance.ratingsData = nil + instance.ratingsData = &testscommon.RatingsInfoMock{} instance.rater = &testscommon.RaterMock{} instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.NodesSetupPath, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index f2036b7e098..4a0e7f98d33 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -20,6 +20,7 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/genesis/data" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/storage/storageunit" "github.com/multiversx/mx-chain-go/testscommon" "github.com/stretchr/testify/require" ) @@ -96,6 +97,10 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } + configs.GeneralConfig.SmartContractsStorage.DB.Type = string(storageunit.MemoryDB) + configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) + configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) + return &ArgsConfigsSimulator{ Configs: configs, ValidatorsPrivateKeys: privateKeys, From 39845e1eae1bd6c6613672d337f5c2fb49b4263d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 1 Nov 2023 15:03:38 +0200 Subject: [PATCH 485/958] process blocks --- node/chainSimulator/chainSimulator.go | 10 +++- node/chainSimulator/chainSimulator_test.go | 6 +++ .../components/testOnlyProcessingNode.go | 51 +++++++++++++++---- node/chainSimulator/interface.go | 2 +- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 292c45f1092..a545401d679 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -98,7 +98,15 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, return components.NewTestOnlyProcessingNode(args) } -func (s *simulator) GenerateBlocks(_ int) error { +func (s *simulator) GenerateBlocks(numOfBlocks int) error { + for idx := 0; idx < numOfBlocks; idx++ { + for _, node := range s.nodes { + err := node.ProcessBlock() + if err != nil { + return err + } + } + } return nil } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 7d831828051..7b646c5faa8 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -2,6 +2,7 @@ package chainSimulator import ( "testing" + "time" "github.com/stretchr/testify/require" ) @@ -14,4 +15,9 @@ func TestNewChainSimulator(t *testing.T) { chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig) require.Nil(t, err) require.NotNil(t, chainSimulator) + + time.Sleep(time.Second) + + err = chainSimulator.GenerateBlocks(10) + require.Nil(t, err) } diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index d6e353e7a25..75ef5a84249 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -1,8 +1,6 @@ package components import ( - "time" - "github.com/multiversx/mx-chain-core-go/core" chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/endProcess" @@ -296,27 +294,54 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc return nil } -func (node *testOnlyProcessingNode) ProcessBlock(nonce uint64, round uint64) error { +func (node *testOnlyProcessingNode) ProcessBlock() error { bp := node.ProcessComponentsHolder.BlockProcessor() - newHeader, err := node.prepareHeader(nonce, round) + currentHeader := node.ChainHandler.GetCurrentBlockHeader() + var nonce, round uint64 + var prevHash, prevRandSeed []byte + if currentHeader != nil { + nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() + prevHash = node.ChainHandler.GetCurrentBlockHeaderHash() + prevRandSeed = currentHeader.GetRandSeed() + } else { + prevHash = node.ChainHandler.GetGenesisHeaderHash() + prevRandSeed = node.ChainHandler.GetGenesisHeader().GetRandSeed() + } + + newHeader, err := node.prepareHeader(nonce+1, round+1, prevHash) if err != nil { return err } - header, block, err := bp.CreateBlock(newHeader, func() bool { - return true - }) + err = newHeader.SetPrevRandSeed(prevRandSeed) + if err != nil { + return err + } + + err = newHeader.SetPubKeysBitmap([]byte{128}) if err != nil { return err } - err = bp.ProcessBlock(header, block, func() time.Duration { - return 1000 + err = newHeader.SetRandSeed([]byte("dummy")) + if err != nil { + return err + } + + header, block, err := bp.CreateBlock(newHeader, func() bool { + return true }) if err != nil { return err } + //err = bp.ProcessBlock(header, block, func() time.Duration { + // return 1000 + //}) + //if err != nil { + // return err + //} + err = bp.CommitBlock(header, block) if err != nil { return err @@ -325,8 +350,9 @@ func (node *testOnlyProcessingNode) ProcessBlock(nonce uint64, round uint64) err return nil } -func (node *testOnlyProcessingNode) prepareHeader(nonce uint64, round uint64) (chainData.HeaderHandler, error) { +func (node *testOnlyProcessingNode) prepareHeader(nonce uint64, round uint64, prevHash []byte) (chainData.HeaderHandler, error) { bp := node.ProcessComponentsHolder.BlockProcessor() + newHeader, err := bp.CreateNewHeader(round, nonce) if err != nil { return nil, err @@ -336,6 +362,11 @@ func (node *testOnlyProcessingNode) prepareHeader(nonce uint64, round uint64) (c return nil, err } + err = newHeader.SetPrevHash(prevHash) + if err != nil { + return nil, err + } + return newHeader, nil } diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go index 8217ec1c77e..a534f4cbbd5 100644 --- a/node/chainSimulator/interface.go +++ b/node/chainSimulator/interface.go @@ -1,6 +1,6 @@ package chainSimulator type ChainHandler interface { - ProcessBlock(nonce uint64, round uint64) error + ProcessBlock() error IsInterfaceNil() bool } From 029aeba28341f2463102613179bdcde129df74d6 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 1 Nov 2023 15:37:24 +0200 Subject: [PATCH 486/958] fixes after review --- node/chainSimulator/chainSimulator.go | 23 ++++++------------- .../components/configLoaders.go | 19 --------------- .../components/cryptoComponents.go | 4 ++-- .../components/testOnlyProcessingNode.go | 12 ++++++---- .../components/testOnlyProcessingNode_test.go | 11 +++++---- node/chainSimulator/configs/configs.go | 9 +++++--- node/chainSimulator/interface.go | 3 ++- node/chainSimulator/testdata/addresses.go | 13 +++++++++++ 8 files changed, 43 insertions(+), 51 deletions(-) delete mode 100644 node/chainSimulator/components/configLoaders.go create mode 100644 node/chainSimulator/testdata/addresses.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 292c45f1092..c23725104f2 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,20 +1,12 @@ package chainSimulator import ( - "errors" - "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" -) - -const ( - genesisAddressWithStake = "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7" - //genesisAddressWithStakeSK = "ZWRlZDAyNDczZTE4NjQ2MTY5NzNhZTIwY2IzYjg3NWFhM2ZmZWU1NWE2MGQ5NDgy\nMjhmMzk4ZTQ4OTk1NjA3NTc4YjUwNmRkYzkyMWU0YmUyNGZlOTUxMTMwN2JlYmYy\nNWFhNzI3NzdiMjBlMjQ4OTNlMmZjN2QwODgwYWQ1MDg=" - genesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" - //genesisAddressWithBalanceSK = "YWQxMTM2YTEyNWZkM2YxY2ZiMTU0MTU5NDQyZTRiYzZhM2I1YzMwOTU5NDMwMjk5\nNThhYzQ2NGRhN2NlMTNlYjFkYzdiNTNmN2I0YTgzYzQwOGQ4OGFkZGZlNDUzZDU2\nYWI3MzY3Mjk5YTNmMDI1N2FkODU1YTFjNjIwNTg0NjU=" + "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" ) type simulator struct { @@ -24,11 +16,8 @@ type simulator struct { numOfShards uint32 } +// NewChainSimulator will create a new instance of simulator func NewChainSimulator(numOfShards uint32, pathToInitialConfig string) (*simulator, error) { - if pathToInitialConfig == "" { - return nil, errors.New("invalid provided path to the initial config") - } - syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() instance := &simulator{ @@ -50,8 +39,8 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: numOfShards, OriginalConfigsPath: originalConfigPath, - GenesisAddressWithStake: genesisAddressWithStake, - GenesisAddressWithBalance: genesisAddressWithBalance, + GenesisAddressWithStake: testdata.GenesisAddressWithStake, + GenesisAddressWithBalance: testdata.GenesisAddressWithBalance, }) if err != nil { return err @@ -92,16 +81,18 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, NumShards: s.numOfShards, GasScheduleFilename: gasScheduleFilename, ShardID: shardID, - SkKeyIndex: skIndex, + SkIndex: skIndex, } return components.NewTestOnlyProcessingNode(args) } +// GenerateBlocks will generate the provided number of blocks func (s *simulator) GenerateBlocks(_ int) error { return nil } +// Stop will stop the simulator func (s *simulator) Stop() { } diff --git a/node/chainSimulator/components/configLoaders.go b/node/chainSimulator/components/configLoaders.go deleted file mode 100644 index 6e895d87724..00000000000 --- a/node/chainSimulator/components/configLoaders.go +++ /dev/null @@ -1,19 +0,0 @@ -package components - -import ( - "os" - - "github.com/pelletier/go-toml" -) - -// LoadConfigFromFile will try to load the config from the specified file -func LoadConfigFromFile(filename string, config interface{}) error { - data, err := os.ReadFile(filename) - if err != nil { - return err - } - - err = toml.Unmarshal(data, config) - - return err -} diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 67ec1e75574..bfaa707cba8 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -21,7 +21,7 @@ type ArgsCryptoComponentsHolder struct { Preferences config.Preferences CoreComponentsHolder factory.CoreComponentsHolder ValidatorKeyPemFileName string - SkKeyIndex int + SkIndex int } type cryptoComponentsHolder struct { @@ -61,7 +61,7 @@ func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.Cryp P2pKeyPemFileName: "", ValidatorKeyPemFileName: args.ValidatorKeyPemFileName, AllValidatorKeysPemFileName: "", - SkIndex: args.SkKeyIndex, + SkIndex: args.SkIndex, } cryptoComponentsFactory, err := cryptoComp.NewCryptoComponentsFactory(cryptoComponentsHandlerArgs) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index d6e353e7a25..a74b696b99e 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -38,9 +38,9 @@ type ArgsTestOnlyProcessingNode struct { GasScheduleFilename string - NumShards uint32 - ShardID uint32 - SkKeyIndex int + NumShards uint32 + ShardID uint32 + SkIndex int } type testOnlyProcessingNode struct { @@ -121,7 +121,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces Preferences: args.PreferencesConfig, CoreComponentsHolder: instance.CoreComponentsHolder, ValidatorKeyPemFileName: args.ConfigurationPathsHolder.ValidatorKey, - SkKeyIndex: args.SkKeyIndex, + SkIndex: args.SkIndex, }) if err != nil { return nil, err @@ -296,7 +296,8 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc return nil } -func (node *testOnlyProcessingNode) ProcessBlock(nonce uint64, round uint64) error { +// CreateNewBlock create and process a new block +func (node *testOnlyProcessingNode) CreateNewBlock(nonce uint64, round uint64) error { bp := node.ProcessComponentsHolder.BlockProcessor() newHeader, err := node.prepareHeader(nonce, round) if err != nil { @@ -311,6 +312,7 @@ func (node *testOnlyProcessingNode) ProcessBlock(nonce uint64, round uint64) err } err = bp.ProcessBlock(header, block, func() time.Duration { + // TODO fix this return 1000 }) if err != nil { diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index d1441971249..f82fee5286a 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" @@ -25,28 +26,28 @@ const ( func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { mainConfig := config.Config{} - err := LoadConfigFromFile(pathForMainConfig, &mainConfig) + err := core.LoadTomlFile(&mainConfig, pathForMainConfig) assert.Nil(t, err) economicsConfig := config.EconomicsConfig{} - err = LoadConfigFromFile(pathForEconomicsConfig, &economicsConfig) + err = core.LoadTomlFile(&economicsConfig, pathForEconomicsConfig) assert.Nil(t, err) gasScheduleName, err := configs.GetLatestGasScheduleFilename(pathForGasSchedules) assert.Nil(t, err) prefsConfig := config.Preferences{} - err = LoadConfigFromFile(pathForPrefsConfig, &prefsConfig) + err = core.LoadTomlFile(&prefsConfig, pathForPrefsConfig) assert.Nil(t, err) systemSCConfig := config.SystemSmartContractsConfig{} - err = LoadConfigFromFile(pathSystemSCConfig, &systemSCConfig) + err = core.LoadTomlFile(&systemSCConfig, pathSystemSCConfig) assert.Nil(t, err) workingDir := t.TempDir() epochConfig := config.EpochConfig{} - err = LoadConfigFromFile(pathToConfigFolder+"enableEpochs.toml", &epochConfig) + err = core.LoadTomlFile(&epochConfig, pathToConfigFolder+"enableEpochs.toml") assert.Nil(t, err) return ArgsTestOnlyProcessingNode{ diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 4a0e7f98d33..ecc41426918 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" ) +// ArgsChainSimulatorConfigs holds all the components needed to create the chain simulator configs type ArgsChainSimulatorConfigs struct { NumOfShards uint32 OriginalConfigsPath string @@ -32,12 +33,14 @@ type ArgsChainSimulatorConfigs struct { GenesisAddressWithBalance string } +// ArgsConfigsSimulator holds the configs for the chain simulator type ArgsConfigsSimulator struct { GasScheduleFilename string Configs *config.Configs ValidatorsPrivateKeys []crypto.PrivateKey } +// CreateChainSimulatorConfigs will create the chain simulator configs func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSimulator, error) { configs, err := testscommon.CreateTestConfigs(args.OriginalConfigsPath) if err != nil { @@ -52,7 +55,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } - // generate validatos key and nodesSetup.json + // generate validators key and nodesSetup.json privateKeys, publicKeys := generateValidatorsKeyAndUpdateFiles(nil, configs, args.NumOfShards, args.GenesisAddressWithStake) // update genesis.json @@ -141,7 +144,7 @@ func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, marshaledNodes, err := json.Marshal(nodes) require.Nil(tb, err) - err = os.WriteFile(nodesSetupFile, marshaledNodes, 0644) + err = os.WriteFile(nodesSetupFile, marshaledNodes, os.ModePerm) require.Nil(tb, err) return privateKeys, publicKeys @@ -198,7 +201,7 @@ func modifyFile(fileName string, f func(i []byte) ([]byte, error)) error { } } - return os.WriteFile(fileName, output, 0644) + return os.WriteFile(fileName, output, os.ModePerm) } // GetLatestGasScheduleFilename will parse the provided path and get the latest gas schedule filename diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go index 8217ec1c77e..40cd67a2ce2 100644 --- a/node/chainSimulator/interface.go +++ b/node/chainSimulator/interface.go @@ -1,6 +1,7 @@ package chainSimulator +// ChainHandler defines what a chain handler should be able to do type ChainHandler interface { - ProcessBlock(nonce uint64, round uint64) error + CreateNewBlock(nonce uint64, round uint64) error IsInterfaceNil() bool } diff --git a/node/chainSimulator/testdata/addresses.go b/node/chainSimulator/testdata/addresses.go new file mode 100644 index 00000000000..6e245d919b9 --- /dev/null +++ b/node/chainSimulator/testdata/addresses.go @@ -0,0 +1,13 @@ +package testdata + +const ( + // GenesisAddressWithStake holds the initial address that has stake + GenesisAddressWithStake = "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7" + + //GenesisAddressWithStakeSK = "eded02473e1864616973ae20cb3b875aa3ffee55a60d948228f398e489956075" + + // GenesisAddressWithBalance holds the initial address that has balance + GenesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" + + //GenesisAddressWithBalanceSK = "ad1136a125fd3f1cfb154159442e4bc6a3b5c3095943029958ac464da7ce13eb" +) From cc1d38ecb22356f6b01edcc5f959896d31bab7a6 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 1 Nov 2023 17:03:12 +0200 Subject: [PATCH 487/958] merge --- node/chainSimulator/chainSimulator.go | 2 +- node/chainSimulator/components/testOnlyProcessingNode.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index d5049ac6a7a..c2f27fd0ceb 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -91,7 +91,7 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, func (s *simulator) GenerateBlocks(numOfBlocks int) error { for idx := 0; idx < numOfBlocks; idx++ { for _, node := range s.nodes { - err := node.ProcessBlock() + err := node.CreateNewBlock() if err != nil { return err } diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 50adb4607a9..7901e6bcc99 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -295,7 +295,7 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc } // CreateNewBlock create and process a new block -func (node *testOnlyProcessingNode) ProcessBlock() error { +func (node *testOnlyProcessingNode) CreateNewBlock() error { bp := node.ProcessComponentsHolder.BlockProcessor() currentHeader := node.ChainHandler.GetCurrentBlockHeader() var nonce, round uint64 From 4b84c4451611a3146728ac07da3ac9a92b70c337 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 2 Nov 2023 10:44:34 +0200 Subject: [PATCH 488/958] remove --- node/chainSimulator/components/testOnlyProcessingNode.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 7901e6bcc99..07e9d324cb3 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -336,13 +336,6 @@ func (node *testOnlyProcessingNode) CreateNewBlock() error { return err } - //err = bp.ProcessBlock(header, block, func() time.Duration { - // return 1000 - //}) - //if err != nil { - // return err - //} - err = bp.CommitBlock(header, block) if err != nil { return err From 5f6fdb4778e8f07c4ba7e3e87b3a8133ac677801 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 3 Nov 2023 16:15:42 +0200 Subject: [PATCH 489/958] continue implementation --- node/chainSimulator/chainSimulator.go | 33 +++- .../components/testOnlyProcessingNode.go | 130 +++++-------- node/chainSimulator/configs/configs.go | 17 ++ node/chainSimulator/process/interface.go | 19 ++ node/chainSimulator/process/processor.go | 172 ++++++++++++++++++ 5 files changed, 279 insertions(+), 92 deletions(-) create mode 100644 node/chainSimulator/process/interface.go create mode 100644 node/chainSimulator/process/processor.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index c2f27fd0ceb..05e39487c22 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -6,6 +6,7 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" ) @@ -46,7 +47,8 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s return err } - metaChainHandler, err := s.createChainHandler(core.MetachainShardId, outputConfigs.Configs, 0, outputConfigs.GasScheduleFilename) + blsKey := outputConfigs.ValidatorsPublicKeys[core.MetachainShardId] + metaChainHandler, err := s.createChainHandler(core.MetachainShardId, outputConfigs.Configs, 0, outputConfigs.GasScheduleFilename, blsKey) if err != nil { return err } @@ -54,7 +56,8 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s s.nodes = append(s.nodes, metaChainHandler) for idx := uint32(0); idx < numOfShards; idx++ { - shardChainHandler, errS := s.createChainHandler(idx, outputConfigs.Configs, int(idx)+1, outputConfigs.GasScheduleFilename) + blsKey = outputConfigs.ValidatorsPublicKeys[idx+1] + shardChainHandler, errS := s.createChainHandler(idx, outputConfigs.Configs, int(idx)+1, outputConfigs.GasScheduleFilename, blsKey) if errS != nil { return errS } @@ -65,7 +68,7 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s return nil } -func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, skIndex int, gasScheduleFilename string) (ChainHandler, error) { +func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, skIndex int, gasScheduleFilename string, blsKeyBytes []byte) (ChainHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Config: *configs.GeneralConfig, EpochConfig: *configs.EpochConfig, @@ -84,17 +87,31 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, SkIndex: skIndex, } - return components.NewTestOnlyProcessingNode(args) + testNode, err := components.NewTestOnlyProcessingNode(args) + if err != nil { + return nil, err + } + + return process.NewBlocksCreator(testNode, blsKeyBytes) } // GenerateBlocks will generate the provided number of blocks func (s *simulator) GenerateBlocks(numOfBlocks int) error { for idx := 0; idx < numOfBlocks; idx++ { - for _, node := range s.nodes { - err := node.CreateNewBlock() - if err != nil { - return err + for idxNode, node := range s.nodes { + // TODO change this + if idxNode == 0 { + err := node.CreateNewBlock() + if err != nil { + return err + } + } else if idxNode == 1 { + err := node.CreateNewBlock() + if err != nil { + return err + } } + } } return nil diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 07e9d324cb3..be163707f61 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -5,6 +5,8 @@ import ( chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/consensus/spos/sposFactory" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" dataRetrieverFactory "github.com/multiversx/mx-chain-go/dataRetriever/factory" @@ -14,7 +16,6 @@ import ( "github.com/multiversx/mx-chain-go/process/block/postprocess" "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/smartContract" - "github.com/multiversx/mx-chain-go/process/transactionLog" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" ) @@ -60,7 +61,8 @@ type testOnlyProcessingNode struct { StoreService dataRetriever.StorageService BuiltinFunctionsCostHandler economics.BuiltInFunctionsCostHandler DataPool dataRetriever.PoolsHolder - TxLogsProcessor process.TransactionLogProcessor + + broadcastMessenger consensus.BroadcastMessenger } // NewTestOnlyProcessingNode creates a new instance of a node that is able to only process transactions @@ -149,11 +151,6 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces if err != nil { return nil, err } - err = instance.createTransactionLogProcessor() - if err != nil { - return nil, err - } - err = instance.createNodesCoordinator(args.PreferencesConfig.Preferences, args.Config) if err != nil { return nil, err @@ -192,6 +189,11 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + err = instance.createBroadcastMessanger() + if err != nil { + return nil, err + } + return instance, nil } @@ -237,22 +239,6 @@ func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNo return err } -func (node *testOnlyProcessingNode) createTransactionLogProcessor() error { - logsStorer, err := node.StoreService.GetStorer(dataRetriever.TxLogsUnit) - if err != nil { - return err - } - argsTxLogProcessor := transactionLog.ArgTxLogProcessor{ - Storer: logsStorer, - Marshalizer: node.CoreComponentsHolder.InternalMarshalizer(), - SaveInStorageEnabled: true, - } - - node.TxLogsProcessor, err = transactionLog.NewTxLogProcessor(argsTxLogProcessor) - - return err -} - func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.PreferencesConfig, generalConfig config.Config) error { nodesShufflerOut, err := bootstrapComp.CreateNodesShuffleOut( node.CoreComponentsHolder.GenesisNodesSetup(), @@ -294,74 +280,50 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc return nil } -// CreateNewBlock create and process a new block -func (node *testOnlyProcessingNode) CreateNewBlock() error { - bp := node.ProcessComponentsHolder.BlockProcessor() - currentHeader := node.ChainHandler.GetCurrentBlockHeader() - var nonce, round uint64 - var prevHash, prevRandSeed []byte - if currentHeader != nil { - nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() - prevHash = node.ChainHandler.GetCurrentBlockHeaderHash() - prevRandSeed = currentHeader.GetRandSeed() - } else { - prevHash = node.ChainHandler.GetGenesisHeaderHash() - prevRandSeed = node.ChainHandler.GetGenesisHeader().GetRandSeed() - } - - newHeader, err := node.prepareHeader(nonce+1, round+1, prevHash) - if err != nil { - return err - } - - err = newHeader.SetPrevRandSeed(prevRandSeed) - if err != nil { - return err - } - - err = newHeader.SetPubKeysBitmap([]byte{128}) - if err != nil { - return err - } - - err = newHeader.SetRandSeed([]byte("dummy")) - if err != nil { - return err - } - - header, block, err := bp.CreateBlock(newHeader, func() bool { - return true - }) - if err != nil { - return err - } +func (node *testOnlyProcessingNode) createBroadcastMessanger() error { + var err error + node.broadcastMessenger, err = sposFactory.GetBroadcastMessenger( + node.CoreComponentsHolder.InternalMarshalizer(), + node.CoreComponentsHolder.Hasher(), + node.NetworkComponentsHolder.NetworkMessenger(), + node.ProcessComponentsHolder.ShardCoordinator(), + node.CryptoComponentsHolder.PeerSignatureHandler(), + node.DataComponentsHolder.Datapool().Headers(), + node.ProcessComponentsHolder.InterceptorsContainer(), + node.CoreComponentsHolder.AlarmScheduler(), + node.CryptoComponentsHolder.KeysHandler(), + ) + return err +} - err = bp.CommitBlock(header, block) - if err != nil { - return err - } +// GetProcessComponents will return the process components +func (node *testOnlyProcessingNode) GetProcessComponents() factory.ProcessComponentsHolder { + return node.ProcessComponentsHolder +} - return nil +// GetChainHandler will return the chain handler +func (node *testOnlyProcessingNode) GetChainHandler() chainData.ChainHandler { + return node.ChainHandler } -func (node *testOnlyProcessingNode) prepareHeader(nonce uint64, round uint64, prevHash []byte) (chainData.HeaderHandler, error) { - bp := node.ProcessComponentsHolder.BlockProcessor() +// GetBroadcastMessenger will return the broadcast messenger +func (node *testOnlyProcessingNode) GetBroadcastMessenger() consensus.BroadcastMessenger { + return node.broadcastMessenger +} - newHeader, err := bp.CreateNewHeader(round, nonce) - if err != nil { - return nil, err - } - err = newHeader.SetShardID(node.ShardCoordinator.SelfId()) - if err != nil { - return nil, err - } +// GetShardCoordinator will return the shard coordinator +func (node *testOnlyProcessingNode) GetShardCoordinator() sharding.Coordinator { + return node.ShardCoordinator +} - err = newHeader.SetPrevHash(prevHash) - if err != nil { - return nil, err - } +// GetCryptoComponents will return the crypto components +func (node *testOnlyProcessingNode) GetCryptoComponents() factory.CryptoComponentsHolder { + return node.CryptoComponentsHolder +} - return newHeader, nil +// GetCoreComponents will return the core components +func (node *testOnlyProcessingNode) GetCoreComponents() factory.CoreComponentsHolder { + return node.CoreComponentsHolder } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index ecc41426918..40ab7418eab 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -38,6 +38,7 @@ type ArgsConfigsSimulator struct { GasScheduleFilename string Configs *config.Configs ValidatorsPrivateKeys []crypto.PrivateKey + ValidatorsPublicKeys map[uint32][]byte } // CreateChainSimulatorConfigs will create the chain simulator configs @@ -47,6 +48,8 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } + configs.GeneralConfig.GeneralSettings.ChainID = "chain" + // empty genesis smart contracts file err = modifyFile(configs.ConfigurationPathsHolder.SmartContracts, func(intput []byte) ([]byte, error) { return []byte("[]"), nil @@ -104,10 +107,24 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) + publicKeysBytes := make(map[uint32][]byte) + publicKeysBytes[core.MetachainShardId], err = publicKeys[0].ToByteArray() + if err != nil { + return nil, err + } + + for idx := uint32(1); idx < uint32(len(publicKeys)); idx++ { + publicKeysBytes[idx], err = publicKeys[idx].ToByteArray() + if err != nil { + return nil, err + } + } + return &ArgsConfigsSimulator{ Configs: configs, ValidatorsPrivateKeys: privateKeys, GasScheduleFilename: gasScheduleName, + ValidatorsPublicKeys: publicKeysBytes, }, nil } diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go new file mode 100644 index 00000000000..aab1d8e9baa --- /dev/null +++ b/node/chainSimulator/process/interface.go @@ -0,0 +1,19 @@ +package process + +import ( + chainData "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/sharding" +) + +// NodeHandler defines what a node handler should be able to do +type NodeHandler interface { + GetProcessComponents() factory.ProcessComponentsHolder + GetChainHandler() chainData.ChainHandler + GetBroadcastMessenger() consensus.BroadcastMessenger + GetShardCoordinator() sharding.Coordinator + GetCryptoComponents() factory.CryptoComponentsHolder + GetCoreComponents() factory.CoreComponentsHolder + IsInterfaceNil() bool +} diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go new file mode 100644 index 00000000000..5d76bb28af7 --- /dev/null +++ b/node/chainSimulator/process/processor.go @@ -0,0 +1,172 @@ +package process + +import ( + "github.com/multiversx/mx-chain-core-go/data" +) + +type blocksCreator struct { + nodeHandler NodeHandler + blsKeyBytes []byte +} + +func NewBlocksCreator(nodeHandler NodeHandler, blsKeyBytes []byte) (*blocksCreator, error) { + return &blocksCreator{ + nodeHandler: nodeHandler, + blsKeyBytes: blsKeyBytes, + }, nil +} + +// CreateNewBlock create and process a new block +func (creator *blocksCreator) CreateNewBlock() error { + bp := creator.nodeHandler.GetProcessComponents().BlockProcessor() + currentHeader := creator.nodeHandler.GetChainHandler().GetCurrentBlockHeader() + var nonce, round uint64 + var prevHash, prevRandSeed []byte + if currentHeader != nil { + nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() + prevHash = creator.nodeHandler.GetChainHandler().GetCurrentBlockHeaderHash() + prevRandSeed = currentHeader.GetRandSeed() + } else { + prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() + prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() + } + + newHeader, err := bp.CreateNewHeader(round+1, nonce+1) + if err != nil { + return err + } + err = newHeader.SetShardID(creator.nodeHandler.GetShardCoordinator().SelfId()) + if err != nil { + return err + } + + err = newHeader.SetPrevHash(prevHash) + if err != nil { + return err + } + + err = newHeader.SetPrevRandSeed(prevRandSeed) + if err != nil { + return err + } + + err = newHeader.SetPubKeysBitmap([]byte{1}) + if err != nil { + return err + } + + err = newHeader.SetChainID([]byte("chain")) + if err != nil { + return err + } + + signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() + randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), creator.blsKeyBytes) + if err != nil { + return err + } + err = newHeader.SetRandSeed(randSeed) + if err != nil { + return err + } + + header, block, err := bp.CreateBlock(newHeader, func() bool { + return true + }) + if err != nil { + return err + } + + err = creator.setHeaderSignatures(header) + if err != nil { + return err + } + + err = bp.CommitBlock(header, block) + if err != nil { + return err + } + + miniBlocks, transactions, err := bp.MarshalizedDataToBroadcast(header, block) + if err != nil { + return err + } + + err = creator.nodeHandler.GetBroadcastMessenger().BroadcastHeader(header, creator.blsKeyBytes) + if err != nil { + return err + } + + return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, creator.blsKeyBytes) +} + +func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) error { + signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() + headerClone := header.ShallowClone() + _ = headerClone.SetPubKeysBitmap(nil) + + marshalizedHdr, err := creator.nodeHandler.GetCoreComponents().InternalMarshalizer().Marshal(headerClone) + if err != nil { + return err + } + + err = signingHandler.Reset([]string{string(creator.blsKeyBytes)}) + if err != nil { + return err + } + + headerHash := creator.nodeHandler.GetCoreComponents().Hasher().Compute(string(marshalizedHdr)) + _, err = signingHandler.CreateSignatureShareForPublicKey( + headerHash, + uint16(0), + header.GetEpoch(), + creator.blsKeyBytes, + ) + if err != nil { + return err + } + + sig, err := signingHandler.AggregateSigs(header.GetPubKeysBitmap(), header.GetEpoch()) + if err != nil { + return err + } + + err = header.SetSignature(sig) + if err != nil { + return err + } + + leaderSignature, err := creator.createLeaderSignature(header) + if err != nil { + return err + } + + err = header.SetLeaderSignature(leaderSignature) + if err != nil { + return err + } + + return nil +} + +func (creator *blocksCreator) createLeaderSignature(header data.HeaderHandler) ([]byte, error) { + headerClone := header.ShallowClone() + err := headerClone.SetLeaderSignature(nil) + if err != nil { + return nil, err + } + + marshalizedHdr, err := creator.nodeHandler.GetCoreComponents().InternalMarshalizer().Marshal(headerClone) + if err != nil { + return nil, err + } + + signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() + + return signingHandler.CreateSignatureForPublicKey(marshalizedHdr, creator.blsKeyBytes) +} + +// IsInterfaceNil returns true if there is no value under the interface +func (creator *blocksCreator) IsInterfaceNil() bool { + return creator == nil +} From bf8470008abfa86d0fdda5fc038ead237242cd61 Mon Sep 17 00:00:00 2001 From: jules01 Date: Mon, 6 Nov 2023 11:02:08 +0200 Subject: [PATCH 490/958] - added & integrated manual round handler --- node/chainSimulator/chainSimulator.go | 33 ++++++----- .../components/coreComponents.go | 3 +- .../components/manualRoundHandler.go | 56 +++++++++++++++++++ node/chainSimulator/interface.go | 1 + node/chainSimulator/process/processor.go | 11 ++++ process/sync/baseForkDetector.go | 3 + 6 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 node/chainSimulator/components/manualRoundHandler.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 05e39487c22..6143d8337af 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -98,22 +98,29 @@ func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, // GenerateBlocks will generate the provided number of blocks func (s *simulator) GenerateBlocks(numOfBlocks int) error { for idx := 0; idx < numOfBlocks; idx++ { - for idxNode, node := range s.nodes { - // TODO change this - if idxNode == 0 { - err := node.CreateNewBlock() - if err != nil { - return err - } - } else if idxNode == 1 { - err := node.CreateNewBlock() - if err != nil { - return err - } - } + s.incrementRoundOnAllValidators() + err := s.allNodesCreateBlocks() + if err != nil { + return err + } + } + return nil +} +func (s *simulator) incrementRoundOnAllValidators() { + for _, node := range s.nodes { + node.IncrementRound() + } +} + +func (s *simulator) allNodesCreateBlocks() error { + for _, node := range s.nodes { + err := node.CreateNewBlock() + if err != nil { + return err } } + return nil } diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 078309959e7..1eb456159fe 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -136,8 +136,7 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.watchdog = &watchdog.DisabledWatchdog{} instance.alarmScheduler = &mock.AlarmSchedulerStub{} instance.syncTimer = &testscommon.SyncTimerStub{} - // TODO discuss with Iulian about the round handler - instance.roundHandler = &testscommon.RoundHandlerMock{} + instance.roundHandler = NewManualRoundHandler() instance.wasmVMChangeLocker = &sync.RWMutex{} instance.txVersionChecker = versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion) diff --git a/node/chainSimulator/components/manualRoundHandler.go b/node/chainSimulator/components/manualRoundHandler.go new file mode 100644 index 00000000000..db1e685cf5b --- /dev/null +++ b/node/chainSimulator/components/manualRoundHandler.go @@ -0,0 +1,56 @@ +package components + +import ( + "sync/atomic" + "time" +) + +const timeDuration = time.Second + +type manualRoundHandler struct { + index int64 +} + +// NewManualRoundHandler returns a manual round handler instance +func NewManualRoundHandler() *manualRoundHandler { + return &manualRoundHandler{} +} + +// IncrementIndex will increment the current round index +func (handler *manualRoundHandler) IncrementIndex() { + atomic.AddInt64(&handler.index, 1) +} + +// Index returns the current index +func (handler *manualRoundHandler) Index() int64 { + return atomic.LoadInt64(&handler.index) +} + +// BeforeGenesis returns false +func (handler *manualRoundHandler) BeforeGenesis() bool { + return false +} + +// UpdateRound does nothing as this implementation does not work with real timers +func (handler *manualRoundHandler) UpdateRound(_ time.Time, _ time.Time) { +} + +// TimeStamp returns the empty time.Time value +func (handler *manualRoundHandler) TimeStamp() time.Time { + return time.Time{} +} + +// TimeDuration returns a hardcoded value +func (handler *manualRoundHandler) TimeDuration() time.Duration { + return timeDuration +} + +// RemainingTime returns the max time as the start time is not taken into account +func (handler *manualRoundHandler) RemainingTime(_ time.Time, maxTime time.Duration) time.Duration { + return maxTime +} + +// IsInterfaceNil returns true if there is no value under the interface +func (handler *manualRoundHandler) IsInterfaceNil() bool { + return handler == nil +} diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go index 961ca87afa5..416d25683cd 100644 --- a/node/chainSimulator/interface.go +++ b/node/chainSimulator/interface.go @@ -2,6 +2,7 @@ package chainSimulator // ChainHandler defines what a chain handler should be able to do type ChainHandler interface { + IncrementRound() CreateNewBlock() error IsInterfaceNil() bool } diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 5d76bb28af7..9d227f38f3c 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -4,6 +4,10 @@ import ( "github.com/multiversx/mx-chain-core-go/data" ) +type manualRoundHandler interface { + IncrementIndex() +} + type blocksCreator struct { nodeHandler NodeHandler blsKeyBytes []byte @@ -16,6 +20,13 @@ func NewBlocksCreator(nodeHandler NodeHandler, blsKeyBytes []byte) (*blocksCreat }, nil } +// IncrementRound will increment the current round +func (creator *blocksCreator) IncrementRound() { + roundHandler := creator.nodeHandler.GetCoreComponents().RoundHandler() + manual := roundHandler.(manualRoundHandler) + manual.IncrementIndex() +} + // CreateNewBlock create and process a new block func (creator *blocksCreator) CreateNewBlock() error { bp := creator.nodeHandler.GetProcessComponents().BlockProcessor() diff --git a/process/sync/baseForkDetector.go b/process/sync/baseForkDetector.go index db5a601524a..b1f62026cc7 100644 --- a/process/sync/baseForkDetector.go +++ b/process/sync/baseForkDetector.go @@ -298,6 +298,9 @@ func (bfd *baseForkDetector) append(hdrInfo *headerInfo) bool { // GetHighestFinalBlockNonce gets the highest nonce of the block which is final, and it can not be reverted anymore func (bfd *baseForkDetector) GetHighestFinalBlockNonce() uint64 { + // TODO remove this + log.Warn("baseForkDetector.GetHighestFinalBlockNonce", "nonce", bfd.finalCheckpoint().nonce) + return bfd.finalCheckpoint().nonce } From dbfdc805f64baba4913cd62e23422df31113df17 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 7 Nov 2023 14:30:25 +0200 Subject: [PATCH 491/958] refactoring --- node/chainSimulator/configs/configs.go | 62 +++++++++----------------- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index ecc41426918..9f0d22060b4 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -48,9 +48,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi } // empty genesis smart contracts file - err = modifyFile(configs.ConfigurationPathsHolder.SmartContracts, func(intput []byte) ([]byte, error) { - return []byte("[]"), nil - }) + err = os.WriteFile(configs.ConfigurationPathsHolder.SmartContracts, []byte("[]"), os.ModePerm) if err != nil { return nil, err } @@ -59,31 +57,28 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi privateKeys, publicKeys := generateValidatorsKeyAndUpdateFiles(nil, configs, args.NumOfShards, args.GenesisAddressWithStake) // update genesis.json - err = modifyFile(configs.ConfigurationPathsHolder.Genesis, func(i []byte) ([]byte, error) { - addresses := make([]data.InitialAccount, 0) - - // 10_000 egld - bigValue, _ := big.NewInt(0).SetString("10000000000000000000000", 0) - addresses = append(addresses, data.InitialAccount{ - Address: args.GenesisAddressWithStake, - StakingValue: bigValue, - Supply: bigValue, - }) + addresses := make([]data.InitialAccount, 0) + // 10_000 egld + bigValue, _ := big.NewInt(0).SetString("10000000000000000000000", 0) + addresses = append(addresses, data.InitialAccount{ + Address: args.GenesisAddressWithStake, + StakingValue: bigValue, + Supply: bigValue, + }) - bigValueAddr, _ := big.NewInt(0).SetString("19990000000000000000000000", 10) - addresses = append(addresses, data.InitialAccount{ - Address: args.GenesisAddressWithBalance, - Balance: bigValueAddr, - Supply: bigValueAddr, - }) + bigValueAddr, _ := big.NewInt(0).SetString("19990000000000000000000000", 10) + addresses = append(addresses, data.InitialAccount{ + Address: args.GenesisAddressWithBalance, + Balance: bigValueAddr, + Supply: bigValueAddr, + }) - addressesBytes, errM := json.Marshal(addresses) - if errM != nil { - return nil, errM - } + addressesBytes, errM := json.Marshal(addresses) + if errM != nil { + return nil, errM + } - return addressesBytes, nil - }) + err = os.WriteFile(configs.ConfigurationPathsHolder.Genesis, addressesBytes, os.ModePerm) if err != nil { return nil, err } @@ -187,23 +182,6 @@ func generateValidatorsPem(validatorsFile string, publicKeys []crypto.PublicKey, return os.WriteFile(validatorsFile, buff.Bytes(), 0644) } -func modifyFile(fileName string, f func(i []byte) ([]byte, error)) error { - input, err := os.ReadFile(fileName) - if err != nil { - return err - } - - output := input - if f != nil { - output, err = f(input) - if err != nil { - return err - } - } - - return os.WriteFile(fileName, output, os.ModePerm) -} - // GetLatestGasScheduleFilename will parse the provided path and get the latest gas schedule filename func GetLatestGasScheduleFilename(directory string) (string, error) { entries, err := os.ReadDir(directory) From f97dce91ae27593f9c66a0c0ad00ef4eb3c73b5a Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 7 Nov 2023 15:35:18 +0200 Subject: [PATCH 492/958] fixes after review --- node/chainSimulator/configs/configs.go | 10 +++++++- node/chainSimulator/process/processor.go | 31 +++++++++++++++--------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 755922afaff..032053af1ca 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -25,6 +25,11 @@ import ( "github.com/stretchr/testify/require" ) +const ( + // ChainID contains the chain id + ChainID = "chain" +) + // ArgsChainSimulatorConfigs holds all the components needed to create the chain simulator configs type ArgsChainSimulatorConfigs struct { NumOfShards uint32 @@ -48,7 +53,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } - configs.GeneralConfig.GeneralSettings.ChainID = "chain" + configs.GeneralConfig.GeneralSettings.ChainID = ChainID // empty genesis smart contracts file err = os.WriteFile(configs.ConfigurationPathsHolder.SmartContracts, []byte("[]"), os.ModePerm) @@ -102,6 +107,9 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) + // enable db lookup extension + configs.GeneralConfig.DbLookupExtensions.Enabled = true + publicKeysBytes := make(map[uint32][]byte) publicKeysBytes[core.MetachainShardId], err = publicKeys[0].ToByteArray() if err != nil { diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 5d76bb28af7..533968c08f0 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -2,6 +2,7 @@ package process import ( "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" ) type blocksCreator struct { @@ -9,6 +10,7 @@ type blocksCreator struct { blsKeyBytes []byte } +// NewBlocksCreator will create a new instance of blocksCreator func NewBlocksCreator(nodeHandler NodeHandler, blsKeyBytes []byte) (*blocksCreator, error) { return &blocksCreator{ nodeHandler: nodeHandler, @@ -19,18 +21,8 @@ func NewBlocksCreator(nodeHandler NodeHandler, blsKeyBytes []byte) (*blocksCreat // CreateNewBlock create and process a new block func (creator *blocksCreator) CreateNewBlock() error { bp := creator.nodeHandler.GetProcessComponents().BlockProcessor() - currentHeader := creator.nodeHandler.GetChainHandler().GetCurrentBlockHeader() - var nonce, round uint64 - var prevHash, prevRandSeed []byte - if currentHeader != nil { - nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() - prevHash = creator.nodeHandler.GetChainHandler().GetCurrentBlockHeaderHash() - prevRandSeed = currentHeader.GetRandSeed() - } else { - prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() - prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() - } + nonce, round, prevHash, prevRandSeed := creator.getPreviousHeaderData() newHeader, err := bp.CreateNewHeader(round+1, nonce+1) if err != nil { return err @@ -55,7 +47,7 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - err = newHeader.SetChainID([]byte("chain")) + err = newHeader.SetChainID([]byte(configs.ChainID)) if err != nil { return err } @@ -100,6 +92,21 @@ func (creator *blocksCreator) CreateNewBlock() error { return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, creator.blsKeyBytes) } +func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prevHash, prevRandSeed []byte) { + currentHeader := creator.nodeHandler.GetChainHandler().GetCurrentBlockHeader() + + if currentHeader != nil { + nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() + prevHash = creator.nodeHandler.GetChainHandler().GetCurrentBlockHeaderHash() + prevRandSeed = currentHeader.GetRandSeed() + } else { + prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() + prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() + } + + return +} + func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) error { signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() headerClone := header.ShallowClone() From c1355c0a94844677e6f170a22efbffaf45c5185e Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 7 Nov 2023 15:43:38 +0200 Subject: [PATCH 493/958] small fix --- node/chainSimulator/process/processor.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 533968c08f0..7fe6211eb4d 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -99,11 +99,13 @@ func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prev nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() prevHash = creator.nodeHandler.GetChainHandler().GetCurrentBlockHeaderHash() prevRandSeed = currentHeader.GetRandSeed() - } else { - prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() - prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() + + return } + prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() + prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() + return } From 8a5fa2820f3410234c16036a67dcf626667dbc7c Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 7 Nov 2023 15:46:45 +0200 Subject: [PATCH 494/958] add missing store units --- node/chainSimulator/components/storageService.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/chainSimulator/components/storageService.go b/node/chainSimulator/components/storageService.go index dcbd19e5a98..364832fbf52 100644 --- a/node/chainSimulator/components/storageService.go +++ b/node/chainSimulator/components/storageService.go @@ -24,6 +24,12 @@ func CreateStore(numOfShards uint32) dataRetriever.StorageService { store.AddStorer(dataRetriever.UserAccountsCheckpointsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.PeerAccountsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.PeerAccountsCheckpointsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.ESDTSuppliesUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.RoundHdrHashDataUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.MiniblocksMetadataUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.MiniblockHashByTxHashUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.EpochByHashUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.ResultsHashesByTxHashUnit, CreateMemUnit()) // TODO add the rest of units for i := uint32(0); i < numOfShards; i++ { From f79254716a98e0d93dcc44a1baab50e3f71a5fb6 Mon Sep 17 00:00:00 2001 From: jules01 Date: Tue, 7 Nov 2023 17:04:49 +0200 Subject: [PATCH 495/958] - fixes --- node/chainSimulator/components/manualRoundHandler.go | 4 +--- process/sync/baseForkDetector.go | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/node/chainSimulator/components/manualRoundHandler.go b/node/chainSimulator/components/manualRoundHandler.go index db1e685cf5b..97bcde90739 100644 --- a/node/chainSimulator/components/manualRoundHandler.go +++ b/node/chainSimulator/components/manualRoundHandler.go @@ -5,8 +5,6 @@ import ( "time" ) -const timeDuration = time.Second - type manualRoundHandler struct { index int64 } @@ -42,7 +40,7 @@ func (handler *manualRoundHandler) TimeStamp() time.Time { // TimeDuration returns a hardcoded value func (handler *manualRoundHandler) TimeDuration() time.Duration { - return timeDuration + return 0 } // RemainingTime returns the max time as the start time is not taken into account diff --git a/process/sync/baseForkDetector.go b/process/sync/baseForkDetector.go index b1f62026cc7..db5a601524a 100644 --- a/process/sync/baseForkDetector.go +++ b/process/sync/baseForkDetector.go @@ -298,9 +298,6 @@ func (bfd *baseForkDetector) append(hdrInfo *headerInfo) bool { // GetHighestFinalBlockNonce gets the highest nonce of the block which is final, and it can not be reverted anymore func (bfd *baseForkDetector) GetHighestFinalBlockNonce() uint64 { - // TODO remove this - log.Warn("baseForkDetector.GetHighestFinalBlockNonce", "nonce", bfd.finalCheckpoint().nonce) - return bfd.finalCheckpoint().nonce } From e0ea98b116b23e096dc85bce509ab4b29e93f184 Mon Sep 17 00:00:00 2001 From: jules01 Date: Tue, 7 Nov 2023 17:14:01 +0200 Subject: [PATCH 496/958] - added TODO --- node/chainSimulator/process/processor.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 9d227f38f3c..92537427752 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -71,6 +71,12 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } + // TODO set the timestamp but refactor the baseForkDetector.computeGenesisTimeFromHeader function + // err = newHeader.SetTimeStamp(uint64(time.Now().Unix())) + // if err != nil { + // return err + // } + signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), creator.blsKeyBytes) if err != nil { From 20d95424cf555d6c3ddf0c610378dc56024efde4 Mon Sep 17 00:00:00 2001 From: jules01 Date: Tue, 7 Nov 2023 17:15:52 +0200 Subject: [PATCH 497/958] - fixed typo --- node/chainSimulator/process/processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 4fe9234334d..509b4e27784 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -29,7 +29,7 @@ func (creator *blocksCreator) IncrementRound() { manual.IncrementIndex() } -// CreateNewBlock create and process a new block +// CreateNewBlock creates and process a new block func (creator *blocksCreator) CreateNewBlock() error { bp := creator.nodeHandler.GetProcessComponents().BlockProcessor() From 9f0c79cc0b27cbebc3bdcad643ba8e50ffe2b46b Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 8 Nov 2023 11:47:02 +0200 Subject: [PATCH 498/958] - fixed timestamp on headers --- node/chainSimulator/chainSimulator.go | 27 ++++++++++-- node/chainSimulator/chainSimulator_test.go | 16 ++++++- .../components/coreComponents.go | 13 +++--- .../components/manualRoundHandler.go | 23 +++++++--- node/chainSimulator/configs/configs.go | 43 +++++++++++++++---- node/chainSimulator/configs/configs_test.go | 2 + node/chainSimulator/process/processor.go | 10 ++--- 7 files changed, 103 insertions(+), 31 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 6143d8337af..414cbfa1964 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -15,10 +15,16 @@ type simulator struct { syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler nodes []ChainHandler numOfShards uint32 + genesisTimestamp int64 } // NewChainSimulator will create a new instance of simulator -func NewChainSimulator(numOfShards uint32, pathToInitialConfig string) (*simulator, error) { +func NewChainSimulator( + numOfShards uint32, + pathToInitialConfig string, + genesisTimestamp int64, + roundDurationInMillis uint64, +) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() instance := &simulator{ @@ -28,7 +34,7 @@ func NewChainSimulator(numOfShards uint32, pathToInitialConfig string) (*simulat chanStopNodeProcess: make(chan endProcess.ArgEndProcess), } - err := instance.createChainHandlers(numOfShards, pathToInitialConfig) + err := instance.createChainHandlers(numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis) if err != nil { return nil, err } @@ -36,12 +42,19 @@ func NewChainSimulator(numOfShards uint32, pathToInitialConfig string) (*simulat return instance, nil } -func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath string) error { +func (s *simulator) createChainHandlers( + numOfShards uint32, + originalConfigPath string, + genesisTimestamp int64, + roundDurationInMillis uint64, +) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: numOfShards, OriginalConfigsPath: originalConfigPath, GenesisAddressWithStake: testdata.GenesisAddressWithStake, GenesisAddressWithBalance: testdata.GenesisAddressWithBalance, + GenesisTimeStamp: genesisTimestamp, + RoundDurationInMillis: roundDurationInMillis, }) if err != nil { return err @@ -68,7 +81,13 @@ func (s *simulator) createChainHandlers(numOfShards uint32, originalConfigPath s return nil } -func (s *simulator) createChainHandler(shardID uint32, configs *config.Configs, skIndex int, gasScheduleFilename string, blsKeyBytes []byte) (ChainHandler, error) { +func (s *simulator) createChainHandler( + shardID uint32, + configs *config.Configs, + skIndex int, + gasScheduleFilename string, + blsKeyBytes []byte, +) (ChainHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Config: *configs.GeneralConfig, EpochConfig: *configs.EpochConfig, diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 7b646c5faa8..841e8a57260 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -12,9 +12,23 @@ const ( ) func TestNewChainSimulator(t *testing.T) { - chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig) + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig, startTime, roundDurationInMillis) require.Nil(t, err) require.NotNil(t, chainSimulator) + defer chainSimulator.Stop() + + time.Sleep(time.Second) +} + +func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig, startTime, roundDurationInMillis) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + defer chainSimulator.Stop() time.Sleep(time.Second) diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 1eb456159fe..d1ae907efb1 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -136,7 +136,14 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.watchdog = &watchdog.DisabledWatchdog{} instance.alarmScheduler = &mock.AlarmSchedulerStub{} instance.syncTimer = &testscommon.SyncTimerStub{} - instance.roundHandler = NewManualRoundHandler() + + instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.NodesSetupPath, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) + if err != nil { + return nil, err + } + + roundDuration := time.Millisecond * time.Duration(instance.genesisNodesSetup.GetRoundDuration()) + instance.roundHandler = NewManualRoundHandler(instance.genesisNodesSetup.GetStartTime(), roundDuration) instance.wasmVMChangeLocker = &sync.RWMutex{} instance.txVersionChecker = versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion) @@ -190,10 +197,6 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp instance.ratingsData = &testscommon.RatingsInfoMock{} instance.rater = &testscommon.RaterMock{} - instance.genesisNodesSetup, err = sharding.NewNodesSetup(args.NodesSetupPath, instance.addressPubKeyConverter, instance.validatorPubKeyConverter, args.NumShards) - if err != nil { - return nil, err - } // TODO check if we need nodes shuffler instance.nodesShuffler = &shardingMocks.NodeShufflerMock{} diff --git a/node/chainSimulator/components/manualRoundHandler.go b/node/chainSimulator/components/manualRoundHandler.go index 97bcde90739..b0503be92fb 100644 --- a/node/chainSimulator/components/manualRoundHandler.go +++ b/node/chainSimulator/components/manualRoundHandler.go @@ -6,12 +6,17 @@ import ( ) type manualRoundHandler struct { - index int64 + index int64 + genesisTimeStamp int64 + roundDuration time.Duration } // NewManualRoundHandler returns a manual round handler instance -func NewManualRoundHandler() *manualRoundHandler { - return &manualRoundHandler{} +func NewManualRoundHandler(genesisTimeStamp int64, roundDuration time.Duration) *manualRoundHandler { + return &manualRoundHandler{ + genesisTimeStamp: genesisTimeStamp, + roundDuration: roundDuration, + } } // IncrementIndex will increment the current round index @@ -33,14 +38,18 @@ func (handler *manualRoundHandler) BeforeGenesis() bool { func (handler *manualRoundHandler) UpdateRound(_ time.Time, _ time.Time) { } -// TimeStamp returns the empty time.Time value +// TimeStamp returns the time based of the genesis timestamp and the current round func (handler *manualRoundHandler) TimeStamp() time.Time { - return time.Time{} + rounds := atomic.LoadInt64(&handler.index) + timeFromGenesis := handler.roundDuration * time.Duration(rounds) + timestamp := time.Unix(handler.genesisTimeStamp, 0).Add(timeFromGenesis) + + return timestamp } -// TimeDuration returns a hardcoded value +// TimeDuration returns the provided time duration for this instance func (handler *manualRoundHandler) TimeDuration() time.Duration { - return 0 + return handler.roundDuration } // RemainingTime returns the max time as the start time is not taken into account diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 032053af1ca..88502f1fcce 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -10,7 +10,6 @@ import ( "path" "strconv" "strings" - "testing" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/pubkeyConverter" @@ -22,7 +21,6 @@ import ( "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/storage/storageunit" "github.com/multiversx/mx-chain-go/testscommon" - "github.com/stretchr/testify/require" ) const ( @@ -36,6 +34,8 @@ type ArgsChainSimulatorConfigs struct { OriginalConfigsPath string GenesisAddressWithStake string GenesisAddressWithBalance string + GenesisTimeStamp int64 + RoundDurationInMillis uint64 } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -62,7 +62,16 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi } // generate validators key and nodesSetup.json - privateKeys, publicKeys := generateValidatorsKeyAndUpdateFiles(nil, configs, args.NumOfShards, args.GenesisAddressWithStake) + privateKeys, publicKeys, err := generateValidatorsKeyAndUpdateFiles( + configs, + args.NumOfShards, + args.GenesisAddressWithStake, + args.GenesisTimeStamp, + args.RoundDurationInMillis, + ) + if err != nil { + return nil, err + } // update genesis.json addresses := make([]data.InitialAccount, 0) @@ -131,14 +140,24 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi }, nil } -func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, numOfShards uint32, address string) ([]crypto.PrivateKey, []crypto.PublicKey) { +func generateValidatorsKeyAndUpdateFiles( + configs *config.Configs, + numOfShards uint32, + address string, + genesisTimeStamp int64, + roundDurationInMillis uint64, +) ([]crypto.PrivateKey, []crypto.PublicKey, error) { blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) nodesSetupFile := configs.ConfigurationPathsHolder.Nodes nodes := &sharding.NodesSetup{} err := core.LoadJsonFile(nodes, nodesSetupFile) - require.Nil(tb, err) + if err != nil { + return nil, nil, err + } + nodes.RoundDuration = roundDurationInMillis + nodes.StartTime = genesisTimeStamp nodes.ConsensusGroupSize = 1 nodes.MinNodesPerShard = 1 nodes.MetaChainMinNodes = 1 @@ -153,7 +172,9 @@ func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, publicKeys = append(publicKeys, pk) pkBytes, errB := pk.ToByteArray() - require.Nil(tb, errB) + if errB != nil { + return nil, nil, errB + } nodes.InitialNodes = append(nodes.InitialNodes, &sharding.InitialNode{ PubKey: hex.EncodeToString(pkBytes), @@ -162,12 +183,16 @@ func generateValidatorsKeyAndUpdateFiles(tb testing.TB, configs *config.Configs, } marshaledNodes, err := json.Marshal(nodes) - require.Nil(tb, err) + if err != nil { + return nil, nil, err + } err = os.WriteFile(nodesSetupFile, marshaledNodes, os.ModePerm) - require.Nil(tb, err) + if err != nil { + return nil, nil, err + } - return privateKeys, publicKeys + return privateKeys, publicKeys, nil } func generateValidatorsPem(validatorsFile string, publicKeys []crypto.PublicKey, privateKey []crypto.PrivateKey) error { diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index c94ec49fa80..227a899cd0a 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -17,6 +17,8 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { OriginalConfigsPath: "../../../cmd/node/config", GenesisAddressWithStake: "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7", GenesisAddressWithBalance: "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz", + RoundDurationInMillis: 6000, + GenesisTimeStamp: 0, }) require.Nil(t, err) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 509b4e27784..775cd86debb 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -63,11 +63,11 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - // TODO set the timestamp but refactor the baseForkDetector.computeGenesisTimeFromHeader function - // err = newHeader.SetTimeStamp(uint64(time.Now().Unix())) - // if err != nil { - // return err - // } + headerCreationTime := creator.nodeHandler.GetProcessComponents().RoundHandler().TimeStamp() + err = newHeader.SetTimeStamp(uint64(headerCreationTime.Unix())) + if err != nil { + return err + } signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), creator.blsKeyBytes) From 9d7c7e71df2eda904f3dfec79ff8501e989bdd7e Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 8 Nov 2023 12:08:54 +0200 Subject: [PATCH 499/958] - linter fix --- node/chainSimulator/chainSimulator.go | 1 - 1 file changed, 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 414cbfa1964..cc0f4a6aa94 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -15,7 +15,6 @@ type simulator struct { syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler nodes []ChainHandler numOfShards uint32 - genesisTimestamp int64 } // NewChainSimulator will create a new instance of simulator From b308a2923f1aa1b9e03e4637175db57c838c51fb Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 8 Nov 2023 13:30:44 +0200 Subject: [PATCH 500/958] - more fixes --- .../realcomponents/processorRunner_test.go | 2 +- .../txsimulator/componentConstruction_test.go | 4 +- node/chainSimulator/chainSimulator.go | 30 +++----- node/chainSimulator/chainSimulator_test.go | 4 +- .../components/testOnlyProcessingNode.go | 73 ++++++++----------- .../components/testOnlyProcessingNode_test.go | 10 --- node/chainSimulator/configs/configs.go | 18 +---- node/chainSimulator/configs/configs_test.go | 1 + node/chainSimulator/process/processor.go | 19 ++--- node/nodeRunner_test.go | 4 +- testscommon/realConfigsHandling.go | 4 +- 11 files changed, 61 insertions(+), 108 deletions(-) diff --git a/integrationTests/realcomponents/processorRunner_test.go b/integrationTests/realcomponents/processorRunner_test.go index 401a7259279..78d0013597e 100644 --- a/integrationTests/realcomponents/processorRunner_test.go +++ b/integrationTests/realcomponents/processorRunner_test.go @@ -12,7 +12,7 @@ func TestNewProcessorRunnerAndClose(t *testing.T) { t.Skip("this is not a short test") } - cfg, err := testscommon.CreateTestConfigs("../../cmd/node/config") + cfg, err := testscommon.CreateTestConfigs(t.TempDir(), "../../cmd/node/config") require.Nil(t, err) pr := NewProcessorRunner(t, *cfg) diff --git a/integrationTests/realcomponents/txsimulator/componentConstruction_test.go b/integrationTests/realcomponents/txsimulator/componentConstruction_test.go index 215e1549c2c..fe162c5a2d5 100644 --- a/integrationTests/realcomponents/txsimulator/componentConstruction_test.go +++ b/integrationTests/realcomponents/txsimulator/componentConstruction_test.go @@ -23,7 +23,7 @@ func TestTransactionSimulationComponentConstructionOnMetachain(t *testing.T) { t.Skip("this is not a short test") } - cfg, err := testscommon.CreateTestConfigs("../../../cmd/node/config") + cfg, err := testscommon.CreateTestConfigs(t.TempDir(), "../../../cmd/node/config") require.Nil(t, err) cfg.EpochConfig.EnableEpochs.ESDTEnableEpoch = 0 @@ -74,7 +74,7 @@ func TestTransactionSimulationComponentConstructionOnShard(t *testing.T) { t.Skip("this is not a short test") } - cfg, err := testscommon.CreateTestConfigs("../../../cmd/node/config") + cfg, err := testscommon.CreateTestConfigs(t.TempDir(), "../../../cmd/node/config") require.Nil(t, err) cfg.EpochConfig.EnableEpochs.SCDeployEnableEpoch = 0 diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index cc0f4a6aa94..78cf256ea21 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,7 +1,6 @@ package chainSimulator import ( - "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" @@ -19,6 +18,7 @@ type simulator struct { // NewChainSimulator will create a new instance of simulator func NewChainSimulator( + tempDir string, numOfShards uint32, pathToInitialConfig string, genesisTimestamp int64, @@ -33,7 +33,7 @@ func NewChainSimulator( chanStopNodeProcess: make(chan endProcess.ArgEndProcess), } - err := instance.createChainHandlers(numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis) + err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis) if err != nil { return nil, err } @@ -42,6 +42,7 @@ func NewChainSimulator( } func (s *simulator) createChainHandlers( + tempDir string, numOfShards uint32, originalConfigPath string, genesisTimestamp int64, @@ -54,38 +55,28 @@ func (s *simulator) createChainHandlers( GenesisAddressWithBalance: testdata.GenesisAddressWithBalance, GenesisTimeStamp: genesisTimestamp, RoundDurationInMillis: roundDurationInMillis, + TempDir: tempDir, }) if err != nil { return err } - blsKey := outputConfigs.ValidatorsPublicKeys[core.MetachainShardId] - metaChainHandler, err := s.createChainHandler(core.MetachainShardId, outputConfigs.Configs, 0, outputConfigs.GasScheduleFilename, blsKey) - if err != nil { - return err - } - - s.nodes = append(s.nodes, metaChainHandler) - - for idx := uint32(0); idx < numOfShards; idx++ { - blsKey = outputConfigs.ValidatorsPublicKeys[idx+1] - shardChainHandler, errS := s.createChainHandler(idx, outputConfigs.Configs, int(idx)+1, outputConfigs.GasScheduleFilename, blsKey) - if errS != nil { - return errS + for idx := range outputConfigs.ValidatorsPrivateKeys { + chainHandler, errCreate := s.createChainHandler(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename) + if errCreate != nil { + return errCreate } - s.nodes = append(s.nodes, shardChainHandler) + s.nodes = append(s.nodes, chainHandler) } return nil } func (s *simulator) createChainHandler( - shardID uint32, configs *config.Configs, skIndex int, gasScheduleFilename string, - blsKeyBytes []byte, ) (ChainHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Config: *configs.GeneralConfig, @@ -101,7 +92,6 @@ func (s *simulator) createChainHandler( SyncedBroadcastNetwork: s.syncedBroadcastNetwork, NumShards: s.numOfShards, GasScheduleFilename: gasScheduleFilename, - ShardID: shardID, SkIndex: skIndex, } @@ -110,7 +100,7 @@ func (s *simulator) createChainHandler( return nil, err } - return process.NewBlocksCreator(testNode, blsKeyBytes) + return process.NewBlocksCreator(testNode) } // GenerateBlocks will generate the provided number of blocks diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 841e8a57260..feef2c449a0 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -14,7 +14,7 @@ const ( func TestNewChainSimulator(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig, startTime, roundDurationInMillis) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis) require.Nil(t, err) require.NotNil(t, chainSimulator) defer chainSimulator.Stop() @@ -25,7 +25,7 @@ func TestNewChainSimulator(t *testing.T) { func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(3, defaultPathToInitialConfig, startTime, roundDurationInMillis) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis) require.Nil(t, err) require.NotNil(t, chainSimulator) defer chainSimulator.Stop() diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index be163707f61..f2e8db4639b 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -36,10 +36,8 @@ type ArgsTestOnlyProcessingNode struct { SyncedBroadcastNetwork SyncedBroadcastNetworkHandler GasScheduleFilename string - - NumShards uint32 - ShardID uint32 - SkIndex int + NumShards uint32 + SkIndex int } type testOnlyProcessingNode struct { @@ -55,7 +53,6 @@ type testOnlyProcessingNode struct { NodesCoordinator nodesCoordinator.NodesCoordinator ChainHandler chainData.ChainHandler - ShardCoordinator sharding.Coordinator ArgumentsParser process.ArgumentsParser TransactionFeeHandler process.TransactionFeeHandler StoreService dataRetriever.StorageService @@ -71,7 +68,9 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces ArgumentsParser: smartContract.NewArgumentParser(), StoreService: CreateStore(args.NumShards), } - err := instance.createBasicComponents(args.NumShards, args.ShardID) + + var err error + instance.TransactionFeeHandler, err = postprocess.NewFeeAccumulator() if err != nil { return nil, err } @@ -96,25 +95,6 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - err = instance.createBlockChain(args.ShardID) - if err != nil { - return nil, err - } - - instance.StateComponentsHolder, err = CreateStateComponents(ArgsStateComponents{ - Config: args.Config, - CoreComponents: instance.CoreComponentsHolder, - StatusCore: instance.StatusCoreComponents, - StoreService: instance.StoreService, - ChainHandler: instance.ChainHandler, - }) - if err != nil { - return nil, err - } - instance.StatusComponentsHolder, err = CreateStatusComponentsHolder(args.ShardID) - if err != nil { - return nil, err - } instance.CryptoComponentsHolder, err = CreateCryptoComponentsHolder(ArgsCryptoComponentsHolder{ Config: args.Config, EnableEpochsConfig: args.EpochConfig.EnableEpochs, @@ -147,6 +127,28 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + selfShardID := instance.GetShardCoordinator().SelfId() + instance.StatusComponentsHolder, err = CreateStatusComponentsHolder(selfShardID) + if err != nil { + return nil, err + } + + err = instance.createBlockChain(selfShardID) + if err != nil { + return nil, err + } + + instance.StateComponentsHolder, err = CreateStateComponents(ArgsStateComponents{ + Config: args.Config, + CoreComponents: instance.CoreComponentsHolder, + StatusCore: instance.StatusCoreComponents, + StoreService: instance.StoreService, + ChainHandler: instance.ChainHandler, + }) + if err != nil { + return nil, err + } + err = instance.createDataPool(args) if err != nil { return nil, err @@ -197,21 +199,6 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return instance, nil } -func (node *testOnlyProcessingNode) createBasicComponents(numShards, selfShardID uint32) error { - var err error - - node.TransactionFeeHandler, err = postprocess.NewFeeAccumulator() - if err != nil { - return err - } - node.ShardCoordinator, err = sharding.NewMultiShardCoordinator(numShards, selfShardID) - if err != nil { - return err - } - - return nil -} - func (node *testOnlyProcessingNode) createBlockChain(selfShardID uint32) error { var err error if selfShardID == core.MetachainShardId { @@ -229,7 +216,7 @@ func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNo argsDataPool := dataRetrieverFactory.ArgsDataPool{ Config: &args.Config, EconomicsData: node.CoreComponentsHolder.EconomicsData(), - ShardCoordinator: node.ShardCoordinator, + ShardCoordinator: node.BootstrapComponentsHolder.ShardCoordinator(), Marshalizer: node.CoreComponentsHolder.InternalMarshalizer(), PathManager: node.CoreComponentsHolder.PathHandler(), } @@ -265,7 +252,7 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc node.CoreComponentsHolder.Rater(), bootstrapStorer, node.CoreComponentsHolder.NodesShuffler(), - node.ShardCoordinator.SelfId(), + node.BootstrapComponentsHolder.ShardCoordinator().SelfId(), node.BootstrapComponentsHolder.EpochBootstrapParams(), node.BootstrapComponentsHolder.EpochBootstrapParams().Epoch(), node.CoreComponentsHolder.ChanStopNodeProcess(), @@ -313,7 +300,7 @@ func (node *testOnlyProcessingNode) GetBroadcastMessenger() consensus.BroadcastM // GetShardCoordinator will return the shard coordinator func (node *testOnlyProcessingNode) GetShardCoordinator() sharding.Coordinator { - return node.ShardCoordinator + return node.BootstrapComponentsHolder.ShardCoordinator() } // GetCryptoComponents will return the crypto components diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index f82fee5286a..a380bc20778 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -63,7 +63,6 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo EconomicsConfig: economicsConfig, GasScheduleFilename: gasScheduleName, NumShards: 3, - ShardID: 0, PreferencesConfig: prefsConfig, SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), ImportDBConfig: config.ImportDbConfig{}, @@ -86,15 +85,6 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo func TestNewTestOnlyProcessingNode(t *testing.T) { t.Parallel() - t.Run("invalid shard configuration should error", func(t *testing.T) { - t.Parallel() - - args := createMockArgsTestOnlyProcessingNode(t) - args.ShardID = args.NumShards - node, err := NewTestOnlyProcessingNode(args) - assert.NotNil(t, err) - assert.Nil(t, node) - }) t.Run("should work", func(t *testing.T) { if testing.Short() { t.Skip("cannot run with -race -short; requires Wasm VM fix") diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 88502f1fcce..8f61d84c015 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -36,6 +36,7 @@ type ArgsChainSimulatorConfigs struct { GenesisAddressWithBalance string GenesisTimeStamp int64 RoundDurationInMillis uint64 + TempDir string } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -43,12 +44,11 @@ type ArgsConfigsSimulator struct { GasScheduleFilename string Configs *config.Configs ValidatorsPrivateKeys []crypto.PrivateKey - ValidatorsPublicKeys map[uint32][]byte } // CreateChainSimulatorConfigs will create the chain simulator configs func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSimulator, error) { - configs, err := testscommon.CreateTestConfigs(args.OriginalConfigsPath) + configs, err := testscommon.CreateTestConfigs(args.TempDir, args.OriginalConfigsPath) if err != nil { return nil, err } @@ -119,24 +119,10 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi // enable db lookup extension configs.GeneralConfig.DbLookupExtensions.Enabled = true - publicKeysBytes := make(map[uint32][]byte) - publicKeysBytes[core.MetachainShardId], err = publicKeys[0].ToByteArray() - if err != nil { - return nil, err - } - - for idx := uint32(1); idx < uint32(len(publicKeys)); idx++ { - publicKeysBytes[idx], err = publicKeys[idx].ToByteArray() - if err != nil { - return nil, err - } - } - return &ArgsConfigsSimulator{ Configs: configs, ValidatorsPrivateKeys: privateKeys, GasScheduleFilename: gasScheduleName, - ValidatorsPublicKeys: publicKeysBytes, }, nil } diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index 227a899cd0a..59e88a3e5a1 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -19,6 +19,7 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { GenesisAddressWithBalance: "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz", RoundDurationInMillis: 6000, GenesisTimeStamp: 0, + TempDir: t.TempDir(), }) require.Nil(t, err) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 775cd86debb..71d85bab81a 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -11,14 +11,12 @@ type manualRoundHandler interface { type blocksCreator struct { nodeHandler NodeHandler - blsKeyBytes []byte } // NewBlocksCreator will create a new instance of blocksCreator -func NewBlocksCreator(nodeHandler NodeHandler, blsKeyBytes []byte) (*blocksCreator, error) { +func NewBlocksCreator(nodeHandler NodeHandler) (*blocksCreator, error) { return &blocksCreator{ nodeHandler: nodeHandler, - blsKeyBytes: blsKeyBytes, }, nil } @@ -69,8 +67,9 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } + blsKeyBytes := creator.nodeHandler.GetCryptoComponents().PublicKeyBytes() signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() - randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), creator.blsKeyBytes) + randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), blsKeyBytes) if err != nil { return err } @@ -101,12 +100,12 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - err = creator.nodeHandler.GetBroadcastMessenger().BroadcastHeader(header, creator.blsKeyBytes) + err = creator.nodeHandler.GetBroadcastMessenger().BroadcastHeader(header, blsKeyBytes) if err != nil { return err } - return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, creator.blsKeyBytes) + return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, blsKeyBytes) } func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prevHash, prevRandSeed []byte) { @@ -136,7 +135,8 @@ func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) err return err } - err = signingHandler.Reset([]string{string(creator.blsKeyBytes)}) + blsKeyBytes := creator.nodeHandler.GetCryptoComponents().PublicKeyBytes() + err = signingHandler.Reset([]string{string(blsKeyBytes)}) if err != nil { return err } @@ -146,7 +146,7 @@ func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) err headerHash, uint16(0), header.GetEpoch(), - creator.blsKeyBytes, + blsKeyBytes, ) if err != nil { return err @@ -189,7 +189,8 @@ func (creator *blocksCreator) createLeaderSignature(header data.HeaderHandler) ( signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() - return signingHandler.CreateSignatureForPublicKey(marshalizedHdr, creator.blsKeyBytes) + blsKeyBytes := creator.nodeHandler.GetCryptoComponents().PublicKeyBytes() + return signingHandler.CreateSignatureForPublicKey(marshalizedHdr, blsKeyBytes) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/nodeRunner_test.go b/node/nodeRunner_test.go index c8afa1a17e3..bb20b16fc47 100644 --- a/node/nodeRunner_test.go +++ b/node/nodeRunner_test.go @@ -35,7 +35,7 @@ func TestNewNodeRunner(t *testing.T) { t.Run("with valid configs should work", func(t *testing.T) { t.Parallel() - configs, err := testscommon.CreateTestConfigs(originalConfigsPath) + configs, err := testscommon.CreateTestConfigs(t.TempDir(), originalConfigsPath) require.Nil(t, err) runner, err := NewNodeRunner(configs) @@ -47,7 +47,7 @@ func TestNewNodeRunner(t *testing.T) { func TestNodeRunner_StartAndCloseNodeUsingSIGINT(t *testing.T) { t.Parallel() - configs, err := testscommon.CreateTestConfigs(originalConfigsPath) + configs, err := testscommon.CreateTestConfigs(t.TempDir(), originalConfigsPath) require.Nil(t, err) runner, _ := NewNodeRunner(configs) diff --git a/testscommon/realConfigsHandling.go b/testscommon/realConfigsHandling.go index eaccef8a75c..e58b36923f8 100644 --- a/testscommon/realConfigsHandling.go +++ b/testscommon/realConfigsHandling.go @@ -12,9 +12,7 @@ import ( // CreateTestConfigs will try to copy the whole configs directory to a temp directory and return the configs after load // The copying of the configs is required because minor adjustments of their contents is required for the tests to pass -func CreateTestConfigs(originalConfigsPath string) (*config.Configs, error) { - tempDir := os.TempDir() - +func CreateTestConfigs(tempDir string, originalConfigsPath string) (*config.Configs, error) { newConfigsPath := path.Join(tempDir, "config") // TODO refactor this cp to work on all OSes From 51ca554527ed111a28efe014bc0ac44e2670d45e Mon Sep 17 00:00:00 2001 From: jules01 Date: Thu, 9 Nov 2023 13:52:30 +0200 Subject: [PATCH 501/958] - epoch change fixes - added & called Close on all inner components --- node/chainSimulator/chainSimulator.go | 76 ++++++++++--- node/chainSimulator/chainSimulator_test.go | 47 +++++++- .../components/bootstrapComponents.go | 16 ++- .../chainSimulator/components/closeHandler.go | 81 +++++++++++++ .../components/coreComponents.go | 17 ++- .../components/dataComponents.go | 14 +++ .../components/instantBroadcastMessenger.go | 106 ++++++++++++++++++ .../components/memoryComponents.go | 63 +++++++++++ .../components/networkComponents.go | 23 +++- .../components/processComponents.go | 19 ++++ .../components/statusComponents.go | 17 ++- .../components/statusCoreComponents.go | 16 +++ .../components/storageService.go | 6 +- .../components/testOnlyProcessingNode.go | 33 +++++- node/chainSimulator/configs/configs.go | 21 ++-- node/chainSimulator/errors.go | 9 ++ node/chainSimulator/facade.go | 54 +++++++++ node/chainSimulator/interface.go | 8 ++ node/chainSimulator/process/interface.go | 2 + 19 files changed, 590 insertions(+), 38 deletions(-) create mode 100644 node/chainSimulator/components/closeHandler.go create mode 100644 node/chainSimulator/components/instantBroadcastMessenger.go create mode 100644 node/chainSimulator/errors.go create mode 100644 node/chainSimulator/facade.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 78cf256ea21..14ee3fd5775 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,18 +1,25 @@ package chainSimulator import ( + "time" + + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" + logger "github.com/multiversx/mx-chain-logger-go" ) +var log = logger.GetOrCreate("chainSimulator") + type simulator struct { chanStopNodeProcess chan endProcess.ArgEndProcess syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler - nodes []ChainHandler + handlers []ChainHandler + nodes map[uint32]process.NodeHandler numOfShards uint32 } @@ -23,17 +30,19 @@ func NewChainSimulator( pathToInitialConfig string, genesisTimestamp int64, roundDurationInMillis uint64, + roundsPerEpoch core.OptionalUint64, ) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() instance := &simulator{ syncedBroadcastNetwork: syncedBroadcastNetwork, - nodes: make([]ChainHandler, 0), + nodes: make(map[uint32]process.NodeHandler), + handlers: make([]ChainHandler, 0, numOfShards+1), numOfShards: numOfShards, chanStopNodeProcess: make(chan endProcess.ArgEndProcess), } - err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis) + err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis, roundsPerEpoch) if err != nil { return nil, err } @@ -47,6 +56,7 @@ func (s *simulator) createChainHandlers( originalConfigPath string, genesisTimestamp int64, roundDurationInMillis uint64, + roundsPerEpoch core.OptionalUint64, ) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: numOfShards, @@ -61,23 +71,42 @@ func (s *simulator) createChainHandlers( return err } + if roundsPerEpoch.HasValue { + outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(roundsPerEpoch.Value) + } + for idx := range outputConfigs.ValidatorsPrivateKeys { - chainHandler, errCreate := s.createChainHandler(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename) + node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename) if errCreate != nil { return errCreate } - s.nodes = append(s.nodes, chainHandler) + chainHandler, errCreate := process.NewBlocksCreator(node) + if errCreate != nil { + return errCreate + } + + shardID := node.GetShardCoordinator().SelfId() + s.nodes[shardID] = node + s.handlers = append(s.handlers, chainHandler) } + log.Info("running the chain simulator with the following parameters", + "number of shards (including meta)", numOfShards+1, + "round per epoch", outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch, + "round duration", time.Millisecond*time.Duration(roundDurationInMillis), + "genesis timestamp", genesisTimestamp, + "original config path", originalConfigPath, + "temporary path", tempDir) + return nil } -func (s *simulator) createChainHandler( +func (s *simulator) createTestNode( configs *config.Configs, skIndex int, gasScheduleFilename string, -) (ChainHandler, error) { +) (process.NodeHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Config: *configs.GeneralConfig, EpochConfig: *configs.EpochConfig, @@ -95,12 +124,7 @@ func (s *simulator) createChainHandler( SkIndex: skIndex, } - testNode, err := components.NewTestOnlyProcessingNode(args) - if err != nil { - return nil, err - } - - return process.NewBlocksCreator(testNode) + return components.NewTestOnlyProcessingNode(args) } // GenerateBlocks will generate the provided number of blocks @@ -116,13 +140,13 @@ func (s *simulator) GenerateBlocks(numOfBlocks int) error { } func (s *simulator) incrementRoundOnAllValidators() { - for _, node := range s.nodes { + for _, node := range s.handlers { node.IncrementRound() } } func (s *simulator) allNodesCreateBlocks() error { - for _, node := range s.nodes { + for _, node := range s.handlers { err := node.CreateNewBlock() if err != nil { return err @@ -132,8 +156,26 @@ func (s *simulator) allNodesCreateBlocks() error { return nil } -// Stop will stop the simulator -func (s *simulator) Stop() { +// GetNodeHandler returns the node handler from the provided shardID +func (s *simulator) GetNodeHandler(shardID uint32) process.NodeHandler { + return s.nodes[shardID] +} + +// Close will stop and close the simulator +func (s *simulator) Close() error { + var errorStrings []string + for _, n := range s.nodes { + err := n.Close() + if err != nil { + errorStrings = append(errorStrings, err.Error()) + } + } + + if len(errorStrings) == 0 { + return nil + } + + return components.AggregateErrors(errorStrings) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index feef2c449a0..3648d62ca1a 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -1,9 +1,13 @@ package chainSimulator import ( + "fmt" "testing" "time" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -14,24 +18,59 @@ const ( func TestNewChainSimulator(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}) require.Nil(t, err) require.NotNil(t, chainSimulator) - defer chainSimulator.Stop() time.Sleep(time.Second) + + err = chainSimulator.Close() + assert.Nil(t, err) } func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}) require.Nil(t, err) require.NotNil(t, chainSimulator) - defer chainSimulator.Stop() time.Sleep(time.Second) err = chainSimulator.GenerateBlocks(10) require.Nil(t, err) + + err = chainSimulator.Close() + assert.Nil(t, err) +} + +func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + + facade, err := NewChainSimulatorFacade(chainSimulator) + require.Nil(t, err) + + initialAccount, err := facade.GetExistingAccountFromBech32AddressString(testdata.GenesisAddressWithStake) + require.Nil(t, err) + + time.Sleep(time.Second) + + err = chainSimulator.GenerateBlocks(80) + require.Nil(t, err) + + accountAfterRewards, err := facade.GetExistingAccountFromBech32AddressString(testdata.GenesisAddressWithStake) + + assert.True(t, accountAfterRewards.GetBalance().Cmp(initialAccount.GetBalance()) > 0, + fmt.Sprintf("initial balance %s, balance after rewards %s", initialAccount.GetBalance().String(), accountAfterRewards.GetBalance().String())) + + err = chainSimulator.Close() + assert.Nil(t, err) } diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index e27693754f5..538f84427db 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -26,6 +26,7 @@ type ArgsBootstrapComponentsHolder struct { } type bootstrapComponentsHolder struct { + closeHandler *closeHandler epochStartBootstrapper factory.EpochStartBootstrapper epochBootstrapParams factory.BootstrapParamsHolder nodeType core.NodeType @@ -38,7 +39,9 @@ type bootstrapComponentsHolder struct { // CreateBootstrapComponentHolder will create a new instance of bootstrap components holder func CreateBootstrapComponentHolder(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHolder, error) { - instance := &bootstrapComponentsHolder{} + instance := &bootstrapComponentsHolder{ + closeHandler: NewCloseHandler(), + } bootstrapComponentsFactoryArgs := bootstrapComp.BootstrapComponentsFactoryArgs{ Config: args.Config, @@ -76,6 +79,8 @@ func CreateBootstrapComponentHolder(args ArgsBootstrapComponentsHolder) (factory instance.headerIntegrityVerifier = managedBootstrapComponents.HeaderIntegrityVerifier() instance.guardedAccountHandler = managedBootstrapComponents.GuardedAccountHandler() + instance.collectClosableComponents() + return instance, nil } @@ -119,6 +124,15 @@ func (b *bootstrapComponentsHolder) GuardedAccountHandler() process.GuardedAccou return b.guardedAccountHandler } +func (b *bootstrapComponentsHolder) collectClosableComponents() { + b.closeHandler.AddComponent(b.epochStartBootstrapper) +} + +// Close will call the Close methods on all inner components +func (b *bootstrapComponentsHolder) Close() error { + return b.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (b *bootstrapComponentsHolder) IsInterfaceNil() bool { return b == nil diff --git a/node/chainSimulator/components/closeHandler.go b/node/chainSimulator/components/closeHandler.go new file mode 100644 index 00000000000..7c802865474 --- /dev/null +++ b/node/chainSimulator/components/closeHandler.go @@ -0,0 +1,81 @@ +package components + +import ( + "errors" + "fmt" + "io" + "runtime/debug" + "strings" + "sync" + + "github.com/multiversx/mx-chain-core-go/core/check" +) + +var errClose = errors.New("error while closing inner components") + +type errorlessCloser interface { + Close() +} + +type allCloser interface { + CloseAll() error +} + +type closeHandler struct { + mut sync.RWMutex + components []interface{} +} + +// NewCloseHandler create a new closeHandler instance +func NewCloseHandler() *closeHandler { + return &closeHandler{ + components: make([]interface{}, 0), + } +} + +// AddComponent will try to add a component to the inner list if that component is not nil +func (handler *closeHandler) AddComponent(component interface{}) { + if check.IfNilReflect(component) { + log.Error("programming error in closeHandler.AddComponent: nil component", "stack", string(debug.Stack())) + return + } + + handler.mut.Lock() + handler.components = append(handler.components, component) + handler.mut.Unlock() +} + +// Close will try to close all components, wrapping errors, if necessary +func (handler *closeHandler) Close() error { + handler.mut.RLock() + defer handler.mut.RUnlock() + + var errorStrings []string + for _, component := range handler.components { + var err error + + switch t := component.(type) { + case errorlessCloser: + t.Close() + case io.Closer: + err = t.Close() + case allCloser: + err = t.CloseAll() + } + + if err != nil { + errorStrings = append(errorStrings, fmt.Errorf("%w while closing the component of type %T", err, component).Error()) + } + } + + return AggregateErrors(errorStrings) +} + +// AggregateErrors can aggregate all provided error strings into a single error variable +func AggregateErrors(errorStrings []string) error { + if len(errorStrings) == 0 { + return nil + } + + return fmt.Errorf("%w %s", errClose, strings.Join(errorStrings, ", ")) +} diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index d1ae907efb1..94e11798502 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -39,6 +39,7 @@ import ( ) type coreComponentsHolder struct { + closeHandler *closeHandler internalMarshaller marshal.Marshalizer txMarshaller marshal.Marshalizer vmMarshaller marshal.Marshalizer @@ -91,7 +92,9 @@ type ArgsCoreComponentsHolder struct { // CreateCoreComponentsHolder will create a new instance of factory.CoreComponentsHolder func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComponentsHolder, error) { var err error - instance := &coreComponentsHolder{} + instance := &coreComponentsHolder{ + closeHandler: NewCloseHandler(), + } instance.internalMarshaller, err = marshalFactory.NewMarshalizer(args.Config.Marshalizer.Type) if err != nil { @@ -225,6 +228,8 @@ func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComp } instance.hardforkTriggerPubKey = pubKeyBytes + instance.collectClosableComponents() + return instance, nil } @@ -414,6 +419,16 @@ func (c *coreComponentsHolder) EnableEpochsHandler() common.EnableEpochsHandler return c.enableEpochsHandler } +func (c *coreComponentsHolder) collectClosableComponents() { + c.closeHandler.AddComponent(c.alarmScheduler) + c.closeHandler.AddComponent(c.syncTimer) +} + +// Close will call the Close methods on all inner components +func (c *coreComponentsHolder) Close() error { + return c.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (c *coreComponentsHolder) IsInterfaceNil() bool { return c == nil diff --git a/node/chainSimulator/components/dataComponents.go b/node/chainSimulator/components/dataComponents.go index f8a01db7697..ab57ea202ad 100644 --- a/node/chainSimulator/components/dataComponents.go +++ b/node/chainSimulator/components/dataComponents.go @@ -17,6 +17,7 @@ type ArgsDataComponentsHolder struct { } type dataComponentsHolder struct { + closeHandler *closeHandler chain data.ChainHandler storageService dataRetriever.StorageService dataPool dataRetriever.PoolsHolder @@ -42,12 +43,15 @@ func CreateDataComponentsHolder(args ArgsDataComponentsHolder) (factory.DataComp } instance := &dataComponentsHolder{ + closeHandler: NewCloseHandler(), chain: args.Chain, storageService: args.StorageService, dataPool: args.DataPool, miniBlockProvider: miniBlocksProvider, } + instance.collectClosableComponents() + return instance, nil } @@ -88,6 +92,16 @@ func (d *dataComponentsHolder) Clone() interface{} { } } +func (d *dataComponentsHolder) collectClosableComponents() { + d.closeHandler.AddComponent(d.storageService) + d.closeHandler.AddComponent(d.dataPool) +} + +// Close will call the Close methods on all inner components +func (d *dataComponentsHolder) Close() error { + return d.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (d *dataComponentsHolder) IsInterfaceNil() bool { return d == nil diff --git a/node/chainSimulator/components/instantBroadcastMessenger.go b/node/chainSimulator/components/instantBroadcastMessenger.go new file mode 100644 index 00000000000..893fc4edbc7 --- /dev/null +++ b/node/chainSimulator/components/instantBroadcastMessenger.go @@ -0,0 +1,106 @@ +package components + +import ( + "strings" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/errors" + "github.com/multiversx/mx-chain-go/sharding" +) + +type instantBroadcastMessenger struct { + consensus.BroadcastMessenger + shardCoordinator sharding.Coordinator +} + +// NewInstantBroadcastMessenger creates a new instance of type instantBroadcastMessenger +func NewInstantBroadcastMessenger(broadcastMessenger consensus.BroadcastMessenger, shardCoordinator sharding.Coordinator) (*instantBroadcastMessenger, error) { + if check.IfNil(broadcastMessenger) { + return nil, errors.ErrNilBroadcastMessenger + } + if check.IfNil(shardCoordinator) { + return nil, errors.ErrNilShardCoordinator + } + + return &instantBroadcastMessenger{ + BroadcastMessenger: broadcastMessenger, + shardCoordinator: shardCoordinator, + }, nil +} + +// BroadcastBlockDataLeader broadcasts the block data as consensus group leader +func (messenger *instantBroadcastMessenger) BroadcastBlockDataLeader(_ data.HeaderHandler, miniBlocks map[uint32][]byte, transactions map[string][][]byte, pkBytes []byte) error { + if messenger.shardCoordinator.SelfId() == common.MetachainShardId { + return messenger.broadcastMiniblockData(miniBlocks, transactions, pkBytes) + } + + return messenger.broadcastBlockDataLeaderWhenShard(miniBlocks, transactions, pkBytes) +} + +func (messenger *instantBroadcastMessenger) broadcastBlockDataLeaderWhenShard(miniBlocks map[uint32][]byte, transactions map[string][][]byte, pkBytes []byte) error { + if len(miniBlocks) == 0 { + return nil + } + + metaMiniBlocks, metaTransactions := messenger.extractMetaMiniBlocksAndTransactions(miniBlocks, transactions) + + return messenger.broadcastMiniblockData(metaMiniBlocks, metaTransactions, pkBytes) +} + +func (messenger *instantBroadcastMessenger) broadcastMiniblockData(miniBlocks map[uint32][]byte, transactions map[string][][]byte, pkBytes []byte) error { + if len(miniBlocks) > 0 { + err := messenger.BroadcastMiniBlocks(miniBlocks, pkBytes) + if err != nil { + log.Warn("instantBroadcastMessenger.BroadcastBlockData: broadcast miniblocks", "error", err.Error()) + } + } + + if len(transactions) > 0 { + err := messenger.BroadcastTransactions(transactions, pkBytes) + if err != nil { + log.Warn("instantBroadcastMessenger.BroadcastBlockData: broadcast transactions", "error", err.Error()) + } + } + + return nil +} + +func (messenger *instantBroadcastMessenger) extractMetaMiniBlocksAndTransactions( + miniBlocks map[uint32][]byte, + transactions map[string][][]byte, +) (map[uint32][]byte, map[string][][]byte) { + + metaMiniBlocks := make(map[uint32][]byte) + metaTransactions := make(map[string][][]byte) + + for shardID, mbsMarshalized := range miniBlocks { + if shardID != core.MetachainShardId { + continue + } + + metaMiniBlocks[shardID] = mbsMarshalized + delete(miniBlocks, shardID) + } + + identifier := messenger.shardCoordinator.CommunicationIdentifier(core.MetachainShardId) + + for broadcastTopic, txsMarshalized := range transactions { + if !strings.Contains(broadcastTopic, identifier) { + continue + } + + metaTransactions[broadcastTopic] = txsMarshalized + delete(transactions, broadcastTopic) + } + + return metaMiniBlocks, metaTransactions +} + +// IsInterfaceNil returns true if there is no value under the interface +func (messenger *instantBroadcastMessenger) IsInterfaceNil() bool { + return messenger == nil +} diff --git a/node/chainSimulator/components/memoryComponents.go b/node/chainSimulator/components/memoryComponents.go index 5384f320790..92b562beb6f 100644 --- a/node/chainSimulator/components/memoryComponents.go +++ b/node/chainSimulator/components/memoryComponents.go @@ -1,6 +1,7 @@ package components import ( + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/storage/database" "github.com/multiversx/mx-chain-go/storage/storageunit" @@ -17,3 +18,65 @@ func CreateMemUnit() storage.Storer { return unit } + +type trieStorage struct { + storage.Storer +} + +// SetEpochForPutOperation does nothing +func (store *trieStorage) SetEpochForPutOperation(_ uint32) { +} + +// GetFromOldEpochsWithoutAddingToCache tries to get directly the key +func (store *trieStorage) GetFromOldEpochsWithoutAddingToCache(key []byte) ([]byte, core.OptionalUint32, error) { + value, err := store.Get(key) + + return value, core.OptionalUint32{}, err +} + +// GetFromLastEpoch tries to get directly the key +func (store *trieStorage) GetFromLastEpoch(key []byte) ([]byte, error) { + return store.Get(key) +} + +// PutInEpoch will put the key directly +func (store *trieStorage) PutInEpoch(key []byte, data []byte, _ uint32) error { + return store.Put(key, data) +} + +// PutInEpochWithoutCache will put the key directly +func (store *trieStorage) PutInEpochWithoutCache(key []byte, data []byte, _ uint32) error { + return store.Put(key, data) +} + +// GetLatestStorageEpoch returns 0 +func (store *trieStorage) GetLatestStorageEpoch() (uint32, error) { + return 0, nil +} + +// GetFromCurrentEpoch tries to get directly the key +func (store *trieStorage) GetFromCurrentEpoch(key []byte) ([]byte, error) { + return store.Get(key) +} + +// GetFromEpoch tries to get directly the key +func (store *trieStorage) GetFromEpoch(key []byte, _ uint32) ([]byte, error) { + return store.Get(key) +} + +// RemoveFromCurrentEpoch removes directly the key +func (store *trieStorage) RemoveFromCurrentEpoch(key []byte) error { + return store.Remove(key) +} + +// RemoveFromAllActiveEpochs removes directly the key +func (store *trieStorage) RemoveFromAllActiveEpochs(key []byte) error { + return store.Remove(key) +} + +// CreateMemUnitForTries returns a special type of storer used on tries instances +func CreateMemUnitForTries() storage.Storer { + return &trieStorage{ + Storer: CreateMemUnit(), + } +} diff --git a/node/chainSimulator/components/networkComponents.go b/node/chainSimulator/components/networkComponents.go index 1afa6037b16..9585da79372 100644 --- a/node/chainSimulator/components/networkComponents.go +++ b/node/chainSimulator/components/networkComponents.go @@ -12,6 +12,7 @@ import ( ) type networkComponentsHolder struct { + closeHandler *closeHandler networkMessenger p2p.Messenger inputAntiFloodHandler factory.P2PAntifloodHandler outputAntiFloodHandler factory.P2PAntifloodHandler @@ -32,7 +33,8 @@ func CreateNetworkComponentsHolder(network SyncedBroadcastNetworkHandler) (*netw return nil, err } - return &networkComponentsHolder{ + instance := &networkComponentsHolder{ + closeHandler: NewCloseHandler(), networkMessenger: messenger, inputAntiFloodHandler: disabled.NewAntiFlooder(), outputAntiFloodHandler: disabled.NewAntiFlooder(), @@ -44,7 +46,11 @@ func CreateNetworkComponentsHolder(network SyncedBroadcastNetworkHandler) (*netw peersRatingMonitor: disabled.NewPeersRatingMonitor(), fullArchiveNetworkMessenger: disabledP2P.NewNetworkMessenger(), fullArchivePreferredPeersHolderHandler: disabledFactory.NewPreferredPeersHolder(), - }, nil + } + + instance.collectClosableComponents() + + return instance, nil } // NetworkMessenger returns the network messenger @@ -102,6 +108,19 @@ func (holder *networkComponentsHolder) FullArchivePreferredPeersHolderHandler() return holder.fullArchivePreferredPeersHolderHandler } +func (holder *networkComponentsHolder) collectClosableComponents() { + holder.closeHandler.AddComponent(holder.networkMessenger) + holder.closeHandler.AddComponent(holder.inputAntiFloodHandler) + holder.closeHandler.AddComponent(holder.outputAntiFloodHandler) + holder.closeHandler.AddComponent(holder.peerHonestyHandler) + holder.closeHandler.AddComponent(holder.fullArchiveNetworkMessenger) +} + +// Close will call the Close methods on all inner components +func (holder *networkComponentsHolder) Close() error { + return holder.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (holder *networkComponentsHolder) IsInterfaceNil() bool { return holder == nil diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index c55d6bbfecf..0b8f8304e3b 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -52,6 +52,7 @@ type ArgsProcessComponentsHolder struct { } type processComponentsHolder struct { + closeHandler *closeHandler receiptsRepository factory.ReceiptsRepository nodesCoordinator nodesCoordinator.NodesCoordinator shardCoordinator sharding.Coordinator @@ -218,6 +219,7 @@ func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.Pr } instance := &processComponentsHolder{ + closeHandler: NewCloseHandler(), receiptsRepository: managedProcessComponents.ReceiptsRepository(), nodesCoordinator: managedProcessComponents.NodesCoordinator(), shardCoordinator: managedProcessComponents.ShardCoordinator(), @@ -260,6 +262,8 @@ func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.Pr accountsParser: managedProcessComponents.AccountsParser(), } + instance.collectClosableComponents() + return instance, nil } @@ -463,6 +467,21 @@ func (p *processComponentsHolder) ReceiptsRepository() factory.ReceiptsRepositor return p.receiptsRepository } +func (p *processComponentsHolder) collectClosableComponents() { + p.closeHandler.AddComponent(p.interceptorsContainer) + p.closeHandler.AddComponent(p.fullArchiveInterceptorsContainer) + p.closeHandler.AddComponent(p.resolversContainer) + p.closeHandler.AddComponent(p.epochStartTrigger) + p.closeHandler.AddComponent(p.blockProcessor) + p.closeHandler.AddComponent(p.validatorsProvider) + p.closeHandler.AddComponent(p.txsSenderHandler) +} + +// Close will call the Close methods on all inner components +func (p *processComponentsHolder) Close() error { + return p.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (p *processComponentsHolder) IsInterfaceNil() bool { return p == nil diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index f332370bf13..be75d124845 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -13,6 +13,7 @@ import ( ) type statusComponentsHolder struct { + closeHandler *closeHandler outportHandler outport.OutportHandler softwareVersionChecker statistics.SoftwareVersionChecker managedPeerMonitor common.ManagedPeersMonitor @@ -21,7 +22,9 @@ type statusComponentsHolder struct { // CreateStatusComponentsHolder will create a new instance of status components holder func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHolder, error) { var err error - instance := &statusComponentsHolder{} + instance := &statusComponentsHolder{ + closeHandler: NewCloseHandler(), + } // TODO add drivers to index data instance.outportHandler, err = outport.NewOutport(100*time.Millisecond, outportCfg.OutportConfig{ @@ -33,6 +36,8 @@ func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHolde instance.softwareVersionChecker = &mock.SoftwareVersionCheckerMock{} instance.managedPeerMonitor = &testscommon.ManagedPeersMonitorStub{} + instance.collectClosableComponents() + return instance, nil } @@ -51,6 +56,16 @@ func (s *statusComponentsHolder) ManagedPeersMonitor() common.ManagedPeersMonito return s.managedPeerMonitor } +func (s *statusComponentsHolder) collectClosableComponents() { + s.closeHandler.AddComponent(s.outportHandler) + s.closeHandler.AddComponent(s.softwareVersionChecker) +} + +// Close will call the Close methods on all inner components +func (s *statusComponentsHolder) Close() error { + return s.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (s *statusComponentsHolder) IsInterfaceNil() bool { return s == nil diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 60e6c8f0f47..c890d68c2c5 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -14,6 +14,7 @@ import ( ) type statusCoreComponentsHolder struct { + closeHandler *closeHandler resourceMonitor factory.ResourceMonitor networkStatisticsProvider factory.NetworkStatisticsProvider trieSyncStatisticsProvider factory.TrieSyncStatisticsProvider @@ -26,6 +27,7 @@ type statusCoreComponentsHolder struct { func CreateStatusCoreComponentsHolder(cfg config.Config, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHolder, error) { var err error instance := &statusCoreComponentsHolder{ + closeHandler: NewCloseHandler(), networkStatisticsProvider: machine.NewNetStatistics(), trieSyncStatisticsProvider: statisticsTrie.NewTrieSyncStatistics(), statusHandler: presenter.NewPresenterStatusHandler(), @@ -41,6 +43,8 @@ func CreateStatusCoreComponentsHolder(cfg config.Config, coreComponents factory. return nil, err } + instance.collectClosableComponents() + return instance, nil } @@ -74,6 +78,18 @@ func (s *statusCoreComponentsHolder) PersistentStatusHandler() factory.Persisten return s.persistentStatusHandler } +func (s *statusCoreComponentsHolder) collectClosableComponents() { + s.closeHandler.AddComponent(s.resourceMonitor) + s.closeHandler.AddComponent(s.networkStatisticsProvider) + s.closeHandler.AddComponent(s.statusHandler) + s.closeHandler.AddComponent(s.persistentStatusHandler) +} + +// Close will call the Close methods on all inner components +func (s *statusCoreComponentsHolder) Close() error { + return s.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (s *statusCoreComponentsHolder) IsInterfaceNil() bool { return s == nil diff --git a/node/chainSimulator/components/storageService.go b/node/chainSimulator/components/storageService.go index 364832fbf52..e33287427a2 100644 --- a/node/chainSimulator/components/storageService.go +++ b/node/chainSimulator/components/storageService.go @@ -20,9 +20,9 @@ func CreateStore(numOfShards uint32) dataRetriever.StorageService { store.AddStorer(dataRetriever.ReceiptsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.ScheduledSCRsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.TxLogsUnit, CreateMemUnit()) - store.AddStorer(dataRetriever.UserAccountsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.UserAccountsUnit, CreateMemUnitForTries()) store.AddStorer(dataRetriever.UserAccountsCheckpointsUnit, CreateMemUnit()) - store.AddStorer(dataRetriever.PeerAccountsUnit, CreateMemUnit()) + store.AddStorer(dataRetriever.PeerAccountsUnit, CreateMemUnitForTries()) store.AddStorer(dataRetriever.PeerAccountsCheckpointsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.ESDTSuppliesUnit, CreateMemUnit()) store.AddStorer(dataRetriever.RoundHdrHashDataUnit, CreateMemUnit()) @@ -30,7 +30,7 @@ func CreateStore(numOfShards uint32) dataRetriever.StorageService { store.AddStorer(dataRetriever.MiniblockHashByTxHashUnit, CreateMemUnit()) store.AddStorer(dataRetriever.EpochByHashUnit, CreateMemUnit()) store.AddStorer(dataRetriever.ResultsHashesByTxHashUnit, CreateMemUnit()) - // TODO add the rest of units + store.AddStorer(dataRetriever.TrieEpochRootHashUnit, CreateMemUnit()) for i := uint32(0); i < numOfShards; i++ { hdrNonceHashDataUnit := dataRetriever.ShardHdrNonceHashDataUnit + dataRetriever.UnitType(i) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index f2e8db4639b..ab818056269 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -41,6 +41,7 @@ type ArgsTestOnlyProcessingNode struct { } type testOnlyProcessingNode struct { + closeHandler *closeHandler CoreComponentsHolder factory.CoreComponentsHolder StatusCoreComponents factory.StatusCoreComponentsHolder StateComponentsHolder factory.StateComponentsHolder @@ -67,6 +68,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces instance := &testOnlyProcessingNode{ ArgumentsParser: smartContract.NewArgumentParser(), StoreService: CreateStore(args.NumShards), + closeHandler: NewCloseHandler(), } var err error @@ -196,6 +198,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + instance.collectClosableComponents() + return instance, nil } @@ -268,8 +272,7 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc } func (node *testOnlyProcessingNode) createBroadcastMessanger() error { - var err error - node.broadcastMessenger, err = sposFactory.GetBroadcastMessenger( + broadcastMessenger, err := sposFactory.GetBroadcastMessenger( node.CoreComponentsHolder.InternalMarshalizer(), node.CoreComponentsHolder.Hasher(), node.NetworkComponentsHolder.NetworkMessenger(), @@ -280,6 +283,11 @@ func (node *testOnlyProcessingNode) createBroadcastMessanger() error { node.CoreComponentsHolder.AlarmScheduler(), node.CryptoComponentsHolder.KeysHandler(), ) + if err != nil { + return err + } + + node.broadcastMessenger, err = NewInstantBroadcastMessenger(broadcastMessenger, node.BootstrapComponentsHolder.ShardCoordinator()) return err } @@ -313,6 +321,27 @@ func (node *testOnlyProcessingNode) GetCoreComponents() factory.CoreComponentsHo return node.CoreComponentsHolder } +// GetStateComponents will return the state components +func (node *testOnlyProcessingNode) GetStateComponents() factory.StateComponentsHolder { + return node.StateComponentsHolder +} + +func (node *testOnlyProcessingNode) collectClosableComponents() { + node.closeHandler.AddComponent(node.ProcessComponentsHolder) + node.closeHandler.AddComponent(node.DataComponentsHolder) + node.closeHandler.AddComponent(node.StateComponentsHolder) + node.closeHandler.AddComponent(node.StatusComponentsHolder) + node.closeHandler.AddComponent(node.BootstrapComponentsHolder) + node.closeHandler.AddComponent(node.NetworkComponentsHolder) + node.closeHandler.AddComponent(node.StatusCoreComponents) + node.closeHandler.AddComponent(node.CoreComponentsHolder) +} + +// Close will call the Close methods on all inner components +func (node *testOnlyProcessingNode) Close() error { + return node.closeHandler.Close() +} + // IsInterfaceNil returns true if there is no value under the interface func (node *testOnlyProcessingNode) IsInterfaceNil() bool { return node == nil diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 8f61d84c015..30ab70f82c6 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -23,6 +23,9 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" ) +var oneEgld = big.NewInt(1000000000000000000) +var initialStakedEgldPerNode = big.NewInt(0).Mul(oneEgld, big.NewInt(2500)) +var initialSupply = big.NewInt(0).Mul(oneEgld, big.NewInt(20000000)) // 20 million EGLD const ( // ChainID contains the chain id ChainID = "chain" @@ -75,19 +78,20 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi // update genesis.json addresses := make([]data.InitialAccount, 0) - // 10_000 egld - bigValue, _ := big.NewInt(0).SetString("10000000000000000000000", 0) + stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) + stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(len(privateKeys)))) // 2500 EGLD * number of nodes addresses = append(addresses, data.InitialAccount{ Address: args.GenesisAddressWithStake, - StakingValue: bigValue, - Supply: bigValue, + StakingValue: stakedValue, + Supply: stakedValue, }) - bigValueAddr, _ := big.NewInt(0).SetString("19990000000000000000000000", 10) + initialBalance := big.NewInt(0).Set(initialSupply) + initialBalance = initialBalance.Sub(initialBalance, stakedValue) addresses = append(addresses, data.InitialAccount{ Address: args.GenesisAddressWithBalance, - Balance: bigValueAddr, - Supply: bigValueAddr, + Balance: initialBalance, + Supply: initialBalance, }) addressesBytes, errM := json.Marshal(addresses) @@ -116,6 +120,9 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) + // set compatible trie configs + configs.GeneralConfig.StateTriesConfig.SnapshotsEnabled = false + // enable db lookup extension configs.GeneralConfig.DbLookupExtensions.Enabled = true diff --git a/node/chainSimulator/errors.go b/node/chainSimulator/errors.go new file mode 100644 index 00000000000..57f0db0c457 --- /dev/null +++ b/node/chainSimulator/errors.go @@ -0,0 +1,9 @@ +package chainSimulator + +import "errors" + +var ( + errNilChainSimulator = errors.New("nil chain simulator") + errNilMetachainNode = errors.New("nil metachain node") + errShardSetupError = errors.New("shard setup error") +) diff --git a/node/chainSimulator/facade.go b/node/chainSimulator/facade.go new file mode 100644 index 00000000000..8cf4d1f50b6 --- /dev/null +++ b/node/chainSimulator/facade.go @@ -0,0 +1,54 @@ +package chainSimulator + +import ( + "fmt" + + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" +) + +type chainSimulatorFacade struct { + chainSimulator ChainSimulator + metaNode process.NodeHandler +} + +// NewChainSimulatorFacade returns the chain simulator facade +func NewChainSimulatorFacade(chainSimulator ChainSimulator) (*chainSimulatorFacade, error) { + if check.IfNil(chainSimulator) { + return nil, errNilChainSimulator + } + + metaNode := chainSimulator.GetNodeHandler(common.MetachainShardId) + if check.IfNil(metaNode) { + return nil, errNilMetachainNode + } + + return &chainSimulatorFacade{ + chainSimulator: chainSimulator, + metaNode: metaNode, + }, nil +} + +// GetExistingAccountFromBech32AddressString will return the existing account for the provided address in bech32 format +func (f *chainSimulatorFacade) GetExistingAccountFromBech32AddressString(address string) (vmcommon.UserAccountHandler, error) { + addressBytes, err := f.metaNode.GetCoreComponents().AddressPubKeyConverter().Decode(address) + if err != nil { + return nil, err + } + + shardID := f.metaNode.GetShardCoordinator().ComputeId(addressBytes) + + shardNodeHandler := f.chainSimulator.GetNodeHandler(shardID) + if check.IfNil(shardNodeHandler) { + return nil, fmt.Errorf("%w missing node handler for shard %d", errShardSetupError, shardID) + } + + account, err := shardNodeHandler.GetStateComponents().AccountsAdapter().GetExistingAccount(addressBytes) + if err != nil { + return nil, err + } + + return account.(vmcommon.UserAccountHandler), nil +} diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go index 416d25683cd..b1540611302 100644 --- a/node/chainSimulator/interface.go +++ b/node/chainSimulator/interface.go @@ -1,8 +1,16 @@ package chainSimulator +import "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + // ChainHandler defines what a chain handler should be able to do type ChainHandler interface { IncrementRound() CreateNewBlock() error IsInterfaceNil() bool } + +// ChainSimulator defines what a chain simulator should be able to do +type ChainSimulator interface { + GetNodeHandler(shardID uint32) process.NodeHandler + IsInterfaceNil() bool +} diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index aab1d8e9baa..26f2ad9c61e 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -15,5 +15,7 @@ type NodeHandler interface { GetShardCoordinator() sharding.Coordinator GetCryptoComponents() factory.CryptoComponentsHolder GetCoreComponents() factory.CoreComponentsHolder + GetStateComponents() factory.StateComponentsHolder + Close() error IsInterfaceNil() bool } From 5e139207bb624cd6a10695f60f61469d9024ab4b Mon Sep 17 00:00:00 2001 From: jules01 Date: Thu, 9 Nov 2023 13:59:31 +0200 Subject: [PATCH 502/958] - linter fix --- node/chainSimulator/chainSimulator_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 3648d62ca1a..fa02edf772a 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -67,6 +67,7 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { require.Nil(t, err) accountAfterRewards, err := facade.GetExistingAccountFromBech32AddressString(testdata.GenesisAddressWithStake) + require.Nil(t, err) assert.True(t, accountAfterRewards.GetBalance().Cmp(initialAccount.GetBalance()) > 0, fmt.Sprintf("initial balance %s, balance after rewards %s", initialAccount.GetBalance().String(), accountAfterRewards.GetBalance().String())) From 1aaa0482297311ba129032000e13d735398f532d Mon Sep 17 00:00:00 2001 From: jules01 Date: Thu, 9 Nov 2023 16:21:13 +0200 Subject: [PATCH 503/958] - fixes after review --- node/chainSimulator/chainSimulator.go | 2 +- node/chainSimulator/components/closeHandler.go | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 14ee3fd5775..6ffb19aebda 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -175,7 +175,7 @@ func (s *simulator) Close() error { return nil } - return components.AggregateErrors(errorStrings) + return components.AggregateErrors(errorStrings, components.ErrClose) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/components/closeHandler.go b/node/chainSimulator/components/closeHandler.go index 7c802865474..19615b50210 100644 --- a/node/chainSimulator/components/closeHandler.go +++ b/node/chainSimulator/components/closeHandler.go @@ -11,7 +11,8 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" ) -var errClose = errors.New("error while closing inner components") +// ErrClose signals that a close error occurred +var ErrClose = errors.New("error while closing inner components") type errorlessCloser interface { Close() @@ -68,14 +69,14 @@ func (handler *closeHandler) Close() error { } } - return AggregateErrors(errorStrings) + return AggregateErrors(errorStrings, ErrClose) } // AggregateErrors can aggregate all provided error strings into a single error variable -func AggregateErrors(errorStrings []string) error { +func AggregateErrors(errorStrings []string, baseError error) error { if len(errorStrings) == 0 { return nil } - return fmt.Errorf("%w %s", errClose, strings.Join(errorStrings, ", ")) + return fmt.Errorf("%w %s", baseError, strings.Join(errorStrings, ", ")) } From 1882d25c9c83c5dfe9166606f1b0c42f7905889f Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 9 Nov 2023 21:24:27 +0200 Subject: [PATCH 504/958] enable rest api interface --- node/chainSimulator/chainSimulator.go | 19 +- node/chainSimulator/chainSimulator_test.go | 8 +- .../components/bootstrapComponents.go | 17 +- .../components/coreComponents.go | 17 +- .../components/cryptoComponents.go | 22 +- .../components/dataComponents.go | 17 +- .../components/networkComponents.go | 17 +- node/chainSimulator/components/nodeFacade.go | 199 ++++++++++++++++++ .../components/processComponents.go | 17 +- .../components/stateComponents.go | 17 +- .../components/statusComponents.go | 29 ++- .../components/statusCoreComponents.go | 56 +++-- .../components/testOnlyProcessingNode.go | 50 +++-- node/chainSimulator/process/interface.go | 2 + 14 files changed, 446 insertions(+), 41 deletions(-) create mode 100644 node/chainSimulator/components/nodeFacade.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 14ee3fd5775..4a4947ebe62 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -31,6 +31,7 @@ func NewChainSimulator( genesisTimestamp int64, roundDurationInMillis uint64, roundsPerEpoch core.OptionalUint64, + enableHttpServer bool, ) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() @@ -42,7 +43,7 @@ func NewChainSimulator( chanStopNodeProcess: make(chan endProcess.ArgEndProcess), } - err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis, roundsPerEpoch) + err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis, roundsPerEpoch, enableHttpServer) if err != nil { return nil, err } @@ -57,6 +58,7 @@ func (s *simulator) createChainHandlers( genesisTimestamp int64, roundDurationInMillis uint64, roundsPerEpoch core.OptionalUint64, + enableHttpServer bool, ) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: numOfShards, @@ -76,7 +78,7 @@ func (s *simulator) createChainHandlers( } for idx := range outputConfigs.ValidatorsPrivateKeys { - node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename) + node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename, enableHttpServer) if errCreate != nil { return errCreate } @@ -106,8 +108,10 @@ func (s *simulator) createTestNode( configs *config.Configs, skIndex int, gasScheduleFilename string, + enableHttpServer bool, ) (process.NodeHandler, error) { args := components.ArgsTestOnlyProcessingNode{ + Configs: *configs, Config: *configs.GeneralConfig, EpochConfig: *configs.EpochConfig, EconomicsConfig: *configs.EconomicsConfig, @@ -122,6 +126,7 @@ func (s *simulator) createTestNode( NumShards: s.numOfShards, GasScheduleFilename: gasScheduleFilename, SkIndex: skIndex, + EnableHTTPServer: enableHttpServer, } return components.NewTestOnlyProcessingNode(args) @@ -161,6 +166,16 @@ func (s *simulator) GetNodeHandler(shardID uint32) process.NodeHandler { return s.nodes[shardID] } +// GetRestAPIInterfaces will return a map with the rest api interfaces for every node +func (s *simulator) GetRestAPIInterfaces() map[uint32]string { + resMap := make(map[uint32]string) + for shardID, node := range s.nodes { + resMap[shardID] = node.GetFacadeHandler().RestApiInterface() + } + + return resMap +} + // Close will stop and close the simulator func (s *simulator) Close() error { var errorStrings []string diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index fa02edf772a..1df892ae08d 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -18,7 +18,7 @@ const ( func TestNewChainSimulator(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, false) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -31,7 +31,7 @@ func TestNewChainSimulator(t *testing.T) { func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, false) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -51,7 +51,7 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { HasValue: true, Value: 20, } - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch, false) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -72,6 +72,8 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { assert.True(t, accountAfterRewards.GetBalance().Cmp(initialAccount.GetBalance()) > 0, fmt.Sprintf("initial balance %s, balance after rewards %s", initialAccount.GetBalance().String(), accountAfterRewards.GetBalance().String())) + fmt.Println(chainSimulator.GetRestAPIInterfaces()) + err = chainSimulator.Close() assert.Nil(t, err) } diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index 538f84427db..179dc742ff5 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -38,7 +38,7 @@ type bootstrapComponentsHolder struct { } // CreateBootstrapComponentHolder will create a new instance of bootstrap components holder -func CreateBootstrapComponentHolder(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHolder, error) { +func CreateBootstrapComponentHolder(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHandler, error) { instance := &bootstrapComponentsHolder{ closeHandler: NewCloseHandler(), } @@ -137,3 +137,18 @@ func (b *bootstrapComponentsHolder) Close() error { func (b *bootstrapComponentsHolder) IsInterfaceNil() bool { return b == nil } + +// Create will do nothing +func (b *bootstrapComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (b *bootstrapComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (b *bootstrapComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 94e11798502..84235115461 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -90,7 +90,7 @@ type ArgsCoreComponentsHolder struct { } // CreateCoreComponentsHolder will create a new instance of factory.CoreComponentsHolder -func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComponentsHolder, error) { +func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComponentsHandler, error) { var err error instance := &coreComponentsHolder{ closeHandler: NewCloseHandler(), @@ -433,3 +433,18 @@ func (c *coreComponentsHolder) Close() error { func (c *coreComponentsHolder) IsInterfaceNil() bool { return c == nil } + +// Create will do nothing +func (c *coreComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (c *coreComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (c *coreComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index bfaa707cba8..ae34e1b4703 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -46,7 +46,7 @@ type cryptoComponentsHolder struct { } // CreateCryptoComponentsHolder will create a new instance of cryptoComponentsHolder -func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHolder, error) { +func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHandler, error) { instance := &cryptoComponentsHolder{} cryptoComponentsHandlerArgs := cryptoComp.CryptoComponentsFactoryArgs{ @@ -237,3 +237,23 @@ func (c *cryptoComponentsHolder) Clone() interface{} { func (c *cryptoComponentsHolder) IsInterfaceNil() bool { return c == nil } + +// Create will do nothing +func (c *cryptoComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (c *cryptoComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (c *cryptoComponentsHolder) String() string { + return "" +} + +// Close will do nothing +func (c *cryptoComponentsHolder) Close() error { + return nil +} diff --git a/node/chainSimulator/components/dataComponents.go b/node/chainSimulator/components/dataComponents.go index ab57ea202ad..0158e5cc1f3 100644 --- a/node/chainSimulator/components/dataComponents.go +++ b/node/chainSimulator/components/dataComponents.go @@ -25,7 +25,7 @@ type dataComponentsHolder struct { } // CreateDataComponentsHolder will create the data components holder -func CreateDataComponentsHolder(args ArgsDataComponentsHolder) (factory.DataComponentsHolder, error) { +func CreateDataComponentsHolder(args ArgsDataComponentsHolder) (factory.DataComponentsHandler, error) { miniBlockStorer, err := args.StorageService.GetStorer(dataRetriever.MiniBlockUnit) if err != nil { return nil, err @@ -106,3 +106,18 @@ func (d *dataComponentsHolder) Close() error { func (d *dataComponentsHolder) IsInterfaceNil() bool { return d == nil } + +// Create will do nothing +func (d *dataComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (d *dataComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (d *dataComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/networkComponents.go b/node/chainSimulator/components/networkComponents.go index 9585da79372..d7c6d6afd62 100644 --- a/node/chainSimulator/components/networkComponents.go +++ b/node/chainSimulator/components/networkComponents.go @@ -27,7 +27,7 @@ type networkComponentsHolder struct { } // CreateNetworkComponentsHolder creates a new networkComponentsHolder instance -func CreateNetworkComponentsHolder(network SyncedBroadcastNetworkHandler) (*networkComponentsHolder, error) { +func CreateNetworkComponentsHolder(network SyncedBroadcastNetworkHandler) (factory.NetworkComponentsHandler, error) { messenger, err := NewSyncedMessenger(network) if err != nil { return nil, err @@ -125,3 +125,18 @@ func (holder *networkComponentsHolder) Close() error { func (holder *networkComponentsHolder) IsInterfaceNil() bool { return holder == nil } + +// Create will do nothing +func (holder *networkComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (holder *networkComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (holder *networkComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go new file mode 100644 index 00000000000..0a9a95d279c --- /dev/null +++ b/node/chainSimulator/components/nodeFacade.go @@ -0,0 +1,199 @@ +package components + +import ( + "errors" + "fmt" + "net" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/api/gin" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/facade" + apiComp "github.com/multiversx/mx-chain-go/factory/api" + nodePack "github.com/multiversx/mx-chain-go/node" + "github.com/multiversx/mx-chain-go/node/metrics" + "github.com/multiversx/mx-chain-go/process/mock" +) + +func (node *testOnlyProcessingNode) createFacade(configs config.Configs, enableHTTPServer bool) error { + log.Debug("creating api resolver structure") + + err := node.createMetrics(configs) + if err != nil { + return err + } + + argsGasScheduleNotifier := forking.ArgsNewGasScheduleNotifier{ + GasScheduleConfig: configs.EpochConfig.GasSchedule, + ConfigDir: configs.ConfigurationPathsHolder.GasScheduleDirectoryName, + EpochNotifier: node.CoreComponentsHolder.EpochNotifier(), + WasmVMChangeLocker: node.CoreComponentsHolder.WasmVMChangeLocker(), + } + gasScheduleNotifier, err := forking.NewGasScheduleNotifier(argsGasScheduleNotifier) + if err != nil { + return err + } + + apiResolverArgs := &apiComp.ApiResolverArgs{ + Configs: &configs, + CoreComponents: node.CoreComponentsHolder, + DataComponents: node.DataComponentsHolder, + StateComponents: node.StateComponentsHolder, + BootstrapComponents: node.BootstrapComponentsHolder, + CryptoComponents: node.CryptoComponentsHolder, + ProcessComponents: node.ProcessComponentsHolder, + StatusCoreComponents: node.StatusCoreComponents, + GasScheduleNotifier: gasScheduleNotifier, + Bootstrapper: &mock.BootstrapperStub{ + GetNodeStateCalled: func() common.NodeState { + return common.NsSynchronized + }, + }, + AllowVMQueriesChan: make(chan struct{}), + StatusComponents: node.StatusComponentsHolder, + ProcessingMode: common.GetNodeProcessingMode(configs.ImportDbConfig), + } + + apiResolver, err := apiComp.CreateApiResolver(apiResolverArgs) + if err != nil { + return err + } + + log.Debug("creating multiversx node facade") + + flagsConfig := configs.FlagsConfig + + nd, err := nodePack.NewNode( + nodePack.WithStatusCoreComponents(node.StatusCoreComponents), + nodePack.WithCoreComponents(node.CoreComponentsHolder), + nodePack.WithCryptoComponents(node.CryptoComponentsHolder), + nodePack.WithBootstrapComponents(node.BootstrapComponentsHolder), + nodePack.WithStateComponents(node.StateComponentsHolder), + nodePack.WithDataComponents(node.DataComponentsHolder), + nodePack.WithStatusComponents(node.StatusComponentsHolder), + nodePack.WithProcessComponents(node.ProcessComponentsHolder), + nodePack.WithNetworkComponents(node.NetworkComponentsHolder), + nodePack.WithInitialNodesPubKeys(node.CoreComponentsHolder.GenesisNodesSetup().InitialNodesPubKeys()), + nodePack.WithRoundDuration(node.CoreComponentsHolder.GenesisNodesSetup().GetRoundDuration()), + nodePack.WithConsensusGroupSize(int(node.CoreComponentsHolder.GenesisNodesSetup().GetShardConsensusGroupSize())), + nodePack.WithGenesisTime(node.CoreComponentsHolder.GenesisTime()), + nodePack.WithConsensusType(configs.GeneralConfig.Consensus.Type), + nodePack.WithRequestedItemsHandler(node.ProcessComponentsHolder.RequestedItemsHandler()), + nodePack.WithAddressSignatureSize(configs.GeneralConfig.AddressPubkeyConverter.SignatureLength), + nodePack.WithValidatorSignatureSize(configs.GeneralConfig.ValidatorPubkeyConverter.SignatureLength), + nodePack.WithPublicKeySize(configs.GeneralConfig.ValidatorPubkeyConverter.Length), + nodePack.WithNodeStopChannel(node.CoreComponentsHolder.ChanStopNodeProcess()), + nodePack.WithImportMode(configs.ImportDbConfig.IsImportDBMode), + nodePack.WithESDTNFTStorageHandler(node.ProcessComponentsHolder.ESDTDataStorageHandlerForAPI()), + ) + if err != nil { + return errors.New("error creating node: " + err.Error()) + } + + restApiInterface := facade.DefaultRestPortOff + if enableHTTPServer { + restApiInterface = fmt.Sprintf("localhost:%d", getFreePort()) + } + + argNodeFacade := facade.ArgNodeFacade{ + Node: nd, + ApiResolver: apiResolver, + RestAPIServerDebugMode: flagsConfig.EnableRestAPIServerDebugMode, + WsAntifloodConfig: configs.GeneralConfig.WebServerAntiflood, + FacadeConfig: config.FacadeConfig{ + RestApiInterface: restApiInterface, + PprofEnabled: flagsConfig.EnablePprof, + }, + ApiRoutesConfig: *configs.ApiRoutesConfig, + AccountsState: node.StateComponentsHolder.AccountsAdapter(), + PeerState: node.StateComponentsHolder.PeerAccounts(), + Blockchain: node.DataComponentsHolder.Blockchain(), + } + + ef, err := facade.NewNodeFacade(argNodeFacade) + if err != nil { + return fmt.Errorf("%w while creating NodeFacade", err) + } + + ef.SetSyncer(node.CoreComponentsHolder.SyncTimer()) + + node.facadeHandler = ef + + return nil +} + +func (node *testOnlyProcessingNode) createHttpServer(configs config.Configs) error { + httpServerArgs := gin.ArgsNewWebServer{ + Facade: node.facadeHandler, + ApiConfig: *configs.ApiRoutesConfig, + AntiFloodConfig: configs.GeneralConfig.WebServerAntiflood, + } + + httpServerWrapper, err := gin.NewGinWebServerHandler(httpServerArgs) + if err != nil { + return err + } + + err = httpServerWrapper.StartHttpServer() + if err != nil { + return err + } + + node.httpServer = httpServerWrapper + + return nil +} + +func getFreePort() int { + // Listen on port 0 to get a free port + l, err := net.Listen("tcp", "localhost:0") + if err != nil { + panic(err) + } + defer func() { + _ = l.Close() + }() + + // Get the port number that was assigned + addr := l.Addr().(*net.TCPAddr) + return addr.Port +} + +func (node *testOnlyProcessingNode) createMetrics(configs config.Configs) error { + err := metrics.InitMetrics( + node.StatusCoreComponents.AppStatusHandler(), + node.CryptoComponentsHolder.PublicKeyString(), + node.BootstrapComponentsHolder.NodeType(), + node.BootstrapComponentsHolder.ShardCoordinator(), + node.CoreComponentsHolder.GenesisNodesSetup(), + configs.FlagsConfig.Version, + configs.EconomicsConfig, + configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch, + node.CoreComponentsHolder.MinTransactionVersion(), + ) + + if err != nil { + return err + } + + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricNodeDisplayName, configs.PreferencesConfig.Preferences.NodeDisplayName) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricRedundancyLevel, fmt.Sprintf("%d", configs.PreferencesConfig.Preferences.RedundancyLevel)) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricRedundancyIsMainActive, common.MetricValueNA) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricChainId, node.CoreComponentsHolder.ChainID()) + metrics.SaveUint64Metric(node.StatusCoreComponents.AppStatusHandler(), common.MetricGasPerDataByte, node.CoreComponentsHolder.EconomicsData().GasPerDataByte()) + metrics.SaveUint64Metric(node.StatusCoreComponents.AppStatusHandler(), common.MetricMinGasPrice, node.CoreComponentsHolder.EconomicsData().MinGasPrice()) + metrics.SaveUint64Metric(node.StatusCoreComponents.AppStatusHandler(), common.MetricMinGasLimit, node.CoreComponentsHolder.EconomicsData().MinGasLimit()) + metrics.SaveUint64Metric(node.StatusCoreComponents.AppStatusHandler(), common.MetricExtraGasLimitGuardedTx, node.CoreComponentsHolder.EconomicsData().ExtraGasLimitGuardedTx()) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricRewardsTopUpGradientPoint, node.CoreComponentsHolder.EconomicsData().RewardsTopUpGradientPoint().String()) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricTopUpFactor, fmt.Sprintf("%g", node.CoreComponentsHolder.EconomicsData().RewardsTopUpFactor())) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricGasPriceModifier, fmt.Sprintf("%g", node.CoreComponentsHolder.EconomicsData().GasPriceModifier())) + metrics.SaveUint64Metric(node.StatusCoreComponents.AppStatusHandler(), common.MetricMaxGasPerTransaction, node.CoreComponentsHolder.EconomicsData().MaxGasLimitPerTx()) + if configs.PreferencesConfig.Preferences.FullArchive { + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricPeerType, core.ObserverPeer.String()) + metrics.SaveStringMetric(node.StatusCoreComponents.AppStatusHandler(), common.MetricPeerSubType, core.FullHistoryObserver.String()) + } + + return nil +} diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 0b8f8304e3b..5acfc6a1edc 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -96,7 +96,7 @@ type processComponentsHolder struct { } // CreateProcessComponentsHolder will create the process components holder -func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.ProcessComponentsHolder, error) { +func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.ProcessComponentsHandler, error) { importStartHandler, err := trigger.NewImportStartHandler(filepath.Join(args.FlagsConfig.DbDir, common.DefaultDBPath), args.FlagsConfig.Version) if err != nil { return nil, err @@ -486,3 +486,18 @@ func (p *processComponentsHolder) Close() error { func (p *processComponentsHolder) IsInterfaceNil() bool { return p == nil } + +// Create will do nothing +func (p *processComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (p *processComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (p *processComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/stateComponents.go b/node/chainSimulator/components/stateComponents.go index a942087be72..65a1a064fe7 100644 --- a/node/chainSimulator/components/stateComponents.go +++ b/node/chainSimulator/components/stateComponents.go @@ -31,7 +31,7 @@ type stateComponentsHolder struct { } // CreateStateComponents will create the state components holder -func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHolder, error) { +func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHandler, error) { stateComponentsFactory, err := factoryState.NewStateComponentsFactory(factoryState.StateComponentsFactoryArgs{ Config: args.Config, Core: args.CoreComponents, @@ -116,3 +116,18 @@ func (s *stateComponentsHolder) Close() error { func (s *stateComponentsHolder) IsInterfaceNil() bool { return s == nil } + +// Create will do nothing +func (s *stateComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (s *stateComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (s *stateComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index be75d124845..1ca7b5a818d 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/outport" + "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/testscommon" ) @@ -20,7 +21,7 @@ type statusComponentsHolder struct { } // CreateStatusComponentsHolder will create a new instance of status components holder -func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHolder, error) { +func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHandler, error) { var err error instance := &statusComponentsHolder{ closeHandler: NewCloseHandler(), @@ -70,3 +71,29 @@ func (s *statusComponentsHolder) Close() error { func (s *statusComponentsHolder) IsInterfaceNil() bool { return s == nil } + +// Create will do nothing +func (s *statusComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (s *statusComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (s *statusComponentsHolder) String() string { + return "" +} + +// SetForkDetector will do nothing +func (s *statusComponentsHolder) SetForkDetector(_ process.ForkDetector) error { + return nil +} + +// StartPolling will do nothing +func (s *statusComponentsHolder) StartPolling() error { + // todo check if this method + return nil +} diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index c890d68c2c5..33259d3b39d 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -2,15 +2,10 @@ package components import ( "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-go/cmd/termui/presenter" - "github.com/multiversx/mx-chain-go/common/statistics" - "github.com/multiversx/mx-chain-go/common/statistics/machine" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/factory/statusCore" "github.com/multiversx/mx-chain-go/node/external" - "github.com/multiversx/mx-chain-go/statusHandler" - "github.com/multiversx/mx-chain-go/statusHandler/persister" - statisticsTrie "github.com/multiversx/mx-chain-go/trie/statistics" ) type statusCoreComponentsHolder struct { @@ -24,25 +19,41 @@ type statusCoreComponentsHolder struct { } // CreateStatusCoreComponentsHolder will create a new instance of factory.StatusCoreComponentsHolder -func CreateStatusCoreComponentsHolder(cfg config.Config, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHolder, error) { +func CreateStatusCoreComponentsHolder(configs config.Configs, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHandler, error) { var err error - instance := &statusCoreComponentsHolder{ - closeHandler: NewCloseHandler(), - networkStatisticsProvider: machine.NewNetStatistics(), - trieSyncStatisticsProvider: statisticsTrie.NewTrieSyncStatistics(), - statusHandler: presenter.NewPresenterStatusHandler(), - statusMetrics: statusHandler.NewStatusMetrics(), + + statusCoreComponentsFactory, err := statusCore.NewStatusCoreComponentsFactory(statusCore.StatusCoreComponentsFactoryArgs{ + Config: *configs.GeneralConfig, + EpochConfig: *configs.EpochConfig, + RoundConfig: *configs.RoundConfig, + RatingsConfig: *configs.RatingsConfig, + EconomicsConfig: *configs.EconomicsConfig, + CoreComp: coreComponents, + }) + if err != nil { + return nil, err } - instance.resourceMonitor, err = statistics.NewResourceMonitor(cfg, instance.networkStatisticsProvider) + managedStatusCoreComponents, err := statusCore.NewManagedStatusCoreComponents(statusCoreComponentsFactory) if err != nil { return nil, err } - instance.persistentStatusHandler, err = persister.NewPersistentStatusHandler(coreComponents.InternalMarshalizer(), coreComponents.Uint64ByteSliceConverter()) + + err = managedStatusCoreComponents.Create() if err != nil { return nil, err } + instance := &statusCoreComponentsHolder{ + closeHandler: NewCloseHandler(), + resourceMonitor: managedStatusCoreComponents.ResourceMonitor(), + networkStatisticsProvider: managedStatusCoreComponents.NetworkStatistics(), + trieSyncStatisticsProvider: managedStatusCoreComponents.TrieSyncStatistics(), + statusHandler: managedStatusCoreComponents.AppStatusHandler(), + statusMetrics: managedStatusCoreComponents.StatusMetrics(), + persistentStatusHandler: managedStatusCoreComponents.PersistentStatusHandler(), + } + instance.collectClosableComponents() return instance, nil @@ -94,3 +105,18 @@ func (s *statusCoreComponentsHolder) Close() error { func (s *statusCoreComponentsHolder) IsInterfaceNil() bool { return s == nil } + +// Create will do nothing +func (s *statusCoreComponentsHolder) Create() error { + return nil +} + +// CheckSubcomponents will do nothing +func (s *statusCoreComponentsHolder) CheckSubcomponents() error { + return nil +} + +// String will do nothing +func (s *statusCoreComponentsHolder) String() string { + return "" +} diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index ab818056269..1553da51a91 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -4,6 +4,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-go/api/shared" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos/sposFactory" @@ -22,6 +23,8 @@ import ( // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function type ArgsTestOnlyProcessingNode struct { + Configs config.Configs + // TODO remove the rest of configs because configs contains all of them Config config.Config EpochConfig config.EpochConfig EconomicsConfig config.EconomicsConfig @@ -35,6 +38,7 @@ type ArgsTestOnlyProcessingNode struct { ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler + EnableHTTPServer bool GasScheduleFilename string NumShards uint32 SkIndex int @@ -42,15 +46,15 @@ type ArgsTestOnlyProcessingNode struct { type testOnlyProcessingNode struct { closeHandler *closeHandler - CoreComponentsHolder factory.CoreComponentsHolder - StatusCoreComponents factory.StatusCoreComponentsHolder - StateComponentsHolder factory.StateComponentsHolder - StatusComponentsHolder factory.StatusComponentsHolder - CryptoComponentsHolder factory.CryptoComponentsHolder - NetworkComponentsHolder factory.NetworkComponentsHolder - BootstrapComponentsHolder factory.BootstrapComponentsHolder - ProcessComponentsHolder factory.ProcessComponentsHolder - DataComponentsHolder factory.DataComponentsHolder + CoreComponentsHolder factory.CoreComponentsHandler + StatusCoreComponents factory.StatusCoreComponentsHandler + StateComponentsHolder factory.StateComponentsHandler + StatusComponentsHolder factory.StatusComponentsHandler + CryptoComponentsHolder factory.CryptoComponentsHandler + NetworkComponentsHolder factory.NetworkComponentsHandler + BootstrapComponentsHolder factory.BootstrapComponentsHandler + ProcessComponentsHolder factory.ProcessComponentsHandler + DataComponentsHolder factory.DataComponentsHandler NodesCoordinator nodesCoordinator.NodesCoordinator ChainHandler chainData.ChainHandler @@ -59,8 +63,10 @@ type testOnlyProcessingNode struct { StoreService dataRetriever.StorageService BuiltinFunctionsCostHandler economics.BuiltInFunctionsCostHandler DataPool dataRetriever.PoolsHolder + broadcastMessenger consensus.BroadcastMessenger - broadcastMessenger consensus.BroadcastMessenger + httpServer shared.UpgradeableHttpServerHandler + facadeHandler shared.FacadeHandler } // NewTestOnlyProcessingNode creates a new instance of a node that is able to only process transactions @@ -92,7 +98,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - instance.StatusCoreComponents, err = CreateStatusCoreComponentsHolder(args.Config, instance.CoreComponentsHolder) + instance.StatusCoreComponents, err = CreateStatusCoreComponentsHolder(args.Configs, instance.CoreComponentsHolder) if err != nil { return nil, err } @@ -198,7 +204,17 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - instance.collectClosableComponents() + err = instance.createFacade(args.Configs, args.EnableHTTPServer) + if err != nil { + return nil, err + } + + err = instance.createHttpServer(args.Configs) + if err != nil { + return nil, err + } + + instance.collectClosableComponents(args.EnableHTTPServer) return instance, nil } @@ -326,7 +342,11 @@ func (node *testOnlyProcessingNode) GetStateComponents() factory.StateComponents return node.StateComponentsHolder } -func (node *testOnlyProcessingNode) collectClosableComponents() { +func (node *testOnlyProcessingNode) GetFacadeHandler() shared.FacadeHandler { + return node.facadeHandler +} + +func (node *testOnlyProcessingNode) collectClosableComponents(enableHTTPServer bool) { node.closeHandler.AddComponent(node.ProcessComponentsHolder) node.closeHandler.AddComponent(node.DataComponentsHolder) node.closeHandler.AddComponent(node.StateComponentsHolder) @@ -335,6 +355,10 @@ func (node *testOnlyProcessingNode) collectClosableComponents() { node.closeHandler.AddComponent(node.NetworkComponentsHolder) node.closeHandler.AddComponent(node.StatusCoreComponents) node.closeHandler.AddComponent(node.CoreComponentsHolder) + node.closeHandler.AddComponent(node.facadeHandler) + if enableHTTPServer { + node.closeHandler.AddComponent(node.httpServer) + } } // Close will call the Close methods on all inner components diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index 26f2ad9c61e..8f64bb53394 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -2,6 +2,7 @@ package process import ( chainData "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/api/shared" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/sharding" @@ -16,6 +17,7 @@ type NodeHandler interface { GetCryptoComponents() factory.CryptoComponentsHolder GetCoreComponents() factory.CoreComponentsHolder GetStateComponents() factory.StateComponentsHolder + GetFacadeHandler() shared.FacadeHandler Close() error IsInterfaceNil() bool } From 262b9916fb68a38bbabe00ec75c65ea6a7645eab Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 10 Nov 2023 17:11:36 +0200 Subject: [PATCH 505/958] fixes after review --- node/chainSimulator/chainSimulator.go | 33 +++---- node/chainSimulator/chainSimulator_test.go | 7 +- .../components/api/fixedAPIInterface.go | 21 ++++ .../components/api/freeAPIInterface.go | 37 ++++++++ .../components/api/noApiInterface.go | 15 +++ .../components/bootstrapComponents.go | 4 +- .../components/coreComponents.go | 4 +- .../components/cryptoComponents.go | 4 +- .../components/dataComponents.go | 4 +- node/chainSimulator/components/interface.go | 4 + .../components/networkComponents.go | 4 +- node/chainSimulator/components/nodeFacade.go | 24 +---- .../components/processComponents.go | 4 +- .../components/statusComponents.go | 4 +- .../components/statusCoreComponents.go | 4 +- .../components/testOnlyProcessingNode.go | 95 +++++++++---------- .../components/testOnlyProcessingNode_test.go | 64 ++++++++----- 17 files changed, 197 insertions(+), 135 deletions(-) create mode 100644 node/chainSimulator/components/api/fixedAPIInterface.go create mode 100644 node/chainSimulator/components/api/freeAPIInterface.go create mode 100644 node/chainSimulator/components/api/noApiInterface.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 903df22f4ff..ece0bec14a8 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -31,7 +31,7 @@ func NewChainSimulator( genesisTimestamp int64, roundDurationInMillis uint64, roundsPerEpoch core.OptionalUint64, - enableHttpServer bool, + apiInterface components.APIConfigurator, // interface ) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() @@ -43,7 +43,7 @@ func NewChainSimulator( chanStopNodeProcess: make(chan endProcess.ArgEndProcess), } - err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis, roundsPerEpoch, enableHttpServer) + err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis, roundsPerEpoch, apiInterface) if err != nil { return nil, err } @@ -58,7 +58,7 @@ func (s *simulator) createChainHandlers( genesisTimestamp int64, roundDurationInMillis uint64, roundsPerEpoch core.OptionalUint64, - enableHttpServer bool, + apiInterface components.APIConfigurator, ) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: numOfShards, @@ -78,7 +78,7 @@ func (s *simulator) createChainHandlers( } for idx := range outputConfigs.ValidatorsPrivateKeys { - node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename, enableHttpServer) + node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename, apiInterface) if errCreate != nil { return errCreate } @@ -108,25 +108,16 @@ func (s *simulator) createTestNode( configs *config.Configs, skIndex int, gasScheduleFilename string, - enableHttpServer bool, + apiInterface components.APIConfigurator, ) (process.NodeHandler, error) { args := components.ArgsTestOnlyProcessingNode{ - Configs: *configs, - Config: *configs.GeneralConfig, - EpochConfig: *configs.EpochConfig, - EconomicsConfig: *configs.EconomicsConfig, - RoundsConfig: *configs.RoundConfig, - PreferencesConfig: *configs.PreferencesConfig, - ImportDBConfig: *configs.ImportDbConfig, - ContextFlagsConfig: *configs.FlagsConfig, - SystemSCConfig: *configs.SystemSCConfig, - ConfigurationPathsHolder: *configs.ConfigurationPathsHolder, - ChanStopNodeProcess: s.chanStopNodeProcess, - SyncedBroadcastNetwork: s.syncedBroadcastNetwork, - NumShards: s.numOfShards, - GasScheduleFilename: gasScheduleFilename, - SkIndex: skIndex, - EnableHTTPServer: enableHttpServer, + Configs: *configs, + ChanStopNodeProcess: s.chanStopNodeProcess, + SyncedBroadcastNetwork: s.syncedBroadcastNetwork, + NumShards: s.numOfShards, + GasScheduleFilename: gasScheduleFilename, + SkIndex: skIndex, + APIInterface: apiInterface, } return components.NewTestOnlyProcessingNode(args) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 1df892ae08d..39a478e03b6 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -18,7 +19,7 @@ const ( func TestNewChainSimulator(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, false) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, api.NewNoApiInterface()) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -31,7 +32,7 @@ func TestNewChainSimulator(t *testing.T) { func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, false) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, api.NewNoApiInterface()) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -51,7 +52,7 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { HasValue: true, Value: 20, } - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch, false) + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch, api.NewNoApiInterface()) require.Nil(t, err) require.NotNil(t, chainSimulator) diff --git a/node/chainSimulator/components/api/fixedAPIInterface.go b/node/chainSimulator/components/api/fixedAPIInterface.go new file mode 100644 index 00000000000..2e03b3b6dd3 --- /dev/null +++ b/node/chainSimulator/components/api/fixedAPIInterface.go @@ -0,0 +1,21 @@ +package api + +import "fmt" + +type fixedPortAPIConfigurator struct { + restAPIInterface string + mapShardPort map[uint32]int +} + +// NewFixedPortAPIConfigurator will create a new instance of fixedPortAPIConfigurator +func NewFixedPortAPIConfigurator(restAPIInterface string, mapShardPort map[uint32]int) *fixedPortAPIConfigurator { + return &fixedPortAPIConfigurator{ + restAPIInterface: restAPIInterface, + mapShardPort: mapShardPort, + } +} + +// RestApiInterface will return the api interface for the provided shard +func (f *fixedPortAPIConfigurator) RestApiInterface(shardID uint32) string { + return fmt.Sprintf("%s:%d", f.restAPIInterface, f.restAPIInterface[shardID]) +} diff --git a/node/chainSimulator/components/api/freeAPIInterface.go b/node/chainSimulator/components/api/freeAPIInterface.go new file mode 100644 index 00000000000..983ce0d93ca --- /dev/null +++ b/node/chainSimulator/components/api/freeAPIInterface.go @@ -0,0 +1,37 @@ +package api + +import ( + "fmt" + "net" +) + +type freePortAPIConfigurator struct { + restAPIInterface string +} + +// NewFreePortAPIConfigurator will create a new instance of freePortAPIConfigurator +func NewFreePortAPIConfigurator(restAPIInterface string) *freePortAPIConfigurator { + return &freePortAPIConfigurator{ + restAPIInterface: restAPIInterface, + } +} + +// RestApiInterface will return the rest api interface with a free port +func (f *freePortAPIConfigurator) RestApiInterface(_ uint32) string { + return fmt.Sprintf("%s:%d", f.restAPIInterface, getFreePort()) +} + +func getFreePort() int { + // Listen on port 0 to get a free port + l, err := net.Listen("tcp", "localhost:0") + if err != nil { + panic(err) + } + defer func() { + _ = l.Close() + }() + + // Get the port number that was assigned + addr := l.Addr().(*net.TCPAddr) + return addr.Port +} diff --git a/node/chainSimulator/components/api/noApiInterface.go b/node/chainSimulator/components/api/noApiInterface.go new file mode 100644 index 00000000000..cd720c2511f --- /dev/null +++ b/node/chainSimulator/components/api/noApiInterface.go @@ -0,0 +1,15 @@ +package api + +import "github.com/multiversx/mx-chain-go/facade" + +type noAPIInterface struct{} + +// NewNoApiInterface will create a new instance of noAPIInterface +func NewNoApiInterface() *noAPIInterface { + return new(noAPIInterface) +} + +// RestApiInterface will return the value for disable api interface +func (n noAPIInterface) RestApiInterface(_ uint32) string { + return facade.DefaultRestPortOff +} diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index 179dc742ff5..95fc78784e5 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -37,8 +37,8 @@ type bootstrapComponentsHolder struct { guardedAccountHandler process.GuardedAccountHandler } -// CreateBootstrapComponentHolder will create a new instance of bootstrap components holder -func CreateBootstrapComponentHolder(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHandler, error) { +// CreateBootstrapComponents will create a new instance of bootstrap components holder +func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHandler, error) { instance := &bootstrapComponentsHolder{ closeHandler: NewCloseHandler(), } diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 84235115461..7a3798dc980 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -89,8 +89,8 @@ type ArgsCoreComponentsHolder struct { WorkingDir string } -// CreateCoreComponentsHolder will create a new instance of factory.CoreComponentsHolder -func CreateCoreComponentsHolder(args ArgsCoreComponentsHolder) (factory.CoreComponentsHandler, error) { +// CreateCoreComponents will create a new instance of factory.CoreComponentsHolder +func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponentsHandler, error) { var err error instance := &coreComponentsHolder{ closeHandler: NewCloseHandler(), diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index ae34e1b4703..b6d99811e19 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -45,8 +45,8 @@ type cryptoComponentsHolder struct { publicKeyString string } -// CreateCryptoComponentsHolder will create a new instance of cryptoComponentsHolder -func CreateCryptoComponentsHolder(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHandler, error) { +// CreateCryptoComponents will create a new instance of cryptoComponentsHolder +func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHandler, error) { instance := &cryptoComponentsHolder{} cryptoComponentsHandlerArgs := cryptoComp.CryptoComponentsFactoryArgs{ diff --git a/node/chainSimulator/components/dataComponents.go b/node/chainSimulator/components/dataComponents.go index 0158e5cc1f3..9eb8605af12 100644 --- a/node/chainSimulator/components/dataComponents.go +++ b/node/chainSimulator/components/dataComponents.go @@ -24,8 +24,8 @@ type dataComponentsHolder struct { miniBlockProvider factory.MiniBlockProvider } -// CreateDataComponentsHolder will create the data components holder -func CreateDataComponentsHolder(args ArgsDataComponentsHolder) (factory.DataComponentsHandler, error) { +// CreateDataComponents will create the data components holder +func CreateDataComponents(args ArgsDataComponentsHolder) (factory.DataComponentsHandler, error) { miniBlockStorer, err := args.StorageService.GetStorer(dataRetriever.MiniBlockUnit) if err != nil { return nil, err diff --git a/node/chainSimulator/components/interface.go b/node/chainSimulator/components/interface.go index 0da375cdf42..351025153d0 100644 --- a/node/chainSimulator/components/interface.go +++ b/node/chainSimulator/components/interface.go @@ -11,3 +11,7 @@ type SyncedBroadcastNetworkHandler interface { GetConnectedPeersOnTopic(topic string) []core.PeerID IsInterfaceNil() bool } + +type APIConfigurator interface { + RestApiInterface(shardID uint32) string +} diff --git a/node/chainSimulator/components/networkComponents.go b/node/chainSimulator/components/networkComponents.go index d7c6d6afd62..6a6bf8d346b 100644 --- a/node/chainSimulator/components/networkComponents.go +++ b/node/chainSimulator/components/networkComponents.go @@ -26,8 +26,8 @@ type networkComponentsHolder struct { fullArchivePreferredPeersHolderHandler factory.PreferredPeersHolderHandler } -// CreateNetworkComponentsHolder creates a new networkComponentsHolder instance -func CreateNetworkComponentsHolder(network SyncedBroadcastNetworkHandler) (factory.NetworkComponentsHandler, error) { +// CreateNetworkComponents creates a new networkComponentsHolder instance +func CreateNetworkComponents(network SyncedBroadcastNetworkHandler) (factory.NetworkComponentsHandler, error) { messenger, err := NewSyncedMessenger(network) if err != nil { return nil, err diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index 0a9a95d279c..a7f1b968bc7 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,7 +3,6 @@ package components import ( "errors" "fmt" - "net" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/api/gin" @@ -17,7 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/process/mock" ) -func (node *testOnlyProcessingNode) createFacade(configs config.Configs, enableHTTPServer bool) error { +func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInterface APIConfigurator) error { log.Debug("creating api resolver structure") err := node.createMetrics(configs) @@ -92,10 +91,8 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, enableH return errors.New("error creating node: " + err.Error()) } - restApiInterface := facade.DefaultRestPortOff - if enableHTTPServer { - restApiInterface = fmt.Sprintf("localhost:%d", getFreePort()) - } + shardID := node.GetShardCoordinator().SelfId() + restApiInterface := apiInterface.RestApiInterface(shardID) argNodeFacade := facade.ArgNodeFacade{ Node: nd, @@ -146,21 +143,6 @@ func (node *testOnlyProcessingNode) createHttpServer(configs config.Configs) err return nil } -func getFreePort() int { - // Listen on port 0 to get a free port - l, err := net.Listen("tcp", "localhost:0") - if err != nil { - panic(err) - } - defer func() { - _ = l.Close() - }() - - // Get the port number that was assigned - addr := l.Addr().(*net.TCPAddr) - return addr.Port -} - func (node *testOnlyProcessingNode) createMetrics(configs config.Configs) error { err := metrics.InitMetrics( node.StatusCoreComponents.AppStatusHandler(), diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 5acfc6a1edc..e5ca52ad96f 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -95,8 +95,8 @@ type processComponentsHolder struct { accountsParser genesis.AccountsParser } -// CreateProcessComponentsHolder will create the process components holder -func CreateProcessComponentsHolder(args ArgsProcessComponentsHolder) (factory.ProcessComponentsHandler, error) { +// CreateProcessComponents will create the process components holder +func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessComponentsHandler, error) { importStartHandler, err := trigger.NewImportStartHandler(filepath.Join(args.FlagsConfig.DbDir, common.DefaultDBPath), args.FlagsConfig.Version) if err != nil { return nil, err diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index 1ca7b5a818d..2ffd403e203 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -20,8 +20,8 @@ type statusComponentsHolder struct { managedPeerMonitor common.ManagedPeersMonitor } -// CreateStatusComponentsHolder will create a new instance of status components holder -func CreateStatusComponentsHolder(shardID uint32) (factory.StatusComponentsHandler, error) { +// CreateStatusComponents will create a new instance of status components holder +func CreateStatusComponents(shardID uint32) (factory.StatusComponentsHandler, error) { var err error instance := &statusComponentsHolder{ closeHandler: NewCloseHandler(), diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 33259d3b39d..88879f2c925 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -18,8 +18,8 @@ type statusCoreComponentsHolder struct { persistentStatusHandler factory.PersistentStatusHandler } -// CreateStatusCoreComponentsHolder will create a new instance of factory.StatusCoreComponentsHolder -func CreateStatusCoreComponentsHolder(configs config.Configs, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHandler, error) { +// CreateStatusCoreComponents will create a new instance of factory.StatusCoreComponentsHolder +func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHandler, error) { var err error statusCoreComponentsFactory, err := statusCore.NewStatusCoreComponentsFactory(statusCore.StatusCoreComponentsFactoryArgs{ diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 1553da51a91..305d95693f0 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" dataRetrieverFactory "github.com/multiversx/mx-chain-go/dataRetriever/factory" + "github.com/multiversx/mx-chain-go/facade" "github.com/multiversx/mx-chain-go/factory" bootstrapComp "github.com/multiversx/mx-chain-go/factory/bootstrap" "github.com/multiversx/mx-chain-go/process" @@ -23,22 +24,12 @@ import ( // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function type ArgsTestOnlyProcessingNode struct { - Configs config.Configs - // TODO remove the rest of configs because configs contains all of them - Config config.Config - EpochConfig config.EpochConfig - EconomicsConfig config.EconomicsConfig - RoundsConfig config.RoundConfig - PreferencesConfig config.Preferences - ImportDBConfig config.ImportDbConfig - ContextFlagsConfig config.ContextFlagsConfig - SystemSCConfig config.SystemSmartContractsConfig - ConfigurationPathsHolder config.ConfigurationPathsHolder + Configs config.Configs + APIInterface APIConfigurator ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler - EnableHTTPServer bool GasScheduleFilename string NumShards uint32 SkIndex int @@ -83,60 +74,60 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - instance.CoreComponentsHolder, err = CreateCoreComponentsHolder(ArgsCoreComponentsHolder{ - Config: args.Config, - EnableEpochsConfig: args.EpochConfig.EnableEpochs, - RoundsConfig: args.RoundsConfig, - EconomicsConfig: args.EconomicsConfig, + instance.CoreComponentsHolder, err = CreateCoreComponents(ArgsCoreComponentsHolder{ + Config: *args.Configs.GeneralConfig, + EnableEpochsConfig: args.Configs.EpochConfig.EnableEpochs, + RoundsConfig: *args.Configs.RoundConfig, + EconomicsConfig: *args.Configs.EconomicsConfig, ChanStopNodeProcess: args.ChanStopNodeProcess, NumShards: args.NumShards, - WorkingDir: args.ContextFlagsConfig.WorkingDir, + WorkingDir: args.Configs.FlagsConfig.WorkingDir, GasScheduleFilename: args.GasScheduleFilename, - NodesSetupPath: args.ConfigurationPathsHolder.Nodes, + NodesSetupPath: args.Configs.ConfigurationPathsHolder.Nodes, }) if err != nil { return nil, err } - instance.StatusCoreComponents, err = CreateStatusCoreComponentsHolder(args.Configs, instance.CoreComponentsHolder) + instance.StatusCoreComponents, err = CreateStatusCoreComponents(args.Configs, instance.CoreComponentsHolder) if err != nil { return nil, err } - instance.CryptoComponentsHolder, err = CreateCryptoComponentsHolder(ArgsCryptoComponentsHolder{ - Config: args.Config, - EnableEpochsConfig: args.EpochConfig.EnableEpochs, - Preferences: args.PreferencesConfig, + instance.CryptoComponentsHolder, err = CreateCryptoComponents(ArgsCryptoComponentsHolder{ + Config: *args.Configs.GeneralConfig, + EnableEpochsConfig: args.Configs.EpochConfig.EnableEpochs, + Preferences: *args.Configs.PreferencesConfig, CoreComponentsHolder: instance.CoreComponentsHolder, - ValidatorKeyPemFileName: args.ConfigurationPathsHolder.ValidatorKey, + ValidatorKeyPemFileName: args.Configs.ConfigurationPathsHolder.ValidatorKey, SkIndex: args.SkIndex, }) if err != nil { return nil, err } - instance.NetworkComponentsHolder, err = CreateNetworkComponentsHolder(args.SyncedBroadcastNetwork) + instance.NetworkComponentsHolder, err = CreateNetworkComponents(args.SyncedBroadcastNetwork) if err != nil { return nil, err } - instance.BootstrapComponentsHolder, err = CreateBootstrapComponentHolder(ArgsBootstrapComponentsHolder{ + instance.BootstrapComponentsHolder, err = CreateBootstrapComponents(ArgsBootstrapComponentsHolder{ CoreComponents: instance.CoreComponentsHolder, CryptoComponents: instance.CryptoComponentsHolder, NetworkComponents: instance.NetworkComponentsHolder, StatusCoreComponents: instance.StatusCoreComponents, - WorkingDir: args.ContextFlagsConfig.WorkingDir, - FlagsConfig: args.ContextFlagsConfig, - ImportDBConfig: args.ImportDBConfig, - PrefsConfig: args.PreferencesConfig, - Config: args.Config, + WorkingDir: args.Configs.FlagsConfig.WorkingDir, + FlagsConfig: *args.Configs.FlagsConfig, + ImportDBConfig: *args.Configs.ImportDbConfig, + PrefsConfig: *args.Configs.PreferencesConfig, + Config: *args.Configs.GeneralConfig, }) if err != nil { return nil, err } selfShardID := instance.GetShardCoordinator().SelfId() - instance.StatusComponentsHolder, err = CreateStatusComponentsHolder(selfShardID) + instance.StatusComponentsHolder, err = CreateStatusComponents(selfShardID) if err != nil { return nil, err } @@ -147,7 +138,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } instance.StateComponentsHolder, err = CreateStateComponents(ArgsStateComponents{ - Config: args.Config, + Config: *args.Configs.GeneralConfig, CoreComponents: instance.CoreComponentsHolder, StatusCore: instance.StatusCoreComponents, StoreService: instance.StoreService, @@ -161,12 +152,12 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces if err != nil { return nil, err } - err = instance.createNodesCoordinator(args.PreferencesConfig.Preferences, args.Config) + err = instance.createNodesCoordinator(args.Configs.PreferencesConfig.Preferences, *args.Configs.GeneralConfig) if err != nil { return nil, err } - instance.DataComponentsHolder, err = CreateDataComponentsHolder(ArgsDataComponentsHolder{ + instance.DataComponentsHolder, err = CreateDataComponents(ArgsDataComponentsHolder{ Chain: instance.ChainHandler, StorageService: instance.StoreService, DataPool: instance.DataPool, @@ -176,7 +167,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - instance.ProcessComponentsHolder, err = CreateProcessComponentsHolder(ArgsProcessComponentsHolder{ + instance.ProcessComponentsHolder, err = CreateProcessComponents(ArgsProcessComponentsHolder{ CoreComponents: instance.CoreComponentsHolder, CryptoComponents: instance.CryptoComponentsHolder, NetworkComponents: instance.NetworkComponentsHolder, @@ -184,14 +175,14 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces StateComponents: instance.StateComponentsHolder, StatusComponents: instance.StatusComponentsHolder, StatusCoreComponents: instance.StatusCoreComponents, - FlagsConfig: args.ContextFlagsConfig, - ImportDBConfig: args.ImportDBConfig, - PrefsConfig: args.PreferencesConfig, - Config: args.Config, - EconomicsConfig: args.EconomicsConfig, - SystemSCConfig: args.SystemSCConfig, - EpochConfig: args.EpochConfig, - ConfigurationPathsHolder: args.ConfigurationPathsHolder, + FlagsConfig: *args.Configs.FlagsConfig, + ImportDBConfig: *args.Configs.ImportDbConfig, + PrefsConfig: *args.Configs.PreferencesConfig, + Config: *args.Configs.GeneralConfig, + EconomicsConfig: *args.Configs.EconomicsConfig, + SystemSCConfig: *args.Configs.SystemSCConfig, + EpochConfig: *args.Configs.EpochConfig, + ConfigurationPathsHolder: *args.Configs.ConfigurationPathsHolder, NodesCoordinator: instance.NodesCoordinator, DataComponents: instance.DataComponentsHolder, }) @@ -204,7 +195,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - err = instance.createFacade(args.Configs, args.EnableHTTPServer) + err = instance.createFacade(args.Configs, args.APIInterface) if err != nil { return nil, err } @@ -214,7 +205,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - instance.collectClosableComponents(args.EnableHTTPServer) + instance.collectClosableComponents(args.APIInterface) return instance, nil } @@ -234,7 +225,7 @@ func (node *testOnlyProcessingNode) createDataPool(args ArgsTestOnlyProcessingNo var err error argsDataPool := dataRetrieverFactory.ArgsDataPool{ - Config: &args.Config, + Config: args.Configs.GeneralConfig, EconomicsData: node.CoreComponentsHolder.EconomicsData(), ShardCoordinator: node.BootstrapComponentsHolder.ShardCoordinator(), Marshalizer: node.CoreComponentsHolder.InternalMarshalizer(), @@ -342,11 +333,12 @@ func (node *testOnlyProcessingNode) GetStateComponents() factory.StateComponents return node.StateComponentsHolder } +// GetFacadeHandler will return the facade handler func (node *testOnlyProcessingNode) GetFacadeHandler() shared.FacadeHandler { return node.facadeHandler } -func (node *testOnlyProcessingNode) collectClosableComponents(enableHTTPServer bool) { +func (node *testOnlyProcessingNode) collectClosableComponents(apiInterface APIConfigurator) { node.closeHandler.AddComponent(node.ProcessComponentsHolder) node.closeHandler.AddComponent(node.DataComponentsHolder) node.closeHandler.AddComponent(node.StateComponentsHolder) @@ -356,7 +348,10 @@ func (node *testOnlyProcessingNode) collectClosableComponents(enableHTTPServer b node.closeHandler.AddComponent(node.StatusCoreComponents) node.closeHandler.AddComponent(node.CoreComponentsHolder) node.closeHandler.AddComponent(node.facadeHandler) - if enableHTTPServer { + + // TODO remove this after http server fix + shardID := node.GetShardCoordinator().SelfId() + if facade.DefaultRestPortOff != apiInterface.RestApiInterface(shardID) { node.closeHandler.AddComponent(node.httpServer) } } diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index a380bc20778..f94a0a1135a 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -50,35 +51,50 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo err = core.LoadTomlFile(&epochConfig, pathToConfigFolder+"enableEpochs.toml") assert.Nil(t, err) + ratingConfig := config.RatingsConfig{} + err = core.LoadTomlFile(&ratingConfig, pathToConfigFolder+"ratings.toml") + assert.Nil(t, err) + + apiConfig := config.ApiRoutesConfig{} + err = core.LoadTomlFile(&apiConfig, pathToConfigFolder+"api.toml") + assert.Nil(t, err) + return ArgsTestOnlyProcessingNode{ - Config: mainConfig, - EpochConfig: epochConfig, - RoundsConfig: config.RoundConfig{ - RoundActivations: map[string]config.ActivationRoundByName{ - "DisableAsyncCallV1": { - Round: "18446744073709551614", + Configs: config.Configs{ + GeneralConfig: &mainConfig, + EpochConfig: &epochConfig, + RoundConfig: &config.RoundConfig{ + RoundActivations: map[string]config.ActivationRoundByName{ + "DisableAsyncCallV1": { + Round: "18446744073709551614", + }, }, }, + EconomicsConfig: &economicsConfig, + PreferencesConfig: &prefsConfig, + ImportDbConfig: &config.ImportDbConfig{}, + FlagsConfig: &config.ContextFlagsConfig{ + WorkingDir: workingDir, + Version: "1", + }, + ConfigurationPathsHolder: &config.ConfigurationPathsHolder{ + GasScheduleDirectoryName: pathToConfigFolder + "gasSchedules", + Genesis: pathToConfigFolder + "genesis.json", + SmartContracts: pathTestData + "genesisSmartContracts.json", + Nodes: nodesSetupConfig, + ValidatorKey: validatorPemFile, + }, + SystemSCConfig: &systemSCConfig, + RatingsConfig: &ratingConfig, + ApiRoutesConfig: &apiConfig, }, - EconomicsConfig: economicsConfig, - GasScheduleFilename: gasScheduleName, - NumShards: 3, - PreferencesConfig: prefsConfig, + + GasScheduleFilename: gasScheduleName, + NumShards: 3, + SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), - ImportDBConfig: config.ImportDbConfig{}, - ContextFlagsConfig: config.ContextFlagsConfig{ - WorkingDir: workingDir, - Version: "1", - }, - ConfigurationPathsHolder: config.ConfigurationPathsHolder{ - GasScheduleDirectoryName: pathToConfigFolder + "gasSchedules", - Genesis: pathToConfigFolder + "genesis.json", - SmartContracts: pathTestData + "genesisSmartContracts.json", - Nodes: nodesSetupConfig, - ValidatorKey: validatorPemFile, - }, - SystemSCConfig: systemSCConfig, - ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), + ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), + APIInterface: api.NewNoApiInterface(), } } From 86a3e17bfc541b7c3032f3652b1e4ea6f46264e1 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 13 Nov 2023 09:51:15 +0200 Subject: [PATCH 506/958] fixes after re review --- node/chainSimulator/chainSimulator.go | 2 +- node/chainSimulator/components/interface.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index ece0bec14a8..06ea0b94995 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -31,7 +31,7 @@ func NewChainSimulator( genesisTimestamp int64, roundDurationInMillis uint64, roundsPerEpoch core.OptionalUint64, - apiInterface components.APIConfigurator, // interface + apiInterface components.APIConfigurator, ) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() diff --git a/node/chainSimulator/components/interface.go b/node/chainSimulator/components/interface.go index 351025153d0..4b1421341a0 100644 --- a/node/chainSimulator/components/interface.go +++ b/node/chainSimulator/components/interface.go @@ -12,6 +12,7 @@ type SyncedBroadcastNetworkHandler interface { IsInterfaceNil() bool } +// APIConfigurator defines what an api configurator should be able to do type APIConfigurator interface { RestApiInterface(shardID uint32) string } From ce9718a5188e73edd34de97665ac9f861b7416dc Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 13 Nov 2023 10:06:05 +0200 Subject: [PATCH 507/958] turn off resource monitor --- node/chainSimulator/components/statusCoreComponents.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 88879f2c925..3eda0cb99fd 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -44,6 +44,9 @@ func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.C return nil, err } + // stop resource monitor + _ = managedStatusCoreComponents.ResourceMonitor().Close() + instance := &statusCoreComponentsHolder{ closeHandler: NewCloseHandler(), resourceMonitor: managedStatusCoreComponents.ResourceMonitor(), From c71f3fc323f47a5dd981ad9182aac0616a9426da Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 13 Nov 2023 13:03:18 +0200 Subject: [PATCH 508/958] expose private --- node/chainSimulator/testdata/addresses.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/testdata/addresses.go b/node/chainSimulator/testdata/addresses.go index 6e245d919b9..c6d267b111e 100644 --- a/node/chainSimulator/testdata/addresses.go +++ b/node/chainSimulator/testdata/addresses.go @@ -9,5 +9,6 @@ const ( // GenesisAddressWithBalance holds the initial address that has balance GenesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" - //GenesisAddressWithBalanceSK = "ad1136a125fd3f1cfb154159442e4bc6a3b5c3095943029958ac464da7ce13eb" + // GenesisAddressWithBalanceSK holds the secret key of the initial address + GenesisAddressWithBalanceSK = "ad1136a125fd3f1cfb154159442e4bc6a3b5c3095943029958ac464da7ce13eb" ) From 90bf06f3211ee884a51c7ba7e70470df0f1052ae Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 14 Nov 2023 14:46:15 +0200 Subject: [PATCH 509/958] fixes after second review --- node/chainSimulator/components/api/fixedAPIInterface.go | 2 +- node/chainSimulator/components/statusComponents.go | 1 - node/chainSimulator/components/statusCoreComponents.go | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/components/api/fixedAPIInterface.go b/node/chainSimulator/components/api/fixedAPIInterface.go index 2e03b3b6dd3..2848be6ad15 100644 --- a/node/chainSimulator/components/api/fixedAPIInterface.go +++ b/node/chainSimulator/components/api/fixedAPIInterface.go @@ -17,5 +17,5 @@ func NewFixedPortAPIConfigurator(restAPIInterface string, mapShardPort map[uint3 // RestApiInterface will return the api interface for the provided shard func (f *fixedPortAPIConfigurator) RestApiInterface(shardID uint32) string { - return fmt.Sprintf("%s:%d", f.restAPIInterface, f.restAPIInterface[shardID]) + return fmt.Sprintf("%s:%d", f.restAPIInterface, f.mapShardPort[shardID]) } diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index 2ffd403e203..cd9089df363 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -94,6 +94,5 @@ func (s *statusComponentsHolder) SetForkDetector(_ process.ForkDetector) error { // StartPolling will do nothing func (s *statusComponentsHolder) StartPolling() error { - // todo check if this method return nil } diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 3eda0cb99fd..27fa6a81a0c 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -18,7 +18,7 @@ type statusCoreComponentsHolder struct { persistentStatusHandler factory.PersistentStatusHandler } -// CreateStatusCoreComponents will create a new instance of factory.StatusCoreComponentsHolder +// CreateStatusCoreComponents will create a new instance of factory.StatusCoreComponentsHandler func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHandler, error) { var err error From 91e9d6c7bc10965487eb792c8c88cf9704550ef2 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 15 Nov 2023 11:41:51 +0200 Subject: [PATCH 510/958] initial wallet keys --- node/chainSimulator/chainSimulator.go | 22 ++- node/chainSimulator/chainSimulator_test.go | 6 +- .../components/testOnlyProcessingNode_test.go | 86 ++-------- node/chainSimulator/configs/configs.go | 158 ++++++++++++++---- node/chainSimulator/configs/configs_test.go | 12 +- node/chainSimulator/dtos/wallet.go | 13 ++ node/chainSimulator/testdata/addresses.go | 14 -- .../testdata/genesisSmartContracts.json | 18 -- 8 files changed, 167 insertions(+), 162 deletions(-) create mode 100644 node/chainSimulator/dtos/wallet.go delete mode 100644 node/chainSimulator/testdata/addresses.go delete mode 100644 node/chainSimulator/testdata/genesisSmartContracts.json diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 06ea0b94995..7b2f984bbeb 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -8,8 +8,8 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/node/chainSimulator/process" - "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" logger "github.com/multiversx/mx-chain-logger-go" ) @@ -19,6 +19,7 @@ type simulator struct { chanStopNodeProcess chan endProcess.ArgEndProcess syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler handlers []ChainHandler + initialWalletKeys *dtos.InitialWalletKeys nodes map[uint32]process.NodeHandler numOfShards uint32 } @@ -61,13 +62,11 @@ func (s *simulator) createChainHandlers( apiInterface components.APIConfigurator, ) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ - NumOfShards: numOfShards, - OriginalConfigsPath: originalConfigPath, - GenesisAddressWithStake: testdata.GenesisAddressWithStake, - GenesisAddressWithBalance: testdata.GenesisAddressWithBalance, - GenesisTimeStamp: genesisTimestamp, - RoundDurationInMillis: roundDurationInMillis, - TempDir: tempDir, + NumOfShards: numOfShards, + OriginalConfigsPath: originalConfigPath, + GenesisTimeStamp: genesisTimestamp, + RoundDurationInMillis: roundDurationInMillis, + TempDir: tempDir, }) if err != nil { return err @@ -93,6 +92,8 @@ func (s *simulator) createChainHandlers( s.handlers = append(s.handlers, chainHandler) } + s.initialWalletKeys = outputConfigs.InitialWallets + log.Info("running the chain simulator with the following parameters", "number of shards (including meta)", numOfShards+1, "round per epoch", outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch, @@ -167,6 +168,11 @@ func (s *simulator) GetRestAPIInterfaces() map[uint32]string { return resMap } +// GetInitialWalletKeys will return the initial wallet keys +func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { + return s.initialWalletKeys +} + // Close will stop and close the simulator func (s *simulator) Close() error { var errorStrings []string diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 39a478e03b6..5a25df93d0e 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -7,7 +7,6 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" - "github.com/multiversx/mx-chain-go/node/chainSimulator/testdata" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -59,7 +58,8 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { facade, err := NewChainSimulatorFacade(chainSimulator) require.Nil(t, err) - initialAccount, err := facade.GetExistingAccountFromBech32AddressString(testdata.GenesisAddressWithStake) + genesisAddressWithStake := chainSimulator.initialWalletKeys.InitialWalletWithStake.Address + initialAccount, err := facade.GetExistingAccountFromBech32AddressString(genesisAddressWithStake) require.Nil(t, err) time.Sleep(time.Second) @@ -67,7 +67,7 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { err = chainSimulator.GenerateBlocks(80) require.Nil(t, err) - accountAfterRewards, err := facade.GetExistingAccountFromBech32AddressString(testdata.GenesisAddressWithStake) + accountAfterRewards, err := facade.GetExistingAccountFromBech32AddressString(genesisAddressWithStake) require.Nil(t, err) assert.True(t, accountAfterRewards.GetBalance().Cmp(initialAccount.GetBalance()) > 0, diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index f94a0a1135a..3518e967122 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -4,92 +4,26 @@ import ( "testing" "time" - "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/endProcess" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -const ( - pathTestData = "../testdata/" - pathToConfigFolder = "../../../cmd/node/config/" - pathForMainConfig = "../../../cmd/node/config/config.toml" - pathForEconomicsConfig = "../../../cmd/node/config/economics.toml" - pathForGasSchedules = "../../../cmd/node/config/gasSchedules" - nodesSetupConfig = "../../../cmd/node/config/nodesSetup.json" - pathForPrefsConfig = "../../../cmd/node/config/prefs.toml" - validatorPemFile = "../../../cmd/node/config/testKeys/validatorKey.pem" - pathSystemSCConfig = "../../../cmd/node/config/systemSmartContractsConfig.toml" -) - func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { - mainConfig := config.Config{} - err := core.LoadTomlFile(&mainConfig, pathForMainConfig) - assert.Nil(t, err) - - economicsConfig := config.EconomicsConfig{} - err = core.LoadTomlFile(&economicsConfig, pathForEconomicsConfig) - assert.Nil(t, err) - - gasScheduleName, err := configs.GetLatestGasScheduleFilename(pathForGasSchedules) - assert.Nil(t, err) - - prefsConfig := config.Preferences{} - err = core.LoadTomlFile(&prefsConfig, pathForPrefsConfig) - assert.Nil(t, err) - - systemSCConfig := config.SystemSmartContractsConfig{} - err = core.LoadTomlFile(&systemSCConfig, pathSystemSCConfig) - assert.Nil(t, err) - - workingDir := t.TempDir() - - epochConfig := config.EpochConfig{} - err = core.LoadTomlFile(&epochConfig, pathToConfigFolder+"enableEpochs.toml") - assert.Nil(t, err) - - ratingConfig := config.RatingsConfig{} - err = core.LoadTomlFile(&ratingConfig, pathToConfigFolder+"ratings.toml") - assert.Nil(t, err) - - apiConfig := config.ApiRoutesConfig{} - err = core.LoadTomlFile(&apiConfig, pathToConfigFolder+"api.toml") - assert.Nil(t, err) + outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ + NumOfShards: 3, + OriginalConfigsPath: "../../../cmd/node/config/", + GenesisTimeStamp: 0, + RoundDurationInMillis: 6000, + TempDir: t.TempDir(), + }) + require.Nil(t, err) return ArgsTestOnlyProcessingNode{ - Configs: config.Configs{ - GeneralConfig: &mainConfig, - EpochConfig: &epochConfig, - RoundConfig: &config.RoundConfig{ - RoundActivations: map[string]config.ActivationRoundByName{ - "DisableAsyncCallV1": { - Round: "18446744073709551614", - }, - }, - }, - EconomicsConfig: &economicsConfig, - PreferencesConfig: &prefsConfig, - ImportDbConfig: &config.ImportDbConfig{}, - FlagsConfig: &config.ContextFlagsConfig{ - WorkingDir: workingDir, - Version: "1", - }, - ConfigurationPathsHolder: &config.ConfigurationPathsHolder{ - GasScheduleDirectoryName: pathToConfigFolder + "gasSchedules", - Genesis: pathToConfigFolder + "genesis.json", - SmartContracts: pathTestData + "genesisSmartContracts.json", - Nodes: nodesSetupConfig, - ValidatorKey: validatorPemFile, - }, - SystemSCConfig: &systemSCConfig, - RatingsConfig: &ratingConfig, - ApiRoutesConfig: &apiConfig, - }, - - GasScheduleFilename: gasScheduleName, + Configs: *outputConfigs.Configs, + GasScheduleFilename: outputConfigs.GasScheduleFilename, NumShards: 3, SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 30ab70f82c6..9ce1d89f27c 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -13,11 +13,15 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/pubkeyConverter" + shardingCore "github.com/multiversx/mx-chain-core-go/core/sharding" crypto "github.com/multiversx/mx-chain-crypto-go" "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/ed25519" "github.com/multiversx/mx-chain-crypto-go/signing/mcl" + "github.com/multiversx/mx-chain-go/common/factory" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/genesis/data" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/storage/storageunit" "github.com/multiversx/mx-chain-go/testscommon" @@ -33,13 +37,11 @@ const ( // ArgsChainSimulatorConfigs holds all the components needed to create the chain simulator configs type ArgsChainSimulatorConfigs struct { - NumOfShards uint32 - OriginalConfigsPath string - GenesisAddressWithStake string - GenesisAddressWithBalance string - GenesisTimeStamp int64 - RoundDurationInMillis uint64 - TempDir string + NumOfShards uint32 + OriginalConfigsPath string + GenesisTimeStamp int64 + RoundDurationInMillis uint64 + TempDir string } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -47,6 +49,7 @@ type ArgsConfigsSimulator struct { GasScheduleFilename string Configs *config.Configs ValidatorsPrivateKeys []crypto.PrivateKey + InitialWallets *dtos.InitialWalletKeys } // CreateChainSimulatorConfigs will create the chain simulator configs @@ -64,11 +67,17 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } + // update genesis.json + initialWallets, err := generateGenesisFile(args, configs) + if err != nil { + return nil, err + } + // generate validators key and nodesSetup.json privateKeys, publicKeys, err := generateValidatorsKeyAndUpdateFiles( configs, args.NumOfShards, - args.GenesisAddressWithStake, + initialWallets.InitialWalletWithStake.Address, args.GenesisTimeStamp, args.RoundDurationInMillis, ) @@ -76,34 +85,6 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } - // update genesis.json - addresses := make([]data.InitialAccount, 0) - stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) - stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(len(privateKeys)))) // 2500 EGLD * number of nodes - addresses = append(addresses, data.InitialAccount{ - Address: args.GenesisAddressWithStake, - StakingValue: stakedValue, - Supply: stakedValue, - }) - - initialBalance := big.NewInt(0).Set(initialSupply) - initialBalance = initialBalance.Sub(initialBalance, stakedValue) - addresses = append(addresses, data.InitialAccount{ - Address: args.GenesisAddressWithBalance, - Balance: initialBalance, - Supply: initialBalance, - }) - - addressesBytes, errM := json.Marshal(addresses) - if errM != nil { - return nil, errM - } - - err = os.WriteFile(configs.ConfigurationPathsHolder.Genesis, addressesBytes, os.ModePerm) - if err != nil { - return nil, err - } - // generate validators.pem configs.ConfigurationPathsHolder.ValidatorKey = path.Join(args.OriginalConfigsPath, "validatorKey.pem") err = generateValidatorsPem(configs.ConfigurationPathsHolder.ValidatorKey, publicKeys, privateKeys) @@ -130,9 +111,80 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi Configs: configs, ValidatorsPrivateKeys: privateKeys, GasScheduleFilename: gasScheduleName, + InitialWallets: initialWallets, }, nil } +func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { + addressConverter, err := factory.NewPubkeyConverter(configs.GeneralConfig.AddressPubkeyConverter) + if err != nil { + return nil, err + } + + initialWalletKeys := &dtos.InitialWalletKeys{ + ShardWallets: make(map[uint32]*dtos.WalletKey), + } + + initialAddressWithStake, err := generateWalletKeyForShard(0, args.NumOfShards, addressConverter) + if err != nil { + return nil, err + } + + initialWalletKeys.InitialWalletWithStake = initialAddressWithStake + + addresses := make([]data.InitialAccount, 0) + stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) + stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(args.NumOfShards)+1)) // 2500 EGLD * number of nodes + addresses = append(addresses, data.InitialAccount{ + Address: initialAddressWithStake.Address, + StakingValue: stakedValue, + Supply: stakedValue, + }) + + // generate an address for every shard + initialBalance := big.NewInt(0).Set(initialSupply) + initialBalance = initialBalance.Sub(initialBalance, stakedValue) + + walletBalance := big.NewInt(0).Set(initialBalance) + walletBalance.Div(walletBalance, big.NewInt(int64(args.NumOfShards))) + + // remainder = balance % numTotalWalletKeys + remainder := big.NewInt(0).Set(initialBalance) + remainder.Mod(remainder, big.NewInt(int64(args.NumOfShards))) + + for shardID := uint32(0); shardID < args.NumOfShards; shardID++ { + walletKey, errG := generateWalletKeyForShard(shardID, args.NumOfShards, addressConverter) + if errG != nil { + return nil, errG + } + + balanceForAddress := big.NewInt(0).Set(walletBalance) + if shardID == args.NumOfShards-1 { + balanceForAddress.Add(balanceForAddress, remainder) + } + + addresses = append(addresses, data.InitialAccount{ + Address: walletKey.Address, + Balance: balanceForAddress, + Supply: balanceForAddress, + }) + + initialWalletKeys.ShardWallets[shardID] = walletKey + } + + addressesBytes, errM := json.Marshal(addresses) + if errM != nil { + return nil, errM + } + + err = os.WriteFile(configs.ConfigurationPathsHolder.Genesis, addressesBytes, os.ModePerm) + if err != nil { + return nil, err + } + + return initialWalletKeys, nil +} + func generateValidatorsKeyAndUpdateFiles( configs *config.Configs, numOfShards uint32, @@ -262,3 +314,37 @@ func GetLatestGasScheduleFilename(directory string) (string, error) { return path.Join(directory, filename), nil } + +func generateWalletKeyForShard(shardID, numOfShards uint32, converter core.PubkeyConverter) (*dtos.WalletKey, error) { + walletSuite := ed25519.NewEd25519() + walletKeyGenerator := signing.NewKeyGenerator(walletSuite) + + for { + sk, pk := walletKeyGenerator.GeneratePair() + + pubKeyBytes, err := pk.ToByteArray() + if err != nil { + return nil, err + } + + addressShardID := shardingCore.ComputeShardID(pubKeyBytes, numOfShards) + if addressShardID != shardID { + continue + } + + privateKeyBytes, err := sk.ToByteArray() + if err != nil { + return nil, err + } + + address, err := converter.Encode(pubKeyBytes) + if err != nil { + return nil, err + } + + return &dtos.WalletKey{ + Address: address, + PrivateKeyHex: hex.EncodeToString(privateKeyBytes[:32]), + }, nil + } +} diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index 59e88a3e5a1..c086b36a4e8 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -13,13 +13,11 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { } outputConfig, err := CreateChainSimulatorConfigs(ArgsChainSimulatorConfigs{ - NumOfShards: 3, - OriginalConfigsPath: "../../../cmd/node/config", - GenesisAddressWithStake: "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7", - GenesisAddressWithBalance: "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz", - RoundDurationInMillis: 6000, - GenesisTimeStamp: 0, - TempDir: t.TempDir(), + NumOfShards: 3, + OriginalConfigsPath: "../../../cmd/node/config", + RoundDurationInMillis: 6000, + GenesisTimeStamp: 0, + TempDir: t.TempDir(), }) require.Nil(t, err) diff --git a/node/chainSimulator/dtos/wallet.go b/node/chainSimulator/dtos/wallet.go new file mode 100644 index 00000000000..a007bc8b735 --- /dev/null +++ b/node/chainSimulator/dtos/wallet.go @@ -0,0 +1,13 @@ +package dtos + +// WalletKey holds the public and the private key of a wallet bey +type WalletKey struct { + Address string `json:"address"` + PrivateKeyHex string `json:"privateKeyHex"` +} + +// InitialWalletKeys holds the initial wallet keys +type InitialWalletKeys struct { + InitialWalletWithStake *WalletKey `json:"initialWalletWithStake"` + ShardWallets map[uint32]*WalletKey `json:"shardWallets"` +} diff --git a/node/chainSimulator/testdata/addresses.go b/node/chainSimulator/testdata/addresses.go deleted file mode 100644 index c6d267b111e..00000000000 --- a/node/chainSimulator/testdata/addresses.go +++ /dev/null @@ -1,14 +0,0 @@ -package testdata - -const ( - // GenesisAddressWithStake holds the initial address that has stake - GenesisAddressWithStake = "erd10z6sdhwfy8jtuf87j5gnq7lt7fd2wfmhkg8zfzf79lrapzq265yqlnmtm7" - - //GenesisAddressWithStakeSK = "eded02473e1864616973ae20cb3b875aa3ffee55a60d948228f398e489956075" - - // GenesisAddressWithBalance holds the initial address that has balance - GenesisAddressWithBalance = "erd1rhrm20mmf2pugzxc3twlu3fa264hxeefnglsy4ads4dpccs9s3jsg6qdrz" - - // GenesisAddressWithBalanceSK holds the secret key of the initial address - GenesisAddressWithBalanceSK = "ad1136a125fd3f1cfb154159442e4bc6a3b5c3095943029958ac464da7ce13eb" -) diff --git a/node/chainSimulator/testdata/genesisSmartContracts.json b/node/chainSimulator/testdata/genesisSmartContracts.json deleted file mode 100644 index c0be11c3c0f..00000000000 --- a/node/chainSimulator/testdata/genesisSmartContracts.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "owner": "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80", - "filename": "../../../cmd/node/config/genesisContracts/delegation.wasm", - "vm-type": "0500", - "init-parameters": "%validator_sc_address%@03E8@00@030D40@030D40", - "type": "delegation", - "version": "0.4.*" - }, - { - "owner": "erd188anxz35atlef7cucszypmvx88lhz4m7a7t7lhcwt6sfphpsqlkswfhcx2", - "filename": "../../../cmd/node/config/genesisContracts/dns.wasm", - "vm-type": "0500", - "init-parameters": "056bc75e2d63100000", - "type": "dns", - "version": "0.2.*" - } -] From baf024b0de909225d7fec319a8746691229e8c9b Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 15 Nov 2023 13:28:45 +0200 Subject: [PATCH 511/958] fixes after review --- node/chainSimulator/configs/configs.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 9ce1d89f27c..a59f2d7ab0e 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -33,6 +33,8 @@ var initialSupply = big.NewInt(0).Mul(oneEgld, big.NewInt(20000000)) // 20 milli const ( // ChainID contains the chain id ChainID = "chain" + + shardIDWalletWithStake = 0 ) // ArgsChainSimulatorConfigs holds all the components needed to create the chain simulator configs @@ -125,7 +127,7 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs ShardWallets: make(map[uint32]*dtos.WalletKey), } - initialAddressWithStake, err := generateWalletKeyForShard(0, args.NumOfShards, addressConverter) + initialAddressWithStake, err := generateWalletKeyForShard(shardIDWalletWithStake, args.NumOfShards, addressConverter) if err != nil { return nil, err } @@ -158,20 +160,18 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs return nil, errG } - balanceForAddress := big.NewInt(0).Set(walletBalance) - if shardID == args.NumOfShards-1 { - balanceForAddress.Add(balanceForAddress, remainder) - } - addresses = append(addresses, data.InitialAccount{ Address: walletKey.Address, - Balance: balanceForAddress, - Supply: balanceForAddress, + Balance: big.NewInt(0).Set(walletBalance), + Supply: big.NewInt(0).Set(walletBalance), }) initialWalletKeys.ShardWallets[shardID] = walletKey } + addresses[1].Balance.Add(walletBalance, remainder) + addresses[1].Supply.Add(walletBalance, remainder) + addressesBytes, errM := json.Marshal(addresses) if errM != nil { return nil, errM From 5d3fbefc1db3a5b8f60d39a87e8cc2d2f301f280 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 15 Nov 2023 15:10:18 +0200 Subject: [PATCH 512/958] change private key --- node/chainSimulator/configs/configs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index a59f2d7ab0e..acc85ad98d8 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -344,7 +344,7 @@ func generateWalletKeyForShard(shardID, numOfShards uint32, converter core.Pubke return &dtos.WalletKey{ Address: address, - PrivateKeyHex: hex.EncodeToString(privateKeyBytes[:32]), + PrivateKeyHex: hex.EncodeToString(privateKeyBytes), }, nil } } From eb60805f7fd8d23dfe6d3568d0ae4d136e6483a0 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 16 Nov 2023 15:19:29 +0200 Subject: [PATCH 513/958] allow vm queries --- node/chainSimulator/components/nodeFacade.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index a7f1b968bc7..6ed2aca8968 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,6 +3,7 @@ package components import ( "errors" "fmt" + "time" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/api/gin" @@ -35,6 +36,12 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte return err } + allowVMQueriesChan := make(chan struct{}) + go func() { + time.Sleep(time.Second) + close(allowVMQueriesChan) + }() + apiResolverArgs := &apiComp.ApiResolverArgs{ Configs: &configs, CoreComponents: node.CoreComponentsHolder, @@ -50,7 +57,7 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte return common.NsSynchronized }, }, - AllowVMQueriesChan: make(chan struct{}), + AllowVMQueriesChan: allowVMQueriesChan, StatusComponents: node.StatusComponentsHolder, ProcessingMode: common.GetNodeProcessingMode(configs.ImportDbConfig), } From 06d1f1af8dfcae6fea52d7c7734d2c843b9b6bcc Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 16 Nov 2023 15:27:27 +0200 Subject: [PATCH 514/958] set metric for vm queries --- node/chainSimulator/components/nodeFacade.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index 6ed2aca8968..7ed67018579 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,6 +3,7 @@ package components import ( "errors" "fmt" + "strconv" "time" "github.com/multiversx/mx-chain-core-go/core" @@ -40,6 +41,7 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte go func() { time.Sleep(time.Second) close(allowVMQueriesChan) + node.StatusCoreComponents.AppStatusHandler().SetStringValue(common.MetricAreVMQueriesReady, strconv.FormatBool(true)) }() apiResolverArgs := &apiComp.ApiResolverArgs{ From ace713f34ca617055a54167e3b8a040a6bfba899 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 16 Nov 2023 15:52:19 +0200 Subject: [PATCH 515/958] set probable highest nonce --- .../components/statusComponents.go | 66 ++++++++++++++++--- .../components/testOnlyProcessingNode.go | 16 ++++- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index cd9089df363..7e2933dc39a 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -1,11 +1,16 @@ package components import ( + "context" + "fmt" "time" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/appStatusPolling" outportCfg "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/common/statistics" + "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/outport" @@ -14,17 +19,23 @@ import ( ) type statusComponentsHolder struct { - closeHandler *closeHandler - outportHandler outport.OutportHandler - softwareVersionChecker statistics.SoftwareVersionChecker - managedPeerMonitor common.ManagedPeersMonitor + closeHandler *closeHandler + outportHandler outport.OutportHandler + softwareVersionChecker statistics.SoftwareVersionChecker + managedPeerMonitor common.ManagedPeersMonitor + appStatusHandler core.AppStatusHandler + forkDetector process.ForkDetector + statusPollingIntervalSec int + cancelFunc func() } // CreateStatusComponents will create a new instance of status components holder -func CreateStatusComponents(shardID uint32) (factory.StatusComponentsHandler, error) { +func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandler, statusPollingIntervalSec int) (factory.StatusComponentsHandler, error) { var err error instance := &statusComponentsHolder{ - closeHandler: NewCloseHandler(), + closeHandler: NewCloseHandler(), + appStatusHandler: appStatusHandler, + statusPollingIntervalSec: statusPollingIntervalSec, } // TODO add drivers to index data @@ -88,11 +99,50 @@ func (s *statusComponentsHolder) String() string { } // SetForkDetector will do nothing -func (s *statusComponentsHolder) SetForkDetector(_ process.ForkDetector) error { +func (s *statusComponentsHolder) SetForkDetector(forkDetector process.ForkDetector) error { + s.forkDetector = forkDetector + return nil } -// StartPolling will do nothing +// StartPolling starts polling for the updated status func (s *statusComponentsHolder) StartPolling() error { + var ctx context.Context + ctx, s.cancelFunc = context.WithCancel(context.Background()) + + appStatusPollingHandler, err := appStatusPolling.NewAppStatusPolling( + s.appStatusHandler, + time.Duration(s.statusPollingIntervalSec)*time.Second, + log, + ) + if err != nil { + return errors.ErrStatusPollingInit + } + + err = registerPollProbableHighestNonce(appStatusPollingHandler, s.forkDetector) + if err != nil { + return err + } + + appStatusPollingHandler.Poll(ctx) + + return nil +} + +func registerPollProbableHighestNonce( + appStatusPollingHandler *appStatusPolling.AppStatusPolling, + forkDetector process.ForkDetector, +) error { + + probableHighestNonceHandlerFunc := func(appStatusHandler core.AppStatusHandler) { + probableHigherNonce := forkDetector.ProbableHighestNonce() + appStatusHandler.SetUInt64Value(common.MetricProbableHighestNonce, probableHigherNonce) + } + + err := appStatusPollingHandler.RegisterPollingFunc(probableHighestNonceHandlerFunc) + if err != nil { + return fmt.Errorf("%w, cannot register handler func for forkdetector's probable higher nonce", err) + } + return nil } diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 305d95693f0..de198b6154c 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -127,7 +127,11 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } selfShardID := instance.GetShardCoordinator().SelfId() - instance.StatusComponentsHolder, err = CreateStatusComponents(selfShardID) + instance.StatusComponentsHolder, err = CreateStatusComponents( + selfShardID, + instance.StatusCoreComponents.AppStatusHandler(), + args.Configs.GeneralConfig.GeneralSettings.StatusPollingIntervalSec, + ) if err != nil { return nil, err } @@ -190,6 +194,16 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + err = instance.StatusComponentsHolder.SetForkDetector(instance.ProcessComponentsHolder.ForkDetector()) + if err != nil { + return nil, err + } + + err = instance.StatusComponentsHolder.StartPolling() + if err != nil { + return nil, err + } + err = instance.createBroadcastMessanger() if err != nil { return nil, err From 63b4b30a963e630bc0055b963a472400c6c70934 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 16 Nov 2023 17:11:44 +0200 Subject: [PATCH 516/958] fixes after first review --- .../components/statusComponents.go | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index 7e2933dc39a..3d75f345325 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/appStatusPolling" + "github.com/multiversx/mx-chain-core-go/core/check" outportCfg "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/common/statistics" @@ -31,6 +32,10 @@ type statusComponentsHolder struct { // CreateStatusComponents will create a new instance of status components holder func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandler, statusPollingIntervalSec int) (factory.StatusComponentsHandler, error) { + if check.IfNil(appStatusHandler) { + return nil, core.ErrNilAppStatusHandler + } + var err error instance := &statusComponentsHolder{ closeHandler: NewCloseHandler(), @@ -75,6 +80,10 @@ func (s *statusComponentsHolder) collectClosableComponents() { // Close will call the Close methods on all inner components func (s *statusComponentsHolder) Close() error { + if s.cancelFunc != nil { + s.cancelFunc() + } + return s.closeHandler.Close() } @@ -98,8 +107,12 @@ func (s *statusComponentsHolder) String() string { return "" } -// SetForkDetector will do nothing +// SetForkDetector will set the fork detector func (s *statusComponentsHolder) SetForkDetector(forkDetector process.ForkDetector) error { + if check.IfNil(forkDetector) { + return process.ErrNilForkDetector + } + s.forkDetector = forkDetector return nil @@ -119,9 +132,9 @@ func (s *statusComponentsHolder) StartPolling() error { return errors.ErrStatusPollingInit } - err = registerPollProbableHighestNonce(appStatusPollingHandler, s.forkDetector) + err = appStatusPollingHandler.RegisterPollingFunc(s.probableHighestNonceHandler) if err != nil { - return err + return fmt.Errorf("%w, cannot register handler func for forkdetector's probable higher nonce", err) } appStatusPollingHandler.Poll(ctx) @@ -129,20 +142,7 @@ func (s *statusComponentsHolder) StartPolling() error { return nil } -func registerPollProbableHighestNonce( - appStatusPollingHandler *appStatusPolling.AppStatusPolling, - forkDetector process.ForkDetector, -) error { - - probableHighestNonceHandlerFunc := func(appStatusHandler core.AppStatusHandler) { - probableHigherNonce := forkDetector.ProbableHighestNonce() - appStatusHandler.SetUInt64Value(common.MetricProbableHighestNonce, probableHigherNonce) - } - - err := appStatusPollingHandler.RegisterPollingFunc(probableHighestNonceHandlerFunc) - if err != nil { - return fmt.Errorf("%w, cannot register handler func for forkdetector's probable higher nonce", err) - } - - return nil +func (s *statusComponentsHolder) probableHighestNonceHandler(appStatusHandler core.AppStatusHandler) { + probableHigherNonce := s.forkDetector.ProbableHighestNonce() + appStatusHandler.SetUInt64Value(common.MetricProbableHighestNonce, probableHigherNonce) } From daceaff53f173849e6ab514eb0d350afb9d7aa21 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 20 Nov 2023 10:51:39 +0200 Subject: [PATCH 517/958] fixes after review --- node/chainSimulator/components/statusComponents.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index 3d75f345325..9aef2ea484b 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -3,6 +3,7 @@ package components import ( "context" "fmt" + "sync" "time" "github.com/multiversx/mx-chain-core-go/core" @@ -28,6 +29,7 @@ type statusComponentsHolder struct { forkDetector process.ForkDetector statusPollingIntervalSec int cancelFunc func() + mutex sync.RWMutex } // CreateStatusComponents will create a new instance of status components holder @@ -113,13 +115,19 @@ func (s *statusComponentsHolder) SetForkDetector(forkDetector process.ForkDetect return process.ErrNilForkDetector } + s.mutex.Lock() s.forkDetector = forkDetector + s.mutex.Unlock() return nil } // StartPolling starts polling for the updated status func (s *statusComponentsHolder) StartPolling() error { + if check.IfNil(s.forkDetector) { + return process.ErrNilForkDetector + } + var ctx context.Context ctx, s.cancelFunc = context.WithCancel(context.Background()) @@ -143,6 +151,9 @@ func (s *statusComponentsHolder) StartPolling() error { } func (s *statusComponentsHolder) probableHighestNonceHandler(appStatusHandler core.AppStatusHandler) { + s.mutex.RLock() probableHigherNonce := s.forkDetector.ProbableHighestNonce() + s.mutex.RUnlock() + appStatusHandler.SetUInt64Value(common.MetricProbableHighestNonce, probableHigherNonce) } From d2cb50404b0503b74ba99c4cb6bbf117a5bb74fd Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 20 Nov 2023 14:11:11 +0200 Subject: [PATCH 518/958] set state --- node/chainSimulator/chainSimulator.go | 19 ++++++++++++++ .../components/testOnlyProcessingNode.go | 26 +++++++++++++++++++ node/chainSimulator/process/interface.go | 1 + 3 files changed, 46 insertions(+) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 7b2f984bbeb..0ebc582ca97 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,9 +1,11 @@ package chainSimulator import ( + "fmt" "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" @@ -173,6 +175,23 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { return s.initialWalletKeys } +// SetState will set the provided state for a given address +func (s *simulator) SetState(address string, state map[string][]byte) error { + addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() + addressBytes, err := addressConverter.Decode(address) + if err != nil { + return err + } + + shardID := sharding.ComputeShardID(addressBytes, s.numOfShards) + testNode, ok := s.nodes[shardID] + if !ok { + return fmt.Errorf("cannot find a test node for the computed shard id, computed shard id: %d", shardID) + } + + return testNode.SetState(addressBytes, state) +} + // Close will stop and close the simulator func (s *simulator) Close() error { var errorStrings []string diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index de198b6154c..54df25e1c74 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -1,6 +1,8 @@ package components import ( + "errors" + "github.com/multiversx/mx-chain-core-go/core" chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/endProcess" @@ -20,6 +22,7 @@ import ( "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/state" ) // ArgsTestOnlyProcessingNode represents the DTO struct for the NewTestOnlyProcessingNode constructor function @@ -370,6 +373,29 @@ func (node *testOnlyProcessingNode) collectClosableComponents(apiInterface APICo } } +// SetState will set the provided state for the given address +func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[string][]byte) error { + accountsAdapter := node.StateComponentsHolder.AccountsAdapter() + account, err := accountsAdapter.LoadAccount(address) + if err != nil { + return err + } + + userAccount, ok := account.(state.UserAccountHandler) + if !ok { + return errors.New("cannot cast AccountHandler to UserAccountHandler") + } + + for key, value := range keyValueMap { + err = userAccount.SaveKeyValue([]byte(key), value) + if err != nil { + return err + } + } + + return accountsAdapter.SaveAccount(account) +} + // Close will call the Close methods on all inner components func (node *testOnlyProcessingNode) Close() error { return node.closeHandler.Close() diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index 8f64bb53394..10c41859be9 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -18,6 +18,7 @@ type NodeHandler interface { GetCoreComponents() factory.CoreComponentsHolder GetStateComponents() factory.StateComponentsHolder GetFacadeHandler() shared.FacadeHandler + SetState(addressBytes []byte, state map[string][]byte) error Close() error IsInterfaceNil() bool } From 9d24a7c2bd135da98cce34ecd08254354525cb21 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 20 Nov 2023 14:32:39 +0200 Subject: [PATCH 519/958] remove built in function cost handler --- epochStart/metachain/systemSCs_test.go | 7 +- epochStart/mock/builtInCostHandlerStub.go | 24 --- factory/core/coreComponents.go | 29 +-- .../mock/builtInCostHandlerStub.go | 24 --- integrationTests/testProcessorNode.go | 9 +- integrationTests/vm/testInitializer.go | 12 +- integrationTests/vm/wasm/utils.go | 7 +- .../timemachine/fee/feeComputer_test.go | 3 +- .../fee/memoryFootprint/memory_test.go | 3 +- process/economics/builtInFunctionsCost.go | 177 ------------------ .../economics/builtInFunctionsCost_test.go | 80 -------- process/economics/economicsData.go | 66 ++----- process/economics/economicsData_test.go | 62 ++---- process/economics/interface.go | 8 - process/errors.go | 6 - process/mock/builtInCostHandlerStub.go | 24 --- testscommon/builtInCostHandlerStub.go | 34 ---- 17 files changed, 52 insertions(+), 523 deletions(-) delete mode 100644 epochStart/mock/builtInCostHandlerStub.go delete mode 100644 integrationTests/mock/builtInCostHandlerStub.go delete mode 100644 process/economics/builtInFunctionsCost.go delete mode 100644 process/economics/builtInFunctionsCost_test.go delete mode 100644 process/mock/builtInCostHandlerStub.go delete mode 100644 testscommon/builtInCostHandlerStub.go diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 884878ad685..0e9104ebc0a 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -1125,10 +1125,9 @@ func createEconomicsData() process.EconomicsDataHandler { MaxGasPriceSetGuardian: "100000", }, }, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData diff --git a/epochStart/mock/builtInCostHandlerStub.go b/epochStart/mock/builtInCostHandlerStub.go deleted file mode 100644 index 4ee3b23b062..00000000000 --- a/epochStart/mock/builtInCostHandlerStub.go +++ /dev/null @@ -1,24 +0,0 @@ -package mock - -import ( - "github.com/multiversx/mx-chain-core-go/data" -) - -// BuiltInCostHandlerStub - -type BuiltInCostHandlerStub struct { -} - -// ComputeBuiltInCost - -func (b *BuiltInCostHandlerStub) ComputeBuiltInCost(_ data.TransactionWithFeeHandler) uint64 { - return 1 -} - -// IsBuiltInFuncCall - -func (b *BuiltInCostHandlerStub) IsBuiltInFuncCall(_ data.TransactionWithFeeHandler) bool { - return false -} - -// IsInterfaceNil - -func (b *BuiltInCostHandlerStub) IsInterfaceNil() bool { - return b == nil -} diff --git a/factory/core/coreComponents.go b/factory/core/coreComponents.go index f04afe47d61..5b0b993e6ca 100644 --- a/factory/core/coreComponents.go +++ b/factory/core/coreComponents.go @@ -33,7 +33,6 @@ import ( "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/rating" - "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/statusHandler" @@ -244,35 +243,15 @@ func (ccf *coreComponentsFactory) Create() (*coreComponents, error) { } wasmVMChangeLocker := &sync.RWMutex{} - gasScheduleConfigurationFolderName := ccf.configPathsHolder.GasScheduleDirectoryName - argsGasScheduleNotifier := forking.ArgsNewGasScheduleNotifier{ - GasScheduleConfig: ccf.epochConfig.GasSchedule, - ConfigDir: gasScheduleConfigurationFolderName, - EpochNotifier: epochNotifier, - WasmVMChangeLocker: wasmVMChangeLocker, - } - gasScheduleNotifier, err := forking.NewGasScheduleNotifier(argsGasScheduleNotifier) - if err != nil { - return nil, err - } - - builtInCostHandler, err := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - ArgsParser: smartContract.NewArgumentParser(), - GasSchedule: gasScheduleNotifier, - }) - if err != nil { - return nil, err - } txVersionChecker := versioning.NewTxVersionChecker(ccf.config.GeneralSettings.MinTransactionVersion) log.Trace("creating economics data components") argsNewEconomicsData := economics.ArgsNewEconomicsData{ - Economics: &ccf.economicsConfig, - EpochNotifier: epochNotifier, - EnableEpochsHandler: enableEpochsHandler, - BuiltInFunctionsCostHandler: builtInCostHandler, - TxVersionChecker: txVersionChecker, + Economics: &ccf.economicsConfig, + EpochNotifier: epochNotifier, + EnableEpochsHandler: enableEpochsHandler, + TxVersionChecker: txVersionChecker, } economicsData, err := economics.NewEconomicsData(argsNewEconomicsData) if err != nil { diff --git a/integrationTests/mock/builtInCostHandlerStub.go b/integrationTests/mock/builtInCostHandlerStub.go deleted file mode 100644 index 4ee3b23b062..00000000000 --- a/integrationTests/mock/builtInCostHandlerStub.go +++ /dev/null @@ -1,24 +0,0 @@ -package mock - -import ( - "github.com/multiversx/mx-chain-core-go/data" -) - -// BuiltInCostHandlerStub - -type BuiltInCostHandlerStub struct { -} - -// ComputeBuiltInCost - -func (b *BuiltInCostHandlerStub) ComputeBuiltInCost(_ data.TransactionWithFeeHandler) uint64 { - return 1 -} - -// IsBuiltInFuncCall - -func (b *BuiltInCostHandlerStub) IsBuiltInFuncCall(_ data.TransactionWithFeeHandler) bool { - return false -} - -// IsInterfaceNil - -func (b *BuiltInCostHandlerStub) IsInterfaceNil() bool { - return b == nil -} diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 5b59fedb896..cfb6b17ab80 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1081,11 +1081,10 @@ func (tpn *TestProcessorNode) initChainHandler() { func (tpn *TestProcessorNode) initEconomicsData(economicsConfig *config.EconomicsConfig) { tpn.EnableEpochs.PenalizedTooMuchGasEnableEpoch = 0 argsNewEconomicsData := economics.ArgsNewEconomicsData{ - Economics: economicsConfig, - EpochNotifier: tpn.EpochNotifier, - EnableEpochsHandler: tpn.EnableEpochsHandler, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + Economics: economicsConfig, + EpochNotifier: tpn.EpochNotifier, + EnableEpochsHandler: tpn.EnableEpochsHandler, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } economicsData, _ := economics.NewEconomicsData(argsNewEconomicsData) tpn.EconomicsData = economics.NewTestEconomicsData(economicsData) diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 0c9fa15b273..0a7826bcbf9 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -322,11 +322,6 @@ func createEconomicsData(enableEpochsConfig config.EnableEpochs) (process.Econom minGasLimit := strconv.FormatUint(1, 10) testProtocolSustainabilityAddress := "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp" - builtInCost, _ := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - ArgsParser: smartContract.NewArgumentParser(), - GasSchedule: mock.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 1)), - }) - realEpochNotifier := forking.NewGenericEpochNotifier() enableEpochsHandler, _ := enablers.NewEnableEpochsHandler(enableEpochsConfig, realEpochNotifier) @@ -371,10 +366,9 @@ func createEconomicsData(enableEpochsConfig config.EnableEpochs) (process.Econom MaxGasPriceSetGuardian: "2000000000", }, }, - EpochNotifier: realEpochNotifier, - EnableEpochsHandler: enableEpochsHandler, - BuiltInFunctionsCostHandler: builtInCost, - TxVersionChecker: versioning.NewTxVersionChecker(minTransactionVersion), + EpochNotifier: realEpochNotifier, + EnableEpochsHandler: enableEpochsHandler, + TxVersionChecker: versioning.NewTxVersionChecker(minTransactionVersion), } return economics.NewEconomicsData(argsNewEconomicsData) diff --git a/integrationTests/vm/wasm/utils.go b/integrationTests/vm/wasm/utils.go index e58d3e25c7b..40955c93f3f 100644 --- a/integrationTests/vm/wasm/utils.go +++ b/integrationTests/vm/wasm/utils.go @@ -247,10 +247,9 @@ func (context *TestContext) initFeeHandlers() { MaxGasPriceSetGuardian: "2000000000", }, }, - EpochNotifier: context.EpochNotifier, - EnableEpochsHandler: context.EnableEpochsHandler, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + EpochNotifier: context.EpochNotifier, + EnableEpochsHandler: context.EnableEpochsHandler, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } economicsData, _ := economics.NewEconomicsData(argsNewEconomicsData) diff --git a/node/external/timemachine/fee/feeComputer_test.go b/node/external/timemachine/fee/feeComputer_test.go index faf1996940e..46e2904d6d2 100644 --- a/node/external/timemachine/fee/feeComputer_test.go +++ b/node/external/timemachine/fee/feeComputer_test.go @@ -21,8 +21,7 @@ import ( func createEconomicsData() process.EconomicsDataHandler { economicsConfig := testscommon.GetEconomicsConfig() economicsData, _ := economics.NewEconomicsData(economics.ArgsNewEconomicsData{ - BuiltInFunctionsCostHandler: &testscommon.BuiltInCostHandlerStub{}, - Economics: &economicsConfig, + Economics: &economicsConfig, EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{ IsFlagEnabledInEpochCalled: func(flag core.EnableEpochFlag, epoch uint32) bool { if flag == common.PenalizedTooMuchGasFlag { diff --git a/node/external/timemachine/fee/memoryFootprint/memory_test.go b/node/external/timemachine/fee/memoryFootprint/memory_test.go index 2f32427e4de..a854a286ddd 100644 --- a/node/external/timemachine/fee/memoryFootprint/memory_test.go +++ b/node/external/timemachine/fee/memoryFootprint/memory_test.go @@ -30,8 +30,7 @@ func TestFeeComputer_MemoryFootprint(t *testing.T) { economicsConfig := testscommon.GetEconomicsConfig() economicsData, _ := economics.NewEconomicsData(economics.ArgsNewEconomicsData{ - BuiltInFunctionsCostHandler: &testscommon.BuiltInCostHandlerStub{}, - Economics: &economicsConfig, + Economics: &economicsConfig, EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{ IsFlagEnabledInEpochCalled: func(flag core.EnableEpochFlag, epoch uint32) bool { if flag == common.PenalizedTooMuchGasFlag { diff --git a/process/economics/builtInFunctionsCost.go b/process/economics/builtInFunctionsCost.go deleted file mode 100644 index f784b5f2332..00000000000 --- a/process/economics/builtInFunctionsCost.go +++ /dev/null @@ -1,177 +0,0 @@ -package economics - -import ( - "github.com/mitchellh/mapstructure" - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-core-go/data" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/process" -) - -// ArgsBuiltInFunctionCost holds all components that are needed to create a new instance of builtInFunctionsCost -type ArgsBuiltInFunctionCost struct { - GasSchedule core.GasScheduleNotifier - ArgsParser process.ArgumentsParser -} - -type builtInFunctionsCost struct { - gasConfig *process.GasCost - specialBuiltInFunctions map[string]struct{} - argsParser process.ArgumentsParser -} - -// NewBuiltInFunctionsCost will create a new instance of builtInFunctionsCost -func NewBuiltInFunctionsCost(args *ArgsBuiltInFunctionCost) (*builtInFunctionsCost, error) { - if args == nil { - return nil, process.ErrNilArgsBuiltInFunctionsConstHandler - } - if check.IfNil(args.ArgsParser) { - return nil, process.ErrNilArgumentParser - } - if check.IfNil(args.GasSchedule) { - return nil, process.ErrNilGasSchedule - } - - bs := &builtInFunctionsCost{ - argsParser: args.ArgsParser, - } - - bs.initSpecialBuiltInFunctionCostMap() - - var err error - bs.gasConfig, err = createGasConfig(args.GasSchedule.LatestGasSchedule()) - if err != nil { - return nil, err - } - - args.GasSchedule.RegisterNotifyHandler(bs) - - return bs, nil -} - -func (bc *builtInFunctionsCost) initSpecialBuiltInFunctionCostMap() { - bc.specialBuiltInFunctions = map[string]struct{}{ - core.BuiltInFunctionClaimDeveloperRewards: {}, - core.BuiltInFunctionChangeOwnerAddress: {}, - core.BuiltInFunctionSetUserName: {}, - core.BuiltInFunctionSaveKeyValue: {}, - core.BuiltInFunctionESDTTransfer: {}, - core.BuiltInFunctionESDTBurn: {}, - core.BuiltInFunctionESDTLocalBurn: {}, - core.BuiltInFunctionESDTLocalMint: {}, - core.BuiltInFunctionESDTNFTAddQuantity: {}, - core.BuiltInFunctionESDTNFTBurn: {}, - core.BuiltInFunctionESDTNFTCreate: {}, - } -} - -// GasScheduleChange is called when gas schedule is changed, thus all contracts must be updated -func (bc *builtInFunctionsCost) GasScheduleChange(gasSchedule map[string]map[string]uint64) { - newGasConfig, err := createGasConfig(gasSchedule) - if err != nil { - return - } - - bc.gasConfig = newGasConfig -} - -// ComputeBuiltInCost will compute built-in function cost -func (bc *builtInFunctionsCost) ComputeBuiltInCost(tx data.TransactionWithFeeHandler) uint64 { - function, arguments, err := bc.argsParser.ParseCallData(string(tx.GetData())) - if err != nil { - return 0 - } - - switch function { - case core.BuiltInFunctionClaimDeveloperRewards: - return bc.gasConfig.BuiltInCost.ClaimDeveloperRewards - case core.BuiltInFunctionChangeOwnerAddress: - return bc.gasConfig.BuiltInCost.ChangeOwnerAddress - case core.BuiltInFunctionSetUserName: - return bc.gasConfig.BuiltInCost.SaveUserName - case core.BuiltInFunctionSaveKeyValue: - return bc.gasConfig.BuiltInCost.SaveKeyValue - case core.BuiltInFunctionESDTTransfer: - return bc.gasConfig.BuiltInCost.ESDTTransfer - case core.BuiltInFunctionESDTBurn: - return bc.gasConfig.BuiltInCost.ESDTBurn - case core.BuiltInFunctionESDTLocalBurn: - return bc.gasConfig.BuiltInCost.ESDTLocalBurn - case core.BuiltInFunctionESDTLocalMint: - return bc.gasConfig.BuiltInCost.ESDTLocalMint - case core.BuiltInFunctionESDTNFTAddQuantity: - return bc.gasConfig.BuiltInCost.ESDTNFTAddQuantity - case core.BuiltInFunctionESDTNFTBurn: - return bc.gasConfig.BuiltInCost.ESDTNFTBurn - case core.BuiltInFunctionESDTNFTCreate: - costStorage := calculateLenOfArguments(arguments) * bc.gasConfig.BaseOperationCost.StorePerByte - return bc.gasConfig.BuiltInCost.ESDTNFTCreate + costStorage - case core.BuiltInFunctionSetGuardian: - return bc.gasConfig.BuiltInCost.SetGuardian - case core.BuiltInFunctionGuardAccount: - return bc.gasConfig.BuiltInCost.GuardAccount - case core.BuiltInFunctionUnGuardAccount: - return bc.gasConfig.BuiltInCost.UnGuardAccount - default: - return 0 - } -} - -func calculateLenOfArguments(arguments [][]byte) uint64 { - totalLen := uint64(0) - for _, arg := range arguments { - totalLen += uint64(len(arg)) - } - - return totalLen -} - -// IsBuiltInFuncCall will check is the provided transaction is a build in function call -func (bc *builtInFunctionsCost) IsBuiltInFuncCall(tx data.TransactionWithFeeHandler) bool { - function, arguments, err := bc.argsParser.ParseCallData(string(tx.GetData())) - if err != nil { - return false - } - - _, isSpecialBuiltIn := bc.specialBuiltInFunctions[function] - isSCCallAfter := core.IsSmartContractAddress(tx.GetRcvAddr()) && len(arguments) > core.MinLenArgumentsESDTTransfer - - return isSpecialBuiltIn && !isSCCallAfter -} - -// IsInterfaceNil returns true if underlying object is nil -func (bc *builtInFunctionsCost) IsInterfaceNil() bool { - return bc == nil -} - -func createGasConfig(gasMap map[string]map[string]uint64) (*process.GasCost, error) { - baseOps := &process.BaseOperationCost{} - err := mapstructure.Decode(gasMap[common.BaseOperationCost], baseOps) - if err != nil { - return nil, err - } - - err = check.ForZeroUintFields(*baseOps) - if err != nil { - return nil, err - } - - builtInOps := &process.BuiltInCost{} - err = mapstructure.Decode(gasMap[common.BuiltInCost], builtInOps) - if err != nil { - return nil, err - } - - err = check.ForZeroUintFields(*builtInOps) - if err != nil { - return nil, err - } - - gasCost := process.GasCost{ - BaseOperationCost: *baseOps, - BuiltInCost: *builtInOps, - } - - return &gasCost, nil -} diff --git a/process/economics/builtInFunctionsCost_test.go b/process/economics/builtInFunctionsCost_test.go deleted file mode 100644 index befcca25912..00000000000 --- a/process/economics/builtInFunctionsCost_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package economics_test - -import ( - "testing" - - "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-go/process" - "github.com/multiversx/mx-chain-go/process/economics" - "github.com/multiversx/mx-chain-go/process/mock" - "github.com/multiversx/mx-chain-go/testscommon" - "github.com/multiversx/mx-chain-go/vm/systemSmartContracts/defaults" - "github.com/stretchr/testify/require" -) - -func TestNewBuiltInFunctionsCost(t *testing.T) { - t.Parallel() - - tests := []struct { - name string - args func() *economics.ArgsBuiltInFunctionCost - exErr error - }{ - { - name: "NilArguments", - args: func() *economics.ArgsBuiltInFunctionCost { - return nil - }, - exErr: process.ErrNilArgsBuiltInFunctionsConstHandler, - }, - { - name: "NilArgumentsParser", - args: func() *economics.ArgsBuiltInFunctionCost { - return &economics.ArgsBuiltInFunctionCost{ - ArgsParser: nil, - GasSchedule: testscommon.NewGasScheduleNotifierMock(nil), - } - }, - exErr: process.ErrNilArgumentParser, - }, - { - name: "NilGasScheduleHandler", - args: func() *economics.ArgsBuiltInFunctionCost { - return &economics.ArgsBuiltInFunctionCost{ - ArgsParser: &mock.ArgumentParserMock{}, - GasSchedule: nil, - } - }, - exErr: process.ErrNilGasSchedule, - }, - { - name: "ShouldWork", - args: func() *economics.ArgsBuiltInFunctionCost { - return &economics.ArgsBuiltInFunctionCost{ - ArgsParser: &mock.ArgumentParserMock{}, - GasSchedule: testscommon.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 1)), - } - }, - exErr: nil, - }, - } - - for _, test := range tests { - _, err := economics.NewBuiltInFunctionsCost(test.args()) - require.Equal(t, test.exErr, err) - } -} - -func TestNewBuiltInFunctionsCost_GasConfig(t *testing.T) { - t.Parallel() - - args := &economics.ArgsBuiltInFunctionCost{ - ArgsParser: &mock.ArgumentParserMock{}, - GasSchedule: testscommon.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 0)), - } - - builtInCostHandler, err := economics.NewBuiltInFunctionsCost(args) - require.NotNil(t, err) - require.Nil(t, builtInCostHandler) - require.True(t, check.IfNil(builtInCostHandler)) -} diff --git a/process/economics/economicsData.go b/process/economics/economicsData.go index 60658b19bf2..5b7ce045237 100644 --- a/process/economics/economicsData.go +++ b/process/economics/economicsData.go @@ -27,31 +27,26 @@ var log = logger.GetOrCreate("process/economics") type economicsData struct { *gasConfigHandler *rewardsConfigHandler - gasPriceModifier float64 - minInflation float64 - yearSettings map[uint32]*config.YearSetting - mutYearSettings sync.RWMutex - statusHandler core.AppStatusHandler - builtInFunctionsCostHandler BuiltInFunctionsCostHandler - enableEpochsHandler common.EnableEpochsHandler - txVersionHandler process.TxVersionCheckerHandler - mut sync.RWMutex + gasPriceModifier float64 + minInflation float64 + yearSettings map[uint32]*config.YearSetting + mutYearSettings sync.RWMutex + statusHandler core.AppStatusHandler + enableEpochsHandler common.EnableEpochsHandler + txVersionHandler process.TxVersionCheckerHandler + mut sync.RWMutex } // ArgsNewEconomicsData defines the arguments needed for new economics economicsData type ArgsNewEconomicsData struct { - TxVersionChecker process.TxVersionCheckerHandler - BuiltInFunctionsCostHandler BuiltInFunctionsCostHandler - Economics *config.EconomicsConfig - EpochNotifier process.EpochNotifier - EnableEpochsHandler common.EnableEpochsHandler + TxVersionChecker process.TxVersionCheckerHandler + Economics *config.EconomicsConfig + EpochNotifier process.EpochNotifier + EnableEpochsHandler common.EnableEpochsHandler } // NewEconomicsData will create an object with information about economics parameters func NewEconomicsData(args ArgsNewEconomicsData) (*economicsData, error) { - if check.IfNil(args.BuiltInFunctionsCostHandler) { - return nil, process.ErrNilBuiltInFunctionsCostHandler - } if check.IfNil(args.TxVersionChecker) { return nil, process.ErrNilTransactionVersionChecker } @@ -75,12 +70,11 @@ func NewEconomicsData(args ArgsNewEconomicsData) (*economicsData, error) { } ed := &economicsData{ - minInflation: args.Economics.GlobalSettings.MinimumInflation, - gasPriceModifier: args.Economics.FeeSettings.GasPriceModifier, - statusHandler: statusHandler.NewNilStatusHandler(), - builtInFunctionsCostHandler: args.BuiltInFunctionsCostHandler, - enableEpochsHandler: args.EnableEpochsHandler, - txVersionHandler: args.TxVersionChecker, + minInflation: args.Economics.GlobalSettings.MinimumInflation, + gasPriceModifier: args.Economics.FeeSettings.GasPriceModifier, + statusHandler: statusHandler.NewNilStatusHandler(), + enableEpochsHandler: args.EnableEpochsHandler, + txVersionHandler: args.TxVersionChecker, } ed.yearSettings = make(map[uint32]*config.YearSetting) @@ -517,23 +511,8 @@ func (ed *economicsData) ComputeGasUsedAndFeeBasedOnRefundValue(tx data.Transact // ComputeGasUsedAndFeeBasedOnRefundValueInEpoch will compute gas used value and transaction fee using refund value from a SCR in a specific epoch func (ed *economicsData) ComputeGasUsedAndFeeBasedOnRefundValueInEpoch(tx data.TransactionWithFeeHandler, refundValue *big.Int, epoch uint32) (uint64, *big.Int) { if refundValue.Cmp(big.NewInt(0)) == 0 { - if ed.builtInFunctionsCostHandler.IsBuiltInFuncCall(tx) { - builtInCost := ed.builtInFunctionsCostHandler.ComputeBuiltInCost(tx) - computedGasLimit := ed.ComputeGasLimitInEpoch(tx, epoch) - - gasLimitWithBuiltInCost := builtInCost + computedGasLimit - txFee := ed.ComputeTxFeeBasedOnGasUsedInEpoch(tx, gasLimitWithBuiltInCost, epoch) - - gasLimitWithoutMoveBalance := tx.GetGasLimit() - computedGasLimit - // transaction will consume all the gas if sender provided too much gas - if isTooMuchGasProvided(gasLimitWithoutMoveBalance, gasLimitWithoutMoveBalance-builtInCost) { - return tx.GetGasLimit(), ed.ComputeTxFeeInEpoch(tx, epoch) - } - - return gasLimitWithBuiltInCost, txFee - } - txFee := ed.ComputeTxFeeInEpoch(tx, epoch) + return tx.GetGasLimit(), txFee } @@ -560,15 +539,6 @@ func (ed *economicsData) ComputeGasUsedAndFeeBasedOnRefundValueInEpoch(tx data.T return gasUsed, txFee } -func isTooMuchGasProvided(gasProvided uint64, gasRemained uint64) bool { - if gasProvided <= gasRemained { - return false - } - - gasUsed := gasProvided - gasRemained - return gasProvided > gasUsed*process.MaxGasFeeHigherFactorAccepted -} - // ComputeTxFeeBasedOnGasUsed will compute transaction fee func (ed *economicsData) ComputeTxFeeBasedOnGasUsed(tx data.TransactionWithFeeHandler, gasUsed uint64) *big.Int { currenEpoch := ed.enableEpochsHandler.GetCurrentEpoch() diff --git a/process/economics/economicsData_test.go b/process/economics/economicsData_test.go index 417ef1b7826..1f2c913a826 100644 --- a/process/economics/economicsData_test.go +++ b/process/economics/economicsData_test.go @@ -16,13 +16,10 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/economics" - "github.com/multiversx/mx-chain-go/process/mock" - "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" - "github.com/multiversx/mx-chain-go/vm/systemSmartContracts/defaults" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -106,13 +103,12 @@ func createArgsForEconomicsData(gasModifier float64) economics.ArgsNewEconomicsD return flag == common.GasPriceModifierFlag }, }, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } return args } -func createArgsForEconomicsDataRealFees(handler economics.BuiltInFunctionsCostHandler) economics.ArgsNewEconomicsData { +func createArgsForEconomicsDataRealFees() economics.ArgsNewEconomicsData { feeSettings := feeSettingsReal() args := economics.ArgsNewEconomicsData{ Economics: createDummyEconomicsConfig(feeSettings), @@ -122,8 +118,7 @@ func createArgsForEconomicsDataRealFees(handler economics.BuiltInFunctionsCostHa return flag == common.GasPriceModifierFlag }, }, - BuiltInFunctionsCostHandler: handler, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } return args } @@ -525,16 +520,6 @@ func TestNewEconomicsData_InvalidTopUpGradientPointShouldErr(t *testing.T) { assert.True(t, errors.Is(err, process.ErrInvalidRewardsTopUpGradientPoint)) } -func TestNewEconomicsData_NilBuiltInFunctionsCostHandlerShouldErr(t *testing.T) { - t.Parallel() - - args := createArgsForEconomicsData(1) - args.BuiltInFunctionsCostHandler = nil - - _, err := economics.NewEconomicsData(args) - assert.Equal(t, process.ErrNilBuiltInFunctionsCostHandler, err) -} - func TestNewEconomicsData_NilTxVersionCheckerShouldErr(t *testing.T) { t.Parallel() @@ -1141,7 +1126,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueZero(t *testing.T) func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueCheckGasUsedValue(t *testing.T) { t.Parallel() - economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees(&mock.BuiltInCostHandlerStub{})) + economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees()) txData := []byte("0061736d0100000001150460037f7f7e017f60027f7f017e60017e0060000002420303656e7611696e74363473746f7261676553746f7265000003656e7610696e74363473746f726167654c6f6164000103656e760b696e74363466696e6973680002030504030303030405017001010105030100020608017f01419088040b072f05066d656d6f7279020004696e6974000309696e6372656d656e7400040964656372656d656e7400050367657400060a8a01041300418088808000410742011080808080001a0b2e01017e4180888080004107418088808000410710818080800042017c22001080808080001a20001082808080000b2e01017e41808880800041074180888080004107108180808000427f7c22001080808080001a20001082808080000b160041808880800041071081808080001082808080000b0b0f01004180080b08434f554e54455200@0500@0100") tx1 := &transaction.Transaction{ GasPrice: 1000000000, @@ -1194,7 +1179,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueCheckGasUsedValue(t func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueCheck(t *testing.T) { t.Parallel() - economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees(&mock.BuiltInCostHandlerStub{})) + economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees()) txData := []byte("0061736d0100000001150460037f7f7e017f60027f7f017e60017e0060000002420303656e7611696e74363473746f7261676553746f7265000003656e7610696e74363473746f726167654c6f6164000103656e760b696e74363466696e6973680002030504030303030405017001010105030100020608017f01419088040b072f05066d656d6f7279020004696e6974000309696e6372656d656e7400040964656372656d656e7400050367657400060a8a01041300418088808000410742011080808080001a0b2e01017e4180888080004107418088808000410710818080800042017c22001080808080001a20001082808080000b2e01017e41808880800041074180888080004107108180808000427f7c22001080808080001a20001082808080000b160041808880800041071081808080001082808080000b0b0f01004180080b08434f554e54455200@0500@0100") tx := &transaction.Transaction{ GasPrice: 1000000000, @@ -1214,11 +1199,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueCheck(t *testing.T) func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltIn_ToMuchGasProvided(t *testing.T) { t.Parallel() - builtInCostHandler, _ := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - GasSchedule: testscommon.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 1)), - ArgsParser: smartContract.NewArgumentParser(), - }) - economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees(builtInCostHandler)) + economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees()) tx := &transaction.Transaction{ GasPrice: 1000000000, @@ -1236,11 +1217,6 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltIn_ToMu } func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueStakeTx(t *testing.T) { - builtInCostHandler, _ := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - GasSchedule: testscommon.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 1)), - ArgsParser: smartContract.NewArgumentParser(), - }) - txStake := &transaction.Transaction{ GasPrice: 1000000000, GasLimit: 250000000, @@ -1250,7 +1226,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueStakeTx(t *testing. expectedGasUsed := uint64(39378847) expectedFee, _ := big.NewInt(0).SetString("39378847000000000", 10) - args := createArgsForEconomicsDataRealFees(builtInCostHandler) + args := createArgsForEconomicsDataRealFees() args.EpochNotifier = forking.NewGenericEpochNotifier() args.EnableEpochsHandler, _ = enablers.NewEnableEpochsHandler(config.EnableEpochs{ PenalizedTooMuchGasEnableEpoch: 1000, @@ -1267,11 +1243,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueStakeTx(t *testing. func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltIn(t *testing.T) { t.Parallel() - builtInCostHandler, _ := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - GasSchedule: testscommon.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 1)), - ArgsParser: smartContract.NewArgumentParser(), - }) - economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees(builtInCostHandler)) + economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees()) tx := &transaction.Transaction{ GasPrice: 1000000000, @@ -1279,8 +1251,8 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltIn(t *t Data: []byte("ESDTTransfer@54474e2d383862383366@0a"), } - expectedGasUsed := uint64(104001) - expectedFee, _ := big.NewInt(0).SetString("104000010000000", 10) + expectedGasUsed := uint64(104009) + expectedFee, _ := big.NewInt(0).SetString("104000090000000", 10) refundValue, _ := big.NewInt(0).SetString("0", 10) gasUsed, fee := economicData.ComputeGasUsedAndFeeBasedOnRefundValue(tx, refundValue) @@ -1291,11 +1263,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltIn(t *t func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltInTooMuchGas(t *testing.T) { t.Parallel() - builtInCostHandler, _ := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - GasSchedule: testscommon.NewGasScheduleNotifierMock(defaults.FillGasMapInternal(map[string]map[string]uint64{}, 1)), - ArgsParser: smartContract.NewArgumentParser(), - }) - economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees(builtInCostHandler)) + economicData, _ := economics.NewEconomicsData(createArgsForEconomicsDataRealFees()) tx := &transaction.Transaction{ GasPrice: 1000000000, @@ -1315,7 +1283,7 @@ func TestEconomicsData_ComputeGasUsedAndFeeBasedOnRefundValueSpecialBuiltInTooMu func TestEconomicsData_ComputeGasLimitBasedOnBalance(t *testing.T) { t.Parallel() - args := createArgsForEconomicsDataRealFees(&mock.BuiltInCostHandlerStub{}) + args := createArgsForEconomicsDataRealFees() args.EpochNotifier = forking.NewGenericEpochNotifier() args.EnableEpochsHandler, _ = enablers.NewEnableEpochsHandler(config.EnableEpochs{ GasPriceModifierEnableEpoch: 1, @@ -1353,7 +1321,7 @@ func TestEconomicsData_ComputeGasLimitBasedOnBalance(t *testing.T) { func TestEconomicsData_MaxGasPriceSetGuardian(t *testing.T) { t.Parallel() - args := createArgsForEconomicsDataRealFees(&mock.BuiltInCostHandlerStub{}) + args := createArgsForEconomicsDataRealFees() maxGasPriceSetGuardianString := "2000000" expectedMaxGasPriceSetGuardian, err := strconv.ParseUint(maxGasPriceSetGuardianString, 10, 64) require.Nil(t, err) @@ -1369,7 +1337,7 @@ func TestEconomicsData_SetStatusHandler(t *testing.T) { t.Run("nil status handler should error", func(t *testing.T) { t.Parallel() - args := createArgsForEconomicsDataRealFees(&mock.BuiltInCostHandlerStub{}) + args := createArgsForEconomicsDataRealFees() economicData, _ := economics.NewEconomicsData(args) err := economicData.SetStatusHandler(nil) @@ -1378,7 +1346,7 @@ func TestEconomicsData_SetStatusHandler(t *testing.T) { t.Run("should work", func(t *testing.T) { t.Parallel() - args := createArgsForEconomicsDataRealFees(&mock.BuiltInCostHandlerStub{}) + args := createArgsForEconomicsDataRealFees() economicData, _ := economics.NewEconomicsData(args) err := economicData.SetStatusHandler(&statusHandler.AppStatusHandlerStub{}) diff --git a/process/economics/interface.go b/process/economics/interface.go index 766ba7563e3..41332c30eef 100644 --- a/process/economics/interface.go +++ b/process/economics/interface.go @@ -1,17 +1,9 @@ package economics import ( - "github.com/multiversx/mx-chain-core-go/data" vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) -// BuiltInFunctionsCostHandler is able to calculate the cost of a built-in function call -type BuiltInFunctionsCostHandler interface { - ComputeBuiltInCost(tx data.TransactionWithFeeHandler) uint64 - IsBuiltInFuncCall(tx data.TransactionWithFeeHandler) bool - IsInterfaceNil() bool -} - // EpochNotifier raises epoch change events type EpochNotifier interface { RegisterNotifyHandler(handler vmcommon.EpochSubscriberHandler) diff --git a/process/errors.go b/process/errors.go index 3df1eb3bcf2..016d2f9111f 100644 --- a/process/errors.go +++ b/process/errors.go @@ -981,12 +981,6 @@ var ErrMaxAccumulatedFeesExceeded = errors.New("max accumulated fees has been ex // ErrMaxDeveloperFeesExceeded signals that max developer fees has been exceeded var ErrMaxDeveloperFeesExceeded = errors.New("max developer fees has been exceeded") -// ErrNilBuiltInFunctionsCostHandler signals that a nil built-in functions cost handler has been provided -var ErrNilBuiltInFunctionsCostHandler = errors.New("nil built in functions cost handler") - -// ErrNilArgsBuiltInFunctionsConstHandler signals that a nil arguments struct for built-in functions cost handler has been provided -var ErrNilArgsBuiltInFunctionsConstHandler = errors.New("nil arguments for built in functions cost handler") - // ErrInvalidEpochStartMetaBlockConsensusPercentage signals that a small epoch start meta block consensus percentage has been provided var ErrInvalidEpochStartMetaBlockConsensusPercentage = errors.New("invalid epoch start meta block consensus percentage") diff --git a/process/mock/builtInCostHandlerStub.go b/process/mock/builtInCostHandlerStub.go deleted file mode 100644 index 4ee3b23b062..00000000000 --- a/process/mock/builtInCostHandlerStub.go +++ /dev/null @@ -1,24 +0,0 @@ -package mock - -import ( - "github.com/multiversx/mx-chain-core-go/data" -) - -// BuiltInCostHandlerStub - -type BuiltInCostHandlerStub struct { -} - -// ComputeBuiltInCost - -func (b *BuiltInCostHandlerStub) ComputeBuiltInCost(_ data.TransactionWithFeeHandler) uint64 { - return 1 -} - -// IsBuiltInFuncCall - -func (b *BuiltInCostHandlerStub) IsBuiltInFuncCall(_ data.TransactionWithFeeHandler) bool { - return false -} - -// IsInterfaceNil - -func (b *BuiltInCostHandlerStub) IsInterfaceNil() bool { - return b == nil -} diff --git a/testscommon/builtInCostHandlerStub.go b/testscommon/builtInCostHandlerStub.go deleted file mode 100644 index 046cc45ac2b..00000000000 --- a/testscommon/builtInCostHandlerStub.go +++ /dev/null @@ -1,34 +0,0 @@ -package testscommon - -import ( - "github.com/multiversx/mx-chain-core-go/data" -) - -// BuiltInCostHandlerStub - -type BuiltInCostHandlerStub struct { - ComputeBuiltInCostCalled func(tx data.TransactionWithFeeHandler) uint64 - IsBuiltInFuncCallCalled func(tx data.TransactionWithFeeHandler) bool -} - -// ComputeBuiltInCost - -func (stub *BuiltInCostHandlerStub) ComputeBuiltInCost(tx data.TransactionWithFeeHandler) uint64 { - if stub.ComputeBuiltInCostCalled != nil { - return stub.ComputeBuiltInCostCalled(tx) - } - - return 1 -} - -// IsBuiltInFuncCall - -func (stub *BuiltInCostHandlerStub) IsBuiltInFuncCall(tx data.TransactionWithFeeHandler) bool { - if stub.IsBuiltInFuncCallCalled != nil { - return stub.IsBuiltInFuncCallCalled(tx) - } - - return false -} - -// IsInterfaceNil returns true if underlying object is nil -func (stub *BuiltInCostHandlerStub) IsInterfaceNil() bool { - return stub == nil -} From e68f5d8988dfb9357235f1d9bf4965bfb5d22403 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 20 Nov 2023 15:54:49 +0200 Subject: [PATCH 520/958] remove unit test --- factory/core/coreComponents_test.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/factory/core/coreComponents_test.go b/factory/core/coreComponents_test.go index 79aba4a2532..d88a8a2284e 100644 --- a/factory/core/coreComponents_test.go +++ b/factory/core/coreComponents_test.go @@ -248,18 +248,6 @@ func TestCoreComponentsFactory_CreateCoreComponentsInvalidRoundConfigShouldErr(t require.NotNil(t, err) } -func TestCoreComponentsFactory_CreateCoreComponentsInvalidEpochConfigShouldErr(t *testing.T) { - t.Parallel() - - args := componentsMock.GetCoreArgs() - args.EpochConfig = config.EpochConfig{} - ccf, _ := coreComp.NewCoreComponentsFactory(args) - - cc, err := ccf.Create() - require.Nil(t, cc) - require.NotNil(t, err) -} - func TestCoreComponentsFactory_CreateCoreComponentsInvalidGenesisMaxNumberOfShardsShouldErr(t *testing.T) { t.Parallel() From cafe1c29057e0f57e41147d57c59f78fb21e9ab6 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 20 Nov 2023 16:07:02 +0200 Subject: [PATCH 521/958] fixes --- .../transactionAPI/gasUsedAndFeeProcessor_test.go | 9 ++++----- process/factory/metachain/vmContainerFactory_test.go | 7 +++---- process/peer/process_test.go | 7 +++---- process/smartContract/process_test.go | 3 +-- process/smartContract/processorV2/process_test.go | 3 +-- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/node/external/transactionAPI/gasUsedAndFeeProcessor_test.go b/node/external/transactionAPI/gasUsedAndFeeProcessor_test.go index 5c0ba4d4c05..99541bfef5d 100644 --- a/node/external/transactionAPI/gasUsedAndFeeProcessor_test.go +++ b/node/external/transactionAPI/gasUsedAndFeeProcessor_test.go @@ -20,11 +20,10 @@ import ( func createEconomicsData(enableEpochsHandler common.EnableEpochsHandler) process.EconomicsDataHandler { economicsConfig := testscommon.GetEconomicsConfig() economicsData, _ := economics.NewEconomicsData(economics.ArgsNewEconomicsData{ - BuiltInFunctionsCostHandler: &testscommon.BuiltInCostHandlerStub{}, - Economics: &economicsConfig, - EnableEpochsHandler: enableEpochsHandler, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, + Economics: &economicsConfig, + EnableEpochsHandler: enableEpochsHandler, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, }) return economicsData diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 41212156305..78398cd4f0f 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -296,10 +296,9 @@ func TestVmContainerFactory_Create(t *testing.T) { MaxGasPriceSetGuardian: "100000", }, }, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(), - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(), + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } economicsData, _ := economics.NewEconomicsData(argsNewEconomicsData) diff --git a/process/peer/process_test.go b/process/peer/process_test.go index daa885cff3a..8d985d7bd29 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -99,10 +99,9 @@ func createMockArguments() peer.ArgValidatorStatisticsProcessor { MaxGasPriceSetGuardian: "100000", }, }, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(), - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(), + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } economicsData, _ := economics.NewEconomicsData(argsNewEconomicsData) diff --git a/process/smartContract/process_test.go b/process/smartContract/process_test.go index 014a1751495..89227f59463 100644 --- a/process/smartContract/process_test.go +++ b/process/smartContract/process_test.go @@ -4253,8 +4253,7 @@ func createRealEconomicsDataArgs() *economics.ArgsNewEconomicsData { return flag == common.GasPriceModifierFlag }, }, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } } diff --git a/process/smartContract/processorV2/process_test.go b/process/smartContract/processorV2/process_test.go index efa09ac7b26..cd49fcf50bd 100644 --- a/process/smartContract/processorV2/process_test.go +++ b/process/smartContract/processorV2/process_test.go @@ -4161,8 +4161,7 @@ func createRealEconomicsDataArgs() *economics.ArgsNewEconomicsData { return flag == common.GasPriceModifierFlag }, }, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + TxVersionChecker: &testscommon.TxVersionCheckerStub{}, } } From 925f8eb3b7952ec6a2b0c76f63176ae7c8178ccb Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 21 Nov 2023 11:20:00 +0200 Subject: [PATCH 522/958] change interface --- node/chainSimulator/chainSimulator.go | 2 +- .../components/testOnlyProcessingNode.go | 16 +++++++++++++--- node/chainSimulator/process/interface.go | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 0ebc582ca97..6918c67e186 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -176,7 +176,7 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { } // SetState will set the provided state for a given address -func (s *simulator) SetState(address string, state map[string][]byte) error { +func (s *simulator) SetState(address string, state map[string]string) error { addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() addressBytes, err := addressConverter.Decode(address) if err != nil { diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 54df25e1c74..b5edf6e5a71 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -1,6 +1,7 @@ package components import ( + "encoding/hex" "errors" "github.com/multiversx/mx-chain-core-go/core" @@ -374,7 +375,7 @@ func (node *testOnlyProcessingNode) collectClosableComponents(apiInterface APICo } // SetState will set the provided state for the given address -func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[string][]byte) error { +func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[string]string) error { accountsAdapter := node.StateComponentsHolder.AccountsAdapter() account, err := accountsAdapter.LoadAccount(address) if err != nil { @@ -386,8 +387,17 @@ func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[str return errors.New("cannot cast AccountHandler to UserAccountHandler") } - for key, value := range keyValueMap { - err = userAccount.SaveKeyValue([]byte(key), value) + for keyHex, valueHex := range keyValueMap { + keyDecoded, errK := hex.DecodeString(keyHex) + if errK != nil { + return errK + } + valueDecoded, errV := hex.DecodeString(valueHex) + if errV != nil { + return errV + } + + err = userAccount.SaveKeyValue(keyDecoded, valueDecoded) if err != nil { return err } diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index 10c41859be9..79b0a583d98 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -18,7 +18,7 @@ type NodeHandler interface { GetCoreComponents() factory.CoreComponentsHolder GetStateComponents() factory.StateComponentsHolder GetFacadeHandler() shared.FacadeHandler - SetState(addressBytes []byte, state map[string][]byte) error + SetState(addressBytes []byte, state map[string]string) error Close() error IsInterfaceNil() bool } From 0d8d49b9408654b3fcee5ef66a8afecd9931d48a Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 21 Nov 2023 11:52:14 +0200 Subject: [PATCH 523/958] commit account --- .../components/testOnlyProcessingNode.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index b5edf6e5a71..feafe5be7df 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -403,7 +403,17 @@ func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[str } } - return accountsAdapter.SaveAccount(account) + err = accountsAdapter.SaveAccount(account) + if err != nil { + return err + } + + _, err = accountsAdapter.Commit() + if err != nil { + return err + } + + return nil } // Close will call the Close methods on all inner components From 20228b6a9adb4fdfa6b8432f715400adf4f83da4 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 21 Nov 2023 13:38:05 +0200 Subject: [PATCH 524/958] unit tests --- node/chainSimulator/chainSimulator_test.go | 30 +++++++++++++++++++ .../components/testOnlyProcessingNode.go | 5 ++-- .../components/testOnlyProcessingNode_test.go | 24 +++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 5a25df93d0e..a4f3074f180 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + coreAPI "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -78,3 +79,32 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { err = chainSimulator.Close() assert.Nil(t, err) } + +func TestChainSimulator_SetState(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch, api.NewNoApiInterface()) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + + keyValueMap := map[string]string{ + "01": "01", + "02": "02", + } + + address := "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj" + err = chainSimulator.SetState(address, keyValueMap) + require.Nil(t, err) + + err = chainSimulator.GenerateBlocks(1) + require.Nil(t, err) + + nodeHandler := chainSimulator.GetNodeHandler(0) + keyValuePairs, _, err := nodeHandler.GetFacadeHandler().GetKeyValuePairs(address, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + require.Equal(t, keyValueMap, keyValuePairs) +} diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index feafe5be7df..a0e58f1f928 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -3,6 +3,7 @@ package components import ( "encoding/hex" "errors" + "fmt" "github.com/multiversx/mx-chain-core-go/core" chainData "github.com/multiversx/mx-chain-core-go/data" @@ -390,11 +391,11 @@ func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[str for keyHex, valueHex := range keyValueMap { keyDecoded, errK := hex.DecodeString(keyHex) if errK != nil { - return errK + return fmt.Errorf("cannot decode key, error: %w", err) } valueDecoded, errV := hex.DecodeString(valueHex) if errV != nil { - return errV + return fmt.Errorf("cannot decode value, error: %w", err) } err = userAccount.SaveKeyValue(keyDecoded, valueDecoded) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 3518e967122..d23ba3b6879 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -1,6 +1,7 @@ package components import ( + "strings" "testing" "time" @@ -82,3 +83,26 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { assert.Nil(t, err) }) } + +func TestOnlyProcessingNodeSetStateShouldError(t *testing.T) { + args := createMockArgsTestOnlyProcessingNode(t) + node, err := NewTestOnlyProcessingNode(args) + require.Nil(t, err) + + address := "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj" + addressBytes, _ := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(address) + + keyValueMap := map[string]string{ + "nonHex": "01", + } + err = node.SetState(addressBytes, keyValueMap) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), "cannot decode key")) + + keyValueMap = map[string]string{ + "01": "nonHex", + } + err = node.SetState(addressBytes, keyValueMap) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), "cannot decode value")) +} From 37c34f8af887c4b3152d4eb81333a0a31602d5ed Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 22 Nov 2023 16:24:42 +0200 Subject: [PATCH 525/958] option to disable transaction signature verification --- node/chainSimulator/chainSimulator.go | 66 +++++++++---------- node/chainSimulator/chainSimulator_test.go | 44 +++++++++++-- .../components/cryptoComponents.go | 10 ++- .../components/testOnlyProcessingNode.go | 8 ++- 4 files changed, 86 insertions(+), 42 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 6918c67e186..dc4b8c63bbd 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -17,6 +17,18 @@ import ( var log = logger.GetOrCreate("chainSimulator") +// ArgsChainSimulator holds the arguments needed to create a new instance of simulator +type ArgsChainSimulator struct { + BypassTxSignatureCheck bool + TempDir string + PathToInitialConfig string + NumOfShards uint32 + GenesisTimestamp int64 + RoundDurationInMillis uint64 + RoundsPerEpoch core.OptionalUint64 + ApiInterface components.APIConfigurator +} + type simulator struct { chanStopNodeProcess chan endProcess.ArgEndProcess syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler @@ -27,26 +39,18 @@ type simulator struct { } // NewChainSimulator will create a new instance of simulator -func NewChainSimulator( - tempDir string, - numOfShards uint32, - pathToInitialConfig string, - genesisTimestamp int64, - roundDurationInMillis uint64, - roundsPerEpoch core.OptionalUint64, - apiInterface components.APIConfigurator, -) (*simulator, error) { +func NewChainSimulator(args ArgsChainSimulator) (*simulator, error) { syncedBroadcastNetwork := components.NewSyncedBroadcastNetwork() instance := &simulator{ syncedBroadcastNetwork: syncedBroadcastNetwork, nodes: make(map[uint32]process.NodeHandler), - handlers: make([]ChainHandler, 0, numOfShards+1), - numOfShards: numOfShards, + handlers: make([]ChainHandler, 0, args.NumOfShards+1), + numOfShards: args.NumOfShards, chanStopNodeProcess: make(chan endProcess.ArgEndProcess), } - err := instance.createChainHandlers(tempDir, numOfShards, pathToInitialConfig, genesisTimestamp, roundDurationInMillis, roundsPerEpoch, apiInterface) + err := instance.createChainHandlers(args) if err != nil { return nil, err } @@ -54,32 +58,24 @@ func NewChainSimulator( return instance, nil } -func (s *simulator) createChainHandlers( - tempDir string, - numOfShards uint32, - originalConfigPath string, - genesisTimestamp int64, - roundDurationInMillis uint64, - roundsPerEpoch core.OptionalUint64, - apiInterface components.APIConfigurator, -) error { +func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ - NumOfShards: numOfShards, - OriginalConfigsPath: originalConfigPath, - GenesisTimeStamp: genesisTimestamp, - RoundDurationInMillis: roundDurationInMillis, - TempDir: tempDir, + NumOfShards: args.NumOfShards, + OriginalConfigsPath: args.PathToInitialConfig, + GenesisTimeStamp: args.GenesisTimestamp, + RoundDurationInMillis: args.RoundDurationInMillis, + TempDir: args.TempDir, }) if err != nil { return err } - if roundsPerEpoch.HasValue { - outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(roundsPerEpoch.Value) + if args.RoundsPerEpoch.HasValue { + outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) } for idx := range outputConfigs.ValidatorsPrivateKeys { - node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename, apiInterface) + node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck) if errCreate != nil { return errCreate } @@ -97,12 +93,12 @@ func (s *simulator) createChainHandlers( s.initialWalletKeys = outputConfigs.InitialWallets log.Info("running the chain simulator with the following parameters", - "number of shards (including meta)", numOfShards+1, + "number of shards (including meta)", args.NumOfShards+1, "round per epoch", outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch, - "round duration", time.Millisecond*time.Duration(roundDurationInMillis), - "genesis timestamp", genesisTimestamp, - "original config path", originalConfigPath, - "temporary path", tempDir) + "round duration", time.Millisecond*time.Duration(args.RoundDurationInMillis), + "genesis timestamp", args.GenesisTimestamp, + "original config path", args.PathToInitialConfig, + "temporary path", args.TempDir) return nil } @@ -112,6 +108,7 @@ func (s *simulator) createTestNode( skIndex int, gasScheduleFilename string, apiInterface components.APIConfigurator, + bypassTxSignatureCheck bool, ) (process.NodeHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Configs: *configs, @@ -121,6 +118,7 @@ func (s *simulator) createTestNode( GasScheduleFilename: gasScheduleFilename, SkIndex: skIndex, APIInterface: apiInterface, + BypassTxSignatureCheck: bypassTxSignatureCheck, } return components.NewTestOnlyProcessingNode(args) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index a4f3074f180..70ab2043878 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -19,7 +19,16 @@ const ( func TestNewChainSimulator(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, api.NewNoApiInterface()) + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: core.OptionalUint64{}, + ApiInterface: api.NewNoApiInterface(), + }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -32,7 +41,16 @@ func TestNewChainSimulator(t *testing.T) { func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, core.OptionalUint64{}, api.NewNoApiInterface()) + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: core.OptionalUint64{}, + ApiInterface: api.NewNoApiInterface(), + }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -52,7 +70,16 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { HasValue: true, Value: 20, } - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch, api.NewNoApiInterface()) + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -87,7 +114,16 @@ func TestChainSimulator_SetState(t *testing.T) { HasValue: true, Value: 20, } - chainSimulator, err := NewChainSimulator(t.TempDir(), 3, defaultPathToInitialConfig, startTime, roundDurationInMillis, roundsPerEpoch, api.NewNoApiInterface()) + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + }) require.Nil(t, err) require.NotNil(t, chainSimulator) diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index b6d99811e19..78f44106a91 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/factory" cryptoComp "github.com/multiversx/mx-chain-go/factory/crypto" + "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/vm" ) @@ -22,6 +23,7 @@ type ArgsCryptoComponentsHolder struct { CoreComponentsHolder factory.CoreComponentsHolder ValidatorKeyPemFileName string SkIndex int + BypassTxSignatureCheck bool } type cryptoComponentsHolder struct { @@ -94,7 +96,7 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp instance.p2pPrivateKey = managedCryptoComponents.P2pPrivateKey() instance.p2pSingleSigner = managedCryptoComponents.P2pSingleSigner() instance.blockSigner = managedCryptoComponents.BlockSigner() - instance.txSingleSigner = managedCryptoComponents.TxSingleSigner() + instance.multiSignerContainer = managedCryptoComponents.MultiSignerContainer() instance.peerSignatureHandler = managedCryptoComponents.PeerSignatureHandler() instance.blockSignKeyGen = managedCryptoComponents.BlockSignKeyGen() @@ -105,6 +107,12 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp instance.managedPeersHolder = managedCryptoComponents.ManagedPeersHolder() instance.keysHandler = managedCryptoComponents.KeysHandler() + if args.BypassTxSignatureCheck { + instance.txSingleSigner = &cryptoMocks.SingleSignerStub{} + } else { + instance.txSingleSigner = managedCryptoComponents.TxSingleSigner() + } + return instance, nil } diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index a0e58f1f928..f67a1e7a004 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -35,9 +35,10 @@ type ArgsTestOnlyProcessingNode struct { ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler - GasScheduleFilename string - NumShards uint32 - SkIndex int + GasScheduleFilename string + NumShards uint32 + SkIndex int + BypassTxSignatureCheck bool } type testOnlyProcessingNode struct { @@ -106,6 +107,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces CoreComponentsHolder: instance.CoreComponentsHolder, ValidatorKeyPemFileName: args.Configs.ConfigurationPathsHolder.ValidatorKey, SkIndex: args.SkIndex, + BypassTxSignatureCheck: args.BypassTxSignatureCheck, }) if err != nil { return nil, err From 98f87764cb757bde5fbee4e5f23af312b12a4d71 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 23 Nov 2023 10:36:10 +0200 Subject: [PATCH 526/958] change signer --- node/chainSimulator/components/cryptoComponents.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 78f44106a91..0fceae60887 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -5,13 +5,13 @@ import ( "github.com/multiversx/mx-chain-core-go/core" crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-crypto-go/signing/disabled/singlesig" "github.com/multiversx/mx-chain-go/common" cryptoCommon "github.com/multiversx/mx-chain-go/common/crypto" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/factory" cryptoComp "github.com/multiversx/mx-chain-go/factory/crypto" - "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/vm" ) @@ -108,7 +108,7 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp instance.keysHandler = managedCryptoComponents.KeysHandler() if args.BypassTxSignatureCheck { - instance.txSingleSigner = &cryptoMocks.SingleSignerStub{} + instance.txSingleSigner = &singlesig.DisabledSingleSig{} } else { instance.txSingleSigner = managedCryptoComponents.TxSingleSigner() } From 9319620b523d0ff44f34a48f68db548c2d0af387 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 27 Nov 2023 14:13:27 +0200 Subject: [PATCH 527/958] mutex --- node/chainSimulator/chainSimulator.go | 12 ++++++++++++ .../components/testOnlyProcessingNode.go | 5 +++++ node/chainSimulator/process/interface.go | 1 + node/chainSimulator/process/processor.go | 3 +++ 4 files changed, 21 insertions(+) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index dc4b8c63bbd..cc47e378231 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -2,6 +2,7 @@ package chainSimulator import ( "fmt" + "sync" "time" "github.com/multiversx/mx-chain-core-go/core" @@ -36,6 +37,7 @@ type simulator struct { initialWalletKeys *dtos.InitialWalletKeys nodes map[uint32]process.NodeHandler numOfShards uint32 + mutex sync.RWMutex } // NewChainSimulator will create a new instance of simulator @@ -48,6 +50,7 @@ func NewChainSimulator(args ArgsChainSimulator) (*simulator, error) { handlers: make([]ChainHandler, 0, args.NumOfShards+1), numOfShards: args.NumOfShards, chanStopNodeProcess: make(chan endProcess.ArgEndProcess), + mutex: sync.RWMutex{}, } err := instance.createChainHandlers(args) @@ -126,6 +129,9 @@ func (s *simulator) createTestNode( // GenerateBlocks will generate the provided number of blocks func (s *simulator) GenerateBlocks(numOfBlocks int) error { + s.mutex.Lock() + defer s.mutex.Unlock() + for idx := 0; idx < numOfBlocks; idx++ { s.incrementRoundOnAllValidators() err := s.allNodesCreateBlocks() @@ -155,6 +161,9 @@ func (s *simulator) allNodesCreateBlocks() error { // GetNodeHandler returns the node handler from the provided shardID func (s *simulator) GetNodeHandler(shardID uint32) process.NodeHandler { + s.mutex.RUnlock() + defer s.mutex.RUnlock() + return s.nodes[shardID] } @@ -175,6 +184,9 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { // SetState will set the provided state for a given address func (s *simulator) SetState(address string, state map[string]string) error { + s.mutex.Lock() + defer s.mutex.Unlock() + addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() addressBytes, err := addressConverter.Decode(address) if err != nil { diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index f67a1e7a004..8dc17d2c4f3 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -359,6 +359,11 @@ func (node *testOnlyProcessingNode) GetFacadeHandler() shared.FacadeHandler { return node.facadeHandler } +// GetStatusCoreComponents will return the status core components +func (node *testOnlyProcessingNode) GetStatusCoreComponents() factory.StatusCoreComponentsHolder { + return node.StatusCoreComponents +} + func (node *testOnlyProcessingNode) collectClosableComponents(apiInterface APIConfigurator) { node.closeHandler.AddComponent(node.ProcessComponentsHolder) node.closeHandler.AddComponent(node.DataComponentsHolder) diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index 79b0a583d98..67c910d4a7b 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -18,6 +18,7 @@ type NodeHandler interface { GetCoreComponents() factory.CoreComponentsHolder GetStateComponents() factory.StateComponentsHolder GetFacadeHandler() shared.FacadeHandler + GetStatusCoreComponents() factory.StatusCoreComponentsHolder SetState(addressBytes []byte, state map[string]string) error Close() error IsInterfaceNil() bool diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 71d85bab81a..d5aa917eceb 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -2,6 +2,7 @@ package process import ( "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" ) @@ -25,6 +26,8 @@ func (creator *blocksCreator) IncrementRound() { roundHandler := creator.nodeHandler.GetCoreComponents().RoundHandler() manual := roundHandler.(manualRoundHandler) manual.IncrementIndex() + + creator.nodeHandler.GetStatusCoreComponents().AppStatusHandler().SetUInt64Value(common.MetricCurrentRound, uint64(roundHandler.Index())) } // CreateNewBlock creates and process a new block From cce546481bb85d18fd3029d8c0aed984a6f29670 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 27 Nov 2023 14:21:40 +0200 Subject: [PATCH 528/958] fix mutex --- node/chainSimulator/chainSimulator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index cc47e378231..1904e3f72ff 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -161,7 +161,7 @@ func (s *simulator) allNodesCreateBlocks() error { // GetNodeHandler returns the node handler from the provided shardID func (s *simulator) GetNodeHandler(shardID uint32) process.NodeHandler { - s.mutex.RUnlock() + s.mutex.RLock() defer s.mutex.RUnlock() return s.nodes[shardID] From abe31546462074d30531176a735de44c46c595c5 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 28 Nov 2023 15:06:09 +0200 Subject: [PATCH 529/958] add mutex lock and unlock --- node/chainSimulator/chainSimulator.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 1904e3f72ff..b3c0f6c71ce 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -169,6 +169,9 @@ func (s *simulator) GetNodeHandler(shardID uint32) process.NodeHandler { // GetRestAPIInterfaces will return a map with the rest api interfaces for every node func (s *simulator) GetRestAPIInterfaces() map[uint32]string { + s.mutex.Lock() + defer s.mutex.Unlock() + resMap := make(map[uint32]string) for shardID, node := range s.nodes { resMap[shardID] = node.GetFacadeHandler().RestApiInterface() @@ -204,6 +207,9 @@ func (s *simulator) SetState(address string, state map[string]string) error { // Close will stop and close the simulator func (s *simulator) Close() error { + s.mutex.Lock() + defer s.mutex.Unlock() + var errorStrings []string for _, n := range s.nodes { err := n.Close() From 89f4792f891ee12177c4fe751bce3b21b99cc621 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 6 Dec 2023 13:00:08 +0200 Subject: [PATCH 530/958] set entire state of multiple accounts --- node/chainSimulator/chainSimulator.go | 28 +++++- node/chainSimulator/chainSimulator_test.go | 2 +- .../components/testOnlyProcessingNode.go | 92 ++++++++++++++++--- .../components/testOnlyProcessingNode_test.go | 4 +- node/chainSimulator/dtos/state.go | 13 +++ node/chainSimulator/process/interface.go | 4 +- 6 files changed, 125 insertions(+), 18 deletions(-) create mode 100644 node/chainSimulator/dtos/state.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index b3c0f6c71ce..d0698bf2225 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -185,8 +185,8 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { return s.initialWalletKeys } -// SetState will set the provided state for a given address -func (s *simulator) SetState(address string, state map[string]string) error { +// SetKeyValueForAddress will set the provided state for a given address +func (s *simulator) SetKeyValueForAddress(address string, state map[string]string) error { s.mutex.Lock() defer s.mutex.Unlock() @@ -202,7 +202,29 @@ func (s *simulator) SetState(address string, state map[string]string) error { return fmt.Errorf("cannot find a test node for the computed shard id, computed shard id: %d", shardID) } - return testNode.SetState(addressBytes, state) + return testNode.SetKeyValueForAddress(addressBytes, state) +} + +// SetStateMultiple will set state for multiple addresses +func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { + s.mutex.Lock() + defer s.mutex.Unlock() + + addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() + for _, state := range stateSlice { + addressBytes, err := addressConverter.Decode(state.Address) + if err != nil { + return err + } + + shardID := sharding.ComputeShardID(addressBytes, s.numOfShards) + err = s.nodes[shardID].SetStateForAddress(addressBytes, state) + if err != nil { + return err + } + } + + return nil } // Close will stop and close the simulator diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 70ab2043878..a89eef99acb 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -133,7 +133,7 @@ func TestChainSimulator_SetState(t *testing.T) { } address := "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj" - err = chainSimulator.SetState(address, keyValueMap) + err = chainSimulator.SetKeyValueForAddress(address, keyValueMap) require.Nil(t, err) err = chainSimulator.GenerateBlocks(1) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 8dc17d2c4f3..434cbba778d 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "errors" "fmt" + "math/big" "github.com/multiversx/mx-chain-core-go/core" chainData "github.com/multiversx/mx-chain-core-go/data" @@ -18,6 +19,7 @@ import ( "github.com/multiversx/mx-chain-go/facade" "github.com/multiversx/mx-chain-go/factory" bootstrapComp "github.com/multiversx/mx-chain-go/factory/bootstrap" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/postprocess" "github.com/multiversx/mx-chain-go/process/economics" @@ -382,26 +384,40 @@ func (node *testOnlyProcessingNode) collectClosableComponents(apiInterface APICo } } -// SetState will set the provided state for the given address -func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[string]string) error { +// SetKeyValueForAddress will set the provided state for the given address +func (node *testOnlyProcessingNode) SetKeyValueForAddress(address []byte, keyValueMap map[string]string) error { + userAccount, err := node.getUserAccount(address) + if err != nil { + return err + } + + err = setKeyValueMap(userAccount, keyValueMap) + if err != nil { + return err + } + accountsAdapter := node.StateComponentsHolder.AccountsAdapter() - account, err := accountsAdapter.LoadAccount(address) + err = accountsAdapter.SaveAccount(userAccount) if err != nil { return err } - userAccount, ok := account.(state.UserAccountHandler) - if !ok { - return errors.New("cannot cast AccountHandler to UserAccountHandler") + _, err = accountsAdapter.Commit() + if err != nil { + return err } + return nil +} + +func setKeyValueMap(userAccount state.UserAccountHandler, keyValueMap map[string]string) error { for keyHex, valueHex := range keyValueMap { - keyDecoded, errK := hex.DecodeString(keyHex) - if errK != nil { + keyDecoded, err := hex.DecodeString(keyHex) + if err != nil { return fmt.Errorf("cannot decode key, error: %w", err) } - valueDecoded, errV := hex.DecodeString(valueHex) - if errV != nil { + valueDecoded, err := hex.DecodeString(valueHex) + if err != nil { return fmt.Errorf("cannot decode value, error: %w", err) } @@ -411,7 +427,46 @@ func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[str } } - err = accountsAdapter.SaveAccount(account) + return nil +} + +// SetStateForAddress will set the state for the give address +func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressState *dtos.AddressState) error { + userAccount, err := node.getUserAccount(address) + if err != nil { + return err + } + + // set nonce to zero + userAccount.IncreaseNonce(-userAccount.GetNonce()) + // set nonce with the provided value + userAccount.IncreaseNonce(addressState.Nonce) + + if addressState.Code != "" { + decodedCode, _ := hex.DecodeString(addressState.Code) + userAccount.SetCode(decodedCode) + } + if addressState.CodeMetadata != "" { + decodedCodeMetadata, _ := hex.DecodeString(addressState.CodeMetadata) + userAccount.SetCodeMetadata(decodedCodeMetadata) + } + + bigValue, ok := big.NewInt(0).SetString(addressState.Balance, 10) + if !ok { + return errors.New("cannot convert string balance to *big.Int") + } + err = userAccount.AddToBalance(bigValue) + if err != nil { + return err + } + + err = setKeyValueMap(userAccount, addressState.Keys) + if err != nil { + return err + } + + accountsAdapter := node.StateComponentsHolder.AccountsAdapter() + err = accountsAdapter.SaveAccount(userAccount) if err != nil { return err } @@ -424,6 +479,21 @@ func (node *testOnlyProcessingNode) SetState(address []byte, keyValueMap map[str return nil } +func (node *testOnlyProcessingNode) getUserAccount(address []byte) (state.UserAccountHandler, error) { + accountsAdapter := node.StateComponentsHolder.AccountsAdapter() + account, err := accountsAdapter.LoadAccount(address) + if err != nil { + return nil, err + } + + userAccount, ok := account.(state.UserAccountHandler) + if !ok { + return nil, errors.New("cannot cast AccountHandler to UserAccountHandler") + } + + return userAccount, nil +} + // Close will call the Close methods on all inner components func (node *testOnlyProcessingNode) Close() error { return node.closeHandler.Close() diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index d23ba3b6879..62655089c0b 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -95,14 +95,14 @@ func TestOnlyProcessingNodeSetStateShouldError(t *testing.T) { keyValueMap := map[string]string{ "nonHex": "01", } - err = node.SetState(addressBytes, keyValueMap) + err = node.SetKeyValueForAddress(addressBytes, keyValueMap) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), "cannot decode key")) keyValueMap = map[string]string{ "01": "nonHex", } - err = node.SetState(addressBytes, keyValueMap) + err = node.SetKeyValueForAddress(addressBytes, keyValueMap) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), "cannot decode value")) } diff --git a/node/chainSimulator/dtos/state.go b/node/chainSimulator/dtos/state.go new file mode 100644 index 00000000000..b5c2acf98ca --- /dev/null +++ b/node/chainSimulator/dtos/state.go @@ -0,0 +1,13 @@ +package dtos + +// AddressState will hold the address state +type AddressState struct { + Address string `json:"address"` + Nonce uint64 `json:"nonce,omitempty"` + Balance string `json:"balance,omitempty"` + Code string `json:"code,omitempty"` + RootHash string `json:"rootHash,omitempty"` + CodeMetadata string `json:"codeMetadata,omitempty"` + Owner string `json:"owner,omitempty"` + Keys map[string]string `json:"keys,omitempty"` +} diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index 67c910d4a7b..6dc0b84fa02 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -5,6 +5,7 @@ import ( "github.com/multiversx/mx-chain-go/api/shared" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/sharding" ) @@ -19,7 +20,8 @@ type NodeHandler interface { GetStateComponents() factory.StateComponentsHolder GetFacadeHandler() shared.FacadeHandler GetStatusCoreComponents() factory.StatusCoreComponentsHolder - SetState(addressBytes []byte, state map[string]string) error + SetKeyValueForAddress(addressBytes []byte, state map[string]string) error + SetStateForAddress(address []byte, state *dtos.AddressState) error Close() error IsInterfaceNil() bool } From 658e3c230ef45b78ec1051c5bedb2f96be35cc21 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 6 Dec 2023 14:09:00 +0200 Subject: [PATCH 531/958] set state and integration test --- node/chainSimulator/chainSimulator_test.go | 59 +++++++++++++++++++ .../components/testOnlyProcessingNode.go | 59 ++++++++++++++++--- node/chainSimulator/dtos/state.go | 18 +++--- 3 files changed, 119 insertions(+), 17 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index a89eef99acb..d396e865212 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -2,12 +2,15 @@ package chainSimulator import ( "fmt" + "math/big" "testing" "time" "github.com/multiversx/mx-chain-core-go/core" coreAPI "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + "github.com/multiversx/mx-chain-go/process" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -144,3 +147,59 @@ func TestChainSimulator_SetState(t *testing.T) { require.Nil(t, err) require.Equal(t, keyValueMap, keyValuePairs) } + +func TestChainSimulator_SetEntireState(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + }) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + + contractAddress := "erd1qqqqqqqqqqqqqpgqmzzm05jeav6d5qvna0q2pmcllelkz8xddz3syjszx5" + accountState := &dtos.AddressState{ + Address: contractAddress, + Nonce: 0, + Balance: "431271308732096033771131", + Code: "0061736d010000000129086000006000017f60027f7f017f60027f7f0060017f0060037f7f7f017f60037f7f7f0060017f017f0290020b03656e7619626967496e74476574556e7369676e6564417267756d656e74000303656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000303656e76126d42756666657253746f726167654c6f6164000203656e76176d427566666572546f426967496e74556e7369676e6564000203656e76196d42756666657246726f6d426967496e74556e7369676e6564000203656e76136d42756666657253746f7261676553746f7265000203656e760f6d4275666665725365744279746573000503656e760e636865636b4e6f5061796d656e74000003656e7614626967496e7446696e697368556e7369676e6564000403656e7609626967496e744164640006030b0a010104070301000000000503010003060f027f0041a080080b7f0041a080080b074607066d656d6f7279020004696e697400110667657453756d00120361646400130863616c6c4261636b00140a5f5f646174615f656e6403000b5f5f686561705f6261736503010aca010a0e01017f4100100c2200100020000b1901017f419c8008419c800828020041016b220036020020000b1400100120004604400f0b4180800841191002000b16002000100c220010031a2000100c220010041a20000b1401017f100c2202200110051a2000200210061a0b1301017f100c220041998008410310071a20000b1401017f10084101100d100b210010102000100f0b0e0010084100100d1010100e10090b2201037f10084101100d100b210110102202100e220020002001100a20022000100f0b0300010b0b2f0200418080080b1c77726f6e67206e756d626572206f6620617267756d656e747373756d00419c80080b049cffffff", + CodeHash: "n9EviPlHS6EV+3Xp0YqP28T0IUfeAFRFBIRC1Jw6pyU=", + RootHash: "76cr5Jhn6HmBcDUMIzikEpqFgZxIrOzgNkTHNatXzC4=", + CodeMetadata: "BQY=", + Owner: "erd1ss6u80ruas2phpmr82r42xnkd6rxy40g9jl69frppl4qez9w2jpsqj8x97", + DeveloperRewards: "5401004999998", + Keys: map[string]string{ + "73756d": "0a", + }, + } + + err = chainSimulator.SetStateMultiple([]*dtos.AddressState{accountState}) + require.Nil(t, err) + + err = chainSimulator.GenerateBlocks(30) + require.Nil(t, err) + + nodeHandler := chainSimulator.GetNodeHandler(1) + scAddress, _ := nodeHandler.GetCoreComponents().AddressPubKeyConverter().Decode(contractAddress) + res, _, err := nodeHandler.GetFacadeHandler().ExecuteSCQuery(&process.SCQuery{ + ScAddress: scAddress, + FuncName: "getSum", + CallerAddr: nil, + BlockNonce: core.OptionalUint64{}, + }) + require.Nil(t, err) + + counterValue := big.NewInt(0).SetBytes(res.ReturnData[0]).Int64() + require.Equal(t, 10, int(counterValue)) +} diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 434cbba778d..6956dd3c146 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -1,6 +1,7 @@ package components import ( + "encoding/base64" "encoding/hex" "errors" "fmt" @@ -442,15 +443,6 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt // set nonce with the provided value userAccount.IncreaseNonce(addressState.Nonce) - if addressState.Code != "" { - decodedCode, _ := hex.DecodeString(addressState.Code) - userAccount.SetCode(decodedCode) - } - if addressState.CodeMetadata != "" { - decodedCodeMetadata, _ := hex.DecodeString(addressState.CodeMetadata) - userAccount.SetCodeMetadata(decodedCodeMetadata) - } - bigValue, ok := big.NewInt(0).SetString(addressState.Balance, 10) if !ok { return errors.New("cannot convert string balance to *big.Int") @@ -465,6 +457,17 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt return err } + err = node.setScDataIfNeeded(address, userAccount, addressState) + if err != nil { + return err + } + + rootHash, err := base64.StdEncoding.DecodeString(addressState.RootHash) + if err != nil { + return err + } + userAccount.SetRootHash(rootHash) + accountsAdapter := node.StateComponentsHolder.AccountsAdapter() err = accountsAdapter.SaveAccount(userAccount) if err != nil { @@ -479,6 +482,44 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt return nil } +func (node *testOnlyProcessingNode) setScDataIfNeeded(address []byte, userAccount state.UserAccountHandler, addressState *dtos.AddressState) error { + if !core.IsSmartContractAddress(address) { + return nil + } + + decodedCode, err := hex.DecodeString(addressState.Code) + if err != nil { + return err + } + userAccount.SetCode(decodedCode) + + codeHash, err := base64.StdEncoding.DecodeString(addressState.CodeHash) + if err != nil { + return err + } + userAccount.SetCodeHash(codeHash) + + decodedCodeMetadata, err := base64.StdEncoding.DecodeString(addressState.CodeMetadata) + if err != nil { + return err + } + userAccount.SetCodeMetadata(decodedCodeMetadata) + + ownerAddress, err := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(addressState.Owner) + if err != nil { + return err + } + userAccount.SetOwnerAddress(ownerAddress) + + developerRewards, ok := big.NewInt(0).SetString(addressState.DeveloperRewards, 10) + if !ok { + return errors.New("cannot convert string developer rewards to *big.Int") + } + userAccount.AddToDeveloperReward(developerRewards) + + return nil +} + func (node *testOnlyProcessingNode) getUserAccount(address []byte) (state.UserAccountHandler, error) { accountsAdapter := node.StateComponentsHolder.AccountsAdapter() account, err := accountsAdapter.LoadAccount(address) diff --git a/node/chainSimulator/dtos/state.go b/node/chainSimulator/dtos/state.go index b5c2acf98ca..cdb0975368d 100644 --- a/node/chainSimulator/dtos/state.go +++ b/node/chainSimulator/dtos/state.go @@ -2,12 +2,14 @@ package dtos // AddressState will hold the address state type AddressState struct { - Address string `json:"address"` - Nonce uint64 `json:"nonce,omitempty"` - Balance string `json:"balance,omitempty"` - Code string `json:"code,omitempty"` - RootHash string `json:"rootHash,omitempty"` - CodeMetadata string `json:"codeMetadata,omitempty"` - Owner string `json:"owner,omitempty"` - Keys map[string]string `json:"keys,omitempty"` + Address string `json:"address"` + Nonce uint64 `json:"nonce,omitempty"` + Balance string `json:"balance,omitempty"` + Code string `json:"code,omitempty"` + RootHash string `json:"rootHash,omitempty"` + CodeMetadata string `json:"codeMetadata,omitempty"` + CodeHash string `json:"codeHash,omitempty"` + DeveloperRewards string `json:"developerRewards,omitempty"` + Owner string `json:"owner,omitempty"` + Keys map[string]string `json:"keys,omitempty"` } From eaf33ec65dcca42dc1a41d8494c457ee114aaa35 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 6 Dec 2023 14:16:48 +0200 Subject: [PATCH 532/958] extra checks --- node/chainSimulator/chainSimulator_test.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index d396e865212..9ca2ff68cb5 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -1,6 +1,7 @@ package chainSimulator import ( + "encoding/base64" "fmt" "math/big" "testing" @@ -168,11 +169,12 @@ func TestChainSimulator_SetEntireState(t *testing.T) { require.Nil(t, err) require.NotNil(t, chainSimulator) + balance := "431271308732096033771131" contractAddress := "erd1qqqqqqqqqqqqqpgqmzzm05jeav6d5qvna0q2pmcllelkz8xddz3syjszx5" accountState := &dtos.AddressState{ Address: contractAddress, Nonce: 0, - Balance: "431271308732096033771131", + Balance: balance, Code: "0061736d010000000129086000006000017f60027f7f017f60027f7f0060017f0060037f7f7f017f60037f7f7f0060017f017f0290020b03656e7619626967496e74476574556e7369676e6564417267756d656e74000303656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000303656e76126d42756666657253746f726167654c6f6164000203656e76176d427566666572546f426967496e74556e7369676e6564000203656e76196d42756666657246726f6d426967496e74556e7369676e6564000203656e76136d42756666657253746f7261676553746f7265000203656e760f6d4275666665725365744279746573000503656e760e636865636b4e6f5061796d656e74000003656e7614626967496e7446696e697368556e7369676e6564000403656e7609626967496e744164640006030b0a010104070301000000000503010003060f027f0041a080080b7f0041a080080b074607066d656d6f7279020004696e697400110667657453756d00120361646400130863616c6c4261636b00140a5f5f646174615f656e6403000b5f5f686561705f6261736503010aca010a0e01017f4100100c2200100020000b1901017f419c8008419c800828020041016b220036020020000b1400100120004604400f0b4180800841191002000b16002000100c220010031a2000100c220010041a20000b1401017f100c2202200110051a2000200210061a0b1301017f100c220041998008410310071a20000b1401017f10084101100d100b210010102000100f0b0e0010084100100d1010100e10090b2201037f10084101100d100b210110102202100e220020002001100a20022000100f0b0300010b0b2f0200418080080b1c77726f6e67206e756d626572206f6620617267756d656e747373756d00419c80080b049cffffff", CodeHash: "n9EviPlHS6EV+3Xp0YqP28T0IUfeAFRFBIRC1Jw6pyU=", RootHash: "76cr5Jhn6HmBcDUMIzikEpqFgZxIrOzgNkTHNatXzC4=", @@ -202,4 +204,14 @@ func TestChainSimulator_SetEntireState(t *testing.T) { counterValue := big.NewInt(0).SetBytes(res.ReturnData[0]).Int64() require.Equal(t, 10, int(counterValue)) + + account, _, err := nodeHandler.GetFacadeHandler().GetAccount(contractAddress, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + require.Equal(t, accountState.Balance, account.Balance) + require.Equal(t, accountState.DeveloperRewards, account.DeveloperReward) + require.Equal(t, accountState.Code, account.Code) + require.Equal(t, accountState.CodeHash, base64.StdEncoding.EncodeToString(account.CodeHash)) + require.Equal(t, accountState.CodeMetadata, base64.StdEncoding.EncodeToString(account.CodeMetadata)) + require.Equal(t, accountState.Owner, account.OwnerAddress) + require.Equal(t, accountState.RootHash, base64.StdEncoding.EncodeToString(account.RootHash)) } From 158df0c84188dc162244e56e87eaca839821012b Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 6 Dec 2023 15:01:17 +0200 Subject: [PATCH 533/958] fix tests --- node/chainSimulator/chainSimulator_test.go | 6 ++++++ .../components/testOnlyProcessingNode_test.go | 4 ---- .../external/timemachine/fee/memoryFootprint/memory_test.go | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 9ca2ff68cb5..2356f2d23fe 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -150,6 +150,10 @@ func TestChainSimulator_SetState(t *testing.T) { } func TestChainSimulator_SetEntireState(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ @@ -205,6 +209,8 @@ func TestChainSimulator_SetEntireState(t *testing.T) { counterValue := big.NewInt(0).SetBytes(res.ReturnData[0]).Int64() require.Equal(t, 10, int(counterValue)) + time.Sleep(time.Second) + account, _, err := nodeHandler.GetFacadeHandler().GetAccount(contractAddress, coreAPI.AccountQueryOptions{}) require.Nil(t, err) require.Equal(t, accountState.Balance, account.Balance) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 62655089c0b..8a0ed522e64 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -41,8 +41,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { t.Skip("cannot run with -race -short; requires Wasm VM fix") } - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) assert.Nil(t, err) @@ -54,8 +52,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { t.Skip("cannot run with -race -short; requires Wasm VM fix") } - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) assert.Nil(t, err) diff --git a/node/external/timemachine/fee/memoryFootprint/memory_test.go b/node/external/timemachine/fee/memoryFootprint/memory_test.go index cba0a5d8c00..034edf81722 100644 --- a/node/external/timemachine/fee/memoryFootprint/memory_test.go +++ b/node/external/timemachine/fee/memoryFootprint/memory_test.go @@ -19,7 +19,7 @@ func TestFeeComputer_MemoryFootprint(t *testing.T) { } numEpochs := 10000 - maxFootprintNumBytes := 50_000_000 + maxFootprintNumBytes := 60_000_000 journal := &memoryFootprintJournal{} journal.before = getMemStats() From 513750c3463d3ea850bd946683a2425107e127e3 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 11 Dec 2023 15:07:52 +0200 Subject: [PATCH 534/958] extend state structure with shard id for system account --- node/chainSimulator/chainSimulator.go | 6 ++++++ node/chainSimulator/dtos/state.go | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index d0698bf2225..aea2baada94 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -1,6 +1,7 @@ package chainSimulator import ( + "bytes" "fmt" "sync" "time" @@ -218,6 +219,11 @@ func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { } shardID := sharding.ComputeShardID(addressBytes, s.numOfShards) + if bytes.Equal(addressBytes, core.SystemAccountAddress) { + // for system account address use the provided shard ID + shardID = state.ShardID + } + err = s.nodes[shardID].SetStateForAddress(addressBytes, state) if err != nil { return err diff --git a/node/chainSimulator/dtos/state.go b/node/chainSimulator/dtos/state.go index cdb0975368d..a48628062ee 100644 --- a/node/chainSimulator/dtos/state.go +++ b/node/chainSimulator/dtos/state.go @@ -2,7 +2,9 @@ package dtos // AddressState will hold the address state type AddressState struct { - Address string `json:"address"` + Address string `json:"address"` + // ShardID: This field is needed for the system account address (it is the same on all shards). + ShardID uint32 `json:"shardID,omitempty"` Nonce uint64 `json:"nonce,omitempty"` Balance string `json:"balance,omitempty"` Code string `json:"code,omitempty"` From ab3c7058357e26379e9e80c52d259fbf145f425b Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 11 Dec 2023 15:57:11 +0200 Subject: [PATCH 535/958] change json tags --- node/chainSimulator/dtos/state.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/dtos/state.go b/node/chainSimulator/dtos/state.go index a48628062ee..6f68d51dc90 100644 --- a/node/chainSimulator/dtos/state.go +++ b/node/chainSimulator/dtos/state.go @@ -11,7 +11,7 @@ type AddressState struct { RootHash string `json:"rootHash,omitempty"` CodeMetadata string `json:"codeMetadata,omitempty"` CodeHash string `json:"codeHash,omitempty"` - DeveloperRewards string `json:"developerRewards,omitempty"` - Owner string `json:"owner,omitempty"` + DeveloperRewards string `json:"developerReward,omitempty"` + Owner string `json:"ownerAddress,omitempty"` Keys map[string]string `json:"keys,omitempty"` } From 6b6c40b624b42ba62bbab0759042da33fd72cc58 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Dec 2023 13:33:42 +0200 Subject: [PATCH 536/958] fix edge case --- .../transactionAPI/gasUsedAndFeeProcessor.go | 2 +- .../transactionsFeeProcessor.go | 5 +- .../transactionsFeeProcessor_test.go | 63 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/node/external/transactionAPI/gasUsedAndFeeProcessor.go b/node/external/transactionAPI/gasUsedAndFeeProcessor.go index a22b689d6a4..c2f02be8e8f 100644 --- a/node/external/transactionAPI/gasUsedAndFeeProcessor.go +++ b/node/external/transactionAPI/gasUsedAndFeeProcessor.go @@ -52,7 +52,7 @@ func (gfp *gasUsedAndFeeProcessor) prepareTxWithResultsBasedOnLogs( tx *transaction.ApiTransactionResult, hasRefund bool, ) { - if tx.Logs == nil { + if tx.Logs == nil || (tx.Function == "" && tx.Operation == "transfer") { return } diff --git a/outport/process/transactionsfee/transactionsFeeProcessor.go b/outport/process/transactionsfee/transactionsFeeProcessor.go index 593a5d6b83b..745c97bb703 100644 --- a/outport/process/transactionsfee/transactionsFeeProcessor.go +++ b/outport/process/transactionsfee/transactionsFeeProcessor.go @@ -145,7 +145,10 @@ func (tep *transactionsFeeProcessor) prepareTxWithResultsBasedOnLogs( txWithResults *transactionWithResults, hasRefund bool, ) { - if check.IfNilReflect(txWithResults.log) { + tx := txWithResults.GetTxHandler() + res := tep.dataFieldParser.Parse(tx.GetData(), tx.GetSndAddr(), tx.GetRcvAddr(), tep.shardCoordinator.NumberOfShards()) + + if check.IfNilReflect(txWithResults.log) || (res.Function == "" && res.Operation == "transfer") { return } diff --git a/outport/process/transactionsfee/transactionsFeeProcessor_test.go b/outport/process/transactionsfee/transactionsFeeProcessor_test.go index e0efbab8ada..8ff4cf14501 100644 --- a/outport/process/transactionsfee/transactionsFeeProcessor_test.go +++ b/outport/process/transactionsfee/transactionsFeeProcessor_test.go @@ -212,11 +212,15 @@ func TestPutFeeAndGasUsedInvalidTxs(t *testing.T) { func TestPutFeeAndGasUsedLogWithErrorAndInformative(t *testing.T) { t.Parallel() + receiver, _ := hex.DecodeString("00000000000000000500d3b28828d62052124f07dcd50ed31b0825f60eee1526") tx1Hash := "h1" tx1 := &outportcore.TxInfo{ Transaction: &transaction.Transaction{ GasLimit: 30000000, GasPrice: 1000000000, + SndAddr: []byte("erd1dglncxk6sl9a3xumj78n6z2xux4ghp5c92cstv5zsn56tjgtdwpsk46qrs"), + RcvAddr: receiver, + Data: []byte("here"), }, FeeInfo: &outportcore.FeeInfo{Fee: big.NewInt(0)}, } @@ -226,6 +230,9 @@ func TestPutFeeAndGasUsedLogWithErrorAndInformative(t *testing.T) { Transaction: &transaction.Transaction{ GasLimit: 50000000, GasPrice: 1000000000, + SndAddr: []byte("erd1dglncxk6sl9a3xumj78n6z2xux4ghp5c92cstv5zsn56tjgtdwpsk46qrs"), + RcvAddr: receiver, + Data: []byte("here"), }, FeeInfo: &outportcore.FeeInfo{Fee: big.NewInt(0)}, } @@ -520,3 +527,59 @@ func TestPutFeeAndGasUsedScrWithRefund(t *testing.T) { require.Equal(t, big.NewInt(552865000000000), initialTx.GetFeeInfo().GetFee()) require.Equal(t, uint64(50_336_500), initialTx.GetFeeInfo().GetGasUsed()) } + +func TestMoveBalanceWithSignalError(t *testing.T) { + txHash := []byte("e3cdb8b4936fdbee2d3b1244b4c49959df5f90ada683d650019d244e5a64afaf") + initialTx := &outportcore.TxInfo{Transaction: &transaction.Transaction{ + Nonce: 1004, + GasLimit: 12_175_500, + GasPrice: 1000000000, + SndAddr: []byte("erd1s8jr8e8hsvv7c9ehmshcjlpzf9ua5l50qeswa8feshrp6xlz9c7quacmtx"), + RcvAddr: []byte("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"), + Data: []byte("start@5465737420526166666c65203120f09f9a80@10000000000000000@0100000002@01000000006082a400@0100000001@01000000023232@"), + }, FeeInfo: &outportcore.FeeInfo{Fee: big.NewInt(0)}} + + scrHash := []byte("scrHash") + scr := &outportcore.SCRInfo{ + SmartContractResult: &smartContractResult.SmartContractResult{ + Nonce: 1005, + SndAddr: []byte("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"), + RcvAddr: []byte("erd1s8jr8e8hsvv7c9ehmshcjlpzf9ua5l50qeswa8feshrp6xlz9c7quacmtx"), + PrevTxHash: txHash, + OriginalTxHash: txHash, + Value: big.NewInt(0), + Data: []byte("@sending value to non payable contract"), + }, + FeeInfo: &outportcore.FeeInfo{Fee: big.NewInt(0)}, + } + + pool := &outportcore.TransactionPool{ + SmartContractResults: map[string]*outportcore.SCRInfo{ + hex.EncodeToString(scrHash): scr, + }, + Transactions: map[string]*outportcore.TxInfo{ + hex.EncodeToString(txHash): initialTx, + }, + Logs: []*outportcore.LogData{ + { + Log: &transaction.Log{ + Events: []*transaction.Event{ + { + Identifier: []byte(core.SignalErrorOperation), + }, + }, + }, + TxHash: hex.EncodeToString(txHash), + }, + }, + } + + arg := prepareMockArg() + txsFeeProc, err := NewTransactionsFeeProcessor(arg) + require.NotNil(t, txsFeeProc) + require.Nil(t, err) + + err = txsFeeProc.PutFeeAndGasUsed(pool) + require.Nil(t, err) + require.Equal(t, uint64(225_500), initialTx.GetFeeInfo().GetGasUsed()) +} From d773bc941392cc8764cb9c24f5ea044884903cfd Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 12 Dec 2023 15:15:45 +0200 Subject: [PATCH 537/958] fix initial paid fee --- outport/process/interface.go | 1 + outport/process/transactionsfee/interface.go | 1 + outport/process/transactionsfee/transactionsFeeProcessor.go | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/outport/process/interface.go b/outport/process/interface.go index abcbbe10fec..5fcb19020f3 100644 --- a/outport/process/interface.go +++ b/outport/process/interface.go @@ -34,6 +34,7 @@ type GasConsumedProvider interface { type EconomicsDataHandler interface { ComputeGasUsedAndFeeBasedOnRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int) (uint64, *big.Int) ComputeTxFeeBasedOnGasUsed(tx data.TransactionWithFeeHandler, gasUsed uint64) *big.Int + ComputeTxFee(tx data.TransactionWithFeeHandler) *big.Int ComputeGasLimit(tx data.TransactionWithFeeHandler) uint64 IsInterfaceNil() bool MaxGasLimitPerBlock(shardID uint32) uint64 diff --git a/outport/process/transactionsfee/interface.go b/outport/process/transactionsfee/interface.go index fa09f18076a..53042467442 100644 --- a/outport/process/transactionsfee/interface.go +++ b/outport/process/transactionsfee/interface.go @@ -12,6 +12,7 @@ import ( type FeesProcessorHandler interface { ComputeGasUsedAndFeeBasedOnRefundValue(tx data.TransactionWithFeeHandler, refundValue *big.Int) (uint64, *big.Int) ComputeTxFeeBasedOnGasUsed(tx data.TransactionWithFeeHandler, gasUsed uint64) *big.Int + ComputeTxFee(tx data.TransactionWithFeeHandler) *big.Int ComputeGasLimit(tx data.TransactionWithFeeHandler) uint64 IsInterfaceNil() bool } diff --git a/outport/process/transactionsfee/transactionsFeeProcessor.go b/outport/process/transactionsfee/transactionsFeeProcessor.go index 745c97bb703..ded9b1318d5 100644 --- a/outport/process/transactionsfee/transactionsFeeProcessor.go +++ b/outport/process/transactionsfee/transactionsFeeProcessor.go @@ -90,7 +90,7 @@ func (tep *transactionsFeeProcessor) PutFeeAndGasUsed(pool *outportcore.Transact func (tep *transactionsFeeProcessor) prepareInvalidTxs(pool *outportcore.TransactionPool) { for _, invalidTx := range pool.InvalidTxs { - fee := tep.txFeeCalculator.ComputeTxFeeBasedOnGasUsed(invalidTx.Transaction, invalidTx.Transaction.GasLimit) + fee := tep.txFeeCalculator.ComputeTxFee(invalidTx.Transaction) invalidTx.FeeInfo.SetGasUsed(invalidTx.Transaction.GetGasLimit()) invalidTx.FeeInfo.SetFee(fee) invalidTx.FeeInfo.SetInitialPaidFee(fee) @@ -103,7 +103,7 @@ func (tep *transactionsFeeProcessor) prepareNormalTxs(transactionsAndScrs *trans gasUsed := tep.txFeeCalculator.ComputeGasLimit(txHandler) fee := tep.txFeeCalculator.ComputeTxFeeBasedOnGasUsed(txHandler, gasUsed) - initialPaidFee := tep.txFeeCalculator.ComputeTxFeeBasedOnGasUsed(txHandler, txHandler.GetGasLimit()) + initialPaidFee := tep.txFeeCalculator.ComputeTxFee(txHandler) feeInfo := txWithResult.GetFeeInfo() feeInfo.SetGasUsed(gasUsed) From 8c4334dbd145e48f9091c62ca22ed2708ee95b54 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 20 Dec 2023 15:53:20 +0200 Subject: [PATCH 538/958] fixes after review --- node/chainSimulator/chainSimulator.go | 39 +++++++++++++++---- .../components/testOnlyProcessingNode.go | 11 +----- node/chainSimulator/dtos/state.go | 4 +- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index aea2baada94..521b99dc5a4 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -187,7 +187,7 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { } // SetKeyValueForAddress will set the provided state for a given address -func (s *simulator) SetKeyValueForAddress(address string, state map[string]string) error { +func (s *simulator) SetKeyValueForAddress(address string, keyValueMap map[string]string) error { s.mutex.Lock() defer s.mutex.Unlock() @@ -197,13 +197,28 @@ func (s *simulator) SetKeyValueForAddress(address string, state map[string]strin return err } + if bytes.Equal(addressBytes, core.SystemAccountAddress) { + return s.setKeyValueSystemAccount(keyValueMap) + } + shardID := sharding.ComputeShardID(addressBytes, s.numOfShards) testNode, ok := s.nodes[shardID] if !ok { return fmt.Errorf("cannot find a test node for the computed shard id, computed shard id: %d", shardID) } - return testNode.SetKeyValueForAddress(addressBytes, state) + return testNode.SetKeyValueForAddress(addressBytes, keyValueMap) +} + +func (s *simulator) setKeyValueSystemAccount(keyValueMap map[string]string) error { + for shard, node := range s.nodes { + err := node.SetKeyValueForAddress(core.SystemAccountAddress, keyValueMap) + if err != nil { + return fmt.Errorf("%w for shard %d", err, shard) + } + } + + return nil } // SetStateMultiple will set state for multiple addresses @@ -218,13 +233,12 @@ func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { return err } - shardID := sharding.ComputeShardID(addressBytes, s.numOfShards) if bytes.Equal(addressBytes, core.SystemAccountAddress) { - // for system account address use the provided shard ID - shardID = state.ShardID + err = s.setStateSystemAccount(state) + } else { + shardID := sharding.ComputeShardID(addressBytes, s.numOfShards) + err = s.nodes[shardID].SetStateForAddress(addressBytes, state) } - - err = s.nodes[shardID].SetStateForAddress(addressBytes, state) if err != nil { return err } @@ -233,6 +247,17 @@ func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { return nil } +func (s *simulator) setStateSystemAccount(state *dtos.AddressState) error { + for shard, node := range s.nodes { + err := node.SetStateForAddress(core.SystemAccountAddress, state) + if err != nil { + return fmt.Errorf("%w for shard %d", err, shard) + } + } + + return nil +} + // Close will stop and close the simulator func (s *simulator) Close() error { s.mutex.Lock() diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 6956dd3c146..ebc03a63113 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -404,11 +404,8 @@ func (node *testOnlyProcessingNode) SetKeyValueForAddress(address []byte, keyVal } _, err = accountsAdapter.Commit() - if err != nil { - return err - } - return nil + return err } func setKeyValueMap(userAccount state.UserAccountHandler, keyValueMap map[string]string) error { @@ -475,11 +472,7 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt } _, err = accountsAdapter.Commit() - if err != nil { - return err - } - - return nil + return err } func (node *testOnlyProcessingNode) setScDataIfNeeded(address []byte, userAccount state.UserAccountHandler, addressState *dtos.AddressState) error { diff --git a/node/chainSimulator/dtos/state.go b/node/chainSimulator/dtos/state.go index 6f68d51dc90..2d2d59f7763 100644 --- a/node/chainSimulator/dtos/state.go +++ b/node/chainSimulator/dtos/state.go @@ -2,9 +2,7 @@ package dtos // AddressState will hold the address state type AddressState struct { - Address string `json:"address"` - // ShardID: This field is needed for the system account address (it is the same on all shards). - ShardID uint32 `json:"shardID,omitempty"` + Address string `json:"address"` Nonce uint64 `json:"nonce,omitempty"` Balance string `json:"balance,omitempty"` Code string `json:"code,omitempty"` From ea8e232a688132ea51fbb79d784ddca579c8e2ec Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 22 Dec 2023 14:05:06 +0200 Subject: [PATCH 539/958] multiple validators --- node/chainSimulator/chainSimulator.go | 19 ++++-- node/chainSimulator/chainSimulator_test.go | 10 +++ .../components/bootstrapComponents.go | 3 + .../components/cryptoComponents.go | 19 +++--- .../components/testOnlyProcessingNode.go | 16 ++--- node/chainSimulator/configs/configs.go | 62 +++++++++++++------ node/chainSimulator/process/processor.go | 43 ++++++++----- 7 files changed, 117 insertions(+), 55 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 521b99dc5a4..980f0d398ff 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -25,6 +25,8 @@ type ArgsChainSimulator struct { TempDir string PathToInitialConfig string NumOfShards uint32 + MinNodesPerShard uint32 + MetaChainMinNodes uint32 GenesisTimestamp int64 RoundDurationInMillis uint64 RoundsPerEpoch core.OptionalUint64 @@ -69,6 +71,8 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { GenesisTimeStamp: args.GenesisTimestamp, RoundDurationInMillis: args.RoundDurationInMillis, TempDir: args.TempDir, + MinNodesPerShard: args.MinNodesPerShard, + MetaChainMinNodes: args.MetaChainMinNodes, }) if err != nil { return err @@ -78,12 +82,19 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) } - for idx := range outputConfigs.ValidatorsPrivateKeys { - node, errCreate := s.createTestNode(outputConfigs.Configs, idx, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck) + for idx := 0; idx < int(args.NumOfShards)+1; idx++ { + shardIDStr := fmt.Sprintf("%d", idx-1) + if idx == 0 { + shardIDStr = "metachain" + } + + node, errCreate := s.createTestNode(outputConfigs.Configs, shardIDStr, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck) if errCreate != nil { return errCreate } + fmt.Println(node.GetProcessComponents().ShardCoordinator().SelfId()) + chainHandler, errCreate := process.NewBlocksCreator(node) if errCreate != nil { return errCreate @@ -109,7 +120,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { func (s *simulator) createTestNode( configs *config.Configs, - skIndex int, + shardIDStr string, gasScheduleFilename string, apiInterface components.APIConfigurator, bypassTxSignatureCheck bool, @@ -120,7 +131,7 @@ func (s *simulator) createTestNode( SyncedBroadcastNetwork: s.syncedBroadcastNetwork, NumShards: s.numOfShards, GasScheduleFilename: gasScheduleFilename, - SkIndex: skIndex, + ShardIDStr: shardIDStr, APIInterface: apiInterface, BypassTxSignatureCheck: bypassTxSignatureCheck, } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 2356f2d23fe..73503230edd 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -32,6 +32,8 @@ func TestNewChainSimulator(t *testing.T) { RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: core.OptionalUint64{}, ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -54,6 +56,8 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: core.OptionalUint64{}, ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -83,6 +87,8 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 100, + MetaChainMinNodes: 100, }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -127,6 +133,8 @@ func TestChainSimulator_SetState(t *testing.T) { RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, }) require.Nil(t, err) require.NotNil(t, chainSimulator) @@ -169,6 +177,8 @@ func TestChainSimulator_SetEntireState(t *testing.T) { RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, }) require.Nil(t, err) require.NotNil(t, chainSimulator) diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index 95fc78784e5..b40eeb0810d 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -23,6 +23,7 @@ type ArgsBootstrapComponentsHolder struct { ImportDBConfig config.ImportDbConfig PrefsConfig config.Preferences Config config.Config + ShardIDStr string } type bootstrapComponentsHolder struct { @@ -43,6 +44,8 @@ func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (factory.Boot closeHandler: NewCloseHandler(), } + args.PrefsConfig.Preferences.DestinationShardAsObserver = args.ShardIDStr + bootstrapComponentsFactoryArgs := bootstrapComp.BootstrapComponentsFactoryArgs{ Config: args.Config, PrefConfig: args.PrefsConfig, diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 0fceae60887..09b320bc72f 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -17,13 +17,12 @@ import ( // ArgsCryptoComponentsHolder holds all arguments needed to create a crypto components holder type ArgsCryptoComponentsHolder struct { - Config config.Config - EnableEpochsConfig config.EnableEpochs - Preferences config.Preferences - CoreComponentsHolder factory.CoreComponentsHolder - ValidatorKeyPemFileName string - SkIndex int - BypassTxSignatureCheck bool + Config config.Config + EnableEpochsConfig config.EnableEpochs + Preferences config.Preferences + CoreComponentsHolder factory.CoreComponentsHolder + AllValidatorKeysPemFileName string + BypassTxSignatureCheck bool } type cryptoComponentsHolder struct { @@ -60,10 +59,8 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp ActivateBLSPubKeyMessageVerification: true, IsInImportMode: false, ImportModeNoSigCheck: false, - P2pKeyPemFileName: "", - ValidatorKeyPemFileName: args.ValidatorKeyPemFileName, - AllValidatorKeysPemFileName: "", - SkIndex: args.SkIndex, + ValidatorKeyPemFileName: "missing.pem", + AllValidatorKeysPemFileName: args.AllValidatorKeysPemFileName, } cryptoComponentsFactory, err := cryptoComp.NewCryptoComponentsFactory(cryptoComponentsHandlerArgs) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index ebc03a63113..36ece2c880e 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -40,7 +40,7 @@ type ArgsTestOnlyProcessingNode struct { GasScheduleFilename string NumShards uint32 - SkIndex int + ShardIDStr string BypassTxSignatureCheck bool } @@ -104,13 +104,12 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } instance.CryptoComponentsHolder, err = CreateCryptoComponents(ArgsCryptoComponentsHolder{ - Config: *args.Configs.GeneralConfig, - EnableEpochsConfig: args.Configs.EpochConfig.EnableEpochs, - Preferences: *args.Configs.PreferencesConfig, - CoreComponentsHolder: instance.CoreComponentsHolder, - ValidatorKeyPemFileName: args.Configs.ConfigurationPathsHolder.ValidatorKey, - SkIndex: args.SkIndex, - BypassTxSignatureCheck: args.BypassTxSignatureCheck, + Config: *args.Configs.GeneralConfig, + EnableEpochsConfig: args.Configs.EpochConfig.EnableEpochs, + Preferences: *args.Configs.PreferencesConfig, + CoreComponentsHolder: instance.CoreComponentsHolder, + BypassTxSignatureCheck: args.BypassTxSignatureCheck, + AllValidatorKeysPemFileName: args.Configs.ConfigurationPathsHolder.AllValidatorKeys, }) if err != nil { return nil, err @@ -131,6 +130,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces ImportDBConfig: *args.Configs.ImportDbConfig, PrefsConfig: *args.Configs.PreferencesConfig, Config: *args.Configs.GeneralConfig, + ShardIDStr: args.ShardIDStr, }) if err != nil { return nil, err diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index acc85ad98d8..6baab61dd99 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -44,6 +44,8 @@ type ArgsChainSimulatorConfigs struct { GenesisTimeStamp int64 RoundDurationInMillis uint64 TempDir string + MinNodesPerShard uint32 + MetaChainMinNodes uint32 } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -78,18 +80,15 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi // generate validators key and nodesSetup.json privateKeys, publicKeys, err := generateValidatorsKeyAndUpdateFiles( configs, - args.NumOfShards, initialWallets.InitialWalletWithStake.Address, - args.GenesisTimeStamp, - args.RoundDurationInMillis, + args, ) if err != nil { return nil, err } - // generate validators.pem - configs.ConfigurationPathsHolder.ValidatorKey = path.Join(args.OriginalConfigsPath, "validatorKey.pem") - err = generateValidatorsPem(configs.ConfigurationPathsHolder.ValidatorKey, publicKeys, privateKeys) + configs.ConfigurationPathsHolder.AllValidatorKeys = path.Join(args.OriginalConfigsPath, "allValidatorsKeys.pem") + err = generateValidatorsPem(configs.ConfigurationPathsHolder.AllValidatorKeys, publicKeys, privateKeys) if err != nil { return nil, err } @@ -103,6 +102,12 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) + maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards + args.MetaChainMinNodes) + configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes + for idx := 0; idx < len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch); idx++ { + configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[idx].MaxNumNodes = uint32(maxNumNodes) + } + // set compatible trie configs configs.GeneralConfig.StateTriesConfig.SnapshotsEnabled = false @@ -136,7 +141,8 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs addresses := make([]data.InitialAccount, 0) stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) - stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(args.NumOfShards)+1)) // 2500 EGLD * number of nodes + numOfNodes := args.MinNodesPerShard*args.NumOfShards + args.MetaChainMinNodes + stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(numOfNodes))) // 2500 EGLD * number of nodes addresses = append(addresses, data.InitialAccount{ Address: initialAddressWithStake.Address, StakingValue: stakedValue, @@ -187,10 +193,8 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs func generateValidatorsKeyAndUpdateFiles( configs *config.Configs, - numOfShards uint32, address string, - genesisTimeStamp int64, - roundDurationInMillis uint64, + args ArgsChainSimulatorConfigs, ) ([]crypto.PrivateKey, []crypto.PublicKey, error) { blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) @@ -201,17 +205,20 @@ func generateValidatorsKeyAndUpdateFiles( return nil, nil, err } - nodes.RoundDuration = roundDurationInMillis - nodes.StartTime = genesisTimeStamp + nodes.RoundDuration = args.RoundDurationInMillis + nodes.StartTime = args.GenesisTimeStamp + nodes.ConsensusGroupSize = 1 - nodes.MinNodesPerShard = 1 - nodes.MetaChainMinNodes = 1 nodes.MetaChainConsensusGroupSize = 1 - nodes.InitialNodes = make([]*sharding.InitialNode, 0) - privateKeys := make([]crypto.PrivateKey, 0, numOfShards+1) - publicKeys := make([]crypto.PublicKey, 0, numOfShards+1) - for idx := uint32(0); idx < numOfShards+1; idx++ { + nodes.MinNodesPerShard = args.MinNodesPerShard + nodes.MetaChainMinNodes = args.MetaChainMinNodes + + nodes.InitialNodes = make([]*sharding.InitialNode, 0) + privateKeys := make([]crypto.PrivateKey, 0) + publicKeys := make([]crypto.PublicKey, 0) + // generate meta keys + for idx := uint32(0); idx < args.MetaChainMinNodes; idx++ { sk, pk := blockSigningGenerator.GeneratePair() privateKeys = append(privateKeys, sk) publicKeys = append(publicKeys, pk) @@ -227,6 +234,25 @@ func generateValidatorsKeyAndUpdateFiles( }) } + // generate shard keys + for idx1 := uint32(0); idx1 < args.NumOfShards; idx1++ { + for idx2 := uint32(0); idx2 < args.MinNodesPerShard; idx2++ { + sk, pk := blockSigningGenerator.GeneratePair() + privateKeys = append(privateKeys, sk) + publicKeys = append(publicKeys, pk) + + pkBytes, errB := pk.ToByteArray() + if errB != nil { + return nil, nil, errB + } + + nodes.InitialNodes = append(nodes.InitialNodes, &sharding.InitialNode{ + PubKey: hex.EncodeToString(pkBytes), + Address: address, + }) + } + } + marshaledNodes, err := json.Marshal(nodes) if err != nil { return nil, nil, err diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index d5aa917eceb..125306cba8d 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -3,9 +3,13 @@ package process import ( "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + logger "github.com/multiversx/mx-chain-logger-go" ) +var log = logger.GetOrCreate("process-block") + type manualRoundHandler interface { IncrementIndex() } @@ -34,12 +38,14 @@ func (creator *blocksCreator) IncrementRound() { func (creator *blocksCreator) CreateNewBlock() error { bp := creator.nodeHandler.GetProcessComponents().BlockProcessor() - nonce, round, prevHash, prevRandSeed := creator.getPreviousHeaderData() + nonce, round, prevHash, prevRandSeed, epoch := creator.getPreviousHeaderData() newHeader, err := bp.CreateNewHeader(round+1, nonce+1) if err != nil { return err } - err = newHeader.SetShardID(creator.nodeHandler.GetShardCoordinator().SelfId()) + + shardID := creator.nodeHandler.GetShardCoordinator().SelfId() + err = newHeader.SetShardID(shardID) if err != nil { return err } @@ -70,9 +76,20 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - blsKeyBytes := creator.nodeHandler.GetCryptoComponents().PublicKeyBytes() + validatorsGroup, err := creator.nodeHandler.GetProcessComponents().NodesCoordinator().ComputeConsensusGroup(prevRandSeed, newHeader.GetRound(), shardID, epoch) + if err != nil { + return err + } + blsKey := validatorsGroup[spos.IndexOfLeaderInConsensusGroup] + + isManaged := creator.nodeHandler.GetCryptoComponents().KeysHandler().IsKeyManagedByCurrentNode(blsKey.PubKey()) + if !isManaged { + log.Debug("cannot propose block", "shard", creator.nodeHandler.GetShardCoordinator().SelfId(), "missing private key") + return nil + } + signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() - randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), blsKeyBytes) + randSeed, err := signingHandler.CreateSignatureForPublicKey(newHeader.GetPrevRandSeed(), blsKey.PubKey()) if err != nil { return err } @@ -88,7 +105,7 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - err = creator.setHeaderSignatures(header) + err = creator.setHeaderSignatures(header, blsKey.PubKey()) if err != nil { return err } @@ -103,22 +120,22 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - err = creator.nodeHandler.GetBroadcastMessenger().BroadcastHeader(header, blsKeyBytes) + err = creator.nodeHandler.GetBroadcastMessenger().BroadcastHeader(header, blsKey.PubKey()) if err != nil { return err } - return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, blsKeyBytes) + return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, blsKey.PubKey()) } -func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prevHash, prevRandSeed []byte) { +func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prevHash, prevRandSeed []byte, epoch uint32) { currentHeader := creator.nodeHandler.GetChainHandler().GetCurrentBlockHeader() if currentHeader != nil { nonce, round = currentHeader.GetNonce(), currentHeader.GetRound() prevHash = creator.nodeHandler.GetChainHandler().GetCurrentBlockHeaderHash() prevRandSeed = currentHeader.GetRandSeed() - + epoch = currentHeader.GetEpoch() return } @@ -128,7 +145,7 @@ func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prev return } -func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) error { +func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler, blsKeyBytes []byte) error { signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() headerClone := header.ShallowClone() _ = headerClone.SetPubKeysBitmap(nil) @@ -138,7 +155,6 @@ func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) err return err } - blsKeyBytes := creator.nodeHandler.GetCryptoComponents().PublicKeyBytes() err = signingHandler.Reset([]string{string(blsKeyBytes)}) if err != nil { return err @@ -165,7 +181,7 @@ func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) err return err } - leaderSignature, err := creator.createLeaderSignature(header) + leaderSignature, err := creator.createLeaderSignature(header, blsKeyBytes) if err != nil { return err } @@ -178,7 +194,7 @@ func (creator *blocksCreator) setHeaderSignatures(header data.HeaderHandler) err return nil } -func (creator *blocksCreator) createLeaderSignature(header data.HeaderHandler) ([]byte, error) { +func (creator *blocksCreator) createLeaderSignature(header data.HeaderHandler, blsKeyBytes []byte) ([]byte, error) { headerClone := header.ShallowClone() err := headerClone.SetLeaderSignature(nil) if err != nil { @@ -192,7 +208,6 @@ func (creator *blocksCreator) createLeaderSignature(header data.HeaderHandler) ( signingHandler := creator.nodeHandler.GetCryptoComponents().ConsensusSigningHandler() - blsKeyBytes := creator.nodeHandler.GetCryptoComponents().PublicKeyBytes() return signingHandler.CreateSignatureForPublicKey(marshalizedHdr, blsKeyBytes) } From e22e4a992fad05717e2ba9a71dd56533031f72d9 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Fri, 22 Dec 2023 14:06:47 +0200 Subject: [PATCH 540/958] export relevant data --- .../processing/blockProcessorCreator_test.go | 5 +- .../executingMiniblocks_test.go | 14 +- process/block/export_test.go | 126 ++++++++++++++++++ .../mainFactoryMocks/dataComponentsStub.go | 69 ++++++++++ .../processMocks}/forkDetectorStub.go | 2 +- 5 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 testscommon/mainFactoryMocks/dataComponentsStub.go rename {factory/mock => testscommon/processMocks}/forkDetectorStub.go (99%) diff --git a/factory/processing/blockProcessorCreator_test.go b/factory/processing/blockProcessorCreator_test.go index 2842b92221f..21123f164bb 100644 --- a/factory/processing/blockProcessorCreator_test.go +++ b/factory/processing/blockProcessorCreator_test.go @@ -19,6 +19,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" componentsMock "github.com/multiversx/mx-chain-go/testscommon/components" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" + "github.com/multiversx/mx-chain-go/testscommon/processMocks" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" storageManager "github.com/multiversx/mx-chain-go/testscommon/storage" @@ -42,7 +43,7 @@ func Test_newBlockProcessorCreatorForShard(t *testing.T) { bp, vmFactoryForSimulate, err := pcf.NewBlockProcessor( &testscommon.RequestHandlerStub{}, - &mock.ForkDetectorStub{}, + &processMocks.ForkDetectorStub{}, &mock.EpochStartTriggerStub{}, &mock.BoostrapStorerStub{}, &mock.ValidatorStatisticsProcessorStub{}, @@ -162,7 +163,7 @@ func Test_newBlockProcessorCreatorForMeta(t *testing.T) { bp, vmFactoryForSimulate, err := pcf.NewBlockProcessor( &testscommon.RequestHandlerStub{}, - &mock.ForkDetectorStub{}, + &processMocks.ForkDetectorStub{}, &mock.EpochStartTriggerStub{}, &mock.BoostrapStorerStub{}, &mock.ValidatorStatisticsProcessorStub{}, diff --git a/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go b/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go index 0a532489422..b0ef9332a60 100644 --- a/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go +++ b/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go @@ -61,15 +61,15 @@ func TestShouldProcessBlocksInMultiShardArchitecture(t *testing.T) { proposerNode := nodes[0] - //sender shard keys, receivers keys + // sender shard keys, receivers keys sendersPrivateKeys := make([]crypto.PrivateKey, 3) receiversPublicKeys := make(map[uint32][]crypto.PublicKey) for i := 0; i < txToGenerateInEachMiniBlock; i++ { sendersPrivateKeys[i], _, _ = integrationTests.GenerateSkAndPkInShard(generateCoordinator, senderShard) - //receivers in same shard with the sender + // receivers in same shard with the sender _, pk, _ := integrationTests.GenerateSkAndPkInShard(generateCoordinator, senderShard) receiversPublicKeys[senderShard] = append(receiversPublicKeys[senderShard], pk) - //receivers in other shards + // receivers in other shards for _, shardId := range recvShards { _, pk, _ = integrationTests.GenerateSkAndPkInShard(generateCoordinator, shardId) receiversPublicKeys[shardId] = append(receiversPublicKeys[shardId], pk) @@ -111,13 +111,13 @@ func TestShouldProcessBlocksInMultiShardArchitecture(t *testing.T) { continue } - //test sender balances + // test sender balances for _, sk := range sendersPrivateKeys { valTransferred := big.NewInt(0).Mul(totalValuePerTx, big.NewInt(int64(len(receiversPublicKeys)))) valRemaining := big.NewInt(0).Sub(valMinting, valTransferred) integrationTests.TestPrivateKeyHasBalance(t, n, sk, valRemaining) } - //test receiver balances from same shard + // test receiver balances from same shard for _, pk := range receiversPublicKeys[proposerNode.ShardCoordinator.SelfId()] { integrationTests.TestPublicKeyHasBalance(t, n, pk, valToTransferPerTx) } @@ -136,7 +136,7 @@ func TestShouldProcessBlocksInMultiShardArchitecture(t *testing.T) { continue } - //test receiver balances from same shard + // test receiver balances from same shard for _, pk := range receiversPublicKeys[n.ShardCoordinator.SelfId()] { integrationTests.TestPublicKeyHasBalance(t, n, pk, valToTransferPerTx) } @@ -353,7 +353,7 @@ func TestSimpleTransactionsWithMoreValueThanBalanceYieldReceiptsInMultiShardedEn } func TestExecuteBlocksWithGapsBetweenBlocks(t *testing.T) { - //TODO fix this test + // TODO fix this test t.Skip("TODO fix this test") if testing.Short() { t.Skip("this is not a short test") diff --git a/process/block/export_test.go b/process/block/export_test.go index 3507ff0c02c..cef3c4de297 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -556,3 +556,129 @@ func (mp *metaProcessor) GetAllMarshalledTxs(body *block.Body) map[string][][]by func (bp *baseProcessor) SetNonceOfFirstCommittedBlock(nonce uint64) { bp.setNonceOfFirstCommittedBlock(nonce) } + +// HdrForBlock - +type HdrForBlock interface { + InitMaps() + Clone() *hdrForBlock + SetNumMissingHdrs(num uint32) + SetNumMissingFinalityAttestingHdrs(num uint32) + SetHighestHdrNonce(shardId uint32, nonce uint64) + SetHdrHashAndInfo(hash string, info *HdrInfo) + GetHdrHashMap() map[string]data.HeaderHandler + GetHighestHdrNonce() map[uint32]uint64 + GetMissingHdrs() uint32 + GetMissingFinalityAttestingHdrs() uint32 + GetHdrHashAndInfo() map[string]*HdrInfo +} + +// GetHdrForBlock - +func (mp *metaProcessor) GetHdrForBlock() *hdrForBlock { + return mp.hdrsForCurrBlock +} + +// InitMaps - +func (hfb *hdrForBlock) InitMaps() { + hfb.initMaps() + hfb.resetMissingHdrs() +} + +// Clone - +func (hfb *hdrForBlock) Clone() *hdrForBlock { + return hfb +} + +// SetNumMissingHdrs - +func (hfb *hdrForBlock) SetNumMissingHdrs(num uint32) { + hfb.mutHdrsForBlock.Lock() + hfb.missingHdrs = num + hfb.mutHdrsForBlock.Unlock() +} + +// SetNumMissingFinalityAttestingHdrs - +func (hfb *hdrForBlock) SetNumMissingFinalityAttestingHdrs(num uint32) { + hfb.mutHdrsForBlock.Lock() + hfb.missingFinalityAttestingHdrs = num + hfb.mutHdrsForBlock.Unlock() +} + +// SetHighestHdrNonce - +func (hfb *hdrForBlock) SetHighestHdrNonce(shardId uint32, nonce uint64) { + hfb.mutHdrsForBlock.Lock() + hfb.highestHdrNonce[shardId] = nonce + hfb.mutHdrsForBlock.Unlock() +} + +// HdrInfo - +type HdrInfo struct { + UsedInBlock bool + Hdr data.HeaderHandler +} + +// SetHdrHashAndInfo - +func (hfb *hdrForBlock) SetHdrHashAndInfo(hash string, info *HdrInfo) { + hfb.mutHdrsForBlock.Lock() + hfb.hdrHashAndInfo[hash] = &hdrInfo{ + hdr: info.Hdr, + usedInBlock: info.UsedInBlock, + } + hfb.mutHdrsForBlock.Unlock() +} + +// GetHdrHashMap - +func (hfb *hdrForBlock) GetHdrHashMap() map[string]data.HeaderHandler { + m := make(map[string]data.HeaderHandler) + + hfb.mutHdrsForBlock.RLock() + for hash, hi := range hfb.hdrHashAndInfo { + m[hash] = hi.hdr + } + hfb.mutHdrsForBlock.RUnlock() + + return m +} + +// GetHighestHdrNonce - +func (hfb *hdrForBlock) GetHighestHdrNonce() map[uint32]uint64 { + m := make(map[uint32]uint64) + + hfb.mutHdrsForBlock.RLock() + for shardId, nonce := range hfb.highestHdrNonce { + m[shardId] = nonce + } + hfb.mutHdrsForBlock.RUnlock() + + return m +} + +// GetMissingHdrs - +func (hfb *hdrForBlock) GetMissingHdrs() uint32 { + hfb.mutHdrsForBlock.RLock() + defer hfb.mutHdrsForBlock.RUnlock() + + return hfb.missingHdrs +} + +// GetMissingFinalityAttestingHdrs - +func (hfb *hdrForBlock) GetMissingFinalityAttestingHdrs() uint32 { + hfb.mutHdrsForBlock.RLock() + defer hfb.mutHdrsForBlock.RUnlock() + + return hfb.missingFinalityAttestingHdrs +} + +// GetHdrHashAndInfo - +func (hfb *hdrForBlock) GetHdrHashAndInfo() map[string]*HdrInfo { + hfb.mutHdrsForBlock.RLock() + defer hfb.mutHdrsForBlock.RUnlock() + + m := make(map[string]*HdrInfo) + for hash, hi := range hfb.hdrHashAndInfo { + m[hash] = &HdrInfo{ + UsedInBlock: hi.usedInBlock, + Hdr: hi.hdr, + } + } + + return m +} diff --git a/testscommon/mainFactoryMocks/dataComponentsStub.go b/testscommon/mainFactoryMocks/dataComponentsStub.go new file mode 100644 index 00000000000..3de2c0b33e6 --- /dev/null +++ b/testscommon/mainFactoryMocks/dataComponentsStub.go @@ -0,0 +1,69 @@ +package mainFactoryMocks + +import ( + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/multiversx/mx-chain-go/factory" +) + +// DataComponentsHolderStub - +type DataComponentsHolderStub struct { + BlockchainCalled func() data.ChainHandler + SetBlockchainCalled func(chain data.ChainHandler) + StorageServiceCalled func() dataRetriever.StorageService + DatapoolCalled func() dataRetriever.PoolsHolder + MiniBlocksProviderCalled func() factory.MiniBlockProvider + CloneCalled func() interface{} +} + +// Blockchain - +func (dchs *DataComponentsHolderStub) Blockchain() data.ChainHandler { + if dchs.BlockchainCalled != nil { + return dchs.BlockchainCalled() + } + return nil +} + +// SetBlockchain - +func (dchs *DataComponentsHolderStub) SetBlockchain(chain data.ChainHandler) { + if dchs.SetBlockchainCalled != nil { + dchs.SetBlockchainCalled(chain) + } +} + +// StorageService - +func (dchs *DataComponentsHolderStub) StorageService() dataRetriever.StorageService { + if dchs.StorageServiceCalled != nil { + return dchs.StorageServiceCalled() + } + return nil +} + +// Datapool - +func (dchs *DataComponentsHolderStub) Datapool() dataRetriever.PoolsHolder { + if dchs.DatapoolCalled != nil { + return dchs.DatapoolCalled() + } + return nil +} + +// MiniBlocksProvider - +func (dchs *DataComponentsHolderStub) MiniBlocksProvider() factory.MiniBlockProvider { + if dchs.MiniBlocksProviderCalled != nil { + return dchs.MiniBlocksProviderCalled() + } + return nil +} + +// Clone - +func (dchs *DataComponentsHolderStub) Clone() interface{} { + if dchs.CloneCalled != nil { + return dchs.CloneCalled() + } + return nil +} + +// IsInterfaceNil - +func (dchs *DataComponentsHolderStub) IsInterfaceNil() bool { + return dchs == nil +} diff --git a/factory/mock/forkDetectorStub.go b/testscommon/processMocks/forkDetectorStub.go similarity index 99% rename from factory/mock/forkDetectorStub.go rename to testscommon/processMocks/forkDetectorStub.go index 640c7e3899f..e21236438b6 100644 --- a/factory/mock/forkDetectorStub.go +++ b/testscommon/processMocks/forkDetectorStub.go @@ -1,4 +1,4 @@ -package mock +package processMocks import ( "github.com/multiversx/mx-chain-core-go/data" From 351d34e9d6a81978244ab2f4cc604cc28feb5ffe Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 29 Dec 2023 11:37:13 +0200 Subject: [PATCH 541/958] fixes after review and fix tests --- node/chainSimulator/chainSimulator.go | 2 -- node/chainSimulator/components/testOnlyProcessingNode_test.go | 3 +++ node/chainSimulator/configs/configs_test.go | 2 ++ node/chainSimulator/process/processor.go | 4 +++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 980f0d398ff..59511a2c7e4 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -93,8 +93,6 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { return errCreate } - fmt.Println(node.GetProcessComponents().ShardCoordinator().SelfId()) - chainHandler, errCreate := process.NewBlocksCreator(node) if errCreate != nil { return errCreate diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 8a0ed522e64..fade9b12e6f 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -19,6 +19,8 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo GenesisTimeStamp: 0, RoundDurationInMillis: 6000, TempDir: t.TempDir(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, }) require.Nil(t, err) @@ -30,6 +32,7 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), APIInterface: api.NewNoApiInterface(), + ShardIDStr: "0", } } diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index c086b36a4e8..15c633ce8cd 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -18,6 +18,8 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { RoundDurationInMillis: 6000, GenesisTimeStamp: 0, TempDir: t.TempDir(), + MetaChainMinNodes: 1, + MinNodesPerShard: 1, }) require.Nil(t, err) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 125306cba8d..8ee45be2c52 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -84,7 +84,9 @@ func (creator *blocksCreator) CreateNewBlock() error { isManaged := creator.nodeHandler.GetCryptoComponents().KeysHandler().IsKeyManagedByCurrentNode(blsKey.PubKey()) if !isManaged { - log.Debug("cannot propose block", "shard", creator.nodeHandler.GetShardCoordinator().SelfId(), "missing private key") + log.Debug("cannot propose block - leader bls key is missing", + "leader key", blsKey.PubKey(), + "shard", creator.nodeHandler.GetShardCoordinator().SelfId()) return nil } From 14c74cbebec4abe510c9f6a5f2b8b73a3105bd6d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 29 Dec 2023 13:36:46 +0200 Subject: [PATCH 542/958] fixes after second review --- node/chainSimulator/components/cryptoComponents.go | 5 +++-- node/chainSimulator/configs/configs.go | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 09b320bc72f..9a8649a0f47 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -59,8 +59,9 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp ActivateBLSPubKeyMessageVerification: true, IsInImportMode: false, ImportModeNoSigCheck: false, - ValidatorKeyPemFileName: "missing.pem", - AllValidatorKeysPemFileName: args.AllValidatorKeysPemFileName, + // set validator key pem file with a file that doesn't exist to all validators key pem file + ValidatorKeyPemFileName: "missing.pem", + AllValidatorKeysPemFileName: args.AllValidatorKeysPemFileName, } cryptoComponentsFactory, err := cryptoComp.NewCryptoComponentsFactory(cryptoComponentsHandlerArgs) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 6baab61dd99..a87d8e83a5e 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -34,7 +34,8 @@ const ( // ChainID contains the chain id ChainID = "chain" - shardIDWalletWithStake = 0 + shardIDWalletWithStake = 0 + allValidatorsPemFileName = "allValidatorsKeys.pem" ) // ArgsChainSimulatorConfigs holds all the components needed to create the chain simulator configs @@ -87,7 +88,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } - configs.ConfigurationPathsHolder.AllValidatorKeys = path.Join(args.OriginalConfigsPath, "allValidatorsKeys.pem") + configs.ConfigurationPathsHolder.AllValidatorKeys = path.Join(args.OriginalConfigsPath, allValidatorsPemFileName) err = generateValidatorsPem(configs.ConfigurationPathsHolder.AllValidatorKeys, publicKeys, privateKeys) if err != nil { return nil, err From 51848991bba14f04959f884d0af5ea16c67e02fc Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 3 Jan 2024 15:53:15 +0200 Subject: [PATCH 543/958] - constant redefinition --- storage/factory/dbConfigHandler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/factory/dbConfigHandler.go b/storage/factory/dbConfigHandler.go index 5dc426ad441..e6066f10c21 100644 --- a/storage/factory/dbConfigHandler.go +++ b/storage/factory/dbConfigHandler.go @@ -12,7 +12,7 @@ const ( dbConfigFileName = "config.toml" defaultType = "LvlDBSerial" defaultBatchDelaySeconds = 2 - defaultMaxBatchSize = 100 + defaultMaxBatchSize = 45000 // TODO: refactor this in next release candidate defaultMaxOpenFiles = 10 ) From 1d84a313cad29b485e56ed142b4b84076c770514 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 3 Jan 2024 17:05:55 +0200 Subject: [PATCH 544/958] - refactored solution --- storage/factory/dbConfigHandler.go | 29 +++++++++++++++---------- storage/factory/dbConfigHandler_test.go | 22 ++++++++++++++----- storage/factory/export_test.go | 13 +++-------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/storage/factory/dbConfigHandler.go b/storage/factory/dbConfigHandler.go index e6066f10c21..28ba8b5dcdb 100644 --- a/storage/factory/dbConfigHandler.go +++ b/storage/factory/dbConfigHandler.go @@ -1,6 +1,7 @@ package factory import ( + "fmt" "os" "path/filepath" @@ -9,11 +10,8 @@ import ( ) const ( - dbConfigFileName = "config.toml" - defaultType = "LvlDBSerial" - defaultBatchDelaySeconds = 2 - defaultMaxBatchSize = 45000 // TODO: refactor this in next release candidate - defaultMaxOpenFiles = 10 + dbConfigFileName = "config.toml" + defaultType = "LvlDBSerial" ) type dbConfigHandler struct { @@ -42,7 +40,10 @@ func (dh *dbConfigHandler) GetDBConfig(path string) (*config.DBConfig, error) { dbConfigFromFile := &config.DBConfig{} err := core.LoadTomlFile(dbConfigFromFile, getPersisterConfigFilePath(path)) if err == nil { - log.Debug("GetDBConfig: loaded db config from toml config file", "path", dbConfigFromFile) + log.Debug("GetDBConfig: loaded db config from toml config file", + "config path", path, + "configuration", fmt.Sprintf("%+v", dbConfigFromFile), + ) return dbConfigFromFile, nil } @@ -50,12 +51,15 @@ func (dh *dbConfigHandler) GetDBConfig(path string) (*config.DBConfig, error) { if !empty { dbConfig := &config.DBConfig{ Type: defaultType, - BatchDelaySeconds: defaultBatchDelaySeconds, - MaxBatchSize: defaultMaxBatchSize, - MaxOpenFiles: defaultMaxOpenFiles, + BatchDelaySeconds: dh.batchDelaySeconds, + MaxBatchSize: dh.maxBatchSize, + MaxOpenFiles: dh.maxOpenFiles, } - log.Debug("GetDBConfig: loaded default db config") + log.Debug("GetDBConfig: loaded default db config", + "configuration", fmt.Sprintf("%+v", dbConfig), + ) + return dbConfig, nil } @@ -68,7 +72,10 @@ func (dh *dbConfigHandler) GetDBConfig(path string) (*config.DBConfig, error) { NumShards: dh.numShards, } - log.Debug("GetDBConfig: loaded db config from main config file") + log.Debug("GetDBConfig: loaded db config from main config file", + "configuration", fmt.Sprintf("%+v", dbConfig), + ) + return dbConfig, nil } diff --git a/storage/factory/dbConfigHandler_test.go b/storage/factory/dbConfigHandler_test.go index 406218be7dc..039da28ebf9 100644 --- a/storage/factory/dbConfigHandler_test.go +++ b/storage/factory/dbConfigHandler_test.go @@ -49,11 +49,16 @@ func TestDBConfigHandler_GetDBConfig(t *testing.T) { require.Nil(t, err) require.Equal(t, &expectedDBConfig, conf) }) - t.Run("not empty dir, load default db config", func(t *testing.T) { t.Parallel() - pf := factory.NewDBConfigHandler(createDefaultDBConfig()) + testConfig := createDefaultDBConfig() + testConfig.BatchDelaySeconds = 37 + testConfig.MaxBatchSize = 38 + testConfig.MaxOpenFiles = 39 + testConfig.ShardIDProviderType = "BinarySplit" + testConfig.NumShards = 4 + pf := factory.NewDBConfigHandler(testConfig) dirPath := t.TempDir() @@ -68,13 +73,21 @@ func TestDBConfigHandler_GetDBConfig(t *testing.T) { _ = f.Close() }() - expectedDBConfig := factory.GetDefaultDBConfig() + expectedDBConfig := &config.DBConfig{ + FilePath: "", + Type: factory.DefaultType, + BatchDelaySeconds: testConfig.BatchDelaySeconds, + MaxBatchSize: testConfig.MaxBatchSize, + MaxOpenFiles: testConfig.MaxOpenFiles, + UseTmpAsFilePath: false, + ShardIDProviderType: "", + NumShards: 0, + } conf, err := pf.GetDBConfig(dirPath) require.Nil(t, err) require.Equal(t, expectedDBConfig, conf) }) - t.Run("empty dir, load db config from main config", func(t *testing.T) { t.Parallel() @@ -88,7 +101,6 @@ func TestDBConfigHandler_GetDBConfig(t *testing.T) { require.Nil(t, err) require.Equal(t, &expectedDBConfig, conf) }) - t.Run("getDBConfig twice, should load from config file if file available", func(t *testing.T) { t.Parallel() diff --git a/storage/factory/export_test.go b/storage/factory/export_test.go index 4b5ac54baac..23317b7d4cf 100644 --- a/storage/factory/export_test.go +++ b/storage/factory/export_test.go @@ -5,21 +5,14 @@ import ( "github.com/multiversx/mx-chain-go/storage" ) +// DefaultType exports the defaultType const to be used in tests +const DefaultType = defaultType + // GetPersisterConfigFilePath - func GetPersisterConfigFilePath(path string) string { return getPersisterConfigFilePath(path) } -// GetDefaultDBConfig - -func GetDefaultDBConfig() *config.DBConfig { - return &config.DBConfig{ - Type: defaultType, - BatchDelaySeconds: defaultBatchDelaySeconds, - MaxBatchSize: defaultMaxBatchSize, - MaxOpenFiles: defaultMaxOpenFiles, - } -} - // NewPersisterCreator - func NewPersisterCreator(config config.DBConfig) *persisterCreator { return newPersisterCreator(config) From 32f1c0e9ba0a5ad88976d0ea8011a635a97b84b5 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 4 Jan 2024 15:33:32 +0200 Subject: [PATCH 545/958] FIX: After merge in stakingV4 1 --- common/constants.go | 1 - common/enablers/enableEpochsHandler.go | 18 ------------------ common/enablers/enableEpochsHandler_test.go | 8 -------- config/tomlConfig_test.go | 2 -- go.mod | 2 +- .../vm/esdt/process/esdtProcess_test.go | 1 - .../vm/txsFee/guardAccount_test.go | 1 - process/smartContract/process.go | 1 - process/smartContract/process_test.go | 1 - process/smartContract/processorV2/processV2.go | 6 ++---- .../smartContract/processorV2/process_test.go | 2 -- process/transaction/metaProcess.go | 1 - process/transaction/metaProcess_test.go | 2 -- sharding/mock/enableEpochsHandlerMock.go | 2 -- 14 files changed, 3 insertions(+), 45 deletions(-) diff --git a/common/constants.go b/common/constants.go index fdc343f4d6c..79e65b7d5d3 100644 --- a/common/constants.go +++ b/common/constants.go @@ -930,7 +930,6 @@ const ( ESDTMultiTransferFlag core.EnableEpochFlag = "ESDTMultiTransferFlag" GlobalMintBurnFlag core.EnableEpochFlag = "GlobalMintBurnFlag" ESDTTransferRoleFlag core.EnableEpochFlag = "ESDTTransferRoleFlag" - BuiltInFunctionOnMetaFlag core.EnableEpochFlag = "BuiltInFunctionOnMetaFlag" ComputeRewardCheckpointFlag core.EnableEpochFlag = "ComputeRewardCheckpointFlag" SCRSizeInvariantCheckFlag core.EnableEpochFlag = "SCRSizeInvariantCheckFlag" BackwardCompSaveKeyValueFlag core.EnableEpochFlag = "BackwardCompSaveKeyValueFlag" diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 6089b7c5874..345ac613477 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -275,18 +275,6 @@ func (handler *enableEpochsHandler) createAllFlagsMap() { }, activationEpoch: handler.enableEpochsConfig.ESDTTransferRoleEnableEpoch, }, - common.BuiltInFunctionOnMetaFlag: { - isActiveInEpoch: func(epoch uint32) bool { - return epoch >= handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch - }, - activationEpoch: handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, - }, - common.TransferToMetaFlag: { - isActiveInEpoch: func(epoch uint32) bool { - return epoch >= handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch - }, - activationEpoch: handler.enableEpochsConfig.BuiltInFunctionOnMetaEnableEpoch, - }, common.ComputeRewardCheckpointFlag: { isActiveInEpoch: func(epoch uint32) bool { return epoch >= handler.enableEpochsConfig.ComputeRewardCheckpointEnableEpoch @@ -671,12 +659,6 @@ func (handler *enableEpochsHandler) createAllFlagsMap() { }, activationEpoch: handler.enableEpochsConfig.BalanceWaitingListsEnableEpoch, }, - common.WaitingListFixFlag: { - isActiveInEpoch: func(epoch uint32) bool { - return epoch >= handler.enableEpochsConfig.WaitingListFixEnableEpoch - }, - activationEpoch: handler.enableEpochsConfig.WaitingListFixEnableEpoch, - }, common.NFTStopCreateFlag: { isActiveInEpoch: func(epoch uint32) bool { return epoch >= handler.enableEpochsConfig.NFTStopCreateEnableEpoch diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 78f19743377..813bcb8a38b 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -14,8 +14,6 @@ import ( "github.com/stretchr/testify/require" ) -LEAVING BUILDING ERROR HERE TO REMEBER TO DELETE BuiltInFunctionOnMeta + WaitingListFixEnableEpoch - func createEnableEpochsConfig() config.EnableEpochs { return config.EnableEpochs{ SCDeployEnableEpoch: 1, @@ -47,12 +45,10 @@ func createEnableEpochsConfig() config.EnableEpochs { SaveJailedAlwaysEnableEpoch: 27, ReDelegateBelowMinCheckEnableEpoch: 28, ValidatorToDelegationEnableEpoch: 29, - WaitingListFixEnableEpoch: 30, IncrementSCRNonceInMultiTransferEnableEpoch: 31, ESDTMultiTransferEnableEpoch: 32, GlobalMintBurnDisableEpoch: 33, ESDTTransferRoleEnableEpoch: 34, - BuiltInFunctionOnMetaEnableEpoch: 35, ComputeRewardCheckpointEnableEpoch: 36, SCRSizeInvariantCheckEnableEpoch: 37, BackwardCompSaveKeyValueEnableEpoch: 38, @@ -232,7 +228,6 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { require.True(t, handler.IsFlagEnabled(common.ESDTMultiTransferFlag)) require.False(t, handler.IsFlagEnabled(common.GlobalMintBurnFlag)) // < require.True(t, handler.IsFlagEnabled(common.ESDTTransferRoleFlag)) - require.True(t, handler.IsFlagEnabled(common.BuiltInFunctionOnMetaFlag)) require.True(t, handler.IsFlagEnabled(common.ComputeRewardCheckpointFlag)) require.True(t, handler.IsFlagEnabled(common.SCRSizeInvariantCheckFlag)) require.False(t, handler.IsFlagEnabled(common.BackwardCompSaveKeyValueFlag)) // < @@ -348,7 +343,6 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { require.Equal(t, cfg.ESDTMultiTransferEnableEpoch, handler.GetActivationEpoch(common.ESDTMultiTransferFlag)) require.Equal(t, cfg.GlobalMintBurnDisableEpoch, handler.GetActivationEpoch(common.GlobalMintBurnFlag)) require.Equal(t, cfg.ESDTTransferRoleEnableEpoch, handler.GetActivationEpoch(common.ESDTTransferRoleFlag)) - require.Equal(t, cfg.BuiltInFunctionOnMetaEnableEpoch, handler.GetActivationEpoch(common.BuiltInFunctionOnMetaFlag)) require.Equal(t, cfg.ComputeRewardCheckpointEnableEpoch, handler.GetActivationEpoch(common.ComputeRewardCheckpointFlag)) require.Equal(t, cfg.SCRSizeInvariantCheckEnableEpoch, handler.GetActivationEpoch(common.SCRSizeInvariantCheckFlag)) require.Equal(t, cfg.BackwardCompSaveKeyValueEnableEpoch, handler.GetActivationEpoch(common.BackwardCompSaveKeyValueFlag)) @@ -389,7 +383,6 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { require.Equal(t, cfg.ESDTMetadataContinuousCleanupEnableEpoch, handler.GetActivationEpoch(common.SendAlwaysFlag)) require.Equal(t, cfg.OptimizeNFTStoreEnableEpoch, handler.GetActivationEpoch(common.ValueLengthCheckFlag)) require.Equal(t, cfg.OptimizeNFTStoreEnableEpoch, handler.GetActivationEpoch(common.CheckTransferFlag)) - require.Equal(t, cfg.BuiltInFunctionOnMetaEnableEpoch, handler.GetActivationEpoch(common.TransferToMetaFlag)) require.Equal(t, cfg.ESDTMultiTransferEnableEpoch, handler.GetActivationEpoch(common.ESDTNFTImprovementV1Flag)) require.Equal(t, cfg.ESDTMetadataContinuousCleanupEnableEpoch, handler.GetActivationEpoch(common.ChangeDelegationOwnerFlag)) require.Equal(t, cfg.RefactorPeersMiniBlocksEnableEpoch, handler.GetActivationEpoch(common.RefactorPeersMiniBlocksFlag)) @@ -415,7 +408,6 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { require.Equal(t, cfg.ScToScLogEventEnableEpoch, handler.GetActivationEpoch(common.ScToScLogEventFlag)) require.Equal(t, cfg.BlockGasAndFeesReCheckEnableEpoch, handler.GetActivationEpoch(common.BlockGasAndFeesReCheckFlag)) require.Equal(t, cfg.BalanceWaitingListsEnableEpoch, handler.GetActivationEpoch(common.BalanceWaitingListsFlag)) - require.Equal(t, cfg.WaitingListFixEnableEpoch, handler.GetActivationEpoch(common.WaitingListFixFlag)) require.Equal(t, cfg.NFTStopCreateEnableEpoch, handler.GetActivationEpoch(common.NFTStopCreateFlag)) require.Equal(t, cfg.ChangeOwnerAddressCrossShardThroughSCEnableEpoch, handler.GetActivationEpoch(common.IsChangeOwnerAddressCrossShardThroughSCFlag)) require.Equal(t, cfg.FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch, handler.GetActivationEpoch(common.FixGasRemainingForSaveKeyValueFlag)) diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 288c5a0b631..fa999cc048f 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -882,12 +882,10 @@ func TestEnableEpochConfig(t *testing.T) { SaveJailedAlwaysEnableEpoch: 27, ReDelegateBelowMinCheckEnableEpoch: 28, ValidatorToDelegationEnableEpoch: 29, - WaitingListFixEnableEpoch: 30, IncrementSCRNonceInMultiTransferEnableEpoch: 31, ESDTMultiTransferEnableEpoch: 32, GlobalMintBurnDisableEpoch: 33, ESDTTransferRoleEnableEpoch: 34, - BuiltInFunctionOnMetaEnableEpoch: 35, ComputeRewardCheckpointEnableEpoch: 36, SCRSizeInvariantCheckEnableEpoch: 37, BackwardCompSaveKeyValueEnableEpoch: 38, diff --git a/go.mod b/go.mod index 4f9efc05b97..7bb8e74c68c 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa -github.com/multiversx/mx-chain-vm-common-go v1.4.1-0.20230321123200-7ad640c0bb4b + github.com/multiversx/mx-chain-vm-common-go 48d626709214a70fa731ece0d9baa723f157fac8 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92-0.20231228071246-c1b45eae5955 diff --git a/integrationTests/vm/esdt/process/esdtProcess_test.go b/integrationTests/vm/esdt/process/esdtProcess_test.go index 34db0d51c6c..d580847067a 100644 --- a/integrationTests/vm/esdt/process/esdtProcess_test.go +++ b/integrationTests/vm/esdt/process/esdtProcess_test.go @@ -1408,7 +1408,6 @@ func TestExecOnDestWithTokenTransferFromScAtoScBWithIntermediaryExecOnDest_NotEn enableEpochs := config.EnableEpochs{ GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, SCProcessorV2EnableEpoch: integrationTests.UnreachableEpoch, FailExecutionOnEveryAPIErrorEnableEpoch: integrationTests.UnreachableEpoch, } diff --git a/integrationTests/vm/txsFee/guardAccount_test.go b/integrationTests/vm/txsFee/guardAccount_test.go index 2baa497f991..3d886fd5bad 100644 --- a/integrationTests/vm/txsFee/guardAccount_test.go +++ b/integrationTests/vm/txsFee/guardAccount_test.go @@ -99,7 +99,6 @@ func prepareTestContextForGuardedAccounts(tb testing.TB) *vm.VMTestContext { testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGasAndRoundConfig( config.EnableEpochs{ GovernanceEnableEpoch: unreachableEpoch, - WaitingListFixEnableEpoch: unreachableEpoch, SetSenderInEeiOutputTransferEnableEpoch: unreachableEpoch, RefactorPeersMiniBlocksEnableEpoch: unreachableEpoch, }, diff --git a/process/smartContract/process.go b/process/smartContract/process.go index e267f5e49c3..7bd0c9a2f52 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -180,7 +180,6 @@ func NewSmartContractProcessor(args scrCommon.ArgsNewSmartContractProcessor) (*s common.OptimizeGasUsedInCrossMiniBlocksFlag, common.OptimizeNFTStoreFlag, common.RemoveNonUpdatedStorageFlag, - common.BuiltInFunctionOnMetaFlag, common.BackwardCompSaveKeyValueFlag, common.ReturnDataToLastTransferFlagAfterEpoch, common.FixAsyncCallBackArgsListFlag, diff --git a/process/smartContract/process_test.go b/process/smartContract/process_test.go index ecd161ea381..fcd543de495 100644 --- a/process/smartContract/process_test.go +++ b/process/smartContract/process_test.go @@ -3341,7 +3341,6 @@ func TestScProcessor_ProcessSmartContractResultExecuteSCIfMetaAndBuiltIn(t *test require.True(t, executeCalled) executeCalled = false - enableEpochsHandlerStub.AddActiveFlags(common.BuiltInFunctionsFlag, common.BuiltInFunctionOnMetaFlag) _, err = sc.ProcessSmartContractResult(&scr) require.Nil(t, err) require.False(t, executeCalled) diff --git a/process/smartContract/processorV2/processV2.go b/process/smartContract/processorV2/processV2.go index 938bfe725c3..126433c6dee 100644 --- a/process/smartContract/processorV2/processV2.go +++ b/process/smartContract/processorV2/processV2.go @@ -163,9 +163,7 @@ func NewSmartContractProcessorV2(args scrCommon.ArgsNewSmartContractProcessor) ( if check.IfNil(args.EnableEpochsHandler) { return nil, process.ErrNilEnableEpochsHandler } - err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ - common.BuiltInFunctionOnMetaFlag, - }) + err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{}) if err != nil { return nil, err } @@ -2735,7 +2733,7 @@ func (sc *scProcessor) ProcessSmartContractResult(scr *smartContractResult.Smart returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err case process.BuiltInFunctionCall: - if sc.shardCoordinator.SelfId() == core.MetachainShardId && !sc.enableEpochsHandler.IsFlagEnabled(common.BuiltInFunctionOnMetaFlag) { + if sc.shardCoordinator.SelfId() == core.MetachainShardId { returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err } diff --git a/process/smartContract/processorV2/process_test.go b/process/smartContract/processorV2/process_test.go index 01a623cbe26..5f3cec626a2 100644 --- a/process/smartContract/processorV2/process_test.go +++ b/process/smartContract/processorV2/process_test.go @@ -371,7 +371,6 @@ func TestNewSmartContractProcessorVerifyAllMembers(t *testing.T) { t.Parallel() arguments := createMockSmartContractProcessorArguments() - arguments.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch = 10 sc, _ := NewSmartContractProcessorV2(arguments) assert.Equal(t, arguments.VmContainer, sc.vmContainer) @@ -3275,7 +3274,6 @@ func TestScProcessor_ProcessSmartContractResultExecuteSCIfMetaAndBuiltIn(t *test require.True(t, executeCalled) executeCalled = false - enableEpochsHandlerStub.AddActiveFlags(common.BuiltInFunctionOnMetaFlag) _, err = sc.ProcessSmartContractResult(&scr) require.Nil(t, err) require.False(t, executeCalled) diff --git a/process/transaction/metaProcess.go b/process/transaction/metaProcess.go index ade6f33329b..963bfa31721 100644 --- a/process/transaction/metaProcess.go +++ b/process/transaction/metaProcess.go @@ -65,7 +65,6 @@ func NewMetaTxProcessor(args ArgsNewMetaTxProcessor) (*metaTxProcessor, error) { } err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ common.PenalizedTooMuchGasFlag, - common.BuiltInFunctionOnMetaFlag, common.ESDTFlag, }) if err != nil { diff --git a/process/transaction/metaProcess_test.go b/process/transaction/metaProcess_test.go index ac536af4e30..63e997ef857 100644 --- a/process/transaction/metaProcess_test.go +++ b/process/transaction/metaProcess_test.go @@ -458,8 +458,6 @@ func TestMetaTxProcessor_ProcessTransactionBuiltInCallTxShouldWork(t *testing.T) return 0, nil } - enableEpochsHandlerStub.AddActiveFlags(common.BuiltInFunctionOnMetaFlag) - _, err = txProc.ProcessTransaction(&tx) assert.Nil(t, err) assert.True(t, builtInCalled) diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index a039dfbbc65..32c6b4fa14c 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -17,8 +17,6 @@ func (mock *EnableEpochsHandlerMock) GetActivationEpoch(flag core.EnableEpochFla switch flag { case common.RefactorPeersMiniBlocksFlag: return mock.RefactorPeersMiniBlocksEnableEpochField - case common.WaitingListFixFlag: - return mock.WaitingListFixEnableEpochField default: return 0 From ec365da5084d5e965b2243d6c17aedde4bb2a58f Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 4 Jan 2024 15:47:18 +0200 Subject: [PATCH 546/958] FIX: After merge in stakingV4 2 + go mod vm common --- go.mod | 4 ++-- go.sum | 4 ++-- .../vm/staking/componentsHolderCreator.go | 14 +++++++------- .../vm/staking/nodesCoordiantorCreator.go | 2 +- process/smartContract/processorV2/processV2.go | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 7bb8e74c68c..6e3481871d3 100644 --- a/go.mod +++ b/go.mod @@ -20,8 +20,8 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.14-0.20231215125130-a3bed6e76040 github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 - github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa - github.com/multiversx/mx-chain-vm-common-go 48d626709214a70fa731ece0d9baa723f157fac8 + github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240104131930-48d626709214 + github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92-0.20231228071246-c1b45eae5955 diff --git a/go.sum b/go.sum index 0375c025713..b0a8eb37484 100644 --- a/go.sum +++ b/go.sum @@ -398,8 +398,8 @@ github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296/go.mod h1:WocyahfHCC3oGILEVdRe7I4/+q/TLCORoTo1X4wGmF4= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 h1:2RJ6T31pLN75l4xfhTicGZ+gVOPMxSGPip+O1XYVYac= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4/go.mod h1:ioCT2oHQ+TyHQYpgjxzlUdy7dCdv56+w5HnBg9z96eY= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa h1:xdDeUC4yOfiUwctkYioYMjjigBZoZo5RZq1e5WoCVRs= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa/go.mod h1:7jjGRykSfLeMs6iQdszlE0lGK2xp9/cctiVdeKbQLLM= +github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240104131930-48d626709214 h1:o8RyWs7X811dCRWRf8qbjegIWCNaVUJE+U8ooWZ+U9w= +github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240104131930-48d626709214/go.mod h1:7jjGRykSfLeMs6iQdszlE0lGK2xp9/cctiVdeKbQLLM= github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 h1:qfzeTPI2oSgxnw52KiVWc2fHMem6FZIkX1Azwy64098= github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3/go.mod h1:4kcpwq70UB3Clnc6Q0krGA8hgQ26JTQpmCP+4y5aiV0= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 h1:CDSn4hgiGwoOSSLmajgOvjdoRxfJSXjEu/CfXiqihwo= diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 9d858208277..52efdfaad0a 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -37,7 +37,6 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/trie" - "github.com/multiversx/mx-chain-go/trie/hashesHolder" ) const hashSize = 32 @@ -163,12 +162,13 @@ func createStateComponents(coreComponents factory.CoreComponentsHolder) factory. func getNewTrieStorageManagerArgs(coreComponents factory.CoreComponentsHolder) trie.NewTrieStorageManagerArgs { return trie.NewTrieStorageManagerArgs{ - MainStorer: testscommon.CreateMemUnit(), - CheckpointsStorer: testscommon.CreateMemUnit(), - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - GeneralConfig: config.TrieStorageManagerConfig{SnapshotsGoroutineNum: 1}, - CheckpointHashesHolder: hashesHolder.NewCheckpointHashesHolder(10, hashSize), + MainStorer: testscommon.CreateMemUnit(), + //CheckpointsStorer: testscommon.CreateMemUnit(), + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + GeneralConfig: config.TrieStorageManagerConfig{SnapshotsGoroutineNum: 1}, + LEAVING BUILD ERROR TO FILL THIS + //CheckpointHashesHolder: hashesHolder.NewCheckpointHashesHolder(10, hashSize), IdleProvider: &testscommon.ProcessStatusHandlerStub{}, } } diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 875eb08cef4..296626337b1 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -5,7 +5,6 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/marshal" - "github.com/multiversx/mx-chain-core-go/storage/lrucache" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever/dataPool" @@ -15,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + "github.com/multiversx/mx-chain-storage-go/lrucache" ) const ( diff --git a/process/smartContract/processorV2/processV2.go b/process/smartContract/processorV2/processV2.go index 126433c6dee..1217717cbca 100644 --- a/process/smartContract/processorV2/processV2.go +++ b/process/smartContract/processorV2/processV2.go @@ -2733,7 +2733,7 @@ func (sc *scProcessor) ProcessSmartContractResult(scr *smartContractResult.Smart returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err case process.BuiltInFunctionCall: - if sc.shardCoordinator.SelfId() == core.MetachainShardId { + if sc.shardCoordinator.SelfId() == core.MetachainShardId && !sc.enableEpochsHandler.IsFlagEnabled(common.BuiltInFunctionOnMetaFlag) { returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err } From a189c1ddfee886d22bb59f9fca2fc6f24c1f82fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 4 Jan 2024 15:51:14 +0200 Subject: [PATCH 547/958] Sandbox for vm queries. --- process/smartContract/scQueryService.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index eb3d9b95e4e..099f8d6afdd 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -199,7 +199,7 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } accountsAdapter := service.blockChainHook.GetAccountsAdapter() - err = accountsAdapter.RecreateTrie(blockRootHash) + err = accountsAdapter.RecreateTrieFromEpoch(holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: 1247})) if err != nil { return nil, nil, err } From 7988db27426c24df3c92394d18cda1242d37dbbe Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 4 Jan 2024 15:59:56 +0200 Subject: [PATCH 548/958] FIX: After merge in stakingV4 3 --- epochStart/bootstrap/baseStorageHandler.go | 3 + epochStart/bootstrap/metaStorageHandler.go | 13 ++- .../bootstrap/metaStorageHandler_test.go | 8 +- epochStart/bootstrap/shardStorageHandler.go | 16 +--- .../bootstrap/shardStorageHandler_test.go | 25 +----- integrationTests/vm/testInitializer.go | 8 +- testscommon/genesisMocks/nodesSetupStub.go | 82 ------------------- 7 files changed, 19 insertions(+), 136 deletions(-) diff --git a/epochStart/bootstrap/baseStorageHandler.go b/epochStart/bootstrap/baseStorageHandler.go index 91a9e2c2230..1442af7e3b0 100644 --- a/epochStart/bootstrap/baseStorageHandler.go +++ b/epochStart/bootstrap/baseStorageHandler.go @@ -34,6 +34,9 @@ type StorageHandlerArgs struct { NodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory SnapshotsEnabled bool ManagedPeersHolder common.ManagedPeersHolder + NodeProcessingMode common.NodeProcessingMode + RepopulateTokensSupplies bool + StateStatsHandler common.StateStatisticsHandler } func checkNilArgs(args StorageHandlerArgs) error { diff --git a/epochStart/bootstrap/metaStorageHandler.go b/epochStart/bootstrap/metaStorageHandler.go index b47baa230c8..01f65ccabe6 100644 --- a/epochStart/bootstrap/metaStorageHandler.go +++ b/epochStart/bootstrap/metaStorageHandler.go @@ -19,11 +19,6 @@ type metaStorageHandler struct { *baseStorageHandler } -LEAVING BUILD ERR TO ADD THESE: - -nodeProcessingMode common.NodeProcessingMode, -- stateStatsHandler common.StateStatisticsHandler, -- RepopulateTokensSupplies : false - // NewMetaStorageHandler will return a new instance of metaStorageHandler func NewMetaStorageHandler(args StorageHandlerArgs) (*metaStorageHandler, error) { err := checkNilArgs(args) @@ -40,11 +35,13 @@ func NewMetaStorageHandler(args StorageHandlerArgs) (*metaStorageHandler, error) PathManager: args.PathManagerHandler, EpochStartNotifier: epochStartNotifier, NodeTypeProvider: args.NodeTypeProvider, - CurrentEpoch: args.CurrentEpoch, StorageType: factory.BootstrapStorageService, - CreateTrieEpochRootHashStorer: false, - SnapshotsEnabled: args.SnapshotsEnabled, ManagedPeersHolder: args.ManagedPeersHolder, + CurrentEpoch: args.CurrentEpoch, + CreateTrieEpochRootHashStorer: false, + NodeProcessingMode: args.NodeProcessingMode, + RepopulateTokensSupplies: false, + StateStatsHandler: args.StateStatsHandler, }, ) if err != nil { diff --git a/epochStart/bootstrap/metaStorageHandler_test.go b/epochStart/bootstrap/metaStorageHandler_test.go index 92f8e8d227d..92603df176a 100644 --- a/epochStart/bootstrap/metaStorageHandler_test.go +++ b/epochStart/bootstrap/metaStorageHandler_test.go @@ -39,10 +39,10 @@ func createStorageHandlerArgs() StorageHandlerArgs { NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, - - LEAVE ERROR HERE - - common.Normal, - - disabled.NewStateStatistics(), + SnapshotsEnabled: false, + NodeProcessingMode: common.Normal, + StateStatsHandler: disabled.NewStateStatistics(), + RepopulateTokensSupplies: false, } } diff --git a/epochStart/bootstrap/shardStorageHandler.go b/epochStart/bootstrap/shardStorageHandler.go index 7a1e5130e95..49535a7228c 100644 --- a/epochStart/bootstrap/shardStorageHandler.go +++ b/epochStart/bootstrap/shardStorageHandler.go @@ -23,11 +23,6 @@ type shardStorageHandler struct { *baseStorageHandler } -LEAVING BUILD ERROR -NodeProcessingMode: nodeProcessingMode, -RepopulateTokensSupplies: false, // tokens supplies cannot be repopulated at this time -StateStatsHandler: stateStatsHandler, - // NewShardStorageHandler will return a new instance of shardStorageHandler func NewShardStorageHandler(args StorageHandlerArgs) (*shardStorageHandler, error) { err := checkNilArgs(args) @@ -44,16 +39,13 @@ func NewShardStorageHandler(args StorageHandlerArgs) (*shardStorageHandler, erro PathManager: args.PathManagerHandler, EpochStartNotifier: epochStartNotifier, NodeTypeProvider: args.NodeTypeProvider, - CurrentEpoch: args.CurrentEpoch, StorageType: factory.BootstrapStorageService, - CreateTrieEpochRootHashStorer: false, - SnapshotsEnabled: args.SnapshotsEnabled, ManagedPeersHolder: args.ManagedPeersHolder, - - NodeProcessingMode: nodeProcessingMode, + CurrentEpoch: args.CurrentEpoch, + CreateTrieEpochRootHashStorer: false, + NodeProcessingMode: args.NodeProcessingMode, RepopulateTokensSupplies: false, // tokens supplies cannot be repopulated at this time - ManagedPeersHolder: managedPeersHolder, - StateStatsHandler: stateStatsHandler, + StateStatsHandler: args.StateStatsHandler, }, ) if err != nil { diff --git a/epochStart/bootstrap/shardStorageHandler_test.go b/epochStart/bootstrap/shardStorageHandler_test.go index 14c4eecf6e6..8443fe27bba 100644 --- a/epochStart/bootstrap/shardStorageHandler_test.go +++ b/epochStart/bootstrap/shardStorageHandler_test.go @@ -17,27 +17,20 @@ import ( "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/common/statistics/disabled" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" + "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage" - "github.com/multiversx/mx-chain-go/testscommon" epochStartMocks "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks/epochStart" - "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" - "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -LEAVING BUILD ERROR --args.nodeProcessingMode, -- disabled.NewStateStatistics(), - func TestNewShardStorageHandler_ShouldWork(t *testing.T) { defer func() { _ = os.RemoveAll("./Epoch_0") @@ -1067,22 +1060,6 @@ type shardStorageArgs struct { managedPeersHolder common.ManagedPeersHolder } -func createDefaultShardStorageArgs() shardStorageArgs { - return shardStorageArgs{ - generalConfig: testscommon.GetGeneralConfig(), - prefsConfig: config.PreferencesConfig{}, - shardCoordinator: &mock.ShardCoordinatorStub{}, - pathManagerHandler: &testscommon.PathManagerStub{}, - marshalizer: &mock.MarshalizerMock{}, - hasher: &hashingMocks.HasherMock{}, - currentEpoch: 0, - uint64Converter: &mock.Uint64ByteSliceConverterMock{}, - nodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - nodeProcessingMode: common.Normal, - managedPeersHolder: &testscommon.ManagedPeersHolderStub{}, - } -} - func createDefaultEpochStartShardData(lastFinishedMetaBlockHash []byte, shardHeaderHash []byte) []block.EpochStartShardData { return []block.EpochStartShardData{ { diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 57bf504b3d3..99e742c9257 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -61,7 +61,6 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" - "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/integrationtests" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" @@ -704,6 +703,7 @@ func CreateVMAndBlockchainHookMeta( Economics: economicsData, MessageSignVerifier: &mock.MessageSignVerifierMock{}, GasSchedule: gasSchedule, + ArgBlockChainHook: args, NodesConfigProvider: &genesisMocks.NodesSetupStub{}, Hasher: integrationtests.TestHasher, Marshalizer: integrationtests.TestMarshalizer, @@ -1200,10 +1200,6 @@ func CreatePreparedTxProcessorWithVMsWithShardCoordinatorAndRoundConfig(enableEp ) } -LEAVING BUILD ERROR TO CHECK THIS in the func below: -feeAccumulator := postprocess.NewFeeAccumulator() -accounts := integrationtests.CreateAccountsDB(db) - // CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGas - func CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGas( enableEpochsConfig config.EnableEpochs, @@ -1250,7 +1246,7 @@ func CreatePreparedTxProcessorWithVMConfigWithShardCoordinatorDBAndGasAndRoundCo roundsConfig config.RoundConfig, vmConfig *config.VirtualMachineConfig, ) (*VMTestContext, error) { - feeAccumulator, _ := postprocess.NewFeeAccumulator() + feeAccumulator := postprocess.NewFeeAccumulator() epochNotifierInstance := forking.NewGenericEpochNotifier() enableEpochsHandler, _ := enablers.NewEnableEpochsHandler(enableEpochsConfig, epochNotifierInstance) accounts := integrationtests.CreateAccountsDB(db, enableEpochsHandler) diff --git a/testscommon/genesisMocks/nodesSetupStub.go b/testscommon/genesisMocks/nodesSetupStub.go index 0484afc4898..ebe1cfe778a 100644 --- a/testscommon/genesisMocks/nodesSetupStub.go +++ b/testscommon/genesisMocks/nodesSetupStub.go @@ -187,88 +187,6 @@ func (n *NodesSetupStub) GetMinTransactionVersion() uint32 { return 1 } -// GetShardConsensusGroupSize - -func (n *NodesSetupStub) GetShardConsensusGroupSize() uint32 { - if n.GetShardConsensusGroupSizeCalled != nil { - return n.GetShardConsensusGroupSizeCalled() - } - return 0 -} - -// GetMetaConsensusGroupSize - -func (n *NodesSetupStub) GetMetaConsensusGroupSize() uint32 { - if n.GetMetaConsensusGroupSizeCalled != nil { - return n.GetMetaConsensusGroupSizeCalled() - } - return 0 -} - -// NumberOfShards - -func (n *NodesSetupStub) NumberOfShards() uint32 { - if n.NumberOfShardsCalled != nil { - return n.NumberOfShardsCalled() - } - return 0 -} - -// InitialNodesInfoForShard - -func (n *NodesSetupStub) InitialNodesInfoForShard(shardId uint32) ([]nodesCoordinator.GenesisNodeInfoHandler, []nodesCoordinator.GenesisNodeInfoHandler, error) { - if n.InitialNodesInfoForShardCalled != nil { - return n.InitialNodesInfoForShardCalled(shardId) - } - return nil, nil, nil -} - -// InitialNodesInfo - -func (n *NodesSetupStub) InitialNodesInfo() (map[uint32][]nodesCoordinator.GenesisNodeInfoHandler, map[uint32][]nodesCoordinator.GenesisNodeInfoHandler) { - if n.InitialNodesInfoCalled != nil { - return n.InitialNodesInfoCalled() - } - return nil, nil -} - -// AllInitialNodes - -func (n *NodesSetupStub) AllInitialNodes() []nodesCoordinator.GenesisNodeInfoHandler { - if n.AllInitialNodesCalled != nil { - return n.AllInitialNodesCalled() - } - return nil -} - -// GetShardIDForPubKey - -func (n *NodesSetupStub) GetShardIDForPubKey(pubkey []byte) (uint32, error) { - if n.GetShardIDForPubKeyCalled != nil { - return n.GetShardIDForPubKeyCalled(pubkey) - } - return 0, nil -} - -// InitialEligibleNodesPubKeysForShard - -func (n *NodesSetupStub) InitialEligibleNodesPubKeysForShard(shardId uint32) ([]string, error) { - if n.InitialEligibleNodesPubKeysForShardCalled != nil { - return n.InitialEligibleNodesPubKeysForShardCalled(shardId) - } - - return []string{"val1", "val2"}, nil -} - -// InitialNodesPubKeys - -func (n *NodesSetupStub) InitialNodesPubKeys() map[uint32][]string { - if n.InitialNodesPubKeysCalled != nil { - return n.InitialNodesPubKeysCalled() - } - - return map[uint32][]string{0: {"val1", "val2"}} -} - -// MinNumberOfNodesWithHysteresis - -func (n *NodesSetupStub) MinNumberOfNodesWithHysteresis() uint32 { - if n.MinNumberOfNodesWithHysteresisCalled != nil { - return n.MinNumberOfNodesWithHysteresisCalled() - } - return n.MinNumberOfNodes() -} - // MinShardHysteresisNodes - func (n *NodesSetupStub) MinShardHysteresisNodes() uint32 { if n.MinShardHysteresisNodesCalled != nil { From 15598e3f96fc04db7b2545c5ebd0ff867f98793b Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 4 Jan 2024 16:13:39 +0200 Subject: [PATCH 549/958] FIX: After merge in stakingV4 4 --- common/constants.go | 6 +++ vm/systemSmartContracts/staking.go | 20 ++------- vm/systemSmartContracts/stakingWaitingList.go | 42 +++++++++---------- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/common/constants.go b/common/constants.go index 79e65b7d5d3..eb8817a9a9b 100644 --- a/common/constants.go +++ b/common/constants.go @@ -1000,5 +1000,11 @@ const ( NFTStopCreateFlag core.EnableEpochFlag = "NFTStopCreateFlag" FixGasRemainingForSaveKeyValueFlag core.EnableEpochFlag = "FixGasRemainingForSaveKeyValueFlag" IsChangeOwnerAddressCrossShardThroughSCFlag core.EnableEpochFlag = "IsChangeOwnerAddressCrossShardThroughSCFlag" + StakeLimitsFlag core.EnableEpochFlag = "StakeLimitsFlag" + StakingV4Step1Flag core.EnableEpochFlag = "StakingV4Step1Flag" + StakingV4Step2Flag core.EnableEpochFlag = "StakingV4Step2Flag" + StakingV4Step3Flag core.EnableEpochFlag = "StakingV4Step3Flag" + StakingQueueEnabledFlag core.EnableEpochFlag = "StakingQueueEnabledFlag" + StakingV4StartedFlag core.EnableEpochFlag = "StakingV4StartedFlag" // all new flags must be added to createAllFlagsMap method, as part of enableEpochsHandler allFlagsDefined ) diff --git a/vm/systemSmartContracts/staking.go b/vm/systemSmartContracts/staking.go index 0ff0e3af1eb..d450ef73f75 100644 --- a/vm/systemSmartContracts/staking.go +++ b/vm/systemSmartContracts/staking.go @@ -234,7 +234,7 @@ func (s *stakingSC) numSpareNodes() int64 { } func (s *stakingSC) canStake() bool { - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { return true } @@ -563,7 +563,7 @@ func (s *stakingSC) activeStakingFor(stakingData *StakedDataV2_0) { } func (s *stakingSC) processStake(blsKey []byte, registrationData *StakedDataV2_0, addFirst bool) error { - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { return s.processStakeV2(registrationData) } @@ -583,7 +583,7 @@ func (s *stakingSC) processStakeV2(registrationData *StakedDataV2_0) error { } func (s *stakingSC) unStake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { return s.unStakeV2(args) } @@ -640,18 +640,6 @@ func (s *stakingSC) checkUnStakeArgs(args *vmcommon.ContractCallInput) (*StakedD return registrationData, vmcommon.Ok } - -LEAVING BUILD ERROR TO CHECK THIS: - -addOneFromQueue := !s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) || s.canStakeIfOneRemoved() -if addOneFromQueue { -_, err = s.moveFirstFromWaitingToStaked() -if err != nil { -s.eei.AddReturnMessage(err.Error()) -return vmcommon.UserError -} -} - func (s *stakingSC) tryUnStake(key []byte, registrationData *StakedDataV2_0) vmcommon.ReturnCode { if !s.canUnStake() { s.eei.AddReturnMessage("unStake is not possible as too many left") @@ -919,7 +907,7 @@ func (s *stakingSC) getBLSKeyStatus(args *vmcommon.ContractCallInput) vmcommon.R } func (s *stakingSC) getTotalNumberOfRegisteredNodes(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsStakingV2FlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index b64bbf28996..e7ba07eab83 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -76,7 +76,7 @@ func (s *stakingSC) unStakeV1(args *vmcommon.ContractCallInput) vmcommon.ReturnC return vmcommon.Ok } - addOneFromQueue := !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() || s.canStakeIfOneRemoved() + addOneFromQueue := !s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) || s.canStakeIfOneRemoved() if addOneFromQueue { _, err = s.moveFirstFromWaitingToStaked() if err != nil { @@ -220,7 +220,7 @@ func (s *stakingSC) insertAfterLastJailed( NextKey: previousFirstKey, } - if s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && len(previousFirstKey) > 0 { + if s.enableEpochsHandler.IsFlagEnabled(common.CorrectFirstQueuedFlag) && len(previousFirstKey) > 0 { previousFirstElement, err := s.getWaitingListElement(previousFirstKey) if err != nil { return err @@ -314,8 +314,8 @@ func (s *stakingSC) removeFromWaitingList(blsKey []byte) error { } // remove the first element - isFirstElementBeforeFix := !s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && bytes.Equal(elementToRemove.PreviousKey, inWaitingListKey) - isFirstElementAfterFix := s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && bytes.Equal(waitingList.FirstKey, inWaitingListKey) + isFirstElementBeforeFix := !s.enableEpochsHandler.IsFlagEnabled(common.CorrectFirstQueuedFlag) && bytes.Equal(elementToRemove.PreviousKey, inWaitingListKey) + isFirstElementAfterFix := s.enableEpochsHandler.IsFlagEnabled(common.CorrectFirstQueuedFlag) && bytes.Equal(waitingList.FirstKey, inWaitingListKey) if isFirstElementBeforeFix || isFirstElementAfterFix { if bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { waitingList.LastJailedKey = make([]byte, 0) @@ -331,14 +331,14 @@ func (s *stakingSC) removeFromWaitingList(blsKey []byte) error { return s.saveElementAndList(elementToRemove.NextKey, nextElement, waitingList) } - if !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() || bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { + if !s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) || bytes.Equal(inWaitingListKey, waitingList.LastJailedKey) { waitingList.LastJailedKey = make([]byte, len(elementToRemove.PreviousKey)) copy(waitingList.LastJailedKey, elementToRemove.PreviousKey) } previousElement, _ := s.getWaitingListElement(elementToRemove.PreviousKey) // search the other way around for the element in front - if s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() && previousElement == nil { + if s.enableEpochsHandler.IsFlagEnabled(common.CorrectFirstQueuedFlag) && previousElement == nil { previousElement, err = s.searchPreviousFromHead(waitingList, inWaitingListKey, elementToRemove) if err != nil { return err @@ -458,7 +458,7 @@ func createWaitingListKey(blsKey []byte) []byte { } func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step1Flag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -498,7 +498,7 @@ func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vm registrationData.Jailed = true registrationData.JailedNonce = s.eei.BlockChainHook().CurrentNonce() - if !switched && !s.enableEpochsHandler.IsCorrectJailedNotUnStakedEmptyQueueFlagEnabled() { + if !switched && !s.enableEpochsHandler.IsFlagEnabled(common.CorrectJailedNotUnStakedEmptyQueueFlag) { s.eei.AddReturnMessage("did not switch as nobody in waiting, but jailed") } else { s.tryRemoveJailedNodeFromStaked(registrationData) @@ -514,7 +514,7 @@ func (s *stakingSC) switchJailedWithWaiting(args *vmcommon.ContractCallInput) vm } func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -582,7 +582,7 @@ func (s *stakingSC) getWaitingListIndex(args *vmcommon.ContractCallInput) vmcomm } func (s *stakingSC) getWaitingListSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -638,11 +638,11 @@ func (s *stakingSC) getWaitingListRegisterNonceAndRewardAddress(args *vmcommon.C } func (s *stakingSC) resetLastUnJailedFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) { // backward compatibility return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step1Flag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -726,11 +726,11 @@ func (s *stakingSC) cleanAdditionalQueueNotEnoughFunds( } func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsStakingV2FlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step1Flag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -755,7 +755,7 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm } nodePriceToUse := big.NewInt(0).Set(s.minNodePrice) - if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) { nodePriceToUse.Set(s.stakeValue) } @@ -802,11 +802,11 @@ func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcomm } func (s *stakingSC) cleanAdditionalQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() && !s.enableEpochsHandler.IsStakingV4Step1Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step1Flag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -898,11 +898,11 @@ func (s *stakingSC) getFirstElementsFromWaitingList(numNodes uint32) (*waitingLi } func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.CorrectFirstQueuedFlag) { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } @@ -973,11 +973,11 @@ func (s *stakingSC) fixWaitingListQueueSize(args *vmcommon.ContractCallInput) vm } func (s *stakingSC) addMissingNodeToQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsCorrectFirstQueuedFlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.CorrectFirstQueuedFlag) { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } - if s.enableEpochsHandler.IsStakingV4Started() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { s.eei.AddReturnMessage(vm.ErrWaitingListDisabled.Error()) return vmcommon.UserError } From 8af94d084cc66935c34fd1a1dc1ea39d46734f19 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 4 Jan 2024 16:28:59 +0200 Subject: [PATCH 550/958] FIX: After merge in stakingV4 5 --- epochStart/metachain/legacySystemSCs.go | 57 ++++++++--------- epochStart/metachain/systemSCs.go | 83 ++----------------------- state/interface.go | 80 +----------------------- 3 files changed, 35 insertions(+), 185 deletions(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 47247a13dc3..44ccb1fec21 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -3,7 +3,6 @@ package metachain import ( "bytes" "context" - "encoding/hex" "fmt" "math" "math/big" @@ -16,13 +15,13 @@ import ( "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/errChan" vInfo "github.com/multiversx/mx-chain-go/common/validatorInfo" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" - "github.com/multiversx/mx-chain-go/trie/keyBuilder" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -137,14 +136,14 @@ func (s *legacySystemSCProcessor) processLegacy( nonce uint64, epoch uint32, ) error { - if s.enableEpochsHandler.IsSwitchHysteresisForMinNodesFlagEnabledForCurrentEpoch() { + if s.enableEpochsHandler.IsFlagEnabled(common.SwitchHysteresisForMinNodesFlagInSpecificEpochOnly) { err := s.updateSystemSCConfigMinNodes() if err != nil { return err } } - if s.enableEpochsHandler.IsStakingV2OwnerFlagEnabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV2OwnerFlagInSpecificEpochOnly) { err := s.updateOwnersForBlsKeys() if err != nil { return err @@ -158,28 +157,28 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabledForCurrentEpoch() { + if s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlagInSpecificEpochOnly) { err := s.resetLastUnJailed() if err != nil { return err } } - if s.enableEpochsHandler.IsDelegationSmartContractFlagEnabledForCurrentEpoch() { + if s.enableEpochsHandler.IsFlagEnabled(common.DelegationSmartContractFlag) { err := s.initDelegationSystemSC() if err != nil { return err } } - if s.enableEpochsHandler.IsCorrectLastUnJailedFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Step2Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) && !s.enableEpochsHandler.IsFlagDefined(common.StakingV4Step2Flag) { err := s.cleanAdditionalQueue() if err != nil { return err } } - if s.enableEpochsHandler.IsSwitchJailWaitingFlagEnabled() && !s.enableEpochsHandler.IsStakingV4Step2Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.SwitchJailWaitingFlag) && !s.enableEpochsHandler.IsFlagDefined(common.StakingV4Step2Flag) { err := s.computeNumWaitingPerShard(validatorsInfoMap) if err != nil { return err @@ -191,7 +190,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsStakingV2FlagEnabled() && !s.enableEpochsHandler.IsStakingV4Step2Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) && !s.enableEpochsHandler.IsFlagDefined(common.StakingV4Step2Flag) { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err @@ -207,7 +206,7 @@ func (s *legacySystemSCProcessor) processLegacy( return err } - if s.enableEpochsHandler.IsStakingQueueEnabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingQueueEnabledFlag) { err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) if err != nil { return err @@ -215,7 +214,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsESDTFlagEnabledForCurrentEpoch() { + if s.enableEpochsHandler.IsFlagEnabled(common.ESDTFlagInSpecificEpochOnly) { err := s.initESDT() if err != nil { // not a critical error @@ -228,7 +227,7 @@ func (s *legacySystemSCProcessor) processLegacy( // ToggleUnStakeUnBond will pause/unPause the unStake/unBond functions on the validator system sc func (s *legacySystemSCProcessor) ToggleUnStakeUnBond(value bool) error { - if !s.enableEpochsHandler.IsStakingV2FlagEnabled() { + if !s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) { return nil } @@ -290,7 +289,7 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( } validatorLeaving := validatorInfo.ShallowClone() - validatorLeaving.SetListAndIndex(string(common.LeavingList), validatorLeaving.GetIndex(), s.enableEpochsHandler.IsStakingV4Started()) + validatorLeaving.SetListAndIndex(string(common.LeavingList), validatorLeaving.GetIndex(), s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) err = validatorsInfoMap.Replace(validatorInfo, validatorLeaving) if err != nil { return 0, err @@ -344,7 +343,7 @@ func (s *legacySystemSCProcessor) unStakeOneNode(blsKey []byte, epoch uint32) er return epochStart.ErrWrongTypeAssertion } - peerAccount.SetListAndIndex(peerAccount.GetShardId(), string(common.LeavingList), peerAccount.GetIndexInList(), s.enableEpochsHandler.IsStakingV4Started()) + peerAccount.SetListAndIndex(peerAccount.GetShardId(), string(common.LeavingList), peerAccount.GetIndexInList(), s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) peerAccount.SetUnStakedEpoch(epoch) err = s.peerAccountsDB.SaveAccount(peerAccount) if err != nil { @@ -586,7 +585,7 @@ func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap state.ShardVa return err } - if s.enableEpochsHandler.IsStakingQueueEnabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingQueueEnabledFlag) { sw.Start("stakeNodesFromQueue") err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) sw.Stop("stakeNodesFromQueue") @@ -685,7 +684,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } if activeStorageUpdate == nil { log.Debug("no one in waiting suitable for switch") - if s.enableEpochsHandler.IsSaveJailedAlwaysFlagEnabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.SaveJailedAlwaysFlag) { err := s.processSCOutputAccounts(vmOutput) if err != nil { return nil, err @@ -733,7 +732,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } } - account.SetListAndIndex(jailedValidator.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce), s.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(jailedValidator.GetShardId(), string(common.NewList), uint32(stakingData.StakedNonce), s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) account.SetTempRating(s.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) @@ -747,7 +746,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( return nil, err } - jailedAccount.SetListAndIndex(jailedValidator.GetShardId(), string(common.JailedList), jailedValidator.GetIndex(), s.enableEpochsHandler.IsStakingV4Started()) + jailedAccount.SetListAndIndex(jailedValidator.GetShardId(), string(common.JailedList), jailedValidator.GetIndex(), s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) jailedAccount.ResetAtNewEpoch() err = s.peerAccountsDB.SaveAccount(jailedAccount) if err != nil { @@ -977,27 +976,18 @@ func (s *legacySystemSCProcessor) getValidatorSystemAccount() (state.UserAccount func (s *legacySystemSCProcessor) getArgumentsForSetOwnerFunctionality(userValidatorAccount state.UserAccountHandler) ([][]byte, error) { arguments := make([][]byte, 0) - rootHash, err := userValidatorAccount.DataTrie().RootHash() - if err != nil { - return nil, err - } - leavesChannels := &common.TrieIteratorChannels{ LeavesChan: make(chan core.KeyValueHolder, common.TrieLeavesChannelDefaultCapacity), - ErrChan: make(chan error, 1), + ErrChan: errChan.NewErrChanWrapper(), } - err = userValidatorAccount.DataTrie().GetAllLeavesOnChannel(leavesChannels, context.Background(), rootHash, keyBuilder.NewKeyBuilder()) + err := userValidatorAccount.GetAllLeaves(leavesChannels, context.Background()) if err != nil { return nil, err } for leaf := range leavesChannels.LeavesChan { validatorData := &systemSmartContracts.ValidatorDataV2{} - value, errTrim := leaf.ValueWithoutSuffix(append(leaf.Key(), vm.ValidatorSCAddress...)) - if errTrim != nil { - return nil, fmt.Errorf("%w for validator key %s", errTrim, hex.EncodeToString(leaf.Key())) - } - err = s.marshalizer.Unmarshal(validatorData, value) + err = s.marshalizer.Unmarshal(validatorData, leaf.Value()) if err != nil { continue } @@ -1007,6 +997,11 @@ func (s *legacySystemSCProcessor) getArgumentsForSetOwnerFunctionality(userValid } } + err = leavesChannels.ErrChan.ReadFromChanNonBlocking() + if err != nil { + return nil, err + } + return arguments, nil } @@ -1223,7 +1218,7 @@ func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( return err } - peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce), s.enableEpochsHandler.IsStakingV4Started()) + peerAcc.SetListAndIndex(peerAcc.GetShardId(), string(list), uint32(nonce), s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) peerAcc.SetTempRating(s.startRating) peerAcc.SetUnStakedEpoch(common.DefaultUnstakedEpoch) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 58a93e063e3..f5cf8e29302 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -1,19 +1,15 @@ package metachain import ( - "bytes" - "context" "fmt" "math" "math/big" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/common/errChan" - vInfo "github.com/multiversx/mx-chain-go/common/validatorInfo" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" @@ -69,7 +65,8 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr if check.IfNil(args.EnableEpochsHandler) { return nil, epochStart.ErrNilEnableEpochsHandler } - err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ + + err = core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ common.SwitchHysteresisForMinNodesFlagInSpecificEpochOnly, common.StakingV2OwnerFlagInSpecificEpochOnly, common.CorrectLastUnJailedFlagInSpecificEpochOnly, @@ -128,21 +125,21 @@ func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - if s.enableEpochsHandler.IsGovernanceFlagEnabledForCurrentEpoch() { + if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlag) { err := s.updateToGovernanceV2() if err != nil { return err } } - if s.enableEpochsHandler.IsStakingV4Step1Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step1Flag) { err := s.stakeNodesFromQueue(validatorsInfoMap, math.MaxUint32, header.GetNonce(), common.AuctionList) if err != nil { return err } } - if s.enableEpochsHandler.IsStakingV4Step2Enabled() { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err @@ -237,71 +234,3 @@ func (s *systemSCProcessor) IsInterfaceNil() bool { func (s *systemSCProcessor) EpochConfirmed(epoch uint32, _ uint64) { s.legacyEpochConfirmed(epoch) } - -LEAVING BUILD ERRORS: - -err = peerAcc.SetBLSPublicKey(blsKey) -if err != nil { -return err -} - -in function - -func (s *systemSCProcessor) addNewlyStakedNodesToValidatorTrie( - validatorInfos map[uint32][]*state.ValidatorInfo, - returnData [][]byte, - nonce uint64, -) error { - for i := 0; i < len(returnData); i += 2 { - blsKey := returnData[i] - rewardAddress := returnData[i+1] - - peerAcc, err := s.getPeerAccount(blsKey) - if err != nil { - return err - } - - err = peerAcc.SetRewardAddress(rewardAddress) - if err != nil { - return err - } - - err = peerAcc.SetBLSPublicKey(blsKey) - if err != nil { - return err - } - - ALSO REFACTOR THIS: - - - func (s *systemSCProcessor) getArgumentsForSetOwnerFunctionality(userValidatorAccount state.UserAccountHandler) ([][]byte, error) { - arguments := make([][]byte, 0) - - leavesChannels := &common.TrieIteratorChannels{ - LeavesChan: make(chan core.KeyValueHolder, common.TrieLeavesChannelDefaultCapacity), - ErrChan: errChan.NewErrChanWrapper(), - } - err := userValidatorAccount.GetAllLeaves(leavesChannels, context.Background()) - if err != nil { - return nil, err - } - for leaf := range leavesChannels.LeavesChan { - validatorData := &systemSmartContracts.ValidatorDataV2{} - - err = s.marshalizer.Unmarshal(validatorData, leaf.Value()) - if err != nil { - continue - } - for _, blsKey := range validatorData.BlsPubKeys { - arguments = append(arguments, blsKey) - arguments = append(arguments, leaf.Key()) - } - } - - err = leavesChannels.ErrChan.ReadFromChanNonBlocking() - if err != nil { - return nil, err - } - - return arguments, nil - } \ No newline at end of file diff --git a/state/interface.go b/state/interface.go index fdd26eeae69..a8b2221e2d3 100644 --- a/state/interface.go +++ b/state/interface.go @@ -24,7 +24,8 @@ type Updater interface { } // PeerAccountHandler models a peer state account, which can journalize a normal account's data -// with some extra features like signing statistics or rating information +// +// with some extra features like signing statistics or rating information type PeerAccountHandler interface { GetBLSPublicKey() []byte SetBLSPublicKey([]byte) error @@ -63,44 +64,6 @@ type PeerAccountHandler interface { vmcommon.AccountHandler } -// UserAccountHandler models a user account, which can journalize account's data with some extra features -// like balance, developer rewards, owner -type UserAccountHandler interface { - SetCode(code []byte) - SetCodeMetadata(codeMetadata []byte) - GetCodeMetadata() []byte - SetCodeHash([]byte) - GetCodeHash() []byte - SetRootHash([]byte) - GetRootHash() []byte - SetDataTrie(trie common.Trie) - DataTrie() common.DataTrieHandler - RetrieveValue(key []byte) ([]byte, uint32, error) - SaveKeyValue(key []byte, value []byte) error - AddToBalance(value *big.Int) error - SubFromBalance(value *big.Int) error - GetBalance() *big.Int - ClaimDeveloperRewards([]byte) (*big.Int, error) - AddToDeveloperReward(*big.Int) - GetDeveloperReward() *big.Int - ChangeOwnerAddress([]byte, []byte) error - SetOwnerAddress([]byte) - GetOwnerAddress() []byte - SetUserName(userName []byte) - GetUserName() []byte - vmcommon.AccountHandler -} - -// DataTrieTracker models what how to manipulate data held by a SC account -type DataTrieTracker interface { - RetrieveValue(key []byte) ([]byte, uint32, error) - SaveKeyValue(key []byte, value []byte) error - SetDataTrie(tr common.Trie) - DataTrie() common.DataTrieHandler - SaveDirtyData(common.Trie) (map[string][]byte, error) - IsInterfaceNil() bool -} - // AccountsAdapter is used for the structure that manages the accounts on top of a trie.PatriciaMerkleTrie // implementation type AccountsAdapter interface { @@ -258,43 +221,6 @@ type DataTrie interface { CollectLeavesForMigration(args vmcommon.ArgsMigrateDataTrieLeaves) error } -// PeerAccountHandler models a peer state account, which can journalize a normal account's data -// with some extra features like signing statistics or rating information -type PeerAccountHandler interface { - SetBLSPublicKey([]byte) error - GetRewardAddress() []byte - SetRewardAddress([]byte) error - GetAccumulatedFees() *big.Int - AddToAccumulatedFees(*big.Int) - GetList() string - GetIndexInList() uint32 - GetShardId() uint32 - SetUnStakedEpoch(epoch uint32) - GetUnStakedEpoch() uint32 - IncreaseLeaderSuccessRate(uint32) - DecreaseLeaderSuccessRate(uint32) - IncreaseValidatorSuccessRate(uint32) - DecreaseValidatorSuccessRate(uint32) - IncreaseValidatorIgnoredSignaturesRate(uint32) - GetNumSelectedInSuccessBlocks() uint32 - IncreaseNumSelectedInSuccessBlocks() - GetLeaderSuccessRate() SignRate - GetValidatorSuccessRate() SignRate - GetValidatorIgnoredSignaturesRate() uint32 - GetTotalLeaderSuccessRate() SignRate - GetTotalValidatorSuccessRate() SignRate - GetTotalValidatorIgnoredSignaturesRate() uint32 - SetListAndIndex(shardID uint32, list string, index uint32) - GetRating() uint32 - SetRating(uint32) - GetTempRating() uint32 - SetTempRating(uint32) - GetConsecutiveProposerMisses() uint32 - SetConsecutiveProposerMisses(uint322 uint32) - ResetAtNewEpoch() - vmcommon.AccountHandler -} - // UserAccountHandler models a user account, which can journalize account's data with some extra features // like balance, developer rewards, owner type UserAccountHandler interface { @@ -370,7 +296,7 @@ type ShardValidatorsInfoMapHandler interface { SetValidatorsInShard(shardID uint32, validators []ValidatorInfoHandler) error } -//ValidatorInfoHandler defines which data shall a validator info hold. +// ValidatorInfoHandler defines which data shall a validator info hold. type ValidatorInfoHandler interface { IsInterfaceNil() bool From 37ef912be630036dd6e58936d2c31b8d13cceffb Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 4 Jan 2024 18:57:17 +0200 Subject: [PATCH 551/958] FIX: After merge in stakingV4 6 + nodes coord build + tests --- .../vm/staking/componentsHolderCreator.go | 48 ++++++++++++------- .../vm/staking/metaBlockProcessorCreator.go | 1 - .../vm/staking/nodesCoordiantorCreator.go | 4 +- .../vm/staking/systemSCCreator.go | 8 ++-- .../nodesCoordinator/hashValidatorShuffler.go | 4 +- .../hashValidatorShuffler_test.go | 2 - .../indexHashedNodesCoordinator.go | 5 +- .../indexHashedNodesCoordinatorRegistry.go | 2 +- ...ndexHashedNodesCoordinatorRegistry_test.go | 10 ++++ .../indexHashedNodesCoordinator_test.go | 8 ++-- 10 files changed, 57 insertions(+), 35 deletions(-) diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index 52efdfaad0a..a337535a602 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -14,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/common/enablers" "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/common/statistics/disabled" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" @@ -32,9 +33,11 @@ import ( "github.com/multiversx/mx-chain-go/statusHandler" "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + factoryTests "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/outport" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + stateTests "github.com/multiversx/mx-chain-go/testscommon/state" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/multiversx/mx-chain-go/trie" ) @@ -139,8 +142,9 @@ func createBootstrapComponents( func createStatusComponents() factory.StatusComponentsHolder { return &integrationMocks.StatusComponentsStub{ - Outport: &outport.OutportStub{}, - AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, + Outport: &outport.OutportStub{}, + SoftwareVersionCheck: &integrationMocks.SoftwareVersionCheckerMock{}, + ManagedPeersMonitorField: &testscommon.ManagedPeersMonitorStub{}, } } @@ -148,13 +152,22 @@ func createStateComponents(coreComponents factory.CoreComponentsHolder) factory. tsmArgs := getNewTrieStorageManagerArgs(coreComponents) tsm, _ := trie.CreateTrieStorageManager(tsmArgs, trie.StorageManagerOptions{}) trieFactoryManager, _ := trie.NewTrieStorageManagerWithoutPruning(tsm) - userAccountsDB := createAccountsDB(coreComponents, stateFactory.NewAccountCreator(), trieFactoryManager) + + argsAccCreator := stateFactory.ArgsAccountCreator{ + Hasher: coreComponents.Hasher(), + Marshaller: coreComponents.InternalMarshalizer(), + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + } + + accCreator, _ := stateFactory.NewAccountCreator(argsAccCreator) + + userAccountsDB := createAccountsDB(coreComponents, accCreator, trieFactoryManager) peerAccountsDB := createAccountsDB(coreComponents, stateFactory.NewPeerAccountCreator(), trieFactoryManager) _ = userAccountsDB.SetSyncer(&mock.AccountsDBSyncerStub{}) _ = peerAccountsDB.SetSyncer(&mock.AccountsDBSyncerStub{}) - return &testscommon.StateComponentsMock{ + return &factoryTests.StateComponentsMock{ PeersAcc: peerAccountsDB, Accounts: userAccountsDB, } @@ -162,14 +175,13 @@ func createStateComponents(coreComponents factory.CoreComponentsHolder) factory. func getNewTrieStorageManagerArgs(coreComponents factory.CoreComponentsHolder) trie.NewTrieStorageManagerArgs { return trie.NewTrieStorageManagerArgs{ - MainStorer: testscommon.CreateMemUnit(), - //CheckpointsStorer: testscommon.CreateMemUnit(), - Marshalizer: coreComponents.InternalMarshalizer(), - Hasher: coreComponents.Hasher(), - GeneralConfig: config.TrieStorageManagerConfig{SnapshotsGoroutineNum: 1}, - LEAVING BUILD ERROR TO FILL THIS - //CheckpointHashesHolder: hashesHolder.NewCheckpointHashesHolder(10, hashSize), - IdleProvider: &testscommon.ProcessStatusHandlerStub{}, + MainStorer: testscommon.CreateMemUnit(), + Marshalizer: coreComponents.InternalMarshalizer(), + Hasher: coreComponents.Hasher(), + GeneralConfig: config.TrieStorageManagerConfig{SnapshotsGoroutineNum: 1}, + IdleProvider: &testscommon.ProcessStatusHandlerStub{}, + Identifier: "id", + StatsCollector: disabled.NewStateStatistics(), } } @@ -178,7 +190,13 @@ func createAccountsDB( accountFactory state.AccountFactory, trieStorageManager common.StorageManager, ) *state.AccountsDB { - tr, _ := trie.NewTrie(trieStorageManager, coreComponents.InternalMarshalizer(), coreComponents.Hasher(), 5) + tr, _ := trie.NewTrie( + trieStorageManager, + coreComponents.InternalMarshalizer(), + coreComponents.Hasher(), + coreComponents.EnableEpochsHandler(), + 5, + ) argsEvictionWaitingList := evictionWaitingList.MemoryEvictionWaitingListArgs{ RootHashesSize: 10, @@ -192,10 +210,8 @@ func createAccountsDB( Marshaller: coreComponents.InternalMarshalizer(), AccountFactory: accountFactory, StoragePruningManager: spm, - ProcessingMode: common.Normal, - ProcessStatusHandler: coreComponents.ProcessStatusHandler(), - AppStatusHandler: &statusHandlerMock.AppStatusHandlerStub{}, AddressConverter: coreComponents.AddressPubKeyConverter(), + SnapshotsManager: &stateTests.SnapshotsManagerStub{}, } adb, _ := state.NewAccountsDB(argsAccountsDb) return adb diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 2e8f0c486c8..5760d1165d4 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -93,7 +93,6 @@ func createMetaBlockProcessor( BlockTracker: blockTracker, BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, - EnableRoundsHandler: coreComponents.EnableRoundsHandler(), VMContainersFactory: metaVMFactory, VmContainer: vmContainer, GasHandler: &mock.GasHandlerMock{}, diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index 296626337b1..ec8418db4f6 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -11,7 +11,7 @@ import ( "github.com/multiversx/mx-chain-go/factory" integrationMocks "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" - "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/state/accounts" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/multiversx/mx-chain-storage-go/lrucache" @@ -222,7 +222,7 @@ func savePeerAcc( shardID uint32, list common.PeerType, ) { - peerAccount, _ := state.NewPeerAccount(pubKey) + peerAccount, _ := accounts.NewPeerAccount(pubKey) peerAccount.SetTempRating(initialRating) peerAccount.ShardId = shardID peerAccount.BLSPublicKey = pubKey diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index d817cdca870..b89e403f8d8 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -198,11 +198,11 @@ func createVMContainerFactory( GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ Active: config.GovernanceSystemSCConfigActive{ ProposalCost: "500", - MinQuorum: "50", - MinPassThreshold: "50", - MinVetoThreshold: "50", + LostProposalFee: "50", + MinQuorum: 50, + MinPassThreshold: 10, + MinVetoThreshold: 10, }, - FirstWhitelistedAddress: "3132333435363738393031323334353637383930313233343536373839303234", }, StakingSystemSCConfig: config.StakingSystemSCConfig{ GenesisNodePrice: strconv.Itoa(nodePrice), diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index f19ea39e68b..058a4b0158c 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/hashing/sha256" "github.com/multiversx/mx-chain-go/common" @@ -836,9 +837,6 @@ func (rhs *randHashShuffler) updateShufflerConfig(epoch uint32) { "maxNodesToShufflePerShard", rhs.activeNodesConfig.NodesToShufflePerShard, ) - rhs.flagBalanceWaitingLists.SetValue(epoch >= rhs.enableEpochsHandler.BalanceWaitingListsEnableEpoch()) - log.Debug("balanced waiting lists", "enabled", rhs.flagBalanceWaitingLists.IsSet()) - rhs.flagStakingV4Step3.SetValue(epoch >= rhs.stakingV4Step3EnableEpoch) log.Debug("staking v4 step3", "enabled", rhs.flagStakingV4Step3.IsSet()) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler_test.go b/sharding/nodesCoordinator/hashValidatorShuffler_test.go index 7f0e6bf371e..788ec3f9b59 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler_test.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler_test.go @@ -13,11 +13,9 @@ import ( "testing" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/sharding/mock" - "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 07da48e04b9..e9793f2dfdb 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -151,7 +151,6 @@ func NewIndexHashedNodesCoordinator(arguments ArgNodesCoordinator) (*indexHashed enableEpochsHandler: arguments.EnableEpochsHandler, validatorInfoCacher: arguments.ValidatorInfoCacher, genesisNodesSetupHandler: arguments.GenesisNodesSetupHandler, - stakingV4Step2EnableEpoch: arguments.StakingV4Step2EnableEpoch, nodesCoordinatorRegistryFactory: arguments.NodesCoordinatorRegistryFactory, } @@ -1292,10 +1291,10 @@ func (ihnc *indexHashedNodesCoordinator) getShardValidatorInfoData(txHash []byte } func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { - ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.StakingV4Step1EnableEpoch()) + ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.GetActivationEpoch(common.StakingV4Step1Flag)) log.Debug("indexHashedNodesCoordinator: flagStakingV4Started", "enabled", ihnc.flagStakingV4Started.IsSet()) - ihnc.flagStakingV4Step2.SetValue(epoch >= ihnc.stakingV4Step2EnableEpoch) + ihnc.flagStakingV4Step2.SetValue(epoch >= ihnc.enableEpochsHandler.GetActivationEpoch(common.StakingV2Flag)) log.Debug("indexHashedNodesCoordinator: flagStakingV4Step2", "enabled", ihnc.flagStakingV4Step2.IsSet()) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go index 0548477aa49..813929bac90 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry.go @@ -74,7 +74,7 @@ func (ihnc *indexHashedNodesCoordinator) saveState(key []byte, epoch uint32) err // NodesCoordinatorToRegistry will export the nodesCoordinator data to the registry func (ihnc *indexHashedNodesCoordinator) NodesCoordinatorToRegistry(epoch uint32) NodesCoordinatorRegistryHandler { - if epoch >= ihnc.stakingV4Step2EnableEpoch { + if epoch >= ihnc.enableEpochsHandler.GetActivationEpoch(common.StakingV4Step2Flag) { log.Debug("indexHashedNodesCoordinator.NodesCoordinatorToRegistry called with auction registry", "epoch", epoch) return ihnc.nodesCoordinatorToRegistryWithAuction() } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go index 3315afa12b4..b2b99e6e87b 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorRegistry_test.go @@ -6,7 +6,9 @@ import ( "strconv" "testing" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -77,6 +79,14 @@ func TestIndexHashedNodesCoordinator_LoadStateAfterSave(t *testing.T) { t.Parallel() args := createArguments() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + GetActivationEpochCalled: func(flag core.EnableEpochFlag) uint32 { + if flag == common.StakingV4Step2Flag { + return stakingV4Epoch + } + return 0 + }, + } nodesCoordinator, _ := NewIndexHashedNodesCoordinator(args) expectedConfig := nodesCoordinator.nodesConfig[0] diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go index 0cabab20abc..5db65609f59 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator_test.go @@ -131,7 +131,6 @@ func createArguments() ArgNodesCoordinator { }, GenesisNodesSetupHandler: &mock.NodesSetupMock{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - StakingV4Step2EnableEpoch: stakingV4Epoch, NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } return arguments @@ -2553,8 +2552,9 @@ func TestIndexHashedGroupSelector_GetWaitingEpochsLeftForPublicKey(t *testing.T) EnableEpochsHandler: &mock.EnableEpochsHandlerMock{ CurrentEpoch: 1, }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &mock.NodesSetupMock{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &mock.NodesSetupMock{}, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -2629,6 +2629,7 @@ func TestIndexHashedGroupSelector_GetWaitingEpochsLeftForPublicKey(t *testing.T) return 0 }, }, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) @@ -2713,6 +2714,7 @@ func TestIndexHashedGroupSelector_GetWaitingEpochsLeftForPublicKey(t *testing.T) return 2 }, }, + NodesCoordinatorRegistryFactory: createNodesCoordinatorRegistryFactory(), } ihnc, _ := NewIndexHashedNodesCoordinator(arguments) From 92323bf9c00736ff95206613f1a2cf0a351ca660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 4 Jan 2024 22:49:34 +0200 Subject: [PATCH 552/958] Recreate trie from epoch. --- process/smartContract/scQueryService.go | 3 +-- state/accountsDBApi.go | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 099f8d6afdd..de98029219a 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -199,7 +199,7 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } accountsAdapter := service.blockChainHook.GetAccountsAdapter() - err = accountsAdapter.RecreateTrieFromEpoch(holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: 1247})) + err = accountsAdapter.RecreateTrieFromEpoch(holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch()})) if err != nil { return nil, nil, err } @@ -260,7 +260,6 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui // TODO: extract duplicated code with nodeBlocks.go func (service *SCQueryService) extractBlockHeaderAndRootHash(query *process.SCQuery) (data.HeaderHandler, []byte, error) { - if len(query.BlockHash) > 0 { currentHeader, err := service.getBlockHeaderByHash(query.BlockHash) if err != nil { diff --git a/state/accountsDBApi.go b/state/accountsDBApi.go index 89c2a27a636..8c73a6fac06 100644 --- a/state/accountsDBApi.go +++ b/state/accountsDBApi.go @@ -171,8 +171,21 @@ func (accountsDB *accountsDBApi) RecreateTrie(rootHash []byte) error { } // RecreateTrieFromEpoch is a not permitted operation in this implementation and thus, will return an error -func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(_ common.RootHashHolder) error { - return ErrOperationNotPermitted +func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(options common.RootHashHolder) error { + newBlockInfo := holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) + + accountsDB.mutRecreatedTrieBlockInfo.Lock() + defer accountsDB.mutRecreatedTrieBlockInfo.Unlock() + + err := accountsDB.innerAccountsAdapter.RecreateTrieFromEpoch(options) + if err != nil { + accountsDB.blockInfo = nil + return err + } + + accountsDB.blockInfo = newBlockInfo + + return nil } // PruneTrie is a not permitted operation in this implementation and thus, does nothing From 94f65723c243be241bd7bf62eaaac0addec4afa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 5 Jan 2024 01:16:02 +0200 Subject: [PATCH 553/958] Fix epoch. --- process/smartContract/scQueryService.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index de98029219a..6b9b54ac82b 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -199,7 +199,9 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } accountsAdapter := service.blockChainHook.GetAccountsAdapter() - err = accountsAdapter.RecreateTrieFromEpoch(holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch()})) + + holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) + err = accountsAdapter.RecreateTrieFromEpoch(holder) if err != nil { return nil, nil, err } From 3de35aba9ec68e6745071b6bec7982db6bbe0cd8 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 09:31:24 +0200 Subject: [PATCH 554/958] - compressed flags & updated configs --- cmd/node/config/config.toml | 10 +++----- cmd/node/config/enableEpochs.toml | 29 +++++++++++----------- cmd/node/config/enableRounds.toml | 2 +- cmd/node/config/genesisContracts/dns.wasm | Bin 31280 -> 9740 bytes 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 24019d56ec3..f6b965ec081 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -694,9 +694,8 @@ TimeOutForSCExecutionInMilliseconds = 10000 # 10 seconds = 10000 milliseconds WasmerSIGSEGVPassthrough = false # must be false for release WasmVMVersions = [ - { StartEpoch = 0, Version = "v1.3" }, - { StartEpoch = 1, Version = "v1.4" }, - { StartEpoch = 3, Version = "v1.5" }, # TODO: set also the RoundActivations.DisableAsyncCallV1 accordingly + { StartEpoch = 0, Version = "v1.4" }, + { StartEpoch = 1, Version = "v1.5" }, # TODO: set also the RoundActivations.DisableAsyncCallV1 accordingly ] [VirtualMachine.Querying] @@ -704,9 +703,8 @@ TimeOutForSCExecutionInMilliseconds = 10000 # 10 seconds = 10000 milliseconds WasmerSIGSEGVPassthrough = false # must be false for release WasmVMVersions = [ - { StartEpoch = 0, Version = "v1.3" }, - { StartEpoch = 1, Version = "v1.4" }, - { StartEpoch = 3, Version = "v1.5" }, # TODO: set also the RoundActivations.DisableAsyncCallV1 accordingly + { StartEpoch = 0, Version = "v1.4" }, + { StartEpoch = 1, Version = "v1.5" }, # TODO: set also the RoundActivations.DisableAsyncCallV1 accordingly ] [VirtualMachine.GasConfig] diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 819108b99eb..ec45ce07a0b 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -62,7 +62,7 @@ ESDTEnableEpoch = 1 # GovernanceEnableEpoch represents the epoch when governance is enabled - GovernanceEnableEpoch = 5 + GovernanceEnableEpoch = 1 # DelegationManagerEnableEpoch represents the epoch when the delegation manager is enabled # epoch should not be 0 @@ -252,40 +252,40 @@ DeterministicSortOnValidatorsInfoEnableEpoch = 1 # SCProcessorV2EnableEpoch represents the epoch when SC processor V2 will be used - SCProcessorV2EnableEpoch = 3 + SCProcessorV2EnableEpoch = 1 # AutoBalanceDataTriesEnableEpoch represents the epoch when the data tries are automatically balanced by inserting at the hashed key instead of the normal key - AutoBalanceDataTriesEnableEpoch = 3 + AutoBalanceDataTriesEnableEpoch = 1 # KeepExecOrderOnCreatedSCRsEnableEpoch represents the epoch when the execution order of created SCRs is ensured - KeepExecOrderOnCreatedSCRsEnableEpoch = 3 + KeepExecOrderOnCreatedSCRsEnableEpoch = 1 # MultiClaimOnDelegationEnableEpoch represents the epoch when the multi claim on delegation is enabled - MultiClaimOnDelegationEnableEpoch = 3 + MultiClaimOnDelegationEnableEpoch = 1 # ChangeUsernameEnableEpoch represents the epoch when changing username is enabled - ChangeUsernameEnableEpoch = 3 + ChangeUsernameEnableEpoch = 10 # ConsistentTokensValuesLengthCheckEnableEpoch represents the epoch when the consistent tokens values length check is enabled - ConsistentTokensValuesLengthCheckEnableEpoch = 3 + ConsistentTokensValuesLengthCheckEnableEpoch = 1 # FixDelegationChangeOwnerOnAccountEnableEpoch represents the epoch when the fix for the delegation system smart contract is enabled - FixDelegationChangeOwnerOnAccountEnableEpoch = 3 + FixDelegationChangeOwnerOnAccountEnableEpoch = 1 # DynamicGasCostForDataTrieStorageLoadEnableEpoch represents the epoch when dynamic gas cost for data trie storage load will be enabled - DynamicGasCostForDataTrieStorageLoadEnableEpoch = 3 + DynamicGasCostForDataTrieStorageLoadEnableEpoch = 1 # ScToScLogEventEnableEpoch represents the epoch when the sc to sc log event feature is enabled - ScToScLogEventEnableEpoch = 3 + ScToScLogEventEnableEpoch = 1 # NFTStopCreateEnableEpoch represents the epoch when NFT stop create feature is enabled - NFTStopCreateEnableEpoch = 3 + NFTStopCreateEnableEpoch = 1 # ChangeOwnerAddressCrossShardThroughSCEnableEpoch represents the epoch when the change owner address built in function will work also through a smart contract call cross shard - ChangeOwnerAddressCrossShardThroughSCEnableEpoch = 3 + ChangeOwnerAddressCrossShardThroughSCEnableEpoch = 1 # FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch represents the epoch when the fix for the remaining gas in the SaveKeyValue builtin function is enabled - FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch = 3 + FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch = 1 # BLSMultiSignerEnableEpoch represents the activation epoch for different types of BLS multi-signers BLSMultiSignerEnableEpoch = [ @@ -302,6 +302,5 @@ [GasSchedule] # GasScheduleByEpochs holds the configuration for the gas schedule that will be applied from specific epochs GasScheduleByEpochs = [ - { StartEpoch = 0, FileName = "gasScheduleV1.toml" }, - { StartEpoch = 1, FileName = "gasScheduleV7.toml" }, + { StartEpoch = 0, FileName = "gasScheduleV7.toml" }, ] diff --git a/cmd/node/config/enableRounds.toml b/cmd/node/config/enableRounds.toml index e9940cf1b7c..c580e02cec3 100644 --- a/cmd/node/config/enableRounds.toml +++ b/cmd/node/config/enableRounds.toml @@ -10,4 +10,4 @@ [RoundActivations] [RoundActivations.DisableAsyncCallV1] Options = [] - Round = "500" + Round = "300" diff --git a/cmd/node/config/genesisContracts/dns.wasm b/cmd/node/config/genesisContracts/dns.wasm index ea6130501714a87c640a5f28d6888d16cb351595..ce692a1260bf44b86b79f8ad1095ff015c8e9ae8 100644 GIT binary patch literal 9740 zcmai4TWlQHc|PaN%7gUhH2|0S7u0J)0=0bQdhuPbEN z171yJwpcJ%)%F3K$DkYGLdlfeoX1u#d({{0q?a#e?FHXfy6AZmiEJ*>xnt?VLO1L6 zayrXdv)NdF@-v6j5LtOB7wg5&jNoM;gP4AM-kY2LRHu)tTUX5(Y zx_-q6az@TvYiHf9yyVnpuXz5q7c6hGx(Hve;f3{v7w*UN89>mPZfmgxtG{^t*#_(* z^9r<_%lexp?JO)wnEw=^L9_s}=Wi^Zc&u~z2I-w!X#rjpv1s0fIh%W4d0B^nj)EWn zACb=&MI7O&DdS(Og!0;%1}$LbllI z!BN!bsuDiV0!FR&qWWUgTxqmc)r3+o|I*-^t00-tzIr)&AL4-t-droKab|dJmd&;JU@RaYh0ec z(CB4>8GiTZ%e%E+w<^{4Q>mI!R@ap^>9>FNo=Ugbz$rUr!-@DoWlK&S52r`t^qpTp z-%dNE;!#eG>Kdc!6Hdq9icA^d_me7pPc7HgZe^x7{@G90L;F}=+sA9lX}dQu4rC6Q zXK?wQJNMKfGmX3PC6F_AA4WWp1o+*bXd5Lan07jxcAPW5WS_7HoKE#}qN_TNotiRJ z{MkKM1221(3#Zd>-o2+%5LM~leV=znm5Na=HacB(L4_w9b}Q&ZQaSP|5`}mAiM6K)g`{To5RD z3wFAX#W|?Qi)=80;{FWSit?~dl`QR=z@5nS*#Vt^E72u&>Y$z#7eG@9afX`;)Qmf5 zJH#NFIVuf~s(d6>bMX+K;T7g;{G^x;%B9Vr$!A4=L>UMV8VGzjfHpujz{DqsiLVD}?FH!s9fS%c_c8vsq(E$J75YsjL3%E5&1nQhoabfBJAl$*l!RZSJSI{R<5j^D2Vj zHdF-I+VcZR7}-Y*vU`kh5Zadz4#dW`3A+V*RrRQv=?IAOc==0Mib1FrPCjpb(4?~N!9Be>5D*JOP-VfxY_ZWH}LLXgF zvoB2lk!^w8(<|kM6Lw%ik#g-JP*e8v_6zYJYaLKK-$U|bNT4It4P^5Ph}bXgD*2se z17bDfO`4nmp8l5cU{c~Holl5>*C(A~Y=z3|a65@6_BF({bU&mSEWy0smtdOnce2EO z@{eU6qR6jf8nPtR@-N1q)MCQVLH|B$gNhB3ApI{29|8YF_1FgPSp2; z&nUabdH<90ZMIM0{)0e>ym9Bw9T2}|UWGSBGau;NXJ=~$vb_S^oduw&IV38&&1@}5 ze@wZy+tXXnyb0Kt0f@ayN876eV&ZZFv0NuiEMLYrsc;lvs?&d_iXO0w-s>=P(*7dx zfl-3GS3Dl}OD*LA<7lE(*+cg82q#ao+IhlGryuGo$3tYEf^X&v7Fb{(t{$a~Fg8X1 zewyt`AP#C*xOmgcotR$k#PqmBroadXpv1cdj*GGmdYbiX?_xhmG89T`up<+3yo5+- zl|2SVKV_eh$oF^>*x4D>mk9ulip&lJ5-#xR=~8* zIRopEML@N+iFl{7b6DaNsd`ST)At$rb`$?qdKtC;FoN^oVFw;+3d$sFbL4i=HHofm zMc4G(Gau^Pb~LUQEzemSPteuBO$JaL+s7ym78qyvmzh#U(>Nr|V!*owbT%-b*pAve zpmy2OLVv$MWVWpvdJ?_A!qVApgK}gAZMP%vqdsS_u%Ay*P`Il70+jTeePFhx(>KY{ zl)&?AMCv2r|5Z$S21VaqdnEl4!h(H$0;P00eUn3wnUWG7;oh)GRt38jzJ?dkZ)bSN~rNU4oSPWr-9Y#qB2~66_R|on!kR(?J_-_)XOb+$Z_=@)DUf7NK#=aDi$w;S>Sg;BKsYFR5q_~( zLqon-!!!13)DG$kU=u~}B8*c`fY==4Au%2i-hA=+}dl2_5cP+z4# zzJ<$n+2F#O@kZGNl%wn-IP6RDpJ)>fHi4oE#vTMX$#O|4J%Uv=cM}pw6*m5eGAccC z1u>y02d+kOt9rlEu^1Ag8|Mujw)!3dy^nlG4>UJ!?KT% z7=tbui6Ze5K`wp*tRb7?V8#eKMq}Gj@kpLB#k#M=@8r8HZ^=A$uH)!>nZfn;6;wjUX~YQf{zWfA)Rd2}gr>nsqrr12eEcFk<|HnueJ-_J-gGXA#OS z%N9d67)98>W+TFt=R_EQ?113z%uxkk_}!yFFNmKTc(>rwVSy?lrz8T}!d@4rr0Z6} z$VZ;so1hpO}d$Nz-XA-PF%C*x`9zQ4Hy(CGa8SDn9>6{Ih9Bz9YdHjaq6+E;=PFQ& z3$Tu~0U|UM+l7m~4{LwyK}IeDw=a|o`!Ae!-^!0E00bOUhyWA{sN2kTxaQh1Kx`NKlH{ITkQWohz971&Pg!>XJvdESN3*EB;S|G+0A z`*NO<5x5$zqr+Ibj^3}-ovYq@3MbIG@58q0;{w)nx!!E_WaynI@~~j z3{#*o1B;gg#WI(e-ZVEy;`Ctd#>pH^TPzO(tS5v3^|XmV;1~Cx13q%t!EZ^9GqET;NZ*x zr1CQh5aF2xa<-Xv`Yd8nFin>^4$lz)8hDM5(P&1-V2wbqAPzaR47e58^4az3AjFGq zSV}@}Xc5UVMCt~}Q2#+N3zK2cc!&@csWMp)uWhb!%Zl9|EmYU8(#IZxR*``bE_Lw0LV;mYRsb;MrCKC&K4vr_6I=lp zu=m4~cw{O>%*o|MDi%3C;Gm&Ra(bA(K5#)M9tKg2VO~H?W;URC2Z;b_&xc0_P>5Fr zY9)FSom<}H<@xC#l~+VbMz@cRlM;YhXu=IF~+kw*R*OwV(dk!^C}8j$T0#`O5QyLfpmgBmN{tg&#z^&87s8@#TqERed(u7lqd zv|q}cpWxq%Lqom(Lc8bW)%t;b2lnmX+&#~3yw+aJ=6ij-+2$Jam+%z>-hI!nLAH5m z;rsgwjplOmf`8@+yf0r{>9;$s=yU@eTx<0&fs;nxt3A7p*Zn;QGtpdBY^yD=(w(gA z^;(#XSA1G=V?#N!?S;#oRvX4{v|XnSAunXIXtv-k+;AO!+yPEocsc(S=xiZtb`~-x z=07SXy_j9wpjPO7%Q!c+=csedwQd(5F=2s)RRzu0JjJWWl2@=9!i%WmVwhCT#~N_M#MBNs4E a`rV3r$uv86>KUcfJbe*O!zwmz%sBEMm=KIYy#(vj`Ra%7rwZ`8$TAw?r;G&2%rF-J}un}o!Rq^v9!RJxkE zmS!Z)NHZhZX^l00CC(EkA;IApS|AR6v1qy)%1eL)DNqO$NLn5-5W46}pl(Qcv{_Am z|8MVe?zy9pW19f0NNesrd!N0({q66)zrD}7L4WOh7z9DMke-aLTnVq74E2#*;a_kv z=93aPf|KC`b~88`xJD1SMikVF>fmHey|{GW+^JiIK*SFSQuJhUOFUS<++JHez1%oQg&PV{{s$E??y$C+9zwgfe+L>YN z*IYWEub#eiez3g07Bnhoy>hT#pi?w((?}PW*QcidSyngI?FKg+x(T6g?4P?daHG`k zSzKOZNTb0`uGJk@Rls-cc9sB&`r~h0AFR2#?{YV*cV0bMKD~Y>2sOCB&ET)NZ+)=J zJdgL!^_S-dZq&}2qp?Um2*%W7hp!UZJtQM?yHfAiFuuOpUtYUsu?k|0i!HjrDbR!pH8 zbOLl@+gKO|+aYlrC$;cGc*`xdI1F~wZ;7vj`Nqc8pnWCCAN$_QcjH&Ww0?eYer5HI zQP7-+0>}IFXM=76N7sXwHCG3x7uR4xaG-&huAI9(2qtUu=lYB1gM&9hgKx0=tNr!G zmF3%4*4BeVDYdt+EJNjaC%eJnajFpG*PZFFF5I;cOf{GL=LaUYN5*t%H-hQT<^H+F zh5q{BHPi(&+tvo_cMSULmsSUNoa>(sW*e6Wt80uC9BrLALA(Bm!SX^JwojZmGw5G9 zajL&Ih@-KIFv!F9uJ?xfzU3dEIN3jSW^w8CrEh&Od|)H|p70&vo5FX8kB4s#zb$P2 z)^EbE@gNJbFx}u^5VU>i{jT(5X_8zCAE;l6A9$%X$UhLC?InBcI-1-1e_qSO^eF-8 z)m{O-7Tos`Q%a-4gsXUTmYQx))@_;v(wQ6SM}-WBoH>jB|e`HmeL<`E%yf- zVIJNw4v_u9gJHK8&8gQ^uOYPSS%Z0eR88CN#-3i?<|CBrm3!Q+ll87zC)EC41wIu-BZ4(+p{ujwA#im{97_l8R1;Y3qL$O+?LJBadG@ z9^`L*7|7jPzN1_3gl*jlx??#t@m$u(YIlrB*;rOvf&y|!Z6NVgs7N3Kxm5u9qyRO^WHeIJSaiMv#w_^qt))4}3 zH!^EAmiY$U+dMr`-84NX(Yu!XTxwtnE|T(eSjS{tU9+syWF;=5o~fG&T|MhaR9=ao zB;vfJesU@OZpTL?@)gqCiKv5&1^E|b8a4?_euKoO0vExd>8G}8`W2F^cAGJ-L-P72 zk~g*>`J-OOoM2Tb?_>>fNCF%KTov<@99+wXf|dxXF{Gd)!fBi-Xox^wpG6RL6N|p2 z1Xe^CTh~AyY7%oKxGo8n821`w4Kos#dt+q{6RN>2r&RPZ!`$+$TjTz*zWTS!g8jg;=SAP@1 z5wU5t&80nzslh`6M>1l9{Pu8ZZ{&0nN@L!g{vnBXV(=-=(OTm0esf(r)2mKI9E|iY zT}dq@%8+X!N{TiU5uGQZJJat}D{P}2ipRl_-r_n7@_)aTcuz>YYwhcG8>tr!%BfC7 zlXlaHA~zW2$r6}4&o1i^r3x>}tUeGf?Ezg}<~x%(B6NtZywuA1$Ah!I*xiff@^)z{ z6S>s*czY)5V7!y*sF}qO7th%C-YrJiGd|K@vP8#+AG*4sn?I*v)Fp2dBBa*K{866y z2qBiphU)72`v`&Zu5Ln4F0$!ppBr`p0JBScOf02eaG>+20qgEq znxO*9tfGh@kGgdz6y_(35w+>#s7PFvFG#G7uFOv$!|oPNL2|~-xiY(5-oiUH-7T)nitAPu z?G5l`cNhH0hp|*klWx%t~T@eg#R(I;QFB${;FnK@{>^@ZM}wJ!=<1R0Jafr&1VWDlO^pRtB1|PvdGH}r587XWX1*0DZ=xlQiSI|wl*wk`IO-G#w5mL;`XG(cud?b zBzH_~E>;9%qhdT}X4N6>ao+-G7kdtI9pc!uKy(DR3RbaXFfOq&m+5Ej#VvLsXj3n% zOaiGY1h7zBK#eJ6AG0AWYLKI&HqX)zD1egZ9p20mmdZwTacZo>8t7bQ97HY{r$(Mr zkBo4t=GIXKUw|;AN1@_)mCc;0Py-$%n|WlMHHKA8jq%9jf;%jE6-I>2W8YHxi^8c3 zqbH($m5ExTNo$lyeIeezeDLZkVxup#Pe3N`)g}UhI zm|PVYNWZJjSDLqlvKdak{{L1~M~2^LcF@PvRHs~cQWQD86zVPvsjh*rdDNy(43ok= z3}w$%0b|SwJxp>{z-c+rSCzPP9XHUH{$NqO8)!>^3S-}9>~axJq`Z{1yr}vac+9uJ z*eUxE(II|Ypk=gk>WuRbGh1JoSF#0uG4En*VO31LtOL1X=C01^4pSq0q8SnfcvTr$ z6=TXvTbjvQBO4zZ$_64r5XRK=f9OQP#pzHD->R@sA-7XVVw)Zb*(J@jNahhlGpuFp z=BA@pb457CB1*yK%V}+toDt~=%K7{lX}k}b-Y{00$FCeuBA`x0xA~+a0IN$Azv3HN zzKGOi7@G`z3W4kObVnV$?tp}XAY-TLgSc6hVHy;?PXD4nmC%_;x(LVrq7&CyB!z|h zQg$`iL)#7U@{=yc3Z2%uG8$yAs<@B(crzKO*&AH9^vxc`Ulw6n=&=iORRIMak5mDO zShc9ig1zw@X5#w_yB^IMNt_Ub(nQ2>Z+xFTStv~`05)e>OSR*u}IR@J) zj|9X$y>NdJ5r>x!Cw!+7;5jWX^=mHEY@etZgRJ>j=i7R zks;F5ZYyT?!@?qvuf-(2!J!ke_L6MTPI7H3>H}=(oM=9b*<-c*O0(B2?tm%Kj4LEO77&6Go2*PovIG;4dp%OXs zX+ljTy5HGplPub#rDRD)^IKeJHY;WHBqw}rEs4*seJ(b8=k>3nuyi_FGu6D)QSug| zM(KYxbwzoUI;lyEQkh;TF0*UVP7U==f5z#i8tk$x7~);q8{O)(3ShN-kEaOALaRSN)JK+Qda2 zaKPLpUtI_A0&O(5XhQs=@}22F*Zj(D(I0fBzhGm!>b9?rgwAqvY^XX4;_VerSzrSN zZ*_sqE_8K5VazU{Y|O*10^%vlH)?Zg(u|euaO~?gN^1kS2}foG^Ht*^1}^~B(5=3? zYT)5|fn^`bN4h-LHqgc1HM&?Y%Y@fmoB}KNfe$pDpq{VHC9Q=WmVT77E<2GGM6?#8 zbY+f8o)$@M1qC829|c*t1U6aMf~=Z$8?34G8i#-l<-&63UNTXGR~Ea|a6wG@P#iXj z$SEt={h}4*|KDmONsDswbK4n-Rjz^)q&weEMlSt7YEe*@K7_ucnDYkFfm*9(f3RJ~ zn^dk+BgwWXjBL4jt8s@A3OX@IV4J1jnRC7y$ybNST2v+<+rJwQ?M+&)Gi{oR$$DWP zDJWygAm~4cz8<=YZVz*>PD%-(WdNivFlx93ZlcEe$Ivx}gH%L`w9ly9E+urFcLxYY z2P=iO=@YJ!+aB{XuwYe8QI5cNkF+Rp!db}Whn!p*wZrsZxYFT~nMYonBQvz=pQ(+e zO+o`5NJk-Xa|1cQ9o|UF0%PbC%A&Z)HhsUlhO1%v4qa~tJFdUGa{ZmUZjWLSdMwN} z1|AC{u%^PWPWq%9_lLuglzmWYB3A3y)Fhg7vAMz<_*Cx3hv{2%Tc{L?3y791rT@`Y z%ewd-e9f$>*ir$%rQV}C6*?}T9U?^K5-lj@3IDsHh%dh-{RxNbhr_VkYLYqj$V$R0 zID%2&ma9&*lJuXcdj;{gc?>6PWha$@@}?7tG+1Fx0Kq&xPAZTQ57X~*eVBpPq0B{& z$r0;XM6G-JuN>CTR46=IB5iQDpfL6FEewj_k4%6{3(c*?CY(t|?h;LftD2?XtFdi$ zMA@uf!iutK*B^tFT4^RfSKJ*PZ_2P#ZAWo=XldFH!}= zOp6TR?<)6&L%x?|Id#kvGy(~6!N zfNWaOBMB46r>8Urw+KX9_r?>?YZ;Hou<&-fl1>AvB7=Ttzp)}R`%00SsA_XXWSCzy zak+`5hO&=aKl!&s>_`j7vGI*BVZ~Y@l?+;D+km)@V}Yy@D29⪼Ecj9=^IE zpJ@z`uX>J@eRn(*mVr&K<*k+Ej%-PBwai3cfhtj~iQ&?t#p=v}6%oZnx z+zBkJN03=~s-9Crm3l2KT|F5HUytktWFTg986PLqJ}rw-&q}Cmp;Ba^>_k$r5VVy} zk+m{Ah>es`&oYWFKq_{SI#vW#p}wsY>e;GL*9?`9N_d>T?6`C!YpAMyeERzS!2oz^ zf3ytR@HcpZ1{y}xX!qam)7`| zI3o{4XlR0NUZWaH3>nc0)}3}Fd2GRSH;jS9o*0g&6@m5w_va5|UaoY%;g5?GD%0j(gJ9!b;9JfSo&oFcf+d zA9s2rlz-N=hyI@e+d@9v`T4DbG}>^CWwVK~1%ZIgiiUsnkjz@g#cQrI%pWydS4)3D z`o_$S-e!}YOW5`S^)l>>u;RIfZLc2&G0!`+_!H&u*ex;p494Xe;`fs|E@fmtz&Q8(?Ip1_7hCW(nadRR% zlm1Tug0&PDTwrMTDl73=f#N2JT0fPZUx-}~VsUEaN5%ZIMR(6o^0q+EyA z_N5hyWS@%N`bhT4qA!}ox)Vds^ciD^I%cATo$|TKFD9ug>_3g^E_#(c1m#vEABUH; z0Q=P;L#CXgp;{+WiWu85YfpJEtK0(^c|<2YqlwBtNQMhK`IE$pm~F3x>7Te!fz8@C zwKS9Lnk(Pr1Vc^1U&~R;YN^<9YowQJojtAAT54GCCjDun3E;?DDReK7y{ZiztEVUT zx#N-u+8f*o|8AOVi%sdh@@WAoC!#lKbMa;$>)c!%bH_>C4Ck%CI&ywA-l8MvLAX5Z zl*NP`!%lI2ZKrrCkMln^9UFF}A=w3R6+hi{eeR2h2Mce=8@BrB^sWV4hvyYsY+(t` zK*cT{e-PSnkc>+kK>OYl05zxFi{P`sfDuZlQX*$h%jymQibD!VI~}^a&n?9vFR2*| zlPW=p%iCCbhsI)Rvf2y9ok%YKCgh#UVkxXg1e7|k`<7J1!Z=wfQXxMn#+P|h3Mzdx z#Bh3%3jDbu&Xt|bA|5Ts!Yoou7@8~0!*vvvQWm{xH|ZfV6M56Ff;-1U!I0%9Zp-4` zy-2;8`coQ4I+18TKxRXohT5X3+;-=j5P>{oJ@@lPAEOf+G@>`@FVUjCy`4S+8$jIv z_^|B5JeEZI_oX%~jBA;CLosx@QULG!DYS`d84x1`x=>W-SSx`lO%pe1`w0o`sX|>==Ewnq!d5fwU zB;^HdbYo6t(4PnbM?lMdS{*>5Set( zDR3^k%o_1XiufTD>o_B}SXOeV9&ujURxN;3@Qh-Vp4x8 zlJOz^Ua?${lF&xF*#4m?stp;QRr$@NLw8;{cNykpVIJYA0`5ezs{fYdD{}W&Ud_fO z@t@t`5iB~hx#6Cv8Hy@eib>TWVH)dnDaTEf&*ZqS&NhmMC_s?{WjM|kT=2FBY$4;>PQ%@!zru?uY;DEH+#Efmme*^3S@OI}PFl5Hq_1rp|R}7>@NQucS+CjoXsK zAYOeF1Egox2ZEtUvOou4*e^K4`_RYSHiNt@kcEH@;F8luWuy2dL z?g6s)eMCluaNXAk59X2;iQIfvPfVA%|5S7Tk+hH)oQcFi7GqAMB^K>HM zDQm;x8%(;AXTRGcQ^EmYVAs?47;J}mvx2Akds~X4f=f!n4cy_QTFFIb)AaD2qgFl7 z>@aXH6YPkin3`scj-E4E{VXQL(*vJsleO7>yTc%|zP8LC4PEn(OAzv}%CEke@ANHB zARhU0qw!v$fnC%Lo(+qSSFxCaG{jl~U--!4DlM;?{z|kC()Za++qYHt-V0OPcYso4 zg`GsYrx^3#>&6l4{ArEHDV|?<95oSxi(41il4) z*d@$NP$jkqgqUn@08f*ChhbU~2c*9chrcJG+^AIV2=ezmCPJs_Z#vSxrDA}u66l3{ zsNX=O%_aotdnAWFw&U`hC1ouf50CFu=p1Ty9lc=Z#|3aF--YWJPr)yFJS{E-sYP zJt|bWRK%iC(-v_WiAt?z^+1DH$)K3N&B_~q8#u@EJ_bcX!t{?cX8Wc}6&CovS>-Db z>}bxnC607$-LpfuQFMUeviMcIeS9*6T7uwE|K6a4QI6+UpwJR6`aaF(#o*h1M}FDC_oqKMJ(Nl;hLH(u5JZFGq*IhSF zo}pKTM)pIoiXJJ4TYt;-THK;vxIyx6m+7VFsQ4I9a~$fVN+`c@P;BVl?d3ka$rTf_OC}cPSY0T*5;Mu%*!cE zAt#b<&i3p;nKl9)C^FGW^84K?Qexo}hoIRb@B%l5@+w8TsS`3#0WC2q&=$%%`Qpl+ zz-rP?xUwmb3q2w*4FWL@OkH3I?6L?RXw}vgK$b%W&_b(v#!}j-C=p>B;sueATd`YX5l>)`~1P z3*~r^$r+Pp*1Nlr&B}If*ej5^h%Vb}H#nD1=m=6*kSn%vR6tbOc`%9Pco1@mebG#K zKvHrh##pvPHu;lg0{>7v;!LpmifKJ17)YDjsI{E*5<+l}0X9;!XCoz_#53Q3xpgUj zMiAU*>fqQ(S<-Pl63fiYHgs`ZNRDe}&x?c57u0iyEq?+Kqdo5?Aj&R#avGOP9-s9! zGJ6DBw+g^@28UH;{|rQ6yNM`E83EblR(}Z)L>Oa-1G?+_gmFtu*V}R^5V)X^?*$#M z8XfG@(*bW1}-WMTIe+$5XqKIJ2JTR@A_r-TEvj zl$d))NCmWmP-G*B0-g$SP%kxM%d2UJ%!G~6G^AgR#7@|l3Z%PS6*=6FqpYl}7dfen zvMoFpuQV@t0NM6c{|?!$>l7VB}f zMDIM%f3U$~y>^_GCTy>lXweBzrG0CmMY4fyAQHH3S_6`MLQrPaj%vz%%d>r2L`mO@ z(^c*r!1-@j&11esHpQRqglgK&kaT%ezyJe#7TeC7m}HHF6NSq?Gt8U{9VSJ1zlsou z9NjIkDn|^x5;|FXgqS!BFm-{lc{W~4Vpg-txFQf?zViK=bT_0QFYr+?aJM`hXA<(( zUA>mnDgQqIwxims#@+c`wXtWk)utm7kG6ptwS0`{8F%N&Ivr%e-h-e5X5wV#ZLzyO06!VIvFMoj52h~}))&R3ak zOK>z!Avo${_QDAcX2ni^TdzWL03t6E&*hW(Cm^#Vojh=O*KSlYxy&oS+zpOe6SX4M zyX~zgGHt|fdgIRZM#UiLtc$#-q_(!@*s;B|=XxN>$}V-o5=3$>2r(6(DT)6Z&m7oM zQK`TS%^ZCE9i}zP9C%pD9Q?pLt+tXm_-3X( zBJ6^>2>)m+dfmYio9PK<#kInsy<7b&8)XIRF#tZEt2p|K_C6L3&%r3==J9}WqZ_Nk zUDZunssSQuQD1~`hk3>yR`(@$6$vL<`%Jr;m5ox$n2F+ih}~y?Bip1L#Lc3)JS$aS z+jc4yn~f;+-Z)bl*q(^>gA`k#f^Svj%g`(p=ZEsGBJF)R3q-VYyD4$d4K$$_n7Y|w z*YmHO(J?jS}Z>GA()T*{sJ9&6VxDBbI_(5MBr|^mr>jjYm4K2zsfHE=WD$`? zoAnJlT4v$H^ox>1;`!ehUGZ$PJ3!gsNC=n%(<%_27arK}?DODBGkx0fkJlC{0x*N>Y`Jr|i8eJO^fcwRY({HP>!Pp|Tp+ z=9Z1nqwA0yo6x6I6?Z#pfjscia1H6-h~PG%TZg&Fc?w6=6eR7jnXVvkewa!m{0S>OW3zvkTUXLv#_7fJm5xXkv>yzI>ci3R*!yNg zO}c~POAai5DF4RQKHhjBep~4{Mvu1|=8wOJVQu+a+}uOo7|istH?DNtK@|xV8Q&;h zRD@-f!^V|_YOJiMAN?Z|CoS+}Ezg7&*l|`^*co_Y9m8h`^vg4^&%XCd%*!TZQ@eIv zKiCL6W+c*K7~r&=rM*%MvA#l8?LxcJI`_CNf#!~fO{H+`SaOJ>6BJzn?!W9O(HWi@jliut^5kx?N;U`##nQDus_2%Xnwpukei_* zR@!Y$roENF!pyOKrAb~Tqp}g+ zq0KK5kKth)uaR=*j`7&=0(hr~oic^Kj{Mj#GNHv#y3C%}aG(^Ol~Ek)wj?*vT+WF5 zgA9)p=kXo8w+@NhPpRpDi*$`@Ptmk|x^H8QiYE>SM#k!eJ8%rVwf?6GR24?ek5$M|u z9hTIYF=7oJ=sf~K)+Aq=u`#^fl`ybVo3%*?f<$iTp>$%N5=;Y*rOz=wBDr?Oppy~< zme|@fip_Xr6eaaE%5xq;?t>Au)27XUp5ZDf5gZqR!V3Hp$R&O=nfFCY+IlTzMfDPk zO!*vkL6^EngC-GDB0j+w@K~|B1{p?yH!}@M4tqKcOGh^IC*@y?$VBAIKk_ANHuK)- z-P5j_=e;44D$R5qj_ZxCp5p=B*5utpJ=cr5if_y{&|KLR(X{+rnWX008kwuDr&`y{ zRp&>=`i5EItf7|%8*LOoiO@DaA9(cP}XKXiYw8a>?sv((VMupL+9?Kl+p3 z|KX3_$srwRY@`;e(zlrcz9$^2wUR6~-T0b$jdBwguzseg}5QbantfI~{$UGD)@t`h`n8a>pWO5a+@d?Vd zNn$${%(E+RlU(j`ZdWcLAkZZo%pbHASWGGZh!&GY@=fBKe@r#Gw$mAb_Bp7YP2VSl z1YD%5J!VORX5?S|Vtg_Gbg<0pq}g-&Md7q`APBxXAmxxhz)mR){&aBetZTTri4IhW zSI58jGoLu{jU+N^pkDV8eeHt``-cHX@jV*A;}!6k>H%Jk%)asU27s85v!1u^+zbSJ zI*KkjR}6#PF-#o~27g?#&cfTgKx8TZN_Lt(t?|)SFZ|>SmI`~%DLZF>TS5V;gOQptJA`FBt0gBP)!TN4sLsY!GB`W$U0qo|oh@HFe`>Ir zt=yCKi=T({zl@eG4CYrB2H8NrYa0R6{H*?VK%Y%n04?t*&v32L0J@)Rv^#H z>N?2lSJI#WM9ciFUdIphtqoRR18V#L+KEeCJ3I>nuRm&eXXVnmSj`XJogQ45|6j%% z{WY*On%&c1gjdJ1lN09#_pE1M^EDYiRCs26@5xq{sfIfz_qAN5u8(C4Q7SPH-o(t({w(AFO3(`j-cY#y$LwA7TP%{dnNoN9a36 z-vg_c*4F0_%=Y^SXXj5X%pX~pIyHaz@TrCAgM&j0NBdK!rl$@s%+B0%WZ}@kg~5Tf z)%gSG7EjIdbAkuX_vcqv)()IsS$Nqhzg8H09+-FWo$@!vpV)xxoqX*Dp?2)prR959 z`xhqmp3D%Les=OTE6anEnKAspnU(W{10cUTSUi7Va1KpeIIujpcWvGm_TS5IS?*t5 z8!0ZMjfT_t)14=P#@~btrz@P(r-0mR(-#gVOTK z@_zJKT2uVT{oCCB1qp-6fh5j; z@9@C|@!=!a~I* zEbv>R&a#~u+=q$3fPqA-tVap^B5=R5GM36mp37Kf+oTYS3)v}t0`#vVJdF3Qx|5%u z;#;)-MZRCC{QNO}zufY(r!gu&mzLKqUATa?M?+UG44hl)udd=)tDbjp*-^+0$Kvt@ zEV%rH{OYh|UgLQSlHB{elO$a^5ej|{Jnw*hllGrWK2xh6%KYdee_f?i|@8WN9c>#s--uBdrZ0<1&lki6wo<2JzHWD_uhSUVX zHv@~W;C{X}@2c++y@=Fo9v|TTPVT>+znl1*yl--H^5Ep5$-|RVlSd|}Cub&SCyySS zJb3Wnp@WAHP8~dQaQfiP!P$dH4^19Ac<9if!-u909XT|8Xy(xDp`(W<4<9^y=Q-`JwPfbl7nVO!OnVOwCdSvp*!6S!`96mC2FJs2+3BM*lQRcr4$T~%nVLB=Gd(jiGdpv1c5?RM?4jAi zvs1H2W~XOoW@l%Q9tFjt41W~RN9lHys?9TYuJ+w6H{aJGgp#|W{4JFCP&UW!2}vlo bioqf>GYa!FuvQ2@=3)FE-{bVLUu*t Date: Fri, 5 Jan 2024 09:41:32 +0200 Subject: [PATCH 555/958] - compressed flags & updated configs --- cmd/node/config/enableRounds.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableRounds.toml b/cmd/node/config/enableRounds.toml index c580e02cec3..d7be75bb524 100644 --- a/cmd/node/config/enableRounds.toml +++ b/cmd/node/config/enableRounds.toml @@ -10,4 +10,4 @@ [RoundActivations] [RoundActivations.DisableAsyncCallV1] Options = [] - Round = "300" + Round = "100" From cb14bf35c776bb8f2d87d0eb078165c980d5e32e Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 10:06:40 +0200 Subject: [PATCH 556/958] - fixed the log.Warn in esdt.go - getSpecialRoles --- vm/systemSmartContracts/esdt.go | 2 +- vm/systemSmartContracts/esdt_test.go | 53 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 810f013858b..c6666db0dfe 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -1343,7 +1343,7 @@ func (e *esdt) getSpecialRoles(args *vmcommon.ContractCallInput) vmcommon.Return rolesAsString = append(rolesAsString, string(role)) } - specialRoleAddress := e.addressPubKeyConverter.SilentEncode(specialRole.Address, log) + specialRoleAddress, _ := e.addressPubKeyConverter.Encode(specialRole.Address) roles := strings.Join(rolesAsString, ",") message := fmt.Sprintf("%s:%s", specialRoleAddress, roles) diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index b3d0f5b698e..e85f9fd9bfb 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -2548,6 +2548,59 @@ func TestEsdt_GetSpecialRolesShouldWork(t *testing.T) { assert.Equal(t, []byte("erd1e7n8rzxdtl2n2fl6mrsg4l7stp2elxhfy6l9p7eeafspjhhrjq7qk05usw:ESDTRoleNFTAddQuantity,ESDTRoleNFTCreate,ESDTRoleNFTBurn"), eei.output[1]) } +func TestEsdt_GetSpecialRolesWithEmptyAddressShouldWork(t *testing.T) { + t.Parallel() + + tokenName := []byte("esdtToken") + args := createMockArgumentsForESDT() + eei := createDefaultEei() + args.Eei = eei + + addr1 := "" + addr1Bytes, _ := testscommon.RealWorldBech32PubkeyConverter.Decode(addr1) + + addr2 := "" + addr2Bytes, _ := testscommon.RealWorldBech32PubkeyConverter.Decode(addr2) + + specialRoles := []*ESDTRoles{ + { + Address: addr1Bytes, + Roles: [][]byte{ + []byte(core.ESDTRoleLocalMint), + []byte(core.ESDTRoleLocalBurn), + }, + }, + { + Address: addr2Bytes, + Roles: [][]byte{ + []byte(core.ESDTRoleNFTAddQuantity), + []byte(core.ESDTRoleNFTCreate), + []byte(core.ESDTRoleNFTBurn), + }, + }, + } + tokensMap := map[string][]byte{} + marshalizedData, _ := args.Marshalizer.Marshal(ESDTDataV2{ + SpecialRoles: specialRoles, + }) + tokensMap[string(tokenName)] = marshalizedData + eei.storageUpdate[string(eei.scAddress)] = tokensMap + args.Eei = eei + + args.AddressPubKeyConverter = testscommon.RealWorldBech32PubkeyConverter + + e, _ := NewESDTSmartContract(args) + + eei.output = make([][]byte, 0) + vmInput := getDefaultVmInputForFunc("getSpecialRoles", [][]byte{[]byte("esdtToken")}) + output := e.Execute(vmInput) + assert.Equal(t, vmcommon.Ok, output) + + assert.Equal(t, 2, len(eei.output)) + assert.Equal(t, []byte(":ESDTRoleLocalMint,ESDTRoleLocalBurn"), eei.output[0]) + assert.Equal(t, []byte(":ESDTRoleNFTAddQuantity,ESDTRoleNFTCreate,ESDTRoleNFTBurn"), eei.output[1]) +} + func TestEsdt_UnsetSpecialRoleWithRemoveEntryFromSpecialRoles(t *testing.T) { t.Parallel() From b52d7834d7050a44eb5d472972fe57dbf62109be Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 11:00:01 +0200 Subject: [PATCH 557/958] - made the dbConfigHandler more robust --- storage/factory/dbConfigHandler.go | 28 ++++++++---- storage/factory/dbConfigHandler_test.go | 58 ++++++++++++++++++++++--- storage/factory/export_test.go | 3 ++ 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/storage/factory/dbConfigHandler.go b/storage/factory/dbConfigHandler.go index 28ba8b5dcdb..9bd857dd0ec 100644 --- a/storage/factory/dbConfigHandler.go +++ b/storage/factory/dbConfigHandler.go @@ -1,6 +1,7 @@ package factory import ( + "errors" "fmt" "os" "path/filepath" @@ -14,6 +15,10 @@ const ( defaultType = "LvlDBSerial" ) +var ( + errInvalidConfiguration = errors.New("invalid configuration") +) + type dbConfigHandler struct { dbType string batchDelaySeconds int @@ -38,7 +43,7 @@ func NewDBConfigHandler(config config.DBConfig) *dbConfigHandler { // GetDBConfig will get the db config based on path func (dh *dbConfigHandler) GetDBConfig(path string) (*config.DBConfig, error) { dbConfigFromFile := &config.DBConfig{} - err := core.LoadTomlFile(dbConfigFromFile, getPersisterConfigFilePath(path)) + err := readCorrectConfigurationFromToml(dbConfigFromFile, getPersisterConfigFilePath(path)) if err == nil { log.Debug("GetDBConfig: loaded db config from toml config file", "config path", path, @@ -79,6 +84,20 @@ func (dh *dbConfigHandler) GetDBConfig(path string) (*config.DBConfig, error) { return dbConfig, nil } +func readCorrectConfigurationFromToml(dbConfig *config.DBConfig, filePath string) error { + err := core.LoadTomlFile(dbConfig, filePath) + if err != nil { + return err + } + + isInvalidConfig := len(dbConfig.Type) == 0 || dbConfig.MaxBatchSize <= 0 || dbConfig.BatchDelaySeconds <= 0 + if isInvalidConfig { + return errInvalidConfiguration + } + + return nil +} + // SaveDBConfigToFilePath will save the provided db config to specified path func (dh *dbConfigHandler) SaveDBConfigToFilePath(path string, dbConfig *config.DBConfig) error { pathExists, err := checkIfDirExists(path) @@ -92,13 +111,6 @@ func (dh *dbConfigHandler) SaveDBConfigToFilePath(path string, dbConfig *config. configFilePath := getPersisterConfigFilePath(path) - loadedDBConfig := &config.DBConfig{} - err = core.LoadTomlFile(loadedDBConfig, configFilePath) - if err == nil { - // config file already exists, no need to save config - return nil - } - err = core.SaveTomlFile(dbConfig, configFilePath) if err != nil { return err diff --git a/storage/factory/dbConfigHandler_test.go b/storage/factory/dbConfigHandler_test.go index 039da28ebf9..97da043aced 100644 --- a/storage/factory/dbConfigHandler_test.go +++ b/storage/factory/dbConfigHandler_test.go @@ -2,11 +2,13 @@ package factory_test import ( "os" + "path" "testing" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/storage/factory" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -88,6 +90,37 @@ func TestDBConfigHandler_GetDBConfig(t *testing.T) { require.Nil(t, err) require.Equal(t, expectedDBConfig, conf) }) + t.Run("empty config.toml file, load default db config", func(t *testing.T) { + t.Parallel() + + testConfig := createDefaultDBConfig() + testConfig.BatchDelaySeconds = 37 + testConfig.MaxBatchSize = 38 + testConfig.MaxOpenFiles = 39 + testConfig.ShardIDProviderType = "BinarySplit" + testConfig.NumShards = 4 + pf := factory.NewDBConfigHandler(testConfig) + + dirPath := t.TempDir() + + f, _ := os.Create(path.Join(dirPath, factory.DBConfigFileName)) + _ = f.Close() + + expectedDBConfig := &config.DBConfig{ + FilePath: "", + Type: factory.DefaultType, + BatchDelaySeconds: testConfig.BatchDelaySeconds, + MaxBatchSize: testConfig.MaxBatchSize, + MaxOpenFiles: testConfig.MaxOpenFiles, + UseTmpAsFilePath: false, + ShardIDProviderType: "", + NumShards: 0, + } + + conf, err := pf.GetDBConfig(dirPath) + require.Nil(t, err) + require.Equal(t, expectedDBConfig, conf) + }) t.Run("empty dir, load db config from main config", func(t *testing.T) { t.Parallel() @@ -146,22 +179,33 @@ func TestDBConfigHandler_SaveDBConfigToFilePath(t *testing.T) { err := pf.SaveDBConfigToFilePath("no/valid/path", &dbConfig) require.Nil(t, err) }) - - t.Run("config file already present, should not fail", func(t *testing.T) { + t.Run("config file already present, should not fail and should rewrite", func(t *testing.T) { t.Parallel() - dbConfig := createDefaultDBConfig() + dbConfig1 := createDefaultDBConfig() + dbConfig1.MaxOpenFiles = 37 + dbConfig1.Type = "dbconfig1" dirPath := t.TempDir() configPath := factory.GetPersisterConfigFilePath(dirPath) - err := core.SaveTomlFile(dbConfig, configPath) + err := core.SaveTomlFile(dbConfig1, configPath) require.Nil(t, err) - pf := factory.NewDBConfigHandler(dbConfig) - err = pf.SaveDBConfigToFilePath(dirPath, &dbConfig) + pf := factory.NewDBConfigHandler(dbConfig1) + + dbConfig2 := createDefaultDBConfig() + dbConfig2.MaxOpenFiles = 38 + dbConfig2.Type = "dbconfig2" + + err = pf.SaveDBConfigToFilePath(dirPath, &dbConfig2) + require.Nil(t, err) + + loadedDBConfig := &config.DBConfig{} + err = core.LoadTomlFile(loadedDBConfig, path.Join(dirPath, "config.toml")) require.Nil(t, err) - }) + assert.Equal(t, dbConfig2, *loadedDBConfig) + }) t.Run("should work", func(t *testing.T) { t.Parallel() diff --git a/storage/factory/export_test.go b/storage/factory/export_test.go index 23317b7d4cf..177bc97358c 100644 --- a/storage/factory/export_test.go +++ b/storage/factory/export_test.go @@ -8,6 +8,9 @@ import ( // DefaultType exports the defaultType const to be used in tests const DefaultType = defaultType +// DBConfigFileName exports the dbConfigFileName const to be used in tests +const DBConfigFileName = dbConfigFileName + // GetPersisterConfigFilePath - func GetPersisterConfigFilePath(path string) string { return getPersisterConfigFilePath(path) From e7997432850a06a5a0eabde0478bb1ce901d8e00 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 12:09:05 +0200 Subject: [PATCH 558/958] - fixes after review --- storage/factory/dbConfigHandler.go | 2 +- vm/systemSmartContracts/esdt.go | 26 ++++++++++++++++++++++++-- vm/systemSmartContracts/esdt_test.go | 20 ++++++++++++-------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/storage/factory/dbConfigHandler.go b/storage/factory/dbConfigHandler.go index 9bd857dd0ec..2e5a611f293 100644 --- a/storage/factory/dbConfigHandler.go +++ b/storage/factory/dbConfigHandler.go @@ -90,7 +90,7 @@ func readCorrectConfigurationFromToml(dbConfig *config.DBConfig, filePath string return err } - isInvalidConfig := len(dbConfig.Type) == 0 || dbConfig.MaxBatchSize <= 0 || dbConfig.BatchDelaySeconds <= 0 + isInvalidConfig := len(dbConfig.Type) == 0 || dbConfig.MaxBatchSize <= 0 || dbConfig.BatchDelaySeconds <= 0 || dbConfig.MaxOpenFiles <= 0 if isInvalidConfig { return errInvalidConfiguration } diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index c6666db0dfe..7fbc7c057a7 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/vm" + logger "github.com/multiversx/mx-chain-logger-go" vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) @@ -1343,9 +1344,11 @@ func (e *esdt) getSpecialRoles(args *vmcommon.ContractCallInput) vmcommon.Return rolesAsString = append(rolesAsString, string(role)) } - specialRoleAddress, _ := e.addressPubKeyConverter.Encode(specialRole.Address) - roles := strings.Join(rolesAsString, ",") + + specialRoleAddress, errEncode := e.addressPubKeyConverter.Encode(specialRole.Address) + e.treatErrorForGetSpecialRoles(errEncode, rolesAsString, specialRole.Address) + message := fmt.Sprintf("%s:%s", specialRoleAddress, roles) e.eei.Finish([]byte(message)) } @@ -1353,6 +1356,25 @@ func (e *esdt) getSpecialRoles(args *vmcommon.ContractCallInput) vmcommon.Return return vmcommon.Ok } +func (e *esdt) treatErrorForGetSpecialRoles(err error, roles []string, address []byte) { + if err == nil { + return + } + + logLevel := logger.LogTrace + for _, role := range roles { + if role != vmcommon.ESDTRoleBurnForAll { + logLevel = logger.LogWarning + break + } + } + + log.Log(logLevel, "esdt.treatErrorForGetSpecialRoles", + "hex specialRole.Address", hex.EncodeToString(address), + "roles", strings.Join(roles, ", "), + "error", err) +} + func (e *esdt) basicOwnershipChecks(args *vmcommon.ContractCallInput) (*ESDTDataV2, vmcommon.ReturnCode) { if args.CallValue.Cmp(zero) != 0 { e.eei.AddReturnMessage("callValue must be 0") diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index e85f9fd9bfb..c857bddc068 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -2556,28 +2556,31 @@ func TestEsdt_GetSpecialRolesWithEmptyAddressShouldWork(t *testing.T) { eei := createDefaultEei() args.Eei = eei - addr1 := "" - addr1Bytes, _ := testscommon.RealWorldBech32PubkeyConverter.Decode(addr1) - - addr2 := "" - addr2Bytes, _ := testscommon.RealWorldBech32PubkeyConverter.Decode(addr2) + addr := "" + addrBytes, _ := testscommon.RealWorldBech32PubkeyConverter.Decode(addr) specialRoles := []*ESDTRoles{ { - Address: addr1Bytes, + Address: addrBytes, Roles: [][]byte{ []byte(core.ESDTRoleLocalMint), []byte(core.ESDTRoleLocalBurn), }, }, { - Address: addr2Bytes, + Address: addrBytes, Roles: [][]byte{ []byte(core.ESDTRoleNFTAddQuantity), []byte(core.ESDTRoleNFTCreate), []byte(core.ESDTRoleNFTBurn), }, }, + { + Address: addrBytes, + Roles: [][]byte{ + []byte(vmcommon.ESDTRoleBurnForAll), + }, + }, } tokensMap := map[string][]byte{} marshalizedData, _ := args.Marshalizer.Marshal(ESDTDataV2{ @@ -2596,9 +2599,10 @@ func TestEsdt_GetSpecialRolesWithEmptyAddressShouldWork(t *testing.T) { output := e.Execute(vmInput) assert.Equal(t, vmcommon.Ok, output) - assert.Equal(t, 2, len(eei.output)) + assert.Equal(t, 3, len(eei.output)) assert.Equal(t, []byte(":ESDTRoleLocalMint,ESDTRoleLocalBurn"), eei.output[0]) assert.Equal(t, []byte(":ESDTRoleNFTAddQuantity,ESDTRoleNFTCreate,ESDTRoleNFTBurn"), eei.output[1]) + assert.Equal(t, []byte(":ESDTRoleBurnForAll"), eei.output[2]) } func TestEsdt_UnsetSpecialRoleWithRemoveEntryFromSpecialRoles(t *testing.T) { From 4790f86f122e6e21ce53eb5cf5e6fd5ae60ad654 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 14:39:14 +0200 Subject: [PATCH 559/958] - fixes after review --- vm/systemSmartContracts/esdt.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 7fbc7c057a7..1adc28b1d58 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -1347,7 +1347,7 @@ func (e *esdt) getSpecialRoles(args *vmcommon.ContractCallInput) vmcommon.Return roles := strings.Join(rolesAsString, ",") specialRoleAddress, errEncode := e.addressPubKeyConverter.Encode(specialRole.Address) - e.treatErrorForGetSpecialRoles(errEncode, rolesAsString, specialRole.Address) + e.treatEncodeErrorForGetSpecialRoles(errEncode, rolesAsString, specialRole.Address) message := fmt.Sprintf("%s:%s", specialRoleAddress, roles) e.eei.Finish([]byte(message)) @@ -1356,7 +1356,7 @@ func (e *esdt) getSpecialRoles(args *vmcommon.ContractCallInput) vmcommon.Return return vmcommon.Ok } -func (e *esdt) treatErrorForGetSpecialRoles(err error, roles []string, address []byte) { +func (e *esdt) treatEncodeErrorForGetSpecialRoles(err error, roles []string, address []byte) { if err == nil { return } @@ -1369,7 +1369,7 @@ func (e *esdt) treatErrorForGetSpecialRoles(err error, roles []string, address [ } } - log.Log(logLevel, "esdt.treatErrorForGetSpecialRoles", + log.Log(logLevel, "esdt.treatEncodeErrorForGetSpecialRoles", "hex specialRole.Address", hex.EncodeToString(address), "roles", strings.Join(roles, ", "), "error", err) From d236d8d7810e220328f899bc8ce10606f4ed66d8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 5 Jan 2024 15:00:33 +0200 Subject: [PATCH 560/958] FIX: After merge in stakingV4 7 + fix staking+governance+delegation+validator system scs --- .../smartContract/processorV2/processV2.go | 2 +- .../enableEpochsHandlerStub.go | 4 + vm/systemSmartContracts/delegation.go | 22 +- .../delegationManager_test.go | 4 +- vm/systemSmartContracts/eei.go | 32 +- vm/systemSmartContracts/governance.go | 13 +- vm/systemSmartContracts/governance_test.go | 815 ++---------------- vm/systemSmartContracts/stakingWaitingList.go | 2 +- vm/systemSmartContracts/staking_test.go | 38 +- vm/systemSmartContracts/validator.go | 4 +- vm/systemSmartContracts/validator_test.go | 12 +- 11 files changed, 116 insertions(+), 832 deletions(-) diff --git a/process/smartContract/processorV2/processV2.go b/process/smartContract/processorV2/processV2.go index 1217717cbca..126433c6dee 100644 --- a/process/smartContract/processorV2/processV2.go +++ b/process/smartContract/processorV2/processV2.go @@ -2733,7 +2733,7 @@ func (sc *scProcessor) ProcessSmartContractResult(scr *smartContractResult.Smart returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err case process.BuiltInFunctionCall: - if sc.shardCoordinator.SelfId() == core.MetachainShardId && !sc.enableEpochsHandler.IsFlagEnabled(common.BuiltInFunctionOnMetaFlag) { + if sc.shardCoordinator.SelfId() == core.MetachainShardId { returnCode, err = sc.ExecuteSmartContractTransaction(scr, sndAcc, dstAcc) return returnCode, err } diff --git a/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go index 16fc9019390..bf633508147 100644 --- a/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go @@ -44,6 +44,10 @@ func (stub *EnableEpochsHandlerStub) AddActiveFlags(flags ...core.EnableEpochFla stub.Lock() defer stub.Unlock() + if len(stub.activeFlags) == 0 { + stub.activeFlags = make(map[core.EnableEpochFlag]struct{}) + } + for _, flag := range flags { stub.activeFlags[flag] = struct{}{} } diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index b16957689fc..c65afdf6942 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1739,11 +1739,6 @@ func (d *delegation) unDelegateValueFromAddress( return vmcommon.UserError } - if isStakeLocked(d.eei, d.governanceSCAddr, args.CallerAddr) { - d.eei.AddReturnMessage("stake is locked for voting") - return vmcommon.UserError - } - delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) if err != nil { d.eei.AddReturnMessage("error getting minimum delegation amount " + err.Error()) @@ -1753,8 +1748,7 @@ func (d *delegation) unDelegateValueFromAddress( minDelegationAmount := delegationManagement.MinDelegationAmount remainedFund := big.NewInt(0).Sub(activeFund.Value, valueToUnDelegate) - err = d.checkRemainingFundValue(remainedFund) - if err != nil { + if remainedFund.Cmp(zero) > 0 && remainedFund.Cmp(minDelegationAmount) < 0 { d.eei.AddReturnMessage("invalid value to undelegate - need to undelegate all - do not leave dust behind") return vmcommon.UserError } @@ -1831,20 +1825,6 @@ func (d *delegation) unDelegateValueFromAddress( return vmcommon.Ok } -func (d *delegation) checkRemainingFundValue(remainedFund *big.Int) error { - delegationManagement, err := getDelegationManagement(d.eei, d.marshalizer, d.delegationMgrSCAddress) - if err != nil { - return err - } - - minDelegationAmount := delegationManagement.MinDelegationAmount - if remainedFund.Cmp(zero) > 0 && remainedFund.Cmp(minDelegationAmount) < 0 { - return vm.ErrNotEnoughRemainingFunds - } - - return nil -} - func (d *delegation) addNewUnStakedFund( delegatorAddress []byte, delegator *DelegatorData, diff --git a/vm/systemSmartContracts/delegationManager_test.go b/vm/systemSmartContracts/delegationManager_test.go index b683ac4331c..e2b4de77d8f 100644 --- a/vm/systemSmartContracts/delegationManager_test.go +++ b/vm/systemSmartContracts/delegationManager_test.go @@ -1171,7 +1171,7 @@ func TestDelegationManagerSystemSC_ClaimMultipleDelegationDuplicatedInput(t *tes GetCalled: func(key []byte) (vm.SystemSmartContract, error) { return &mock.SystemSCStub{ ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - _ = d.eei.Transfer(args.RecipientAddr, args.CallerAddr, big.NewInt(10), nil, 0) + d.eei.Transfer(args.RecipientAddr, args.CallerAddr, big.NewInt(10), nil, 0) return vmcommon.Ok }, }, nil @@ -1197,7 +1197,7 @@ func TestDelegationManagerSystemSC_ClaimMultipleDelegation(t *testing.T) { GetCalled: func(key []byte) (vm.SystemSmartContract, error) { return &mock.SystemSCStub{ ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - _ = d.eei.Transfer(args.CallerAddr, args.RecipientAddr, big.NewInt(10), nil, 0) + d.eei.Transfer(args.CallerAddr, args.RecipientAddr, big.NewInt(10), nil, 0) return vmcommon.Ok }, }, nil diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index de4899ae3c8..d4c242cf47c 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -1,8 +1,8 @@ package systemSmartContracts import ( - "fmt" "errors" + "fmt" "math/big" "github.com/multiversx/mx-chain-core-go/core" @@ -218,10 +218,18 @@ func (host *vmContext) SendGlobalSettingToAll(_ []byte, input []byte) { } } -// Transfer handles any necessary value transfer required and takes -// the necessary steps to create accounts -func (host *vmContext) Transfer(destination []byte, sender []byte, value *big.Int, input []byte, gasLimit uint64) { +func (host *vmContext) transferValueOnly( + destination []byte, + sender []byte, + value *big.Int, +) { + senderAcc, destAcc := host.getSenderDestination(sender, destination) + + _ = senderAcc.BalanceDelta.Sub(senderAcc.BalanceDelta, value) + _ = destAcc.BalanceDelta.Add(destAcc.BalanceDelta, value) +} +func (host *vmContext) getSenderDestination(sender, destination []byte) (*vmcommon.OutputAccount, *vmcommon.OutputAccount) { senderAcc, exists := host.outputAccounts[string(sender)] if !exists { senderAcc = &vmcommon.OutputAccount{ @@ -245,17 +253,6 @@ func (host *vmContext) Transfer(destination []byte, sender []byte, value *big.In return senderAcc, destAcc } -func (host *vmContext) transferValueOnly( - destination []byte, - sender []byte, - value *big.Int, -) { - senderAcc, destAcc := host.getSenderDestination(sender, destination) - - _ = senderAcc.BalanceDelta.Sub(senderAcc.BalanceDelta, value) - _ = destAcc.BalanceDelta.Add(destAcc.BalanceDelta, value) -} - // Transfer handles any necessary value transfer required and takes // the necessary steps to create accounts func (host *vmContext) Transfer( @@ -264,7 +261,7 @@ func (host *vmContext) Transfer( value *big.Int, input []byte, gasLimit uint64, -) error { +) { host.transferValueOnly(destination, sender, value) senderAcc, destAcc := host.getSenderDestination(sender, destination) outputTransfer := vmcommon.OutputTransfer{ @@ -434,7 +431,8 @@ func createDirectCallInput( func (host *vmContext) transferBeforeInternalExec(callInput *vmcommon.ContractCallInput, sender []byte, callType string) error { if !host.enableEpochsHandler.IsFlagEnabled(common.MultiClaimOnDelegationFlag) { - return host.Transfer(callInput.RecipientAddr, sender, callInput.CallValue, nil, 0) + host.Transfer(callInput.RecipientAddr, sender, callInput.CallValue, nil, 0) + return nil } host.transferValueOnly(callInput.RecipientAddr, sender, callInput.CallValue) diff --git a/vm/systemSmartContracts/governance.go b/vm/systemSmartContracts/governance.go index 042df1bc204..ae3f080c636 100644 --- a/vm/systemSmartContracts/governance.go +++ b/vm/systemSmartContracts/governance.go @@ -648,11 +648,7 @@ func (g *governanceContract) closeProposal(args *vmcommon.ContractCallInput) vmc g.addToAccumulatedFees(baseConfig.LostProposalFee) } - err = g.eei.Transfer(args.CallerAddr, args.RecipientAddr, tokensToReturn, nil, 0) - if err != nil { - g.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } + g.eei.Transfer(args.CallerAddr, args.RecipientAddr, tokensToReturn, nil, 0) logEntry := &vmcommon.LogEntry{ Identifier: []byte(args.Function), @@ -701,12 +697,7 @@ func (g *governanceContract) claimAccumulatedFees(args *vmcommon.ContractCallInp accumulatedFees := g.getAccumulatedFees() g.setAccumulatedFees(big.NewInt(0)) - err = g.eei.Transfer(args.CallerAddr, args.RecipientAddr, accumulatedFees, nil, 0) - if err != nil { - g.eei.AddReturnMessage(err.Error()) - return vmcommon.UserError - } - + g.eei.Transfer(args.CallerAddr, args.RecipientAddr, accumulatedFees, nil, 0) return vmcommon.Ok } diff --git a/vm/systemSmartContracts/governance_test.go b/vm/systemSmartContracts/governance_test.go index 3f0b82e6ed0..387e16b33fb 100644 --- a/vm/systemSmartContracts/governance_test.go +++ b/vm/systemSmartContracts/governance_test.go @@ -348,591 +348,44 @@ func TestGovernanceContract_ChangeConfig(t *testing.T) { return nil }, } - voteArgs := [][]byte{ - proposalIdentifier, - []byte("wrong vote"), - } - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "vote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, errInvalidVoteSubstr) -} - -func TestGovernanceContract_ValidatorVoteInvalidDelegated(t *testing.T) { - t.Parallel() - - returnMessage := "" - errInvalidVoteSubstr := "invalid delegator address" - callerAddress := vm.FirstDelegationSCAddress - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - AddReturnMessageCalled: func(msg string) { - returnMessage = msg - }, - } - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - []byte("delegatedToWrongAddress"), - big.NewInt(1000).Bytes(), - } - - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "delegateVote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, errInvalidVoteSubstr) -} - -func TestGovernanceContract_ValidatorVoteComputePowerError(t *testing.T) { - t.Parallel() - - returnMessage := "" - errInvalidVoteSubstr := "could not return total stake for the provided address" - callerAddress := []byte("address") - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - - return nil - }, - GetStorageFromAddressCalled: func(_ []byte, _ []byte) []byte { - return []byte("invalid proposal bytes") - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - AddReturnMessageCalled: func(msg string) { - returnMessage = msg - }, - } - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - } - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "vote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, errInvalidVoteSubstr) -} - -func TestGovernanceContract_ValidatorVoteInvalidVoteSetError(t *testing.T) { - t.Parallel() - - mockBlsKey := []byte("bls key") - mockValidatorBlsKeys := [][]byte{ - mockBlsKey, - mockBlsKey, - mockBlsKey, - mockBlsKey, - } - - callerAddress := []byte("address") - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - votePower := big.NewInt(100).Bytes() - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - if bytes.Equal(key, append(proposalIdentifier, callerAddress...)) { - return []byte("invalid vote set") - } - - return nil - }, - GetStorageFromAddressCalled: func(address []byte, key []byte) []byte { - if bytes.Equal(address, args.ValidatorSCAddress) && bytes.Equal(key, callerAddress) { - auctionBytes, _ := args.Marshalizer.Marshal(&ValidatorDataV2{ - BlsPubKeys: mockValidatorBlsKeys, - TotalStakeValue: big.NewInt(0).SetBytes(votePower), - }) - - return auctionBytes - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - } - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - } - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "vote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.ExecutionFailed, retCode) -} - -func TestGovernanceContract_DelegateVoteVoteNotEnoughPower(t *testing.T) { - t.Parallel() - - mockBlsKey := []byte("bls key") - returnMessage := "" - errInvalidVoteSubstr := "not enough voting power to cast this vote" - mockValidatorBlsKeys := [][]byte{ - mockBlsKey, - mockBlsKey, - mockBlsKey, - mockBlsKey, - } - - callerAddress := vm.FirstDelegationSCAddress - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - votePower := big.NewInt(100).Bytes() - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - - return nil - }, - AddReturnMessageCalled: func(msg string) { - returnMessage = msg - }, - GetStorageFromAddressCalled: func(address []byte, key []byte) []byte { - if bytes.Equal(address, args.ValidatorSCAddress) && bytes.Equal(key, callerAddress) { - auctionBytes, _ := args.Marshalizer.Marshal(&ValidatorDataV2{ - BlsPubKeys: mockValidatorBlsKeys, - TotalStakeValue: big.NewInt(0).SetBytes(votePower), - }) - - return auctionBytes - } - if bytes.Equal(address, vm.DelegationManagerSCAddress) && bytes.Equal(key, []byte(delegationContractsList)) { - contractList := &DelegationContractList{} - marshaledData, _ := args.Marshalizer.Marshal(contractList) - return marshaledData - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - } - - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - big.NewInt(100000).Bytes(), - callerAddress, - } - gsc, _ := NewGovernanceContract(args) - - callInput := createVMInput(big.NewInt(0), "delegateVote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, errInvalidVoteSubstr) -} - -func TestGovernanceContract_DelegateVoteSuccess(t *testing.T) { - t.Parallel() - - mockBlsKey := []byte("bls key") - mockValidatorBlsKeys := [][]byte{ - mockBlsKey, - mockBlsKey, - mockBlsKey, - mockBlsKey, - } - - callerAddress := vm.FirstDelegationSCAddress - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - votePower := big.NewInt(100) - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - Yes: big.NewInt(10), - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - - return nil - }, - GetStorageFromAddressCalled: func(address []byte, key []byte) []byte { - if bytes.Equal(address, args.ValidatorSCAddress) && bytes.Equal(key, callerAddress) { - auctionBytes, _ := args.Marshalizer.Marshal(&ValidatorDataV2{ - BlsPubKeys: mockValidatorBlsKeys, - TotalStakeValue: big.NewInt(0).Set(votePower), - }) - - return auctionBytes - } - if bytes.Equal(address, vm.DelegationManagerSCAddress) && bytes.Equal(key, []byte(delegationContractsList)) { - contractList := &DelegationContractList{} - marshaledData, _ := args.Marshalizer.Marshal(contractList) - return marshaledData - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - } - - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - big.NewInt(10).Bytes(), - callerAddress, - } - gsc, _ := NewGovernanceContract(args) - - callInput := createVMInput(big.NewInt(0), "delegateVote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.Ok, retCode) -} - -func TestGovernanceContract_ValidatorVote(t *testing.T) { - t.Parallel() - - mockBlsKey := []byte("bls key") - mockValidatorBlsKeys := [][]byte{ - mockBlsKey, - mockBlsKey, - mockBlsKey, - mockBlsKey, - } - - callerAddress := []byte("address") - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - votePower := big.NewInt(10) - proposalKey := append([]byte(proposalPrefix), proposalIdentifier...) - voteItemKey := append(proposalKey, callerAddress...) - - finalVoteSet := &VoteSet{} - finalProposal := &GeneralProposal{} - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - Yes: big.NewInt(0), - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - if bytes.Equal(key, append([]byte(stakeLockPrefix), callerAddress...)) { - return big.NewInt(10).Bytes() - } - - return nil - }, - GetStorageFromAddressCalled: func(address []byte, key []byte) []byte { - if bytes.Equal(address, args.ValidatorSCAddress) && bytes.Equal(key, callerAddress) { - auctionBytes, _ := args.Marshalizer.Marshal(&ValidatorDataV2{ - BlsPubKeys: mockValidatorBlsKeys, - TotalStakeValue: big.NewInt(100), - }) - - return auctionBytes - } - if bytes.Equal(address, vm.DelegationManagerSCAddress) && bytes.Equal(key, []byte(delegationContractsList)) { - contractList := &DelegationContractList{Addresses: [][]byte{vm.FirstDelegationSCAddress}} - marshaledData, _ := args.Marshalizer.Marshal(contractList) - return marshaledData - } - - return nil - }, - - SetStorageCalled: func(key []byte, value []byte) { - if bytes.Equal(key, voteItemKey) { - _ = args.Marshalizer.Unmarshal(finalVoteSet, value) - } - if bytes.Equal(key, proposalKey) { - _ = args.Marshalizer.Unmarshal(finalProposal, value) - } - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - } - - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - } - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "vote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.Ok, retCode) - require.Equal(t, votePower, finalProposal.Yes) - require.Equal(t, 1, len(finalProposal.Votes)) - require.Equal(t, votePower, finalVoteSet.TotalYes) - require.Equal(t, votePower, finalVoteSet.UsedPower) - require.Equal(t, big.NewInt(0), finalVoteSet.UsedBalance) -} - -func TestGovernanceContract_ValidatorVoteTwice(t *testing.T) { - t.Parallel() - - callerAddress := []byte("address") - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - - args := createMockGovernanceArgs() - - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteNonce: 10, - EndVoteNonce: 15, - Yes: big.NewInt(0), - } - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) - return proposalBytes - } - if bytes.Equal(key, append(proposalIdentifier, callerAddress...)) { - voteSetBytes, _ := args.Marshalizer.Marshal(&VoteSet{VoteItems: []*VoteDetails{{Value: 0}}}) - return voteSetBytes - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 14 - }, - } - }, - AddReturnMessageCalled: func(msg string) { - require.Equal(t, msg, "vote only once") - }, - } - - voteArgs := [][]byte{ - proposalIdentifier, - []byte("yes"), - } - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "vote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) -} - -func TestGovernanceContract_DelegateVoteUserErrors(t *testing.T) { - t.Parallel() - - args := createMockGovernanceArgs() - - mockEI := &mock.SystemEIStub{} - args.Eei = mockEI - - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "delegateVote", []byte("address"), vm.GovernanceSCAddress, nil) - - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - - callInput.Arguments = [][]byte{{1}, {2}, {3}, {4}} - callInput.CallValue = big.NewInt(10) - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Equal(t, mockEI.ReturnMessage, "function is not payable") - - mockEI.UseGasCalled = func(_ uint64) error { - return vm.ErrNotEnoughGas - } - callInput.CallValue = big.NewInt(0) - args.Eei = mockEI - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.OutOfGas, retCode) - - mockEI.AddReturnMessageCalled = func(msg string) { - require.Equal(t, msg, "only SC can call this") - } - mockEI.UseGasCalled = func(gas uint64) error { - return nil - } - args.Eei = mockEI - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - - mockEI.AddReturnMessageCalled = func(msg string) { - require.Equal(t, msg, "invalid delegator address") - } - callInput.CallerAddr = vm.ESDTSCAddress - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - - mockEI.AddReturnMessageCalled = func(msg string) { - require.Equal(t, msg, vm.ErrProposalNotFound.Error()) - } - args.Eei = mockEI - callInput.Arguments[3] = vm.ESDTSCAddress - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - - mockEI.GetStorageCalled = func(key []byte) []byte { - proposalBytes, _ := args.Marshalizer.Marshal(&GeneralProposal{}) - return proposalBytes - } - mockEI.AddReturnMessageCalled = func(msg string) { - require.True(t, bytes.Contains([]byte(msg), []byte("invalid vote type option: "))) - } - args.Eei = mockEI - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) -} - -func TestGovernanceContract_ClaimFundsWrongCallValue(t *testing.T) { - t.Parallel() - - returnMessage := "" - expectedErrorSubstr := "invalid callValue" - args := createMockGovernanceArgs() - args.Eei = &mock.SystemEIStub{ - AddReturnMessageCalled: func(msg string) { - returnMessage = msg - }, - } gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(9), "claimFunds", vm.GovernanceSCAddress, vm.GovernanceSCAddress, nil) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, expectedErrorSubstr) -} - -func TestGovernanceContract_ClaimFundsWrongNumberOfArguments(t *testing.T) { - t.Parallel() - returnMessage := "" - expectedErrorSubstr := "invalid number of arguments" - args := createMockGovernanceArgs() - args.Eei = &mock.SystemEIStub{ - AddReturnMessageCalled: func(msg string) { - returnMessage = msg - }, + callInputArgs := [][]byte{ + []byte("1"), + []byte("1"), + []byte("10"), + []byte("10"), + []byte("15"), } - - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(big.NewInt(0), "claimFunds", vm.GovernanceSCAddress, vm.GovernanceSCAddress, nil) + initInput := createVMInput(zero, "initV2", vm.GovernanceSCAddress, vm.GovernanceSCAddress, nil) + _ = gsc.Execute(initInput) + callInput := createVMInput(zero, "changeConfig", args.OwnerAddress, vm.GovernanceSCAddress, callInputArgs) retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.FunctionWrongSignature, retCode) - require.Contains(t, returnMessage, expectedErrorSubstr) + + require.Equal(t, vmcommon.Ok, retCode) } -func TestGovernanceContract_ClaimFundsStillLocked(t *testing.T) { +func TestGovernanceContract_ValidatorVoteInvalidDelegated(t *testing.T) { t.Parallel() returnMessage := "" - expectedErrorSubstr := "your funds are still locked" - callerAddress := []byte("address") + errInvalidVoteSubstr := "invalid delegator address" + callerAddress := vm.FirstDelegationSCAddress proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) + args := createMockGovernanceArgs() + + generalProposal := &GeneralProposal{ + CommitHash: proposalIdentifier, + StartVoteEpoch: 10, + EndVoteEpoch: 15, + } args.Eei = &mock.SystemEIStub{ - AddReturnMessageCalled: func(msg string) { - returnMessage = msg - }, GetStorageCalled: func(key []byte) []byte { - expectedKeyPrefix := append([]byte(fundsLockPrefix), proposalIdentifier...) - if bytes.Equal(key, append(expectedKeyPrefix, callerAddress...)) { - voteSetBytes, _ := args.Marshalizer.Marshal(&VoteSet{ - UsedBalance: big.NewInt(100), - }) - return voteSetBytes - } if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalByes, _ := args.Marshalizer.Marshal(&GeneralProposal{EndVoteNonce: 100}) - return proposalByes + proposalBytes, _ := args.Marshalizer.Marshal(generalProposal) + return proposalBytes } return nil @@ -940,166 +393,72 @@ func TestGovernanceContract_ClaimFundsStillLocked(t *testing.T) { BlockChainHookCalled: func() vm.BlockchainHook { return &mock.BlockChainHookStub{ CurrentNonceCalled: func() uint64 { - return 11 + return 14 }, } }, - } - claimArgs := [][]byte{ - proposalIdentifier, - } - - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(zero, "claimFunds", callerAddress, vm.GovernanceSCAddress, claimArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, expectedErrorSubstr) -} - -func TestGovernanceContract_ClaimFundsNothingToClaim(t *testing.T) { - t.Parallel() - - returnMessage := "" - expectedErrorSubstr := "no funds to claim for this proposal" - callerAddress := []byte("address") - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - args := createMockGovernanceArgs() - args.Eei = &mock.SystemEIStub{ AddReturnMessageCalled: func(msg string) { returnMessage = msg }, - GetStorageCalled: func(key []byte) []byte { - expectedKeyPrefix := append([]byte(fundsLockPrefix), proposalIdentifier...) - if bytes.Equal(key, append(expectedKeyPrefix, callerAddress...)) { - voteSetBytes, _ := args.Marshalizer.Marshal(&VoteSet{ - UsedBalance: zero, - }) - return voteSetBytes - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 11 - }, - } - }, } - claimArgs := [][]byte{ + voteArgs := [][]byte{ proposalIdentifier, + []byte("yes"), + []byte("delegatedToWrongAddress"), + big.NewInt(1000).Bytes(), } gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(zero, "claimFunds", callerAddress, vm.GovernanceSCAddress, claimArgs) + callInput := createVMInput(big.NewInt(0), "delegateVote", callerAddress, vm.GovernanceSCAddress, voteArgs) retCode := gsc.Execute(callInput) require.Equal(t, vmcommon.UserError, retCode) - require.Contains(t, returnMessage, expectedErrorSubstr) + require.Contains(t, returnMessage, errInvalidVoteSubstr) } -func TestGovernanceContract_ClaimFunds(t *testing.T) { +func TestGovernanceContract_DelegateVoteUserErrors(t *testing.T) { t.Parallel() - callerAddress := []byte("address") - voteValue := big.NewInt(10) - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - - finalVoteSet := &VoteSet{} - transferFrom := make([]byte, 0) - transferTo := make([]byte, 0) - transferValue := big.NewInt(0) - - args := createMockGovernanceArgs() - args.Eei = &mock.SystemEIStub{ - GetStorageCalled: func(key []byte) []byte { - expectedKeyPrefix := append([]byte(fundsLockPrefix), proposalIdentifier...) - if bytes.Equal(key, append(expectedKeyPrefix, callerAddress...)) { - voteSetBytes, _ := args.Marshalizer.Marshal(&VoteSet{ - UsedBalance: voteValue, - }) - return voteSetBytes - } - if bytes.Equal(key, append([]byte(proposalPrefix), proposalIdentifier...)) { - proposalByes, _ := args.Marshalizer.Marshal(&GeneralProposal{EndVoteNonce: 100}) - return proposalByes - } - - return nil - }, - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 101 - }, - } - }, - SetStorageCalled: func(key []byte, value []byte) { - proposalKey := append([]byte(proposalPrefix), proposalIdentifier...) - if bytes.Equal(key, append(proposalKey, callerAddress...)) { - _ = args.Marshalizer.Unmarshal(finalVoteSet, value) - } - }, - TransferCalled: func(destination []byte, sender []byte, value *big.Int, _ []byte, _ uint64) { - transferTo = destination - transferFrom = sender - transferValue.Set(value) - }, - } - claimArgs := [][]byte{ - proposalIdentifier, + gsc, blockchainHook, eei := createGovernanceBlockChainHookStubContextHandler() + blockchainHook.CurrentNonceCalled = func() uint64 { + return 12 } - gsc, _ := NewGovernanceContract(args) - callInput := createVMInput(zero, "claimFunds", callerAddress, vm.GovernanceSCAddress, claimArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.Ok, retCode) - require.Equal(t, args.GovernanceSCAddress, transferFrom) - require.Equal(t, callerAddress, transferTo) - require.Equal(t, voteValue, transferValue) -} - -func TestGovernanceContract_WhiteListProposal(t *testing.T) { - t.Parallel() - - callerAddress := []byte("address") - finalWhitelistProposal := &WhiteListProposal{} - finalProposal := &GeneralProposal{} - proposalIdentifier := bytes.Repeat([]byte("a"), commitHashLength) - args := createMockGovernanceArgs() - args.Eei = &mock.SystemEIStub{ - BlockChainHookCalled: func() vm.BlockchainHook { - return &mock.BlockChainHookStub{ - CurrentNonceCalled: func() uint64 { - return 1 - }, - } - }, - SetStorageCalled: func(key []byte, value []byte) { - if bytes.Equal(key, append([]byte(whiteListPrefix), callerAddress...)) { - _ = args.Marshalizer.Unmarshal(finalWhitelistProposal, value) - } - if bytes.Equal(key, append([]byte(proposalPrefix), callerAddress...)) { - _ = args.Marshalizer.Unmarshal(finalProposal, value) - } - }, + callerAddress := bytes.Repeat([]byte{2}, 32) + proposalIdentifier := []byte("aaaaaaaaa") + generalProposal := &GeneralProposal{ + CommitHash: proposalIdentifier, + StartVoteEpoch: 10, + EndVoteEpoch: 15, + Yes: big.NewInt(0), + No: big.NewInt(0), + Veto: big.NewInt(0), + Abstain: big.NewInt(0), } - gsc, _ := NewGovernanceContract(args) - - callInputArgs := [][]byte{ - []byte("1"), + voteArgs := [][]byte{ []byte("1"), - []byte("10"), - []byte("10"), - []byte("15"), + []byte("yes"), } - initInput := createVMInput(zero, "initV2", vm.GovernanceSCAddress, vm.GovernanceSCAddress, nil) - _ = gsc.Execute(initInput) - callInput := createVMInput(zero, "changeConfig", args.OwnerAddress, vm.GovernanceSCAddress, callInputArgs) + gsc.eei.SetStorage(voteArgs[0], proposalIdentifier) + _ = gsc.saveGeneralProposal(proposalIdentifier, generalProposal) + + callInput := createVMInput(big.NewInt(0), "delegateVote", callerAddress, vm.GovernanceSCAddress, voteArgs) retCode := gsc.Execute(callInput) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, eei.GetReturnMessage(), "invalid number of arguments") - require.Equal(t, vmcommon.Ok, retCode) + callInput.Arguments = append(callInput.Arguments, []byte{1}, []byte{2}) + callInput.CallValue = big.NewInt(10) + retCode = gsc.Execute(callInput) + require.Equal(t, vmcommon.UserError, retCode) + require.True(t, strings.Contains(eei.GetReturnMessage(), "function is not payable")) + + callInput.CallValue = big.NewInt(0) + callInput.GasProvided = 0 + gsc.gasCost.MetaChainSystemSCsCost.DelegateVote = 10 + retCode = gsc.Execute(callInput) + require.Equal(t, vmcommon.OutOfGas, retCode) + require.True(t, strings.Contains(eei.GetReturnMessage(), "not enough gas")) } func TestGovernanceContract_ChangeConfigWrongCaller(t *testing.T) { @@ -1563,52 +922,6 @@ func TestGovernanceContract_VoteTwice(t *testing.T) { require.Equal(t, eei.GetReturnMessage(), "double vote is not allowed") } -func TestGovernanceContract_DelegateVoteUserErrors(t *testing.T) { - t.Parallel() - - gsc, blockchainHook, eei := createGovernanceBlockChainHookStubContextHandler() - blockchainHook.CurrentNonceCalled = func() uint64 { - return 12 - } - - callerAddress := bytes.Repeat([]byte{2}, 32) - proposalIdentifier := []byte("aaaaaaaaa") - generalProposal := &GeneralProposal{ - CommitHash: proposalIdentifier, - StartVoteEpoch: 10, - EndVoteEpoch: 15, - Yes: big.NewInt(0), - No: big.NewInt(0), - Veto: big.NewInt(0), - Abstain: big.NewInt(0), - } - - voteArgs := [][]byte{ - []byte("1"), - []byte("yes"), - } - gsc.eei.SetStorage(voteArgs[0], proposalIdentifier) - _ = gsc.saveGeneralProposal(proposalIdentifier, generalProposal) - - callInput := createVMInput(big.NewInt(0), "delegateVote", callerAddress, vm.GovernanceSCAddress, voteArgs) - retCode := gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.Equal(t, eei.GetReturnMessage(), "invalid number of arguments") - - callInput.Arguments = append(callInput.Arguments, []byte{1}, []byte{2}) - callInput.CallValue = big.NewInt(10) - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.UserError, retCode) - require.True(t, strings.Contains(eei.GetReturnMessage(), "function is not payable")) - - callInput.CallValue = big.NewInt(0) - callInput.GasProvided = 0 - gsc.gasCost.MetaChainSystemSCsCost.DelegateVote = 10 - retCode = gsc.Execute(callInput) - require.Equal(t, vmcommon.OutOfGas, retCode) - require.True(t, strings.Contains(eei.GetReturnMessage(), "not enough gas")) -} - func TestGovernanceContract_DelegateVoteMoreErrors(t *testing.T) { t.Parallel() diff --git a/vm/systemSmartContracts/stakingWaitingList.go b/vm/systemSmartContracts/stakingWaitingList.go index e7ba07eab83..16d979a6a86 100644 --- a/vm/systemSmartContracts/stakingWaitingList.go +++ b/vm/systemSmartContracts/stakingWaitingList.go @@ -726,7 +726,7 @@ func (s *stakingSC) cleanAdditionalQueueNotEnoughFunds( } func (s *stakingSC) stakeNodesFromQueue(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { - if !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { + if !s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) { s.eei.AddReturnMessage("invalid method to call") return vmcommon.UserError } diff --git a/vm/systemSmartContracts/staking_test.go b/vm/systemSmartContracts/staking_test.go index 21cf87bcb25..c5419dddd20 100644 --- a/vm/systemSmartContracts/staking_test.go +++ b/vm/systemSmartContracts/staking_test.go @@ -63,8 +63,6 @@ func createMockStakingScArgumentsWithSystemScAddresses( common.CorrectFirstQueuedFlag, common.CorrectJailedNotUnStakedEmptyQueueFlag, common.ValidatorToDelegationFlag, - IsStakingV4Step1FlagEnabledField: false, - IsStakingV4Step2FlagEnabledField: false, ), } } @@ -107,7 +105,8 @@ func createArgsVMContext() VMContextArgs { InputParser: &mock.ArgumentParserMock{}, ValidatorAccountsDB: &stateMock.AccountsStub{}, ChanceComputer: &mock.RaterMock{}, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + UserAccountsDB: &stateMock.AccountsStub{}, } } @@ -1017,7 +1016,8 @@ func TestStakingSc_ExecuteIsStaked(t *testing.T) { func TestStakingSc_StakeWithStakingV4(t *testing.T) { t.Parallel() - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsStakingV2FlagEnabledField: true} + enableEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{} + enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) args := createMockStakingScArguments() stakingAccessAddress := []byte("stakingAccessAddress") @@ -1050,7 +1050,7 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("addr0"), []byte("addr0"), vmcommon.Ok) requireRegisteredNodes(t, stakingSmartContract, eei, 4, 5) - enableEpochsHandler.IsStakingV4StartedField = true + enableEpochsHandler.AddActiveFlags(common.StakingV4StartedFlag) for i := 5; i < 10; i++ { idxStr := strconv.Itoa(i) addr := []byte("addr" + idxStr) @@ -1073,7 +1073,8 @@ func TestStakingSc_StakeWithStakingV4(t *testing.T) { func TestStakingSc_UnStakeNodeFromWaitingListAfterStakingV4ShouldError(t *testing.T) { t.Parallel() - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{IsStakingV2FlagEnabledField: true} + enableEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{} + enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) args := createMockStakingScArguments() stakingAccessAddress := []byte("stakingAccessAddress") @@ -1093,7 +1094,7 @@ func TestStakingSc_UnStakeNodeFromWaitingListAfterStakingV4ShouldError(t *testin doStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2")) requireRegisteredNodes(t, stakingSmartContract, eei, 2, 1) - enableEpochsHandler.IsStakingV4StartedField = true + enableEpochsHandler.AddActiveFlags(common.StakingV4StartedFlag) eei.returnMessage = "" doUnStake(t, stakingSmartContract, stakingAccessAddress, []byte("address2"), []byte("address2"), vmcommon.ExecutionFailed) require.Equal(t, eei.returnMessage, vm.ErrWaitingListDisabled.Error()) @@ -3420,17 +3421,16 @@ func TestStakingSc_fixMissingNodeAddOneNodeOnly(t *testing.T) { func TestStakingSC_StakingV4Flags(t *testing.T) { t.Parallel() - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ - IsStakeFlagEnabledField: true, - IsCorrectLastUnJailedFlagEnabledField: true, - IsCorrectFirstQueuedFlagEnabledField: true, - IsCorrectJailedNotUnStakedEmptyQueueFlagEnabledField: true, - IsSwitchJailWaitingFlagEnabledField: true, - IsValidatorToDelegationFlagEnabledField: true, - IsStakingV4Step1FlagEnabledField: true, - IsStakingV4StartedField: true, - IsStakingV2FlagEnabledField: true, - } + enableEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{} + enableEpochsHandler.AddActiveFlags(common.StakeFlag) + enableEpochsHandler.AddActiveFlags(common.CorrectLastUnJailedFlag) + enableEpochsHandler.AddActiveFlags(common.CorrectFirstQueuedFlag) + enableEpochsHandler.AddActiveFlags(common.CorrectJailedNotUnStakedEmptyQueueFlag) + enableEpochsHandler.AddActiveFlags(common.ValidatorToDelegationFlag) + enableEpochsHandler.AddActiveFlags(common.StakingV4Step1Flag) + enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) + enableEpochsHandler.AddActiveFlags(common.StakingV4StartedFlag) + argsVMContext := createArgsVMContext() argsVMContext.EnableEpochsHandler = enableEpochsHandler eei, _ := NewVMContext(argsVMContext) @@ -3490,7 +3490,7 @@ func TestStakingSC_StakingV4Flags(t *testing.T) { require.Equal(t, vmcommon.UserError, retCode) require.True(t, strings.Contains(eei.returnMessage, "can be called by endOfEpochAccess address only")) - enableEpochsHandler.IsStakingV4Step1FlagEnabledField = false + enableEpochsHandler.RemoveActiveFlags(common.StakingV4Step1Flag) // All functions from above are not allowed anymore starting STAKING V4 epoch eei.CleanCache() arguments.Function = "getQueueIndex" diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index b47405f1b29..509ec89b624 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -923,7 +923,7 @@ func (v *validatorSC) checkAllGivenKeysAreUnStaked(registrationData *ValidatorDa } func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { - if !v.enableEpochsHandler.IsStakeLimitsFlagEnabled() { + if !v.enableEpochsHandler.IsFlagEnabled(common.StakeLimitsFlag) { return false } @@ -931,7 +931,7 @@ func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { } func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) bool { - if !v.enableEpochsHandler.IsStakeLimitsFlagEnabled() { + if !v.enableEpochsHandler.IsFlagEnabled(common.StakeLimitsFlag) { return false } diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 0dc3280fc3c..12d66464625 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -66,7 +66,7 @@ func createMockArgumentsForValidatorSCWithSystemScAddresses( common.ValidatorToDelegationFlag, common.DoubleKeyProtectionFlag, common.MultiClaimOnDelegationFlag, - IsStakeLimitsFlagEnabledField: true, + common.StakeLimitsFlag, ), NodesCoordinator: &mock.NodesCoordinatorStub{}, } @@ -5228,9 +5228,8 @@ func TestStakingValidatorSC_MergeValidatorData(t *testing.T) { func TestStakingValidatorSC_MergeValidatorDataTooMuchStake(t *testing.T) { t.Parallel() - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ - IsStakingV2FlagEnabledField: false, - } + enableEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{} + enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) argsVMContext := createArgsVMContext() argsVMContext.InputParser = parsers.NewCallArgsParser() argsVMContext.EnableEpochsHandler = enableEpochsHandler @@ -5276,9 +5275,8 @@ func TestStakingValidatorSC_MergeValidatorDataTooMuchStake(t *testing.T) { func TestStakingValidatorSC_MergeValidatorDataTooMuchNodes(t *testing.T) { t.Parallel() - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ - IsStakingV2FlagEnabledField: false, - } + enableEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{} + enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) argsVMContext := createArgsVMContext() argsVMContext.InputParser = parsers.NewCallArgsParser() argsVMContext.EnableEpochsHandler = enableEpochsHandler From d0ecb33f42e07045ade46e64bb9005286165b1b0 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 5 Jan 2024 16:37:48 +0200 Subject: [PATCH 561/958] FIX: After merge in stakingV4 8 + fix systemSCs+stakingDataProvider+legacySystemSC --- .../metachain/auctionListSelector_test.go | 2 +- epochStart/metachain/legacySystemSCs.go | 16 ++--- .../metachain/rewardsCreatorProxy_test.go | 1 + epochStart/metachain/stakingDataProvider.go | 6 +- .../metachain/stakingDataProvider_test.go | 17 ++--- epochStart/metachain/systemSCs_test.go | 62 ++++++++++--------- epochStart/metachain/validators.go | 14 ++--- epochStart/metachain/validators_test.go | 35 +++++++---- process/peer/process.go | 17 ++--- state/interface.go | 1 + testscommon/stakingcommon/stakingCommon.go | 14 +++-- .../stakingcommon/validatorsProviderStub.go | 2 +- 12 files changed, 102 insertions(+), 85 deletions(-) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 5bbe9777654..7a96e00bd94 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -47,7 +47,7 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha epochNotifier := forking.NewGenericEpochNotifier() nodesConfigProvider, _ := notifier.NewNodesConfigProvider(epochNotifier, maxNodesChangeConfig) - argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + argsSystemSC, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) argsSystemSC.EpochNotifier.CheckEpoch(&testscommon.HeaderHandlerStub{ EpochField: stakingV4Step2EnableEpoch, }) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 44ccb1fec21..8bf2185e4de 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -171,14 +171,14 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) && !s.enableEpochsHandler.IsFlagDefined(common.StakingV4Step2Flag) { + if s.enableEpochsHandler.IsFlagEnabled(common.CorrectLastUnJailedFlag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { err := s.cleanAdditionalQueue() if err != nil { return err } } - if s.enableEpochsHandler.IsFlagEnabled(common.SwitchJailWaitingFlag) && !s.enableEpochsHandler.IsFlagDefined(common.StakingV4Step2Flag) { + if s.enableEpochsHandler.IsFlagEnabled(common.SwitchJailWaitingFlag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { err := s.computeNumWaitingPerShard(validatorsInfoMap) if err != nil { return err @@ -190,7 +190,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) && !s.enableEpochsHandler.IsFlagDefined(common.StakingV4Step2Flag) { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) && !s.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { err := s.prepareStakingDataForEligibleNodes(validatorsInfoMap) if err != nil { return err @@ -707,7 +707,7 @@ func (s *legacySystemSCProcessor) 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 } @@ -719,13 +719,7 @@ func (s *legacySystemSCProcessor) stakingToValidatorStatistics( } } - if !bytes.Equal(account.GetBLSPublicKey(), blsPubKey) { - err = account.SetBLSPublicKey(blsPubKey) - if err != nil { - return nil, err - } - } else { - // old jailed validator getting switched back after unJail with stake - must remove first from exported map + if !isNew { err = validatorsInfoMap.Delete(jailedValidator) if err != nil { return nil, err diff --git a/epochStart/metachain/rewardsCreatorProxy_test.go b/epochStart/metachain/rewardsCreatorProxy_test.go index 48b22544f75..e41730d34f1 100644 --- a/epochStart/metachain/rewardsCreatorProxy_test.go +++ b/epochStart/metachain/rewardsCreatorProxy_test.go @@ -15,6 +15,7 @@ import ( "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/epochStart/mock" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" diff --git a/epochStart/metachain/stakingDataProvider.go b/epochStart/metachain/stakingDataProvider.go index 883f86ca011..722a838193f 100644 --- a/epochStart/metachain/stakingDataProvider.go +++ b/epochStart/metachain/stakingDataProvider.go @@ -351,7 +351,7 @@ func (sdp *stakingDataProvider) checkAndFillOwnerValidatorAuctionData( hex.EncodeToString(validator.GetPublicKey()), ) } - if !sdp.enableEpochsHandler.IsStakingV4Started() { + if !sdp.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { return fmt.Errorf("stakingDataProvider.checkAndFillOwnerValidatorAuctionData for validator in auction error: %w, owner: %s, node: %s", epochStart.ErrReceivedAuctionValidatorsBeforeStakingV4, hex.EncodeToString(ownerPubKey), @@ -447,7 +447,7 @@ func (sdp *stakingDataProvider) createMapBLSKeyStatus(validatorsInfo state.Shard list := validator.GetList() pubKey := validator.GetPublicKey() - if sdp.enableEpochsHandler.IsStakingV4Step2Enabled() && list == string(common.NewList) { + if sdp.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) && list == string(common.NewList) { return nil, fmt.Errorf("%w, bls key = %s", epochStart.ErrReceivedNewListNodeInStakingV4, hex.EncodeToString(pubKey), @@ -517,7 +517,7 @@ func (sdp *stakingDataProvider) arrangeBlsKeysByStatus(mapBlsKeyStatus map[strin func (sdp *stakingDataProvider) getNewNodesList() string { newNodesList := string(common.NewList) - if sdp.enableEpochsHandler.IsStakingV4Step2Enabled() { + if sdp.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { newNodesList = string(common.AuctionList) } diff --git a/epochStart/metachain/stakingDataProvider_test.go b/epochStart/metachain/stakingDataProvider_test.go index c986eacc786..e3bfc1e6259 100644 --- a/epochStart/metachain/stakingDataProvider_test.go +++ b/epochStart/metachain/stakingDataProvider_test.go @@ -17,6 +17,7 @@ import ( "github.com/multiversx/mx-chain-go/epochStart/mock" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" @@ -28,7 +29,7 @@ const stakingV4Step2EnableEpoch = 445 func createStakingDataProviderArgs() StakingDataProviderArgs { return StakingDataProviderArgs{ - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, SystemVM: &mock.VMExecutionHandlerStub{}, MinNodePrice: "2500", } @@ -271,7 +272,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithStakingV4ReceivedNewList _ = valInfo.Add(v2) sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4Step2Flag) keysToUnStake, ownersWithNotEnoughFunds, err := sdp.ComputeUnQualifiedNodes(valInfo) require.Error(t, err) @@ -334,7 +335,7 @@ func TestStakingDataProvider_ComputeUnQualifiedNodesWithOwnerNotEnoughFundsWithS _ = valInfo.Add(v1) sdp := createStakingDataProviderAndUpdateCache(t, valInfo, big.NewInt(0)) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4Step2Flag) sdp.cache[owner].blsKeys = append(sdp.cache[owner].blsKeys, []byte("newKey")) sdp.cache[owner].totalStaked = big.NewInt(2500) @@ -528,7 +529,7 @@ func TestCheckAndFillOwnerValidatorAuctionData(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4StartedField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4StartedFlag) owner := []byte("owner") ownerData := &ownerStats{numStakedNodes: 3, numActiveNodes: 3} @@ -551,7 +552,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4Step2Flag) sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -565,7 +566,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4Step2Flag) sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -581,7 +582,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4Step2Flag) sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, @@ -597,7 +598,7 @@ func TestSelectKeysToUnStake(t *testing.T) { t.Parallel() args := createStakingDataProviderArgs() sdp, _ := NewStakingDataProvider(args) - sdp.enableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV4Step2FlagEnabledField: true} + sdp.enableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV4Step2Flag) sortedKeys := map[string][][]byte{ string(common.AuctionList): {[]byte("pk0")}, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 26bc487d66b..954f149ce07 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -210,11 +210,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContract(t *testing.T) { } _ = validatorsInfo.Add(vInfo) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + require.Nil(t, err) - assert.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 1) + require.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 1) newValidatorInfo := validatorsInfo.GetShardValidatorsInfoMap()[0][0] - assert.Equal(t, newValidatorInfo.GetList(), string(common.NewList)) + require.Equal(t, newValidatorInfo.GetList(), string(common.NewList)) } func TestSystemSCProcessor_JailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T) { @@ -258,12 +258,12 @@ func testSystemSCProcessorJailedNodesShouldNotBeSwappedAllAtOnce(t *testing.T, s _ = validatorsInfo.SetValidatorsInShard(0, jailed) err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + require.Nil(t, err) for i := 0; i < numWaiting; i++ { - assert.Equal(t, string(common.NewList), validatorsInfo.GetShardValidatorsInfoMap()[0][i].GetList()) + require.Equal(t, string(common.NewList), validatorsInfo.GetShardValidatorsInfoMap()[0][i].GetList()) } for i := numWaiting; i < numJailed; i++ { - assert.Equal(t, string(common.JailedList), validatorsInfo.GetShardValidatorsInfoMap()[0][i].GetList()) + require.Equal(t, string(common.JailedList), validatorsInfo.GetShardValidatorsInfoMap()[0][i].GetList()) } newJailedNodes := jailed[numWaiting:numJailed] @@ -805,10 +805,10 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp ShardCoordinator: &mock.ShardCoordinatorStub{}, Marshalizer: marshalizer, Uint64Converter: &mock.Uint64ByteSliceConverterMock{}, - NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, - BuiltInFunctions: vmcommonBuiltInFunctions.NewBuiltInFunctionContainer(), - DataPool: testDataPool, - GlobalSettingsHandler: &testscommon.ESDTGlobalSettingsHandlerStub{}, + NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, + BuiltInFunctions: vmcommonBuiltInFunctions.NewBuiltInFunctionContainer(), + DataPool: testDataPool, + GlobalSettingsHandler: &testscommon.ESDTGlobalSettingsHandlerStub{}, CompiledSCPool: testDataPool.SmartContracts(), EpochNotifier: en, EnableEpochsHandler: enableEpochsHandler, @@ -880,6 +880,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp ShardCoordinator: &mock.ShardCoordinatorStub{}, EnableEpochsHandler: enableEpochsHandler, NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + ArgBlockChainHook: argsHook, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) @@ -1783,36 +1784,33 @@ func TestSystemSCProcessor_ProcessSystemSmartContractSwapJailedWithWaiting(t *te jailedAcc, _ := args.PeerAccountsDB.LoadAccount([]byte("jailedPubKey0")) _ = args.PeerAccountsDB.SaveAccount(jailedAcc) - validatorInfos := make(map[uint32][]*state.ValidatorInfo) - vInfo := &state.ValidatorInfo{ + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(&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{ + }) + _ = validatorsInfo.Add(&state.ValidatorInfo{ PublicKey: []byte("waitingPubKey"), ShardId: 0, List: string(common.WaitingList), - } - validatorInfos[0] = append(validatorInfos[0], vInfo1) + }) - err := s.ProcessSystemSmartContract(validatorInfos, 0, 0) + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - assert.Equal(t, 2, len(validatorInfos[0])) - newValidatorInfo := validatorInfos[0][0] - assert.Equal(t, newValidatorInfo.List, string(common.NewList)) + require.Len(t, validatorsInfo.GetShardValidatorsInfoMap()[0], 2) + newValidatorInfo := validatorsInfo.GetShardValidatorsInfoMap()[0][0] + require.Equal(t, newValidatorInfo.GetList(), string(common.NewList)) } func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) s, _ := NewSystemSCProcessor(args) owner1 := []byte("owner1") @@ -1877,7 +1875,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Init(t *testing.T) func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepareStakingData(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) errProcessStakingData := errors.New("error processing staking data") args.StakingDataProvider = &stakingcommon.StakingDataProviderStub{ @@ -1904,7 +1902,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4EnabledCannotPrepa func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 8}}) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: args.ShardCoordinator, @@ -2067,7 +2065,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestart(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) nodesConfigEpoch0 := config.MaxNodesChangeConfig{ EpochEnable: 0, MaxNumNodes: 36, @@ -2091,7 +2089,15 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar nodesConfigEpoch6, }) args.MaxNodesChangeConfigProvider = nodesConfigProvider - args.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{IsStakingV2FlagEnabledField: true} + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + if flag == common.StakingV2Flag { + return true + } + + return false + }, + } validatorsInfoMap := state.NewShardValidatorsInfoMap() s, _ := NewSystemSCProcessor(args) @@ -2157,7 +2163,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar func TestSystemSCProcessor_ProcessSystemSmartContractNilInputValues(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, createMemUnit()) + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) s, _ := NewSystemSCProcessor(args) t.Run("nil validators info map, expect error", func(t *testing.T) { diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index 5d463c5fc0c..6518ae8384e 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -142,9 +142,9 @@ func (vic *validatorInfoCreator) createMiniBlock(validatorsInfo []state.Validato validatorCopy := make([]state.ValidatorInfoHandler, len(validatorsInfo)) copy(validatorCopy, validatorsInfo) - vic.sortValidators(validatorsCopy) + vic.sortValidators(validatorCopy) - for index, validator := range validatorsCopy { + for index, validator := range validatorCopy { shardValidatorInfo := createShardValidatorInfo(validator) shardValidatorInfoData, err := vic.getShardValidatorInfoData(shardValidatorInfo) @@ -158,7 +158,7 @@ func (vic *validatorInfoCreator) createMiniBlock(validatorsInfo []state.Validato return miniBlock, nil } -func (vic *validatorInfoCreator) sortValidators(validators []*state.ValidatorInfo) { +func (vic *validatorInfoCreator) sortValidators(validators []state.ValidatorInfoHandler) { if vic.enableEpochsHandler.IsFlagEnabled(common.DeterministicSortOnValidatorsInfoFixFlag) { vic.deterministicSortValidators(validators) return @@ -167,9 +167,9 @@ func (vic *validatorInfoCreator) sortValidators(validators []*state.ValidatorInf vic.legacySortValidators(validators) } -func (vic *validatorInfoCreator) deterministicSortValidators(validators []*state.ValidatorInfo) { +func (vic *validatorInfoCreator) deterministicSortValidators(validators []state.ValidatorInfoHandler) { sort.SliceStable(validators, func(a, b int) bool { - result := bytes.Compare(validators[a].PublicKey, validators[b].PublicKey) + result := bytes.Compare(validators[a].GetPublicKey(), validators[b].GetPublicKey()) if result != 0 { return result < 0 } @@ -186,12 +186,12 @@ func (vic *validatorInfoCreator) deterministicSortValidators(validators []*state }) } -func (vic *validatorInfoCreator) legacySortValidators(validators []*state.ValidatorInfo) { +func (vic *validatorInfoCreator) legacySortValidators(validators []state.ValidatorInfoHandler) { swap := func(a, b int) { validators[a], validators[b] = validators[b], validators[a] } less := func(a, b int) bool { - return bytes.Compare(validators[a].PublicKey, validators[b].PublicKey) < 0 + return bytes.Compare(validators[a].GetPublicKey(), validators[b].GetPublicKey()) < 0 } compatibility.SortSlice(swap, less, len(validators)) } diff --git a/epochStart/metachain/validators_test.go b/epochStart/metachain/validators_test.go index 6de4df1672b..72a71f2b9c5 100644 --- a/epochStart/metachain/validators_test.go +++ b/epochStart/metachain/validators_test.go @@ -1129,7 +1129,7 @@ func testCreateMiniblockBackwardsCompatibility(t *testing.T, deterministFixEnabl require.Equal(t, len(input), len(expected)) - validators := make([]*state.ValidatorInfo, 0, len(input)) + validators := state.NewShardValidatorsInfoMap() marshaller := &marshal.GogoProtoMarshalizer{} for _, marshalledData := range input { vinfo := &state.ValidatorInfo{} @@ -1139,7 +1139,8 @@ func testCreateMiniblockBackwardsCompatibility(t *testing.T, deterministFixEnabl err = marshaller.Unmarshal(vinfo, buffMarshalledData) require.Nil(t, err) - validators = append(validators, vinfo) + err = validators.Add(vinfo) + require.Nil(t, err) } arguments := createMockEpochValidatorInfoCreatorsArguments() @@ -1157,7 +1158,7 @@ func testCreateMiniblockBackwardsCompatibility(t *testing.T, deterministFixEnabl arguments.ValidatorInfoStorage = storer vic, _ := NewValidatorInfoCreator(arguments) - mb, err := vic.createMiniBlock(validators) + mb, err := vic.createMiniBlock(validators.GetAllValidatorsInfo()) require.Nil(t, err) // test all generated miniblock's "txhashes" are the same with the expected ones @@ -1274,12 +1275,16 @@ func TestValidatorInfoCreator_sortValidators(t *testing.T) { } vic, _ := NewValidatorInfoCreator(arguments) - list := []*state.ValidatorInfo{thirdValidator, secondValidator, firstValidator} - vic.sortValidators(list) + list := state.NewShardValidatorsInfoMap() + _ = list.Add(thirdValidator) + _ = list.Add(secondValidator) + _ = list.Add(firstValidator) + + vic.sortValidators(list.GetAllValidatorsInfo()) - assert.Equal(t, list[0], secondValidator) // order not changed for the ones with same public key - assert.Equal(t, list[1], firstValidator) - assert.Equal(t, list[2], thirdValidator) + assert.Equal(t, list.GetAllValidatorsInfo()[0], secondValidator) // order not changed for the ones with same public key + assert.Equal(t, list.GetAllValidatorsInfo()[1], firstValidator) + assert.Equal(t, list.GetAllValidatorsInfo()[2], thirdValidator) }) t.Run("deterministic sort should change order taking into consideration all fields", func(t *testing.T) { t.Parallel() @@ -1292,12 +1297,16 @@ func TestValidatorInfoCreator_sortValidators(t *testing.T) { } vic, _ := NewValidatorInfoCreator(arguments) - list := []*state.ValidatorInfo{thirdValidator, secondValidator, firstValidator} - vic.sortValidators(list) + list := state.NewShardValidatorsInfoMap() + _ = list.Add(thirdValidator) + _ = list.Add(secondValidator) + _ = list.Add(firstValidator) + + vic.sortValidators(list.GetAllValidatorsInfo()) - assert.Equal(t, list[0], firstValidator) // proper sorting - assert.Equal(t, list[1], secondValidator) - assert.Equal(t, list[2], thirdValidator) + assert.Equal(t, list.GetAllValidatorsInfo()[0], firstValidator) // proper sorting + assert.Equal(t, list.GetAllValidatorsInfo()[1], secondValidator) + assert.Equal(t, list.GetAllValidatorsInfo()[2], thirdValidator) }) } diff --git a/process/peer/process.go b/process/peer/process.go index deabc6f783b..2c2be271183 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -196,7 +196,7 @@ func (vs *validatorStatistics) saveNodesCoordinatorUpdates(epoch uint32) (bool, } nodeForcedToRemain = nodeForcedToRemain || tmpNodeForcedToRemain - if vs.enableEpochsHandler.IsStakingV4Step2Enabled() { + if vs.enableEpochsHandler.IsFlagEnabled(common.StakingV4Step2Flag) { nodesMap, err = vs.nodesCoordinator.GetAllShuffledOutValidatorsPublicKeys(epoch) if err != nil { return false, err @@ -250,12 +250,13 @@ func (vs *validatorStatistics) saveUpdatesForList( isNodeLeaving := (peerType == common.WaitingList || peerType == common.EligibleList) && peerAcc.GetList() == string(common.LeavingList) isNodeWithLowRating := vs.isValidatorWithLowRating(peerAcc) isNodeJailed := vs.enableEpochsHandler.IsFlagEnabled(common.SwitchJailWaitingFlag) && peerType == common.InactiveList && isNodeWithLowRating + isStakingV4Started := vs.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) if isNodeJailed { - peerAcc.SetListAndIndex(shardID, string(common.JailedList), uint32(index), vs.enableEpochsHandler.IsStakingV4Started()) + peerAcc.SetListAndIndex(shardID, string(common.JailedList), uint32(index), isStakingV4Started) } else if isNodeLeaving { - peerAcc.SetListAndIndex(shardID, string(common.LeavingList), uint32(index), vs.enableEpochsHandler.IsStakingV4Started()) + peerAcc.SetListAndIndex(shardID, string(common.LeavingList), uint32(index), isStakingV4Started) } else { - peerAcc.SetListAndIndex(shardID, string(peerType), uint32(index), vs.enableEpochsHandler.IsStakingV4Started()) + peerAcc.SetListAndIndex(shardID, string(peerType), uint32(index), isStakingV4Started) } err = vs.peerAdapter.SaveAccount(peerAcc) @@ -565,7 +566,7 @@ func (vs *validatorStatistics) jailValidatorIfBadRatingAndInactive(validatorAcco return } - validatorAccount.SetListAndIndex(validatorAccount.GetShardId(), string(common.JailedList), validatorAccount.GetIndexInList(), vs.enableEpochsHandler.IsStakingV4Started()) + validatorAccount.SetListAndIndex(validatorAccount.GetShardId(), string(common.JailedList), validatorAccount.GetIndexInList(), vs.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) } func (vs *validatorStatistics) unmarshalPeer(peerAccountData core.KeyValueHolder) (state.PeerAccountHandler, error) { @@ -736,12 +737,12 @@ func (vs *validatorStatistics) setToJailedIfNeeded( } if validator.GetList() == string(common.JailedList) && peerAccount.GetList() != string(common.JailedList) { - peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex(), vs.enableEpochsHandler.IsStakingV4Started()) + peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex(), vs.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) return } if vs.isValidatorWithLowRating(peerAccount) { - peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex(), vs.enableEpochsHandler.IsStakingV4Started()) + peerAccount.SetListAndIndex(validator.GetShardId(), string(common.JailedList), validator.GetIndex(), vs.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) } } @@ -1002,7 +1003,7 @@ func (vs *validatorStatistics) savePeerAccountData( peerAccount.SetRating(startRating) peerAccount.SetTempRating(startRating) - peerAccount.SetListAndIndex(shardID, string(peerType), index, vs.enableEpochsHandler.IsStakingV4Started()) + peerAccount.SetListAndIndex(shardID, string(peerType), index, vs.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag)) return vs.peerAdapter.SaveAccount(peerAccount) } diff --git a/state/interface.go b/state/interface.go index a8b2221e2d3..2776889473c 100644 --- a/state/interface.go +++ b/state/interface.go @@ -348,4 +348,5 @@ type ValidatorInfoHandler interface { ShallowClone() ValidatorInfoHandler String() string + GoString() string } diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index edcc713d33b..31585006e69 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -6,11 +6,12 @@ import ( "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/genesis/process/disabled" "github.com/multiversx/mx-chain-go/process" economicsHandler "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/state" - "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" @@ -265,16 +266,19 @@ func CreateEconomicsData() process.EconomicsDataHandler { MaxGasLimitPerMetaMiniBlock: maxGasLimitPerBlock, MaxGasLimitPerTx: maxGasLimitPerBlock, MinGasLimit: minGasLimit, + ExtraGasLimitGuardedTx: maxGasLimitPerBlock, }, }, - MinGasPrice: minGasPrice, - GasPerDataByte: "1", - GasPriceModifier: 1.0, + MinGasPrice: minGasPrice, + GasPerDataByte: "1", + GasPriceModifier: 1.0, + MaxGasPriceSetGuardian: minGasPrice, }, }, EpochNotifier: &epochNotifier.EpochNotifierStub{}, BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{}, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + TxVersionChecker: &disabled.TxVersionChecker{}, } economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData diff --git a/testscommon/stakingcommon/validatorsProviderStub.go b/testscommon/stakingcommon/validatorsProviderStub.go index db50da743c3..587fa0225ff 100644 --- a/testscommon/stakingcommon/validatorsProviderStub.go +++ b/testscommon/stakingcommon/validatorsProviderStub.go @@ -1,8 +1,8 @@ package stakingcommon import ( + "github.com/multiversx/mx-chain-core-go/data/validator" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/state" ) // ValidatorsProviderStub - From 9be1252b10bde4d944b6a92be63d7b75873d0b73 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 16:42:00 +0200 Subject: [PATCH 562/958] - fixed username pricing --- cmd/node/config/genesisSmartContracts.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/genesisSmartContracts.json b/cmd/node/config/genesisSmartContracts.json index f102c18d489..198798c36fe 100644 --- a/cmd/node/config/genesisSmartContracts.json +++ b/cmd/node/config/genesisSmartContracts.json @@ -11,7 +11,7 @@ "owner": "erd188anxz35atlef7cucszypmvx88lhz4m7a7t7lhcwt6sfphpsqlkswfhcx2", "filename": "./config/genesisContracts/dns.wasm", "vm-type": "0500", - "init-parameters": "056bc75e2d63100000", + "init-parameters": "00", "type": "dns", "version": "0.2.*" } From 6f6778d504be1a86796406094cd994fc3eefd314 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 5 Jan 2024 18:58:45 +0200 Subject: [PATCH 563/958] - cancel start subround in single key redundancy mode --- consensus/spos/bls/subroundStartRound.go | 4 ++++ consensus/spos/bls/subroundStartRound_test.go | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/consensus/spos/bls/subroundStartRound.go b/consensus/spos/bls/subroundStartRound.go index 8e330f791bb..1bcdb1d3e20 100644 --- a/consensus/spos/bls/subroundStartRound.go +++ b/consensus/spos/bls/subroundStartRound.go @@ -155,6 +155,10 @@ func (sr *subroundStartRound) initCurrentRound() bool { sr.ConsensusGroup(), sr.RoundHandler().Index(), ) + // TODO refactor the usage of the single key & multikey redundancy system + if sr.NodeRedundancyHandler().IsMainMachineActive() { + return false + } } leader, err := sr.GetLeader() diff --git a/consensus/spos/bls/subroundStartRound_test.go b/consensus/spos/bls/subroundStartRound_test.go index 583861032d1..960bae5bf3f 100644 --- a/consensus/spos/bls/subroundStartRound_test.go +++ b/consensus/spos/bls/subroundStartRound_test.go @@ -428,7 +428,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenGenerateNextCon assert.False(t, r) } -func TestSubroundStartRound_InitCurrentRoundShouldReturnTrueWhenMainMachineIsActive(t *testing.T) { +func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenMainMachineIsActive(t *testing.T) { t.Parallel() nodeRedundancyMock := &mock.NodeRedundancyHandlerStub{ @@ -442,7 +442,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldReturnTrueWhenMainMachineIsAct srStartRound := *initSubroundStartRoundWithContainer(container) r := srStartRound.InitCurrentRound() - assert.True(t, r) + assert.False(t, r) } func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenGetLeaderErr(t *testing.T) { From b4e3198b48fcf86b60a876399e5fc20369108dee Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Sat, 6 Jan 2024 23:03:16 +0200 Subject: [PATCH 564/958] - proper fix for redundancy --- consensus/spos/bls/subroundBlock.go | 3 ++- consensus/spos/bls/subroundStartRound.go | 6 ++---- consensus/spos/bls/subroundStartRound_test.go | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/consensus/spos/bls/subroundBlock.go b/consensus/spos/bls/subroundBlock.go index d032a04eb63..a83969721b8 100644 --- a/consensus/spos/bls/subroundBlock.go +++ b/consensus/spos/bls/subroundBlock.go @@ -63,7 +63,8 @@ func checkNewSubroundBlockParams( // doBlockJob method does the job of the subround Block func (sr *subroundBlock) doBlockJob(ctx context.Context) bool { - if !sr.IsSelfLeaderInCurrentRound() && !sr.IsMultiKeyLeaderInCurrentRound() { // is NOT self leader in this round? + isSelfLeader := sr.IsSelfLeaderInCurrentRound() && sr.ShouldConsiderSelfKeyInConsensus() + if !isSelfLeader && !sr.IsMultiKeyLeaderInCurrentRound() { // is NOT self leader in this round? return false } diff --git a/consensus/spos/bls/subroundStartRound.go b/consensus/spos/bls/subroundStartRound.go index 1bcdb1d3e20..6a799928769 100644 --- a/consensus/spos/bls/subroundStartRound.go +++ b/consensus/spos/bls/subroundStartRound.go @@ -155,10 +155,8 @@ func (sr *subroundStartRound) initCurrentRound() bool { sr.ConsensusGroup(), sr.RoundHandler().Index(), ) - // TODO refactor the usage of the single key & multikey redundancy system - if sr.NodeRedundancyHandler().IsMainMachineActive() { - return false - } + // we should not return here, the multikey redundancy system relies on it + // the NodeRedundancyHandler "thinks" it is in redundancy mode even if we use the multikey redundancy system } leader, err := sr.GetLeader() diff --git a/consensus/spos/bls/subroundStartRound_test.go b/consensus/spos/bls/subroundStartRound_test.go index 960bae5bf3f..583861032d1 100644 --- a/consensus/spos/bls/subroundStartRound_test.go +++ b/consensus/spos/bls/subroundStartRound_test.go @@ -428,7 +428,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenGenerateNextCon assert.False(t, r) } -func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenMainMachineIsActive(t *testing.T) { +func TestSubroundStartRound_InitCurrentRoundShouldReturnTrueWhenMainMachineIsActive(t *testing.T) { t.Parallel() nodeRedundancyMock := &mock.NodeRedundancyHandlerStub{ @@ -442,7 +442,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenMainMachineIsAc srStartRound := *initSubroundStartRoundWithContainer(container) r := srStartRound.InitCurrentRound() - assert.False(t, r) + assert.True(t, r) } func TestSubroundStartRound_InitCurrentRoundShouldReturnFalseWhenGetLeaderErr(t *testing.T) { From de4f3e46d4a8b0fadd943c734a1fbf56046bdc20 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Mon, 8 Jan 2024 10:16:54 +0200 Subject: [PATCH 565/958] tests for block requests during processing --- process/block/export_test.go | 4 + process/block/metablock_request_test.go | 197 ++++++++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 process/block/metablock_request_test.go diff --git a/process/block/export_test.go b/process/block/export_test.go index cef3c4de297..f7696d12138 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -177,6 +177,10 @@ func (mp *metaProcessor) ReceivedShardHeader(header data.HeaderHandler, shardHea mp.receivedShardHeader(header, shardHeaderHash) } +func (mp *metaProcessor) GetDataPool() dataRetriever.PoolsHolder { + return mp.dataPool +} + func (mp *metaProcessor) AddHdrHashToRequestedList(hdr data.HeaderHandler, hdrHash []byte) { mp.hdrsForCurrBlock.mutHdrsForBlock.Lock() defer mp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go new file mode 100644 index 00000000000..363aef3adac --- /dev/null +++ b/process/block/metablock_request_test.go @@ -0,0 +1,197 @@ +package block_test + +import ( + "sync/atomic" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/data/block" + blockProcess "github.com/multiversx/mx-chain-go/process/block" + "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" + dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" + stateMock "github.com/multiversx/mx-chain-go/testscommon/state" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func createMetaProcessorArguments(t *testing.T, noOfShards uint32) *blockProcess.ArgMetaProcessor { + pool := dataRetrieverMock.NewPoolsHolderMock() + pool.Headers() + coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() + coreComponents.Hash = &hashingMocks.HasherMock{} + dataComponents.DataPool = pool + dataComponents.Storage = initStore() + bootstrapComponents.Coordinator = mock.NewMultiShardsCoordinatorMock(noOfShards) + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) + arguments.AccountsDB[state.UserAccountsState] = &stateMock.AccountsStub{ + RevertToSnapshotCalled: func(snapshot int) error { + assert.Fail(t, "revert should have not been called") + return nil + }, + JournalLenCalled: func() int { + return 0 + }, + } + + startHeaders := createGenesisBlocks(bootstrapComponents.ShardCoordinator()) + arguments.BlockTracker = mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders) + arguments.ArgBaseProcessor.RequestHandler = &testscommon.RequestHandlerStub{ + RequestShardHeaderByNonceCalled: func(shardID uint32, nonce uint64) { + require.Fail(t, "should not have been called") + }, + RequestMetaHeaderByNonceCalled: func(nonce uint64) { + require.Fail(t, "should not have been called") + }, + + RequestShardHeaderCalled: func(shardID uint32, hash []byte) { + require.Fail(t, "should not have been called") + }, + RequestMetaHeaderCalled: func(hash []byte) { + require.Fail(t, "should not have been called") + }, + } + + return &arguments +} + +func TestMetaProcessor_receivedShardHeader(t *testing.T) { + noOfShards := uint32(5) + header1Hash := []byte("testHash1") + header2Hash := []byte("testHash2") + + header1 := &block.HeaderV2{ + Header: &block.Header{ + ShardID: 0, + Round: 100, + Nonce: 100, + }, + } + + header2 := &block.HeaderV2{ + Header: &block.Header{ + ShardID: 0, + Round: 101, + Nonce: 101, + PrevHash: header1Hash, + }, + } + + t.Run("receiving the last used in block shard header", func(t *testing.T) { + numCalls := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + if nonce != 101 { + require.Fail(t, "nonce should have been 101") + } + numCalls.Add(1) + } + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + hdrsForBlock := mp.GetHdrForBlock() + hdrsForBlock.SetNumMissingHdrs(1) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(0, 99) + hdrsForBlock.SetHdrHashAndInfo(string(header1Hash), &blockProcess.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + + mp.ReceivedShardHeader(header1, header1Hash) + + time.Sleep(100 * time.Millisecond) + require.Nil(t, err) + require.NotNil(t, mp) + require.Equal(t, uint32(1), numCalls.Load()) + require.Equal(t, uint32(1), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + }) + + t.Run("shard header used in block received, not latest", func(t *testing.T) { + numCalls := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + + // for requesting attestation header + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + if nonce != 101 { + require.Fail(t, "nonce should have been 101") + } + numCalls.Add(1) + } + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + hdrsForBlock := mp.GetHdrForBlock() + hdrsForBlock.SetNumMissingHdrs(2) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(0, 99) + hdrsForBlock.SetHdrHashAndInfo(string(header1Hash), &blockProcess.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + + mp.ReceivedShardHeader(header1, header1Hash) + + time.Sleep(100 * time.Millisecond) + require.Nil(t, err) + require.NotNil(t, mp) + // not yet requested attestation blocks as still missing one header + require.Equal(t, uint32(0), numCalls.Load()) + // not yet computed + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + }) + t.Run("shard attestation header received", func(t *testing.T) { + numCalls := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + arguments.DataComponents + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + + // for requesting attestation header + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + if nonce != 101 { + require.Fail(t, "nonce should have been 101") + } + numCalls.Add(1) + } + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + hdrsForBlock := mp.GetHdrForBlock() + hdrsForBlock.SetNumMissingHdrs(1) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(0, 99) + hdrsForBlock.SetHdrHashAndInfo(string(header1Hash), &blockProcess.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + + headersPool := mp.GetDataPool().Headers() + // mp.ReceivedShardHeader(header1, header1Hash) is called through the headersPool.AddHeader callback + + time.Sleep(100 * time.Millisecond) + require.Nil(t, err) + require.NotNil(t, mp) + require.Equal(t, uint32(1), numCalls.Load()) + require.Equal(t, uint32(1), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + + // receive also the attestation header + headersPool.AddHeader(header2Hash, header2) + // mp.ReceivedShardHeader(header2, header2Hash) is called through the headersPool.AddHeader callback + require.Equal(t, uint32(1), numCalls.Load()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + }) +} From c64c8ed53d50986c0afb615f372f007f3849c46c Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 11:01:36 +0200 Subject: [PATCH 566/958] FIX: After merge in stakingV4 9 --- epochStart/bootstrap/process.go | 10 ++--- epochStart/bootstrap/process_test.go | 9 ++++- epochStart/bootstrap/syncValidatorStatus.go | 41 ++++++++++----------- epochStart/metachain/validators_test.go | 28 +++++--------- factory/api/apiResolverFactory.go | 12 +++--- update/genesis/common.go | 1 + 6 files changed, 48 insertions(+), 53 deletions(-) diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index 78e5555503f..522ed3491ce 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -800,10 +800,9 @@ func (e *epochStartBootstrap) requestAndProcessForMeta(peerMiniBlocks []*block.M Uint64Converter: e.coreComponentsHolder.Uint64ByteSliceConverter(), NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, - SnapshotsEnabled: e.flagsConfig.SnapshotsEnabled, ManagedPeersHolder: e.cryptoComponentsHolder.ManagedPeersHolder(), - e.nodeProcessingMode, - e.stateStatsHandler, + NodeProcessingMode: e.nodeProcessingMode, + StateStatsHandler: e.stateStatsHandler, } storageHandlerComponent, err := NewMetaStorageHandler(argsStorageHandler) if err != nil { @@ -973,10 +972,9 @@ func (e *epochStartBootstrap) requestAndProcessForShard(peerMiniBlocks []*block. Uint64Converter: e.coreComponentsHolder.Uint64ByteSliceConverter(), NodeTypeProvider: e.coreComponentsHolder.NodeTypeProvider(), NodesCoordinatorRegistryFactory: e.nodesCoordinatorRegistryFactory, - SnapshotsEnabled: e.flagsConfig.SnapshotsEnabled, ManagedPeersHolder: e.cryptoComponentsHolder.ManagedPeersHolder(), - e.nodeProcessingMode, - e.stateStatsHandler, + NodeProcessingMode: e.nodeProcessingMode, + StateStatsHandler: e.stateStatsHandler, } storageHandlerComponent, err := NewShardStorageHandler(argsStorageHandler) if err != nil { diff --git a/epochStart/bootstrap/process_test.go b/epochStart/bootstrap/process_test.go index 6c8a8283bfc..11a42a22301 100644 --- a/epochStart/bootstrap/process_test.go +++ b/epochStart/bootstrap/process_test.go @@ -87,7 +87,12 @@ func createComponentsForEpochStart() (*mock.CoreComponentsMock, *mock.CryptoComp ProcessStatusHandlerInstance: &testscommon.ProcessStatusHandlerStub{}, HardforkTriggerPubKeyField: []byte("provided hardfork pub key"), EnableEpochsHandlerField: &enableEpochsHandlerMock.EnableEpochsHandlerStub{ - StakingV4Step2EnableEpochField: 99999, + GetActivationEpochCalled: func(flag core.EnableEpochFlag) uint32 { + if flag == common.StakingV4Step2Flag { + return 99999 + } + return 0 + }, }, }, &mock.CryptoComponentsMock{ @@ -116,7 +121,7 @@ func createMockEpochStartBootstrapArgs( return []core.PeerID{"peer0", "peer1", "peer2", "peer3", "peer4", "peer5"} }}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, - FullArchiveMessenger: &p2pmocks.MessengerStub{}, + FullArchiveMessenger: &p2pmocks.MessengerStub{}, GeneralConfig: config.Config{ MiniBlocksStorage: generalCfg.MiniBlocksStorage, PeerBlockBodyStorage: generalCfg.PeerBlockBodyStorage, diff --git a/epochStart/bootstrap/syncValidatorStatus.go b/epochStart/bootstrap/syncValidatorStatus.go index 3d8cd605770..0bcb9308311 100644 --- a/epochStart/bootstrap/syncValidatorStatus.go +++ b/epochStart/bootstrap/syncValidatorStatus.go @@ -112,28 +112,27 @@ func NewSyncValidatorStatus(args ArgsNewSyncValidatorStatus) (*syncValidatorStat s.memDB = disabled.CreateMemUnit() argsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), - MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), - Marshalizer: args.Marshalizer, - Hasher: args.Hasher, - Shuffler: args.NodeShuffler, - EpochStartNotifier: &disabled.EpochStartNotifier{}, - BootStorer: s.memDB, - ShardIDAsObserver: args.ShardIdAsObserver, - NbShards: args.GenesisNodesConfig.NumberOfShards(), - EligibleNodes: eligibleValidators, - WaitingNodes: waitingValidators, - SelfPublicKey: args.PubKey, - ConsensusGroupCache: consensusGroupCache, - ShuffledOutHandler: disabled.NewShuffledOutHandler(), - ChanStopNode: args.ChanNodeStop, - NodeTypeProvider: args.NodeTypeProvider, - IsFullArchive: args.IsFullArchive, - EnableEpochsHandler: args.EnableEpochsHandler, - ValidatorInfoCacher: s.dataPool.CurrentEpochValidatorInfo(), - GenesisNodesSetupHandler: s.genesisNodesConfig, + ShardConsensusGroupSize: int(args.GenesisNodesConfig.GetShardConsensusGroupSize()), + MetaConsensusGroupSize: int(args.GenesisNodesConfig.GetMetaConsensusGroupSize()), + Marshalizer: args.Marshalizer, + Hasher: args.Hasher, + Shuffler: args.NodeShuffler, + EpochStartNotifier: &disabled.EpochStartNotifier{}, + BootStorer: s.memDB, + ShardIDAsObserver: args.ShardIdAsObserver, + NbShards: args.GenesisNodesConfig.NumberOfShards(), + EligibleNodes: eligibleValidators, + WaitingNodes: waitingValidators, + SelfPublicKey: args.PubKey, + ConsensusGroupCache: consensusGroupCache, + ShuffledOutHandler: disabled.NewShuffledOutHandler(), + ChanStopNode: args.ChanNodeStop, + NodeTypeProvider: args.NodeTypeProvider, + IsFullArchive: args.IsFullArchive, + EnableEpochsHandler: args.EnableEpochsHandler, + ValidatorInfoCacher: s.dataPool.CurrentEpochValidatorInfo(), + GenesisNodesSetupHandler: s.genesisNodesConfig, NodesCoordinatorRegistryFactory: args.NodesCoordinatorRegistryFactory, - StakingV4Step2EnableEpoch: args.EnableEpochsHandler.StakingV4Step2EnableEpoch(), } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argsNodesCoordinator) if err != nil { diff --git a/epochStart/metachain/validators_test.go b/epochStart/metachain/validators_test.go index 72a71f2b9c5..662b0192044 100644 --- a/epochStart/metachain/validators_test.go +++ b/epochStart/metachain/validators_test.go @@ -1275,16 +1275,12 @@ func TestValidatorInfoCreator_sortValidators(t *testing.T) { } vic, _ := NewValidatorInfoCreator(arguments) - list := state.NewShardValidatorsInfoMap() - _ = list.Add(thirdValidator) - _ = list.Add(secondValidator) - _ = list.Add(firstValidator) + list := []state.ValidatorInfoHandler{thirdValidator, secondValidator, firstValidator} + vic.sortValidators(list) - vic.sortValidators(list.GetAllValidatorsInfo()) - - assert.Equal(t, list.GetAllValidatorsInfo()[0], secondValidator) // order not changed for the ones with same public key - assert.Equal(t, list.GetAllValidatorsInfo()[1], firstValidator) - assert.Equal(t, list.GetAllValidatorsInfo()[2], thirdValidator) + assert.Equal(t, list[0], secondValidator) // order not changed for the ones with same public key + assert.Equal(t, list[1], firstValidator) + assert.Equal(t, list[2], thirdValidator) }) t.Run("deterministic sort should change order taking into consideration all fields", func(t *testing.T) { t.Parallel() @@ -1297,16 +1293,12 @@ func TestValidatorInfoCreator_sortValidators(t *testing.T) { } vic, _ := NewValidatorInfoCreator(arguments) - list := state.NewShardValidatorsInfoMap() - _ = list.Add(thirdValidator) - _ = list.Add(secondValidator) - _ = list.Add(firstValidator) - - vic.sortValidators(list.GetAllValidatorsInfo()) + list := []state.ValidatorInfoHandler{thirdValidator, secondValidator, firstValidator} + vic.sortValidators(list) - assert.Equal(t, list.GetAllValidatorsInfo()[0], firstValidator) // proper sorting - assert.Equal(t, list.GetAllValidatorsInfo()[1], secondValidator) - assert.Equal(t, list.GetAllValidatorsInfo()[2], thirdValidator) + assert.Equal(t, list[0], firstValidator) // proper sorting + assert.Equal(t, list[1], secondValidator) + assert.Equal(t, list[2], thirdValidator) }) } diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index c271d1f97b9..5f46ccc028e 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -470,12 +470,12 @@ func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBl Marshalizer: args.coreComponents.InternalMarshalizer(), SystemSCConfig: args.systemSCConfig, ValidatorAccountsDB: args.stateComponents.PeerAccounts(), - UserAccountsDB: args.stateComponents.AccountsAdapterAPI(), ChanceComputer: args.coreComponents.Rater(), - ShardCoordinator: args.processComponents.ShardCoordinator(), - EnableEpochsHandler: args.coreComponents.EnableEpochsHandler(), - NodesCoordinator: args.processComponents.NodesCoordinator(), - } - vmFactory, err := metachain.NewVMContainerFactory(argsNewVmFactory) + UserAccountsDB: args.stateComponents.AccountsAdapterAPI(), ChanceComputer: args.coreComponents.Rater(), + ShardCoordinator: args.processComponents.ShardCoordinator(), + EnableEpochsHandler: args.coreComponents.EnableEpochsHandler(), + NodesCoordinator: args.processComponents.NodesCoordinator(), + } + vmFactory, err := metachain.NewVMContainerFactory(argsNewVmFactory) if err != nil { return nil, nil, err } diff --git a/update/genesis/common.go b/update/genesis/common.go index cd79006bbe5..d8d3b11ca0e 100644 --- a/update/genesis/common.go +++ b/update/genesis/common.go @@ -3,6 +3,7 @@ package genesis import ( "math/big" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" From dd66e58acf8c8a7e1e9c30a24d27c9edbeef0d5c Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 12:25:18 +0200 Subject: [PATCH 567/958] FIX: After merge in stakingV4 10 + fix factory package --- common/constants.go | 4 +- common/enablers/enableEpochsHandler.go | 2 +- common/enablers/enableEpochsHandler_test.go | 26 ++++---- epochStart/metachain/legacySystemSCs.go | 4 +- factory/api/apiResolverFactory_test.go | 3 +- factory/bootstrap/bootstrapComponents.go | 2 +- factory/bootstrap/shardingFactory.go | 2 - factory/bootstrap/shardingFactory_test.go | 66 +++++++++++-------- factory/consensus/consensusComponents_test.go | 3 +- factory/processing/blockProcessorCreator.go | 2 +- factory/processing/processComponents_test.go | 24 ++++--- factory/status/statusComponents_test.go | 5 +- .../statusCore/statusCoreComponents_test.go | 45 +------------ go.mod | 2 +- go.sum | 4 +- .../consensusComponents_test.go | 1 - .../heartbeatComponents_test.go | 1 - .../processComponents_test.go | 1 - .../statusComponents/statusComponents_test.go | 1 - process/scToProtocol/stakingToPeer.go | 23 ++++--- .../nodesCoordinator/hashValidatorShuffler.go | 1 - .../indexHashedNodesCoordinator.go | 1 - testscommon/components/default.go | 24 +++---- 23 files changed, 109 insertions(+), 138 deletions(-) diff --git a/common/constants.go b/common/constants.go index eb8817a9a9b..5af0ba1aef4 100644 --- a/common/constants.go +++ b/common/constants.go @@ -970,7 +970,6 @@ const ( SendAlwaysFlag core.EnableEpochFlag = "SendAlwaysFlag" ValueLengthCheckFlag core.EnableEpochFlag = "ValueLengthCheckFlag" CheckTransferFlag core.EnableEpochFlag = "CheckTransferFlag" - TransferToMetaFlag core.EnableEpochFlag = "TransferToMetaFlag" ESDTNFTImprovementV1Flag core.EnableEpochFlag = "ESDTNFTImprovementV1Flag" ChangeDelegationOwnerFlag core.EnableEpochFlag = "ChangeDelegationOwnerFlag" RefactorPeersMiniBlocksFlag core.EnableEpochFlag = "RefactorPeersMiniBlocksFlag" @@ -996,7 +995,6 @@ const ( ScToScLogEventFlag core.EnableEpochFlag = "ScToScLogEventFlag" BlockGasAndFeesReCheckFlag core.EnableEpochFlag = "BlockGasAndFeesReCheckFlag" BalanceWaitingListsFlag core.EnableEpochFlag = "BalanceWaitingListsFlag" - WaitingListFixFlag core.EnableEpochFlag = "WaitingListFixFlag" NFTStopCreateFlag core.EnableEpochFlag = "NFTStopCreateFlag" FixGasRemainingForSaveKeyValueFlag core.EnableEpochFlag = "FixGasRemainingForSaveKeyValueFlag" IsChangeOwnerAddressCrossShardThroughSCFlag core.EnableEpochFlag = "IsChangeOwnerAddressCrossShardThroughSCFlag" @@ -1004,7 +1002,7 @@ const ( StakingV4Step1Flag core.EnableEpochFlag = "StakingV4Step1Flag" StakingV4Step2Flag core.EnableEpochFlag = "StakingV4Step2Flag" StakingV4Step3Flag core.EnableEpochFlag = "StakingV4Step3Flag" - StakingQueueEnabledFlag core.EnableEpochFlag = "StakingQueueEnabledFlag" + StakingQueueFlag core.EnableEpochFlag = "StakingQueueFlag" StakingV4StartedFlag core.EnableEpochFlag = "StakingV4StartedFlag" // all new flags must be added to createAllFlagsMap method, as part of enableEpochsHandler allFlagsDefined ) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 345ac613477..a61220126fa 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -701,7 +701,7 @@ func (handler *enableEpochsHandler) createAllFlagsMap() { }, activationEpoch: handler.enableEpochsConfig.StakingV4Step3EnableEpoch, }, - common.StakingQueueEnabledFlag: { + common.StakingQueueFlag: { isActiveInEpoch: func(epoch uint32) bool { return epoch < handler.enableEpochsConfig.StakingV4Step1EnableEpoch }, diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 813bcb8a38b..181ad5dc34c 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -268,7 +268,6 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { require.True(t, handler.IsFlagEnabled(common.SendAlwaysFlag)) require.True(t, handler.IsFlagEnabled(common.ValueLengthCheckFlag)) require.True(t, handler.IsFlagEnabled(common.CheckTransferFlag)) - require.True(t, handler.IsFlagEnabled(common.TransferToMetaFlag)) require.True(t, handler.IsFlagEnabled(common.ESDTNFTImprovementV1Flag)) require.True(t, handler.IsFlagEnabled(common.ChangeDelegationOwnerFlag)) require.True(t, handler.IsFlagEnabled(common.RefactorPeersMiniBlocksFlag)) @@ -294,16 +293,15 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { require.True(t, handler.IsFlagEnabled(common.ScToScLogEventFlag)) require.True(t, handler.IsFlagEnabled(common.BlockGasAndFeesReCheckFlag)) require.True(t, handler.IsFlagEnabled(common.BalanceWaitingListsFlag)) - require.True(t, handler.IsFlagEnabled(common.WaitingListFixFlag)) require.True(t, handler.IsFlagEnabled(common.NFTStopCreateFlag)) require.True(t, handler.IsFlagEnabled(common.FixGasRemainingForSaveKeyValueFlag)) require.True(t, handler.IsFlagEnabled(common.IsChangeOwnerAddressCrossShardThroughSCFlag)) - assert.True(t, handler.IsStakeLimitsFlagEnabled()) - assert.True(t, handler.IsStakingV4Step1Enabled()) - assert.True(t, handler.IsStakingV4Step2Enabled()) - assert.True(t, handler.IsStakingV4Step3Enabled()) - assert.False(t, handler.IsStakingQueueEnabled()) - assert.True(t, handler.IsStakingV4Started()) + require.True(t, handler.IsFlagEnabled(common.StakeLimitsFlag)) + require.True(t, handler.IsFlagEnabled(common.StakingV4Step1Flag)) + require.True(t, handler.IsFlagEnabled(common.StakingV4Step2Flag)) + require.True(t, handler.IsFlagEnabled(common.StakingV4Step3Flag)) + require.False(t, handler.IsFlagEnabled(common.StakingQueueFlag)) + require.True(t, handler.IsFlagEnabled(common.StakingV4StartedFlag)) } func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { @@ -411,12 +409,12 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { require.Equal(t, cfg.NFTStopCreateEnableEpoch, handler.GetActivationEpoch(common.NFTStopCreateFlag)) require.Equal(t, cfg.ChangeOwnerAddressCrossShardThroughSCEnableEpoch, handler.GetActivationEpoch(common.IsChangeOwnerAddressCrossShardThroughSCFlag)) require.Equal(t, cfg.FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch, handler.GetActivationEpoch(common.FixGasRemainingForSaveKeyValueFlag)) - assert.True(t, handler.IsStakeLimitsFlagEnabled()) - assert.True(t, handler.IsStakingV4Step1Enabled()) - assert.True(t, handler.IsStakingV4Step2Enabled()) - assert.True(t, handler.IsStakingV4Step3Enabled()) - assert.False(t, handler.IsStakingQueueEnabled()) - assert.True(t, handler.IsStakingV4Started()) + require.Equal(t, cfg.StakeLimitsEnableEpoch, handler.GetActivationEpoch(common.StakeLimitsFlag)) + require.Equal(t, cfg.StakingV4Step1EnableEpoch, handler.GetActivationEpoch(common.StakingV4Step1Flag)) + require.Equal(t, cfg.StakingV4Step2EnableEpoch, handler.GetActivationEpoch(common.StakingV4Step2Flag)) + require.Equal(t, cfg.StakingV4Step3EnableEpoch, handler.GetActivationEpoch(common.StakingV4Step3Flag)) + require.Equal(t, cfg.StakingV4Step1EnableEpoch, handler.GetActivationEpoch(common.StakingQueueFlag)) + require.Equal(t, cfg.StakingV4Step1EnableEpoch, handler.GetActivationEpoch(common.StakingV4StartedFlag)) } func TestEnableEpochsHandler_IsInterfaceNil(t *testing.T) { diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 8bf2185e4de..e5432faa41e 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -206,7 +206,7 @@ func (s *legacySystemSCProcessor) processLegacy( return err } - if s.enableEpochsHandler.IsFlagEnabled(common.StakingQueueEnabledFlag) { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingQueueFlag) { err = s.stakeNodesFromQueue(validatorsInfoMap, numUnStaked, nonce, common.NewList) if err != nil { return err @@ -585,7 +585,7 @@ func (s *legacySystemSCProcessor) updateMaxNodes(validatorsInfoMap state.ShardVa return err } - if s.enableEpochsHandler.IsFlagEnabled(common.StakingQueueEnabledFlag) { + if s.enableEpochsHandler.IsFlagEnabled(common.StakingQueueFlag) { sw.Start("stakeNodesFromQueue") err = s.stakeNodesFromQueue(validatorsInfoMap, maxNumberOfNodes-prevMaxNumberOfNodes, nonce, common.NewList) sw.Stop("stakeNodesFromQueue") diff --git a/factory/api/apiResolverFactory_test.go b/factory/api/apiResolverFactory_test.go index 591ea31b79f..57008ca340c 100644 --- a/factory/api/apiResolverFactory_test.go +++ b/factory/api/apiResolverFactory_test.go @@ -26,6 +26,7 @@ import ( epochNotifierMock "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/guardianMocks" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" @@ -327,7 +328,7 @@ func createMockSCQueryElementArgs() api.SCQueryElementArgs { EnableEpochsHandlerField: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, UInt64ByteSliceConv: &testsMocks.Uint64ByteSliceConverterMock{}, EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &genesisMocks.NodesSetupStub{}, Hash: &testscommon.HasherStub{}, RatingHandler: &testscommon.RaterMock{}, WasmVMChangeLockerInternal: &sync.RWMutex{}, diff --git a/factory/bootstrap/bootstrapComponents.go b/factory/bootstrap/bootstrapComponents.go index bcec92fcabf..da4b2a0fef4 100644 --- a/factory/bootstrap/bootstrapComponents.go +++ b/factory/bootstrap/bootstrapComponents.go @@ -189,7 +189,7 @@ func (bcf *bootstrapComponentsFactory) Create() (*bootstrapComponents, error) { nodesCoordinatorRegistryFactory, err := nodesCoordinator.NewNodesCoordinatorRegistryFactory( bcf.coreComponents.InternalMarshalizer(), - bcf.coreComponents.EnableEpochsHandler().StakingV4Step2EnableEpoch(), + bcf.coreComponents.EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step2Flag), ) if err != nil { return nil, err diff --git a/factory/bootstrap/shardingFactory.go b/factory/bootstrap/shardingFactory.go index 6823aea43dd..6662129299b 100644 --- a/factory/bootstrap/shardingFactory.go +++ b/factory/bootstrap/shardingFactory.go @@ -114,7 +114,6 @@ func CreateNodesCoordinator( enableEpochsHandler common.EnableEpochsHandler, validatorInfoCacher epochStart.ValidatorInfoCacher, nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory, - stakingV4Step2EnableEpoch uint32, ) (nodesCoordinator.NodesCoordinator, error) { if check.IfNil(nodeShufflerOut) { return nil, errErd.ErrNilShuffleOutCloser @@ -222,7 +221,6 @@ func CreateNodesCoordinator( ValidatorInfoCacher: validatorInfoCacher, GenesisNodesSetupHandler: nodesConfig, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, } baseNodesCoordinator, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/factory/bootstrap/shardingFactory_test.go b/factory/bootstrap/shardingFactory_test.go index 0df777933b0..c7a54e077f4 100644 --- a/factory/bootstrap/shardingFactory_test.go +++ b/factory/bootstrap/shardingFactory_test.go @@ -17,6 +17,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -41,7 +42,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Run("nil pub key should error", func(t *testing.T) { t.Parallel() - shardC, nodeType, err := CreateShardCoordinator(&testscommon.NodesSetupStub{}, nil, config.PreferencesConfig{}, nil) + shardC, nodeType, err := CreateShardCoordinator(&genesisMocks.NodesSetupStub{}, nil, config.PreferencesConfig{}, nil) require.Equal(t, errErd.ErrNilPublicKey, err) require.Empty(t, nodeType) require.True(t, check.IfNil(shardC)) @@ -49,7 +50,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Run("nil logger should error", func(t *testing.T) { t.Parallel() - shardC, nodeType, err := CreateShardCoordinator(&testscommon.NodesSetupStub{}, &cryptoMocks.PublicKeyStub{}, config.PreferencesConfig{}, nil) + shardC, nodeType, err := CreateShardCoordinator(&genesisMocks.NodesSetupStub{}, &cryptoMocks.PublicKeyStub{}, config.PreferencesConfig{}, nil) require.Equal(t, errErd.ErrNilLogger, err) require.Empty(t, nodeType) require.True(t, check.IfNil(shardC)) @@ -58,7 +59,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Parallel() shardC, nodeType, err := CreateShardCoordinator( - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, &cryptoMocks.PublicKeyStub{ ToByteArrayStub: func() ([]byte, error) { return nil, expectedErr @@ -75,7 +76,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Parallel() shardC, nodeType, err := CreateShardCoordinator( - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, &cryptoMocks.PublicKeyStub{ ToByteArrayStub: func() ([]byte, error) { return nil, sharding.ErrPublicKeyNotFoundInGenesis // force this error here @@ -95,7 +96,7 @@ func TestCreateShardCoordinator(t *testing.T) { counter := 0 shardC, nodeType, err := CreateShardCoordinator( - &testscommon.NodesSetupStub{ + &genesisMocks.NodesSetupStub{ GetShardIDForPubKeyCalled: func(pubKey []byte) (uint32, error) { return 0, sharding.ErrPublicKeyNotFoundInGenesis // force this error }, @@ -123,7 +124,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Parallel() shardC, nodeType, err := CreateShardCoordinator( - &testscommon.NodesSetupStub{ + &genesisMocks.NodesSetupStub{ GetShardIDForPubKeyCalled: func(pubKey []byte) (uint32, error) { return 0, sharding.ErrPublicKeyNotFoundInGenesis // force this error }, @@ -149,7 +150,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Parallel() shardC, nodeType, err := CreateShardCoordinator( - &testscommon.NodesSetupStub{ + &genesisMocks.NodesSetupStub{ GetShardIDForPubKeyCalled: func(pubKey []byte) (uint32, error) { return core.MetachainShardId, nil }, @@ -169,7 +170,7 @@ func TestCreateShardCoordinator(t *testing.T) { t.Parallel() shardC, nodeType, err := CreateShardCoordinator( - &testscommon.NodesSetupStub{ + &genesisMocks.NodesSetupStub{ GetShardIDForPubKeyCalled: func(pubKey []byte) (uint32, error) { return core.MetachainShardId, nil }, @@ -192,7 +193,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( nil, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{}, &mock.EpochStartNotifierStub{}, &cryptoMocks.PublicKeyStub{}, @@ -208,6 +209,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Equal(t, errErd.ErrNilShuffleOutCloser, err) require.True(t, check.IfNil(nodesC)) @@ -233,6 +235,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Equal(t, errErd.ErrNilGenesisNodesSetupHandler, err) require.True(t, check.IfNil(nodesC)) @@ -242,7 +245,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{}, nil, &cryptoMocks.PublicKeyStub{}, @@ -258,6 +261,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Equal(t, errErd.ErrNilEpochStartNotifier, err) require.True(t, check.IfNil(nodesC)) @@ -267,7 +271,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{}, &mock.EpochStartNotifierStub{}, nil, @@ -283,6 +287,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Equal(t, errErd.ErrNilPublicKey, err) require.True(t, check.IfNil(nodesC)) @@ -292,7 +297,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{}, &mock.EpochStartNotifierStub{}, &cryptoMocks.PublicKeyStub{}, @@ -308,6 +313,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Equal(t, errErd.ErrNilBootstrapParamsHandler, err) require.True(t, check.IfNil(nodesC)) @@ -317,7 +323,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{}, &mock.EpochStartNotifierStub{}, &cryptoMocks.PublicKeyStub{}, @@ -333,6 +339,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Equal(t, nodesCoordinator.ErrNilNodeStopChannel, err) require.True(t, check.IfNil(nodesC)) @@ -342,7 +349,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "", }, @@ -360,6 +367,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.NotNil(t, err) require.True(t, check.IfNil(nodesC)) @@ -369,7 +377,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "disabled", }, @@ -391,6 +399,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.True(t, errors.Is(err, expectedErr)) require.True(t, check.IfNil(nodesC)) @@ -400,7 +409,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "0", }, @@ -422,6 +431,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.True(t, errors.Is(err, expectedErr)) require.True(t, check.IfNil(nodesC)) @@ -431,7 +441,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "0", }, @@ -453,6 +463,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.NotNil(t, err) require.True(t, check.IfNil(nodesC)) @@ -462,7 +473,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "0", }, @@ -484,6 +495,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.NotNil(t, err) require.True(t, check.IfNil(nodesC)) @@ -493,7 +505,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "0", }, @@ -510,7 +522,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &shardingMocks.NodeShufflerMock{}, 0, &bootstrapMocks.BootstrapParamsHandlerMock{ - NodesConfigCalled: func() *nodesCoordinator.NodesCoordinatorRegistry { + NodesConfigCalled: func() nodesCoordinator.NodesCoordinatorRegistryHandler { return &nodesCoordinator.NodesCoordinatorRegistry{ EpochsConfig: map[string]*nodesCoordinator.EpochValidators{ "0": { @@ -536,6 +548,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.NotNil(t, err) require.True(t, check.IfNil(nodesC)) @@ -545,7 +558,7 @@ func TestCreateNodesCoordinator(t *testing.T) { nodesC, err := CreateNodesCoordinator( &testscommon.ShuffleOutCloserStub{}, - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.PreferencesConfig{ DestinationShardAsObserver: "disabled", }, @@ -562,7 +575,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &shardingMocks.NodeShufflerMock{}, 0, &bootstrapMocks.BootstrapParamsHandlerMock{ - NodesConfigCalled: func() *nodesCoordinator.NodesCoordinatorRegistry { + NodesConfigCalled: func() nodesCoordinator.NodesCoordinatorRegistryHandler { return &nodesCoordinator.NodesCoordinatorRegistry{ EpochsConfig: map[string]*nodesCoordinator.EpochValidators{ "0": { @@ -588,6 +601,7 @@ func TestCreateNodesCoordinator(t *testing.T) { &nodeTypeProviderMock.NodeTypeProviderStub{}, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, &validatorInfoCacherMocks.ValidatorInfoCacherStub{}, + &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, ) require.Nil(t, err) require.False(t, check.IfNil(nodesC)) @@ -608,7 +622,7 @@ func TestCreateNodesShuffleOut(t *testing.T) { t.Parallel() shuffler, err := CreateNodesShuffleOut( - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.EpochStartConfig{ MaxShuffledOutRestartThreshold: 5.0, }, @@ -621,7 +635,7 @@ func TestCreateNodesShuffleOut(t *testing.T) { t.Parallel() shuffler, err := CreateNodesShuffleOut( - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.EpochStartConfig{ MinShuffledOutRestartThreshold: 5.0, }, @@ -634,7 +648,7 @@ func TestCreateNodesShuffleOut(t *testing.T) { t.Parallel() shuffler, err := CreateNodesShuffleOut( - &testscommon.NodesSetupStub{}, + &genesisMocks.NodesSetupStub{}, config.EpochStartConfig{}, nil, // force NewShuffleOutCloser to fail ) @@ -645,7 +659,7 @@ func TestCreateNodesShuffleOut(t *testing.T) { t.Parallel() shuffler, err := CreateNodesShuffleOut( - &testscommon.NodesSetupStub{ + &genesisMocks.NodesSetupStub{ GetRoundDurationCalled: func() uint64 { return 4000 }, diff --git a/factory/consensus/consensusComponents_test.go b/factory/consensus/consensusComponents_test.go index 67f551acf1d..c6b56492bf6 100644 --- a/factory/consensus/consensusComponents_test.go +++ b/factory/consensus/consensusComponents_test.go @@ -29,6 +29,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" factoryMocks "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" outportMocks "github.com/multiversx/mx-chain-go/testscommon/outport" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" @@ -57,7 +58,7 @@ func createMockConsensusComponentsFactoryArgs() consensusComp.ConsensusComponent AlarmSch: &testscommon.AlarmSchedulerStub{}, NtpSyncTimer: &testscommon.SyncTimerStub{}, GenesisBlockTime: time.Time{}, - NodesConfig: &testscommon.NodesSetupStub{ + NodesConfig: &genesisMocks.NodesSetupStub{ GetShardConsensusGroupSizeCalled: func() uint32 { return 2 }, diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 306b09d5453..aac9359777d 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -453,7 +453,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( pcf.stakingDataProviderAPI = factoryDisabled.NewDisabledStakingDataProvider() pcf.auctionListSelectorAPI = factoryDisabled.NewDisabledAuctionListSelector() - return blockProcessorAndVmFactories, nil + return blockProcessorComponents, nil } func (pcf *processComponentsFactory) newMetaBlockProcessor( diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index e264b185dac..df419e2df9b 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -44,6 +44,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" factoryMocks "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + nodesSetupMock "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/guardianMocks" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" @@ -107,8 +108,9 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto MaxRating: 100, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + BaseIssuingCost: "1000", + OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ @@ -127,7 +129,7 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto OwnerAddress: "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80", }, StakingSystemSCConfig: config.StakingSystemSCConfig{ - GenesisNodePrice: "2500000000000000000000", + GenesisNodePrice: "2500", MinStakeValue: "1", UnJailValue: "1", MinStepValue: "1", @@ -138,6 +140,8 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + NodeLimitPercentage: 100.0, + StakeLimitPercentage: 100.0, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -170,7 +174,7 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto UInt64ByteSliceConv: &testsMocks.Uint64ByteSliceConverterMock{}, AddrPubKeyConv: addrPubKeyConv, ValPubKeyConv: valPubKeyConv, - NodesConfig: &testscommon.NodesSetupStub{ + NodesConfig: &nodesSetupMock.NodesSetupStub{ GetShardConsensusGroupSizeCalled: func() uint32 { return 2 }, @@ -352,7 +356,7 @@ func TestNewProcessComponentsFactory(t *testing.T) { args := createMockProcessComponentsFactoryArgs() args.CoreData = &mock.CoreComponentsMock{ EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &nodesSetupMock.NodesSetupStub{}, AddrPubKeyConv: nil, } pcf, err := processComp.NewProcessComponentsFactory(args) @@ -365,7 +369,7 @@ func TestNewProcessComponentsFactory(t *testing.T) { args := createMockProcessComponentsFactoryArgs() args.CoreData = &mock.CoreComponentsMock{ EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &nodesSetupMock.NodesSetupStub{}, AddrPubKeyConv: &testscommon.PubkeyConverterStub{}, EpochChangeNotifier: nil, } @@ -379,7 +383,7 @@ func TestNewProcessComponentsFactory(t *testing.T) { args := createMockProcessComponentsFactoryArgs() args.CoreData = &mock.CoreComponentsMock{ EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &nodesSetupMock.NodesSetupStub{}, AddrPubKeyConv: &testscommon.PubkeyConverterStub{}, EpochChangeNotifier: &epochNotifier.EpochNotifierStub{}, ValPubKeyConv: nil, @@ -394,7 +398,7 @@ func TestNewProcessComponentsFactory(t *testing.T) { args := createMockProcessComponentsFactoryArgs() args.CoreData = &mock.CoreComponentsMock{ EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &nodesSetupMock.NodesSetupStub{}, AddrPubKeyConv: &testscommon.PubkeyConverterStub{}, EpochChangeNotifier: &epochNotifier.EpochNotifierStub{}, ValPubKeyConv: &testscommon.PubkeyConverterStub{}, @@ -410,7 +414,7 @@ func TestNewProcessComponentsFactory(t *testing.T) { args := createMockProcessComponentsFactoryArgs() args.CoreData = &mock.CoreComponentsMock{ EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &nodesSetupMock.NodesSetupStub{}, AddrPubKeyConv: &testscommon.PubkeyConverterStub{}, EpochChangeNotifier: &epochNotifier.EpochNotifierStub{}, ValPubKeyConv: &testscommon.PubkeyConverterStub{}, @@ -731,7 +735,7 @@ func TestProcessComponentsFactory_Create(t *testing.T) { args := createMockProcessComponentsFactoryArgs() coreCompStub := factoryMocks.NewCoreComponentsHolderStubFromRealComponent(args.CoreData) coreCompStub.GenesisNodesSetupCalled = func() sharding.GenesisNodesSetupHandler { - return &testscommon.NodesSetupStub{ + return &nodesSetupMock.NodesSetupStub{ AllInitialNodesCalled: func() []nodesCoordinator.GenesisNodeInfoHandler { return []nodesCoordinator.GenesisNodeInfoHandler{ &genesisMocks.GenesisNodeInfoHandlerMock{ diff --git a/factory/status/statusComponents_test.go b/factory/status/statusComponents_test.go index 35c7041d844..4505a0d6a77 100644 --- a/factory/status/statusComponents_test.go +++ b/factory/status/statusComponents_test.go @@ -15,6 +15,7 @@ import ( componentsMock "github.com/multiversx/mx-chain-go/testscommon/components" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/stretchr/testify/require" @@ -45,7 +46,7 @@ func createMockStatusComponentsFactoryArgs() statusComp.StatusComponentsFactoryA NodesCoordinator: &shardingMocks.NodesCoordinatorMock{}, EpochStartNotifier: &mock.EpochStartNotifierStub{}, CoreComponents: &mock.CoreComponentsMock{ - NodesConfig: &testscommon.NodesSetupStub{ + NodesConfig: &genesisMocks.NodesSetupStub{ GetRoundDurationCalled: func() uint64 { return 1000 }, @@ -185,7 +186,7 @@ func TestStatusComponentsFactory_Create(t *testing.T) { args := createMockStatusComponentsFactoryArgs() args.CoreComponents = &mock.CoreComponentsMock{ - NodesConfig: &testscommon.NodesSetupStub{ + NodesConfig: &genesisMocks.NodesSetupStub{ GetRoundDurationCalled: func() uint64 { return 0 }, diff --git a/factory/statusCore/statusCoreComponents_test.go b/factory/statusCore/statusCoreComponents_test.go index dc6d7f2feb0..bd85752faeb 100644 --- a/factory/statusCore/statusCoreComponents_test.go +++ b/factory/statusCore/statusCoreComponents_test.go @@ -15,7 +15,6 @@ import ( componentsMock "github.com/multiversx/mx-chain-go/testscommon/components" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/multiversx/mx-chain-go/testscommon/factory" - "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -40,49 +39,7 @@ func TestNewStatusCoreComponentsFactory(t *testing.T) { args := componentsMock.GetStatusCoreArgs(coreComp) sccf, err := statusCore.NewStatusCoreComponentsFactory(args) - assert.Equal(t, errErd.ErrNilEconomicsData, err) - require.Nil(t, sccf) - }) - t.Run("nil genesis node setup should error", func(t *testing.T) { - t.Parallel() - - coreComp := &mock.CoreComponentsStub{ - EconomicsDataField: &economicsmocks.EconomicsHandlerStub{}, - GenesisNodesSetupField: nil, - } - - args := componentsMock.GetStatusCoreArgs(coreComp) - sccf, err := statusCore.NewStatusCoreComponentsFactory(args) - assert.Equal(t, errErd.ErrNilGenesisNodesSetupHandler, err) - require.Nil(t, sccf) - }) - t.Run("nil marshaller should error", func(t *testing.T) { - t.Parallel() - - coreComp := &mock.CoreComponentsStub{ - EconomicsDataField: &economicsmocks.EconomicsHandlerStub{}, - GenesisNodesSetupField: &genesisMocks.NodesSetupStub{}, - InternalMarshalizerField: nil, - } - - args := componentsMock.GetStatusCoreArgs(coreComp) - sccf, err := statusCore.NewStatusCoreComponentsFactory(args) - assert.Equal(t, errErd.ErrNilMarshalizer, err) - require.Nil(t, sccf) - }) - t.Run("nil slice converter should error", func(t *testing.T) { - t.Parallel() - - coreComp := &mock.CoreComponentsStub{ - EconomicsDataField: &economicsmocks.EconomicsHandlerStub{}, - GenesisNodesSetupField: &genesisMocks.NodesSetupStub{}, - InternalMarshalizerField: &testscommon.MarshalizerStub{}, - Uint64ByteSliceConverterField: nil, - } - - args := componentsMock.GetStatusCoreArgs(coreComp) - sccf, err := statusCore.NewStatusCoreComponentsFactory(args) - assert.Equal(t, errErd.ErrNilUint64ByteSliceConverter, err) + assert.Equal(t, errorsMx.ErrNilEconomicsData, err) require.Nil(t, sccf) }) t.Run("should work", func(t *testing.T) { diff --git a/go.mod b/go.mod index 6e3481871d3..f79232e6aa4 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.14-0.20231215125130-a3bed6e76040 github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 - github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240104131930-48d626709214 + github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240108095836-fdc18df9935d github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 diff --git a/go.sum b/go.sum index b0a8eb37484..cd24301ff0e 100644 --- a/go.sum +++ b/go.sum @@ -398,8 +398,8 @@ github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296/go.mod h1:WocyahfHCC3oGILEVdRe7I4/+q/TLCORoTo1X4wGmF4= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 h1:2RJ6T31pLN75l4xfhTicGZ+gVOPMxSGPip+O1XYVYac= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4/go.mod h1:ioCT2oHQ+TyHQYpgjxzlUdy7dCdv56+w5HnBg9z96eY= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240104131930-48d626709214 h1:o8RyWs7X811dCRWRf8qbjegIWCNaVUJE+U8ooWZ+U9w= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240104131930-48d626709214/go.mod h1:7jjGRykSfLeMs6iQdszlE0lGK2xp9/cctiVdeKbQLLM= +github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240108095836-fdc18df9935d h1:ba/GxX7dSnvVPZRfkxkBrwzUnAWanurcFcGNyo5N2N0= +github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240108095836-fdc18df9935d/go.mod h1:7jjGRykSfLeMs6iQdszlE0lGK2xp9/cctiVdeKbQLLM= github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 h1:qfzeTPI2oSgxnw52KiVWc2fHMem6FZIkX1Azwy64098= github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3/go.mod h1:4kcpwq70UB3Clnc6Q0krGA8hgQ26JTQpmCP+4y5aiV0= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 h1:CDSn4hgiGwoOSSLmajgOvjdoRxfJSXjEu/CfXiqihwo= diff --git a/integrationTests/factory/consensusComponents/consensusComponents_test.go b/integrationTests/factory/consensusComponents/consensusComponents_test.go index 0f9a30f42d4..f560f099705 100644 --- a/integrationTests/factory/consensusComponents/consensusComponents_test.go +++ b/integrationTests/factory/consensusComponents/consensusComponents_test.go @@ -68,7 +68,6 @@ func TestConsensusComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go b/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go index 94d68e87871..9082ce63c06 100644 --- a/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go +++ b/integrationTests/factory/heartbeatComponents/heartbeatComponents_test.go @@ -68,7 +68,6 @@ func TestHeartbeatComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/processComponents/processComponents_test.go b/integrationTests/factory/processComponents/processComponents_test.go index 03391b3ef50..2f2c859bc94 100644 --- a/integrationTests/factory/processComponents/processComponents_test.go +++ b/integrationTests/factory/processComponents/processComponents_test.go @@ -69,7 +69,6 @@ func TestProcessComponents_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/integrationTests/factory/statusComponents/statusComponents_test.go b/integrationTests/factory/statusComponents/statusComponents_test.go index 766ac57748d..62e2ad1e289 100644 --- a/integrationTests/factory/statusComponents/statusComponents_test.go +++ b/integrationTests/factory/statusComponents/statusComponents_test.go @@ -69,7 +69,6 @@ func TestStatusComponents_Create_Close_ShouldWork(t *testing.T) { managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) require.Nil(t, err) managedStatusComponents, err := nr.CreateManagedStatusComponents( diff --git a/process/scToProtocol/stakingToPeer.go b/process/scToProtocol/stakingToPeer.go index fb02c2fbd50..e9b166b52ea 100644 --- a/process/scToProtocol/stakingToPeer.go +++ b/process/scToProtocol/stakingToPeer.go @@ -230,16 +230,17 @@ func (stp *stakingToPeer) updatePeerStateV1( isValidator := account.GetList() == string(common.EligibleList) || account.GetList() == string(common.WaitingList) isJailed := stakingData.JailedNonce >= stakingData.UnJailedNonce && stakingData.JailedNonce > 0 + isStakingV4Started := stp.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) if !isJailed { if stakingData.StakedNonce == nonce && !isValidator { - account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.RegisterNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.RegisterNonce), isStakingV4Started) account.SetTempRating(stp.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) } if stakingData.UnStakedNonce == nonce && account.GetList() != string(common.InactiveList) { - account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce), isStakingV4Started) account.SetUnStakedEpoch(stakingData.UnStakedEpoch) } } @@ -250,7 +251,7 @@ func (stp *stakingToPeer) updatePeerStateV1( } if !isValidator && account.GetUnStakedEpoch() == common.DefaultUnstakedEpoch { - account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.NewList), uint32(stakingData.UnJailedNonce), isStakingV4Started) } } @@ -276,11 +277,13 @@ func (stp *stakingToPeer) updatePeerState( return err } + isStakingV4Started := stp.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) + isUnJailForInactive := !isNew && !stakingData.Staked && stakingData.UnJailedNonce == nonce && account.GetList() == string(common.JailedList) if isUnJailForInactive { log.Debug("unJail for inactive node changed status to inactive list", "blsKey", account.AddressBytes(), "unStakedEpoch", stakingData.UnStakedEpoch) - account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce), isStakingV4Started) if account.GetTempRating() < stp.unJailRating { account.SetTempRating(stp.unJailRating) } @@ -314,7 +317,7 @@ func (stp *stakingToPeer) updatePeerState( } newNodesList := common.NewList - if stp.enableEpochsHandler.IsStakingV4Started() { + if isStakingV4Started { newNodesList = common.AuctionList } @@ -322,14 +325,14 @@ func (stp *stakingToPeer) updatePeerState( if !stakingData.Jailed { if stakingData.StakedNonce == nonce && !isValidator { log.Debug("node is staked, changed status to", "list", newNodesList, "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.StakedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.StakedNonce), isStakingV4Started) account.SetTempRating(stp.startRating) account.SetUnStakedEpoch(common.DefaultUnstakedEpoch) } if stakingData.UnStakedNonce == nonce && account.GetList() != string(common.InactiveList) { log.Debug("node is unStaked, changed status to leaving list", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.UnStakedNonce), isStakingV4Started) account.SetUnStakedEpoch(stakingData.UnStakedEpoch) } } @@ -343,19 +346,19 @@ func (stp *stakingToPeer) updatePeerState( isNewValidator := !isValidator && stakingData.Staked if isNewValidator { log.Debug("node is unJailed and staked, changing status to", "list", newNodesList, "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(newNodesList), uint32(stakingData.UnJailedNonce), isStakingV4Started) } if account.GetList() == string(common.JailedList) { log.Debug("node is unJailed and not staked, changing status to inactive list", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.InactiveList), uint32(stakingData.UnJailedNonce), isStakingV4Started) account.SetUnStakedEpoch(stakingData.UnStakedEpoch) } } if stakingData.JailedNonce == nonce && account.GetList() != string(common.InactiveList) { log.Debug("node is jailed, setting status to leaving", "blsKey", blsPubKey) - account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.JailedNonce), stp.enableEpochsHandler.IsStakingV4Started()) + account.SetListAndIndex(account.GetShardId(), string(common.LeavingList), uint32(stakingData.JailedNonce), isStakingV4Started) account.SetTempRating(stp.jailRating) } diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 058a4b0158c..ff7a897bf8f 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -91,7 +91,6 @@ func NewHashValidatorsShuffler(args *NodesShufflerArgs) (*randHashShuffler, erro } err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ common.BalanceWaitingListsFlag, - common.WaitingListFixFlag, }) if err != nil { return nil, err diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index e9793f2dfdb..96a1738dde1 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -237,7 +237,6 @@ func checkArguments(arguments ArgNodesCoordinator) error { } err := core.CheckHandlerCompatibility(arguments.EnableEpochsHandler, []core.EnableEpochFlag{ common.RefactorPeersMiniBlocksFlag, - common.WaitingListFixFlag, }) if err != nil { return err diff --git a/testscommon/components/default.go b/testscommon/components/default.go index d583b346ffb..514b8355407 100644 --- a/testscommon/components/default.go +++ b/testscommon/components/default.go @@ -13,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverTests "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" epochNotifierMock "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" @@ -44,17 +45,18 @@ func GetDefaultCoreComponents() *mock.CoreComponentsMock { MinTransactionVersionCalled: func() uint32 { return 1 }, - WatchdogTimer: &testscommon.WatchdogMock{}, - AlarmSch: &testscommon.AlarmSchedulerStub{}, - NtpSyncTimer: &testscommon.SyncTimerStub{}, - RoundHandlerField: &testscommon.RoundHandlerMock{}, - EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, - RatingsConfig: &testscommon.RatingsInfoMock{}, - RatingHandler: &testscommon.RaterMock{}, - NodesConfig: &testscommon.NodesSetupStub{}, - StartTime: time.Time{}, - NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, - EpochChangeNotifier: &epochNotifierMock.EpochNotifierStub{}, + WatchdogTimer: &testscommon.WatchdogMock{}, + AlarmSch: &testscommon.AlarmSchedulerStub{}, + NtpSyncTimer: &testscommon.SyncTimerStub{}, + RoundHandlerField: &testscommon.RoundHandlerMock{}, + EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, + RatingsConfig: &testscommon.RatingsInfoMock{}, + RatingHandler: &testscommon.RaterMock{}, + NodesConfig: &genesisMocks.NodesSetupStub{}, + StartTime: time.Time{}, + NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, + EpochChangeNotifier: &epochNotifierMock.EpochNotifierStub{}, + EnableEpochsHandlerField: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, } } From d1fe13ecef8c4b230f9c7d5cc1b6f113c8bf08f5 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 8 Jan 2024 13:14:16 +0200 Subject: [PATCH 568/958] - fixed comments --- cmd/node/config/prefs.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/node/config/prefs.toml b/cmd/node/config/prefs.toml index 98d5c02557f..42e16624ab8 100644 --- a/cmd/node/config/prefs.toml +++ b/cmd/node/config/prefs.toml @@ -8,7 +8,7 @@ # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default NodeDisplayName = "" - # Identity represents the keybase/GitHub identity when the node does not run in multikey mode + # Identity represents the GitHub identity when the node does not run in multikey mode # In multikey mode, all bls keys not mentioned in NamedIdentity section will use this one as default Identity = "" @@ -28,7 +28,7 @@ # ] PreferredConnections = [] - # ConnectionWatcherType represents the type of a connection watcher needed. + # ConnectionWatcherType represents the type of the connection watcher needed. # possible options: # - "disabled" - no connection watching should be made # - "print" - new connection found will be printed in the log file @@ -71,7 +71,7 @@ # NamedIdentity represents an identity that runs nodes on the multikey # There can be multiple identities set on the same node, each one of them having different bls keys, just by duplicating the NamedIdentity [[NamedIdentity]] - # Identity represents the keybase/GitHub identity for the current NamedIdentity + # Identity represents the GitHub identity for the current NamedIdentity Identity = "" # NodeName represents the name that will be given to the names of the current identity NodeName = "" From c53ef0ad4c77aefa4d8166d444aa0712a774d0cb Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 13:16:33 +0200 Subject: [PATCH 569/958] FIX: After merge in stakingV4 11 + fix node build --- api/groups/validatorGroup.go | 1 - common/enablers/enableEpochsHandler_test.go | 16 +++++++++++++++- integrationTests/nodesCoordinatorFactory.go | 16 ++++++---------- .../realcomponents/processorRunner.go | 1 + node/nodeRunner.go | 3 +-- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/api/groups/validatorGroup.go b/api/groups/validatorGroup.go index 68028bf2eda..1120ae4186d 100644 --- a/api/groups/validatorGroup.go +++ b/api/groups/validatorGroup.go @@ -11,7 +11,6 @@ import ( "github.com/multiversx/mx-chain-go/api/errors" "github.com/multiversx/mx-chain-go/api/shared" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/state" ) const ( diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 181ad5dc34c..d96ca808667 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -190,6 +190,20 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { handler.EpochConfirmed(cfg.SetGuardianEnableEpoch+1, 0) require.True(t, handler.IsFlagEnabled(common.SetGuardianFlag)) + handler.EpochConfirmed(cfg.StakingV4Step1EnableEpoch-1, 0) + require.True(t, handler.IsFlagEnabled(common.StakingQueueFlag)) + handler.EpochConfirmed(cfg.StakingV4Step1EnableEpoch, 0) + require.False(t, handler.IsFlagEnabled(common.StakingQueueFlag)) + handler.EpochConfirmed(cfg.StakingV4Step1EnableEpoch+1, 0) + require.False(t, handler.IsFlagEnabled(common.StakingQueueFlag)) + + handler.EpochConfirmed(cfg.StakingV4Step1EnableEpoch-1, 0) + require.False(t, handler.IsFlagEnabled(common.StakingV4StartedFlag)) + handler.EpochConfirmed(cfg.StakingV4Step1EnableEpoch, 0) + require.True(t, handler.IsFlagEnabled(common.StakingV4StartedFlag)) + handler.EpochConfirmed(cfg.StakingV4Step1EnableEpoch+1, 0) + require.True(t, handler.IsFlagEnabled(common.StakingV4StartedFlag)) + handler.EpochConfirmed(math.MaxUint32, 0) require.True(t, handler.IsFlagEnabled(common.SCDeployFlag)) require.True(t, handler.IsFlagEnabled(common.BuiltInFunctionsFlag)) @@ -297,7 +311,7 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { require.True(t, handler.IsFlagEnabled(common.FixGasRemainingForSaveKeyValueFlag)) require.True(t, handler.IsFlagEnabled(common.IsChangeOwnerAddressCrossShardThroughSCFlag)) require.True(t, handler.IsFlagEnabled(common.StakeLimitsFlag)) - require.True(t, handler.IsFlagEnabled(common.StakingV4Step1Flag)) + require.False(t, handler.IsFlagEnabled(common.StakingV4Step1Flag)) require.True(t, handler.IsFlagEnabled(common.StakingV4Step2Flag)) require.True(t, handler.IsFlagEnabled(common.StakingV4Step3Flag)) require.False(t, handler.IsFlagEnabled(common.StakingQueueFlag)) diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 6df00d68bbe..2c5d6686304 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -11,8 +11,8 @@ import ( "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage" - "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" vic "github.com/multiversx/mx-chain-go/testscommon/validatorInfoCacher" ) @@ -80,17 +80,15 @@ func (tpn *IndexHashedNodesCoordinatorFactory) CreateNodesCoordinator(arg ArgInd IsFullArchive: false, EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{ GetActivationEpochCalled: func(flag core.EnableEpochFlag) uint32 { - if flag == common.RefactorPeersMiniBlocksFlag { + if flag == common.RefactorPeersMiniBlocksFlag || flag == common.StakingV4Step2Flag { return UnreachableEpoch } return 0 }, - LEAVING ERROR HERE }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) if err != nil { @@ -120,9 +118,7 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato Adaptivity: adaptivity, ShuffleBetweenShards: shuffleBetweenShards, MaxNodesEnableConfig: nil, - EnableEpochsHandler: &testscommon.EnableEpochsHandlerStub{ - IsBalanceWaitingListsFlagEnabledField: true, - }, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, } nodeShuffler, _ := nodesCoordinator.NewHashValidatorsShuffler(shufflerArgs) @@ -156,7 +152,7 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato return 0 }, }, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } diff --git a/integrationTests/realcomponents/processorRunner.go b/integrationTests/realcomponents/processorRunner.go index 6881284899b..290eaccbae0 100644 --- a/integrationTests/realcomponents/processorRunner.go +++ b/integrationTests/realcomponents/processorRunner.go @@ -304,6 +304,7 @@ func (pr *ProcessorRunner) createStatusComponents(tb testing.TB) { pr.CoreComponents.NodeTypeProvider(), pr.CoreComponents.EnableEpochsHandler(), pr.DataComponents.Datapool().CurrentEpochValidatorInfo(), + pr.BootstrapComponents.NodesCoordinatorRegistryFactory(), ) require.Nil(tb, err) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index b8801ac0390..cfdc8d2788f 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -387,7 +387,6 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( managedCoreComponents.EnableEpochsHandler(), managedDataComponents.Datapool().CurrentEpochValidatorInfo(), managedBootstrapComponents.NodesCoordinatorRegistryFactory(), - configs.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch, ) if err != nil { return true, err @@ -1248,7 +1247,7 @@ func (nr *nodeRunner) CreateManagedProcessComponents( EpochConfig: *configs.EpochConfig, PrefConfigs: *configs.PreferencesConfig, ImportDBConfig: *configs.ImportDbConfig, - EconomicsConfig: *configs.EconomicsConfig, + EconomicsConfig: *configs.EconomicsConfig, AccountsParser: accountsParser, SmartContractParser: smartContractParser, GasSchedule: gasScheduleNotifier, From 52c90658d4e43d496303bf51735be9a7b044bf89 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 14:25:29 +0200 Subject: [PATCH 570/958] FIX: After merge in stakingV4 12 + fix stakingV4_test.go --- integrationTests/testConsensusNode.go | 3 +- integrationTests/testHeartbeatNode.go | 85 ++++++++--------- integrationTests/testInitializer.go | 55 ----------- .../testProcessorNodeWithCoordinator.go | 4 +- .../testProcessorNodeWithMultisigner.go | 93 +++++++++---------- .../vm/staking/baseTestMetaProcessor.go | 5 +- .../vm/staking/componentsHolderCreator.go | 3 + .../vm/staking/metaBlockProcessorCreator.go | 2 + .../vm/staking/nodesCoordiantorCreator.go | 3 +- integrationTests/vm/staking/stakingV4_test.go | 18 +++- .../vm/staking/systemSCCreator.go | 59 ++++++------ .../indexHashedNodesCoordinator.go | 2 +- 12 files changed, 151 insertions(+), 181 deletions(-) diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 0aaea48d81e..43bba6e46f6 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -386,8 +386,7 @@ func (tcn *TestConsensusNode) initNodesCoordinator( EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, ShardIDAsObserver: tcn.ShardCoordinator.SelfId(), - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, - StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, } diff --git a/integrationTests/testHeartbeatNode.go b/integrationTests/testHeartbeatNode.go index 8fa7ccf4de8..77be093f9eb 100644 --- a/integrationTests/testHeartbeatNode.go +++ b/integrationTests/testHeartbeatNode.go @@ -52,6 +52,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -349,27 +350,27 @@ func CreateNodesWithTestHeartbeatNode( suCache, _ := storageunit.NewCache(cacherCfg) for shardId, validatorList := range validatorsMap { argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: uint32(numShards), - EligibleNodes: validatorsForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: suCache, - Shuffler: &shardingMocks.NodeShufflerMock{}, - BootStorer: CreateMemUnit(), - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - Epoch: 0, - EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: uint32(numShards), + EligibleNodes: validatorsForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: suCache, + Shuffler: &shardingMocks.NodeShufflerMock{}, + BootStorer: CreateMemUnit(), + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + Epoch: 0, + EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -397,27 +398,27 @@ func CreateNodesWithTestHeartbeatNode( } argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - ShardIDAsObserver: shardId, - NbShards: uint32(numShards), - EligibleNodes: validatorsForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: suCache, - Shuffler: &shardingMocks.NodeShufflerMock{}, - BootStorer: CreateMemUnit(), - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - Epoch: 0, - EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + ShardIDAsObserver: shardId, + NbShards: uint32(numShards), + EligibleNodes: validatorsForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: suCache, + Shuffler: &shardingMocks.NodeShufflerMock{}, + BootStorer: CreateMemUnit(), + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + Epoch: 0, + EpochStartNotifier: notifier.NewEpochStartSubscriptionHandler(), + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: &shardingMocks.NodesCoordinatorRegistryFactoryMock{}, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 06da0bbd6e3..5c9026e1e3d 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -1597,61 +1597,6 @@ func CreateNodesWithFullGenesisCustomEnableEpochs( return nodes, hardforkStarter } -// CreateNodesWithCustomStateCheckpointModulus creates multiple nodes in different shards with custom stateCheckpointModulus -func CreateNodesWithCustomStateCheckpointModulus( - numOfShards int, - nodesPerShard int, - numMetaChainNodes int, - stateCheckpointModulus uint, -) []*TestProcessorNode { - nodes := make([]*TestProcessorNode, numOfShards*nodesPerShard+numMetaChainNodes) - connectableNodes := make([]Connectable, len(nodes)) - - enableEpochsConfig := GetDefaultEnableEpochsConfig() - enableEpochsConfig.StakingV2EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4Step1EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4Step2EnableEpoch = UnreachableEpoch - enableEpochsConfig.StakingV4Step3EnableEpoch = UnreachableEpoch - - scm := &IntWrapper{ - Value: stateCheckpointModulus, - } - - idx := 0 - for shardId := uint32(0); shardId < uint32(numOfShards); shardId++ { - for j := 0; j < nodesPerShard; j++ { - n := NewTestProcessorNode(ArgTestProcessorNode{ - MaxShards: uint32(numOfShards), - NodeShardId: shardId, - TxSignPrivKeyShardId: shardId, - StateCheckpointModulus: scm, - EpochsConfig: enableEpochsConfig, - }) - - nodes[idx] = n - connectableNodes[idx] = n - idx++ - } - } - - for i := 0; i < numMetaChainNodes; i++ { - metaNode := NewTestProcessorNode(ArgTestProcessorNode{ - MaxShards: uint32(numOfShards), - NodeShardId: core.MetachainShardId, - TxSignPrivKeyShardId: 0, - StateCheckpointModulus: scm, - EpochsConfig: enableEpochsConfig, - }) - idx = i + numOfShards*nodesPerShard - nodes[idx] = metaNode - connectableNodes[idx] = metaNode - } - - ConnectNodes(connectableNodes) - - return nodes -} - // DisplayAndStartNodes prints each nodes shard ID, sk and pk, and then starts the node func DisplayAndStartNodes(nodes []*TestProcessorNode) { for _, n := range nodes { diff --git a/integrationTests/testProcessorNodeWithCoordinator.go b/integrationTests/testProcessorNodeWithCoordinator.go index 54d97320b4c..63392658a76 100644 --- a/integrationTests/testProcessorNodeWithCoordinator.go +++ b/integrationTests/testProcessorNodeWithCoordinator.go @@ -13,7 +13,6 @@ import ( "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage/cache" - "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" vic "github.com/multiversx/mx-chain-go/testscommon/validatorInfoCacher" @@ -77,8 +76,7 @@ func CreateProcessorNodesWithNodesCoordinator( IsFullArchive: false, EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, - StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/testProcessorNodeWithMultisigner.go b/integrationTests/testProcessorNodeWithMultisigner.go index 2538b3dc359..42f08a62b39 100644 --- a/integrationTests/testProcessorNodeWithMultisigner.go +++ b/integrationTests/testProcessorNodeWithMultisigner.go @@ -32,6 +32,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" + "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" vic "github.com/multiversx/mx-chain-go/testscommon/validatorInfoCacher" @@ -237,9 +238,9 @@ func CreateNodesWithNodesCoordinatorFactory( MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, RefactorPeersMiniBlocksEnableEpoch: UnreachableEpoch, DynamicGasCostForDataTrieStorageLoadEnableEpoch: UnreachableEpoch, - StakingV4Step1EnableEpoch: UnreachableEpoch, - StakingV4Step2EnableEpoch: UnreachableEpoch, - StakingV4Step3EnableEpoch: UnreachableEpoch, + StakingV4Step1EnableEpoch: UnreachableEpoch, + StakingV4Step2EnableEpoch: UnreachableEpoch, + StakingV4Step3EnableEpoch: UnreachableEpoch, } nodesMap := make(map[uint32][]*TestProcessorNode) @@ -415,34 +416,33 @@ func CreateNodesWithNodesCoordinatorAndHeaderSigVerifier( }} nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( - &testscommon.MarshalizerMock{}, + &marshallerMock.MarshalizerMock{}, StakingV4Step2EnableEpoch, ) completeNodesList := make([]Connectable, 0) for shardId, validatorList := range validatorsMap { consensusCache, _ := cache.NewLRUCache(10000) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - Shuffler: nodeShuffler, - BootStorer: bootStorer, - EpochStartNotifier: epochStartSubscriber, - ShardIDAsObserver: shardId, - NbShards: uint32(nbShards), - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: consensusCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, - StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + Shuffler: nodeShuffler, + BootStorer: bootStorer, + EpochStartNotifier: epochStartSubscriber, + ShardIDAsObserver: shardId, + NbShards: uint32(nbShards), + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: make(map[uint32][]nodesCoordinator.Validator), + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: consensusCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } nodesCoordinatorInstance, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) @@ -536,7 +536,7 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( } nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( - &testscommon.MarshalizerMock{}, + &marshallerMock.MarshalizerMock{}, StakingV4Step2EnableEpoch, ) completeNodesList := make([]Connectable, 0) @@ -544,28 +544,27 @@ func CreateNodesWithNodesCoordinatorKeygenAndSingleSigner( bootStorer := CreateMemUnit() lruCache, _ := cache.NewLRUCache(10000) argumentsNodesCoordinator := nodesCoordinator.ArgNodesCoordinator{ - ShardConsensusGroupSize: shardConsensusGroupSize, - MetaConsensusGroupSize: metaConsensusGroupSize, - Marshalizer: TestMarshalizer, - Hasher: TestHasher, - Shuffler: nodeShuffler, - EpochStartNotifier: epochStartSubscriber, - BootStorer: bootStorer, - ShardIDAsObserver: shardId, - NbShards: uint32(nbShards), - EligibleNodes: validatorsMapForNodesCoordinator, - WaitingNodes: waitingMapForNodesCoordinator, - SelfPublicKey: []byte(strconv.Itoa(int(shardId))), - ConsensusGroupCache: lruCache, - ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, - ChanStopNode: endProcess.GetDummyEndProcessChannel(), - NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, - IsFullArchive: false, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, - ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, - GenesisNodesSetupHandler: &testscommon.NodesSetupStub{}, + ShardConsensusGroupSize: shardConsensusGroupSize, + MetaConsensusGroupSize: metaConsensusGroupSize, + Marshalizer: TestMarshalizer, + Hasher: TestHasher, + Shuffler: nodeShuffler, + EpochStartNotifier: epochStartSubscriber, + BootStorer: bootStorer, + ShardIDAsObserver: shardId, + NbShards: uint32(nbShards), + EligibleNodes: validatorsMapForNodesCoordinator, + WaitingNodes: waitingMapForNodesCoordinator, + SelfPublicKey: []byte(strconv.Itoa(int(shardId))), + ConsensusGroupCache: lruCache, + ShuffledOutHandler: &mock.ShuffledOutHandlerStub{}, + ChanStopNode: endProcess.GetDummyEndProcessChannel(), + NodeTypeProvider: &nodeTypeProviderMock.NodeTypeProviderStub{}, + IsFullArchive: false, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, - StakingV4Step2EnableEpoch: StakingV4Step2EnableEpoch, } nodesCoord, err := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/vm/staking/baseTestMetaProcessor.go b/integrationTests/vm/staking/baseTestMetaProcessor.go index fe922b2d13e..0ae2b5ed2d8 100644 --- a/integrationTests/vm/staking/baseTestMetaProcessor.go +++ b/integrationTests/vm/staking/baseTestMetaProcessor.go @@ -97,7 +97,7 @@ func newTestMetaProcessor( ) gasScheduleNotifier := createGasScheduleNotifier() - blockChainHook := createBlockChainHook( + argsBlockChainHook, blockChainHook := createBlockChainHook( dataComponents, coreComponents, stateComponents.AccountsAdapter(), @@ -109,7 +109,8 @@ func newTestMetaProcessor( coreComponents, gasScheduleNotifier, blockChainHook, - stateComponents.PeerAccounts(), + argsBlockChainHook, + stateComponents, bootstrapComponents.ShardCoordinator(), nc, maxNodesConfig[0].MaxNumNodes, diff --git a/integrationTests/vm/staking/componentsHolderCreator.go b/integrationTests/vm/staking/componentsHolderCreator.go index a337535a602..e3673b08ec7 100644 --- a/integrationTests/vm/staking/componentsHolderCreator.go +++ b/integrationTests/vm/staking/componentsHolderCreator.go @@ -33,6 +33,7 @@ import ( "github.com/multiversx/mx-chain-go/statusHandler" "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + notifierMocks "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" factoryTests "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/outport" @@ -66,6 +67,7 @@ func createCoreComponents() factory.CoreComponentsHolder { StakingV4Step1EnableEpoch: stakingV4Step1EnableEpoch, StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, StakingV4Step3EnableEpoch: stakingV4Step3EnableEpoch, + GovernanceEnableEpoch: integrationTests.UnreachableEpoch, RefactorPeersMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, } @@ -87,6 +89,7 @@ func createCoreComponents() factory.CoreComponentsHolder { ProcessStatusHandlerInternal: statusHandler.NewProcessStatusHandler(), EnableEpochsHandlerField: enableEpochsHandler, EnableRoundsHandlerField: &testscommon.EnableRoundsHandlerStub{}, + RoundNotifierField: ¬ifierMocks.RoundNotifierStub{}, } } diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 5760d1165d4..66ada9ee344 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -101,6 +101,8 @@ func createMetaBlockProcessor( ProcessedMiniBlocksTracker: processedMb.NewProcessedMiniBlocksTracker(), OutportDataProvider: &outport.OutportDataProviderStub{}, ReceiptsRepository: &testscommon.ReceiptsRepositoryStub{}, + ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, + BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, }, SCToProtocol: stakingToPeer, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, diff --git a/integrationTests/vm/staking/nodesCoordiantorCreator.go b/integrationTests/vm/staking/nodesCoordiantorCreator.go index ec8418db4f6..27a54719521 100644 --- a/integrationTests/vm/staking/nodesCoordiantorCreator.go +++ b/integrationTests/vm/staking/nodesCoordiantorCreator.go @@ -13,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state/accounts" "github.com/multiversx/mx-chain-go/storage" + nodesSetupMock "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/multiversx/mx-chain-storage-go/lrucache" ) @@ -69,11 +70,11 @@ func createNodesCoordinator( Shuffler: nodeShuffler, BootStorer: bootStorer, EpochStartNotifier: coreComponents.EpochStartNotifierWithConfirm(), - StakingV4Step2EnableEpoch: stakingV4Step2EnableEpoch, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, NodeTypeProvider: coreComponents.NodeTypeProvider(), EnableEpochsHandler: coreComponents.EnableEpochsHandler(), ValidatorInfoCacher: dataPool.NewCurrentEpochValidatorInfoPool(), + GenesisNodesSetupHandler: &nodesSetupMock.NodesSetupStub{}, } baseNodesCoordinator, _ := nodesCoordinator.NewIndexHashedNodesCoordinator(argumentsNodesCoordinator) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 92ab77ff24a..3c146b6a069 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -162,6 +162,8 @@ func checkStakingV4EpochChangeFlow( } func TestStakingV4(t *testing.T) { + t.Parallel() + numOfMetaNodes := uint32(400) numOfShards := uint32(3) numOfEligibleNodesPerShard := uint32(400) @@ -256,6 +258,8 @@ func TestStakingV4(t *testing.T) { } func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootHash(t *testing.T) { + t.Parallel() + numOfMetaNodes := uint32(6) numOfShards := uint32(3) numOfEligibleNodesPerShard := uint32(6) @@ -301,6 +305,8 @@ func TestStakingV4MetaProcessor_ProcessMultipleNodesWithSameSetupExpectSameRootH } func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { + t.Parallel() + pubKeys := generateAddresses(0, 20) // Owner1 has 8 nodes, but enough stake for just 7 nodes. At the end of the epoch(staking v4 init), @@ -457,6 +463,8 @@ func TestStakingV4_UnStakeNodesWithNotEnoughFunds(t *testing.T) { } func TestStakingV4_StakeNewNodes(t *testing.T) { + t.Parallel() + pubKeys := generateAddresses(0, 20) // Owner1 has 6 nodes, zero top up @@ -596,6 +604,8 @@ func TestStakingV4_StakeNewNodes(t *testing.T) { } func TestStakingV4_UnStakeNodes(t *testing.T) { + t.Parallel() + pubKeys := generateAddresses(0, 20) owner1 := "owner1" @@ -689,9 +699,9 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { }) currNodesConfig = node.NodesConfig require.Len(t, currNodesConfig.new, 1) - require.Equal(t, currNodesConfig.new[0], queue[0]) + requireSliceContains(t, queue, currNodesConfig.new) require.Empty(t, currNodesConfig.auction) - queue = remove(queue, queue[0]) + queue = remove(queue, currNodesConfig.new[0]) require.Len(t, currNodesConfig.queue, 5) requireSameSliceDifferentOrder(t, queue, currNodesConfig.queue) @@ -789,6 +799,8 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { } func TestStakingV4_JailAndUnJailNodes(t *testing.T) { + t.Parallel() + pubKeys := generateAddresses(0, 20) owner1 := "owner1" @@ -944,6 +956,8 @@ func TestStakingV4_JailAndUnJailNodes(t *testing.T) { } func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffledToToWaiting(t *testing.T) { + t.Parallel() + pubKeys := generateAddresses(0, 20) owner1 := "owner1" diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index b89e403f8d8..906832b8e8f 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -25,6 +25,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" + "github.com/multiversx/mx-chain-go/testscommon/guardianMocks" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" vmcommonMock "github.com/multiversx/mx-chain-vm-common-go/mock" @@ -127,7 +128,7 @@ func createBlockChainHook( accountsAdapter state.AccountsAdapter, shardCoordinator sharding.Coordinator, gasScheduleNotifier core.GasScheduleNotifier, -) process.BlockChainHookHandler { +) (hooks.ArgBlockChainHook, process.BlockChainHookWithAccountsAdapter) { argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ GasSchedule: gasScheduleNotifier, MapDNSAddresses: make(map[string]struct{}), @@ -138,6 +139,8 @@ func createBlockChainHook( EnableEpochsHandler: coreComponents.EnableEpochsHandler(), AutomaticCrawlerAddresses: [][]byte{core.SystemAccountAddress}, MaxNumNodesInTransferRole: 1, + GuardedAccountHandler: &guardianMocks.GuardedAccountHandlerStub{}, + MapDNSV2Addresses: make(map[string]struct{}), } builtInFunctionsContainer, _ := builtInFunctions.CreateBuiltInFunctionsFactory(argsBuiltIn) @@ -145,35 +148,36 @@ func createBlockChainHook( builtInFunctionsContainer.BuiltInFunctionContainer() argsHook := hooks.ArgBlockChainHook{ - Accounts: accountsAdapter, - PubkeyConv: coreComponents.AddressPubKeyConverter(), - StorageService: dataComponents.StorageService(), - BlockChain: dataComponents.Blockchain(), - ShardCoordinator: shardCoordinator, - Marshalizer: coreComponents.InternalMarshalizer(), - Uint64Converter: coreComponents.Uint64ByteSliceConverter(), - NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, - BuiltInFunctions: builtInFunctionsContainer.BuiltInFunctionContainer(), - DataPool: dataComponents.Datapool(), - CompiledSCPool: dataComponents.Datapool().SmartContracts(), - EpochNotifier: coreComponents.EpochNotifier(), - GlobalSettingsHandler: &vmcommonMock.GlobalSettingsHandlerStub{}, - NilCompiledSCStore: true, - EnableEpochsHandler: coreComponents.EnableEpochsHandler(), - GasSchedule: gasScheduleNotifier, - Counter: counters.NewDisabledCounter(), + Accounts: accountsAdapter, + PubkeyConv: coreComponents.AddressPubKeyConverter(), + StorageService: dataComponents.StorageService(), + BlockChain: dataComponents.Blockchain(), + ShardCoordinator: shardCoordinator, + Marshalizer: coreComponents.InternalMarshalizer(), + Uint64Converter: coreComponents.Uint64ByteSliceConverter(), + NFTStorageHandler: &testscommon.SimpleNFTStorageHandlerStub{}, + BuiltInFunctions: builtInFunctionsContainer.BuiltInFunctionContainer(), + DataPool: dataComponents.Datapool(), + CompiledSCPool: dataComponents.Datapool().SmartContracts(), + EpochNotifier: coreComponents.EpochNotifier(), + GlobalSettingsHandler: &vmcommonMock.GlobalSettingsHandlerStub{}, + NilCompiledSCStore: true, + EnableEpochsHandler: coreComponents.EnableEpochsHandler(), + GasSchedule: gasScheduleNotifier, + Counter: counters.NewDisabledCounter(), + MissingTrieNodesNotifier: &testscommon.MissingTrieNodesNotifierStub{}, } - blockChainHook, err := hooks.NewBlockChainHookImpl(argsHook) - _ = err - return blockChainHook + blockChainHook, _ := hooks.NewBlockChainHookImpl(argsHook) + return argsHook, blockChainHook } func createVMContainerFactory( coreComponents factory.CoreComponentsHolder, gasScheduleNotifier core.GasScheduleNotifier, - blockChainHook process.BlockChainHookHandler, - peerAccounts state.AccountsAdapter, + blockChainHook process.BlockChainHookWithAccountsAdapter, + argsBlockChainHook hooks.ArgBlockChainHook, + stateComponents factory.StateComponentsHandler, shardCoordinator sharding.Coordinator, nc nodesCoordinator.NodesCoordinator, maxNumNodes uint32, @@ -196,13 +200,14 @@ func createVMContainerFactory( DelegationTicker: "DEL", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ - Active: config.GovernanceSystemSCConfigActive{ + V1: config.GovernanceSystemSCConfigV1{ + NumNodes: 2000, ProposalCost: "500", - LostProposalFee: "50", MinQuorum: 50, MinPassThreshold: 10, MinVetoThreshold: 10, }, + OwnerAddress: "3132333435363738393031323334353637383930313233343536373839303234", }, StakingSystemSCConfig: config.StakingSystemSCConfig{ GenesisNodePrice: strconv.Itoa(nodePrice), @@ -229,11 +234,13 @@ func createVMContainerFactory( MaxServiceFee: 100, }, }, - ValidatorAccountsDB: peerAccounts, + ValidatorAccountsDB: stateComponents.PeerAccounts(), ChanceComputer: coreComponents.Rater(), EnableEpochsHandler: coreComponents.EnableEpochsHandler(), ShardCoordinator: shardCoordinator, NodesCoordinator: nc, + UserAccountsDB: stateComponents.AccountsAdapter(), + ArgBlockChainHook: argsBlockChainHook, } metaVmFactory, _ := metaProcess.NewVMContainerFactory(argsNewVMContainerFactory) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 96a1738dde1..0f4c5545030 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -1293,7 +1293,7 @@ func (ihnc *indexHashedNodesCoordinator) updateEpochFlags(epoch uint32) { ihnc.flagStakingV4Started.SetValue(epoch >= ihnc.enableEpochsHandler.GetActivationEpoch(common.StakingV4Step1Flag)) log.Debug("indexHashedNodesCoordinator: flagStakingV4Started", "enabled", ihnc.flagStakingV4Started.IsSet()) - ihnc.flagStakingV4Step2.SetValue(epoch >= ihnc.enableEpochsHandler.GetActivationEpoch(common.StakingV2Flag)) + ihnc.flagStakingV4Step2.SetValue(epoch >= ihnc.enableEpochsHandler.GetActivationEpoch(common.StakingV4Step2Flag)) log.Debug("indexHashedNodesCoordinator: flagStakingV4Step2", "enabled", ihnc.flagStakingV4Step2.IsSet()) } From 8e02fd626d00054babac75343dd3121e5cda6c47 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 14:51:23 +0200 Subject: [PATCH 571/958] FIX: After merge in stakingV4 13 --- api/groups/validatorGroup_test.go | 10 +++---- api/mock/facadeStub.go | 12 +++++--- .../startInEpoch/startInEpoch_test.go | 7 +++-- integrationTests/nodesCoordinatorFactory.go | 1 + process/peer/process_test.go | 28 ++++++++++--------- process/scToProtocol/stakingToPeer_test.go | 14 ++++------ process/smartContract/process_test.go | 5 ---- .../smartContract/processorV2/process_test.go | 11 ++------ process/transaction/metaProcess_test.go | 11 -------- 9 files changed, 40 insertions(+), 59 deletions(-) diff --git a/api/groups/validatorGroup_test.go b/api/groups/validatorGroup_test.go index 611e4f0e3bb..ff17095b852 100644 --- a/api/groups/validatorGroup_test.go +++ b/api/groups/validatorGroup_test.go @@ -105,7 +105,7 @@ func TestValidatorStatistics_ReturnsSuccessfully(t *testing.T) { response := shared.GenericAPIResponse{} loadResponse(resp.Body, &response) - validatorStatistics := ValidatorStatisticsResponse{} + validatorStatistics := validatorStatisticsResponse{} mapResponseData := response.Data.(map[string]interface{}) mapResponseDataBytes, _ := json.Marshal(mapResponseData) _ = json.Unmarshal(mapResponseDataBytes, &validatorStatistics) @@ -154,10 +154,10 @@ func TestValidatorGroup_UpdateFacade(t *testing.T) { validatorGroup, err := groups.NewValidatorGroup(&facade) require.NoError(t, err) - ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) - req, _ := http.NewRequest("GET", "/validator/statistics", nil) - resp := httptest.NewRecorder() - ws.ServeHTTP(resp, req) + ws := startWebServer(validatorGroup, "validator", getValidatorRoutesConfig()) + req, _ := http.NewRequest("GET", "/validator/statistics", nil) + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) response := shared.GenericAPIResponse{} loadResponse(resp.Body, &response) diff --git a/api/mock/facadeStub.go b/api/mock/facadeStub.go index bc95c6f0c44..bf646b2035e 100644 --- a/api/mock/facadeStub.go +++ b/api/mock/facadeStub.go @@ -388,7 +388,7 @@ func (f *FacadeStub) ExecuteSCQuery(query *process.SCQuery) (*vm.VMOutputApi, ap return f.ExecuteSCQueryHandler(query) } - return nil, nil + return nil, api.BlockInfo{}, nil } // StatusMetrics is the mock implementation for the StatusMetrics @@ -473,12 +473,16 @@ func (f *FacadeStub) GetPeerInfo(pid string) ([]core.QueryP2PPeerInfo, error) { return f.GetPeerInfoCalled(pid) } + return nil, nil +} + // GetConnectedPeersRatingsOnMainNetwork - func (f *FacadeStub) GetConnectedPeersRatingsOnMainNetwork() (string, error) { - return f.GetConnectedPeersRatingsOnMainNetworkCalled() -} + if f.GetConnectedPeersRatingsOnMainNetworkCalled != nil { + return f.GetConnectedPeersRatingsOnMainNetworkCalled() + } - return nil, nil + return "", nil } // GetEpochStartDataAPI - diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index 59685230184..fd64f95262a 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -34,6 +34,7 @@ import ( epochNotifierMock "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/genericMocks" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" + "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/scheduledDataSyncer" @@ -235,15 +236,15 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui coreComponents.HardforkTriggerPubKeyField = []byte("provided hardfork pub key") nodesCoordinatorRegistryFactory, _ := nodesCoordinator.NewNodesCoordinatorRegistryFactory( - &testscommon.MarshalizerMock{}, + &marshallerMock.MarshalizerMock{}, 444, ) argsBootstrapHandler := bootstrap.ArgsEpochStartBootstrap{ NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, CryptoComponentsHolder: cryptoComponents, CoreComponentsHolder: coreComponents, - MainMessenger: nodeToJoinLate.MainMessenger, - FullArchiveMessenger: nodeToJoinLate.FullArchiveMessenger, + MainMessenger: nodeToJoinLate.MainMessenger, + FullArchiveMessenger: nodeToJoinLate.FullArchiveMessenger, GeneralConfig: generalConfig, PrefsConfig: config.PreferencesConfig{ FullArchive: false, diff --git a/integrationTests/nodesCoordinatorFactory.go b/integrationTests/nodesCoordinatorFactory.go index 2c5d6686304..28267d44c5a 100644 --- a/integrationTests/nodesCoordinatorFactory.go +++ b/integrationTests/nodesCoordinatorFactory.go @@ -153,6 +153,7 @@ func (ihncrf *IndexHashedNodesCoordinatorWithRaterFactory) CreateNodesCoordinato }, }, ValidatorInfoCacher: &vic.ValidatorInfoCacherStub{}, + GenesisNodesSetupHandler: &genesisMocks.NodesSetupStub{}, NodesCoordinatorRegistryFactory: nodesCoordinatorRegistryFactory, } diff --git a/process/peer/process_test.go b/process/peer/process_test.go index b3692f450ab..afeef4fdaf9 100644 --- a/process/peer/process_test.go +++ b/process/peer/process_test.go @@ -2660,9 +2660,9 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t pk1 := []byte("pk1") pk2 := []byte("pk2") - account0, _ := state.NewPeerAccount(pk0) - account1, _ := state.NewPeerAccount(pk1) - account2, _ := state.NewPeerAccount(pk2) + account0, _ := accounts.NewPeerAccount(pk0) + account1, _ := accounts.NewPeerAccount(pk1) + account2, _ := accounts.NewPeerAccount(pk2) ctLoadAccount := &atomic.Counter{} ctSaveAccount := &atomic.Counter{} @@ -2722,16 +2722,18 @@ func TestValidatorStatisticsProcessor_SaveNodesCoordinatorUpdatesWithStakingV4(t }, } stakingV4Step2EnableEpochCalledCt := 0 - arguments.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ - IsStakingV4Step2Called: func() bool { - stakingV4Step2EnableEpochCalledCt++ - switch stakingV4Step2EnableEpochCalledCt { - case 1: - return false - case 2: - return true - default: - require.Fail(t, "should only call this twice") + arguments.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + if flag == common.StakingV4Step2Flag { + stakingV4Step2EnableEpochCalledCt++ + switch stakingV4Step2EnableEpochCalledCt { + case 1: + return false + case 2: + return true + default: + require.Fail(t, "should only call this twice") + } } return false diff --git a/process/scToProtocol/stakingToPeer_test.go b/process/scToProtocol/stakingToPeer_test.go index 151dffe49dc..f53495e92c9 100644 --- a/process/scToProtocol/stakingToPeer_test.go +++ b/process/scToProtocol/stakingToPeer_test.go @@ -673,11 +673,7 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { }, } - enableEpochsHandler := &testscommon.EnableEpochsHandlerStub{ - IsStakeFlagEnabledField: true, - IsValidatorToDelegationFlagEnabledField: true, - } - + enableEpochsHandler := enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakeFlag, common.ValidatorToDelegationFlag) arguments := createMockArgumentsNewStakingToPeer() arguments.PeerState = peerAccountsDB arguments.EnableEpochsHandler = enableEpochsHandler @@ -709,13 +705,13 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.NewList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4StartedField = true + enableEpochsHandler.AddActiveFlags(common.StakingV4StartedFlag) err = stp.updatePeerState(stakingData, blsPubKey, nonce) assert.NoError(t, err) assert.True(t, bytes.Equal(blsPubKey, peerAccount.GetBLSPublicKey())) assert.True(t, bytes.Equal(stakingData.RewardAddress, peerAccount.GetRewardAddress())) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4StartedField = false + enableEpochsHandler.RemoveActiveFlags(common.StakingV4StartedFlag) stakingData.UnStakedNonce = 11 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) @@ -735,11 +731,11 @@ func TestStakingToPeer_UpdatePeerState(t *testing.T) { _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.Equal(t, string(common.NewList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4StartedField = true + enableEpochsHandler.AddActiveFlags(common.StakingV4StartedFlag) err = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnJailedNonce) assert.NoError(t, err) assert.Equal(t, string(common.AuctionList), peerAccount.GetList()) - enableEpochsHandler.IsStakingV4StartedField = false + enableEpochsHandler.RemoveActiveFlags(common.StakingV4StartedFlag) stakingData.UnStakedNonce = 15 _ = stp.updatePeerState(stakingData, blsPubKey, stakingData.UnStakedNonce) diff --git a/process/smartContract/process_test.go b/process/smartContract/process_test.go index fcd543de495..14821021436 100644 --- a/process/smartContract/process_test.go +++ b/process/smartContract/process_test.go @@ -3339,11 +3339,6 @@ func TestScProcessor_ProcessSmartContractResultExecuteSCIfMetaAndBuiltIn(t *test _, err = sc.ProcessSmartContractResult(&scr) require.Nil(t, err) require.True(t, executeCalled) - - executeCalled = false - _, err = sc.ProcessSmartContractResult(&scr) - require.Nil(t, err) - require.False(t, executeCalled) } func TestScProcessor_ProcessRelayedSCRValueBackToRelayer(t *testing.T) { diff --git a/process/smartContract/processorV2/process_test.go b/process/smartContract/processorV2/process_test.go index 5f3cec626a2..cc79ab69902 100644 --- a/process/smartContract/processorV2/process_test.go +++ b/process/smartContract/processorV2/process_test.go @@ -3272,11 +3272,6 @@ func TestScProcessor_ProcessSmartContractResultExecuteSCIfMetaAndBuiltIn(t *test _, err = sc.ProcessSmartContractResult(&scr) require.Nil(t, err) require.True(t, executeCalled) - - executeCalled = false - _, err = sc.ProcessSmartContractResult(&scr) - require.Nil(t, err) - require.False(t, executeCalled) } func TestScProcessor_ProcessRelayedSCRValueBackToRelayer(t *testing.T) { @@ -3702,7 +3697,7 @@ func TestSmartContractProcessor_computeTotalConsumedFeeAndDevRwdWithDifferentSCC feeHandler, err := economics.NewEconomicsData(*args) require.Nil(t, err) require.NotNil(t, feeHandler) - arguments.TxFeeHandler, _ = postprocess.NewFeeAccumulator() + arguments.TxFeeHandler = postprocess.NewFeeAccumulator() arguments.EconomicsFee = feeHandler arguments.ShardCoordinator = shardCoordinator @@ -3788,9 +3783,7 @@ func TestSmartContractProcessor_finishSCExecutionV2(t *testing.T) { arguments.EconomicsFee, err = economics.NewEconomicsData(*args) require.Nil(t, err) - arguments.TxFeeHandler, err = postprocess.NewFeeAccumulator() - require.Nil(t, err) - + arguments.TxFeeHandler = postprocess.NewFeeAccumulator() arguments.ShardCoordinator = shardCoordinator arguments.AccountsDB = &stateMock.AccountsStub{ RevertToSnapshotCalled: func(snapshot int) error { diff --git a/process/transaction/metaProcess_test.go b/process/transaction/metaProcess_test.go index 63e997ef857..eaaa1382d2e 100644 --- a/process/transaction/metaProcess_test.go +++ b/process/transaction/metaProcess_test.go @@ -451,17 +451,6 @@ func TestMetaTxProcessor_ProcessTransactionBuiltInCallTxShouldWork(t *testing.T) assert.Nil(t, err) assert.True(t, wasCalled) assert.Equal(t, 0, saveAccountCalled) - - builtInCalled := false - scProcessorMock.ExecuteBuiltInFunctionCalled = func(tx data.TransactionHandler, acntSrc, acntDst state.UserAccountHandler) (vmcommon.ReturnCode, error) { - builtInCalled = true - return 0, nil - } - - _, err = txProc.ProcessTransaction(&tx) - assert.Nil(t, err) - assert.True(t, builtInCalled) - assert.Equal(t, 0, saveAccountCalled) } func TestMetaTxProcessor_ProcessTransactionWithInvalidUsernameShouldNotError(t *testing.T) { From ca1059026bef78c89c34055c539661aaf007a82f Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 14:58:08 +0200 Subject: [PATCH 572/958] FIX: After merge in stakingV4 14 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f79232e6aa4..faf7419ce2e 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240108095836-fdc18df9935d - github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 + github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240108125548-2ca5bfdab0a8 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92-0.20231228071246-c1b45eae5955 diff --git a/go.sum b/go.sum index cd24301ff0e..430c2e92c2b 100644 --- a/go.sum +++ b/go.sum @@ -400,8 +400,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4/go.mod h1:ioCT2oHQ+TyHQYpgjxzlUdy7dCdv56+w5HnBg9z96eY= github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240108095836-fdc18df9935d h1:ba/GxX7dSnvVPZRfkxkBrwzUnAWanurcFcGNyo5N2N0= github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240108095836-fdc18df9935d/go.mod h1:7jjGRykSfLeMs6iQdszlE0lGK2xp9/cctiVdeKbQLLM= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 h1:qfzeTPI2oSgxnw52KiVWc2fHMem6FZIkX1Azwy64098= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3/go.mod h1:4kcpwq70UB3Clnc6Q0krGA8hgQ26JTQpmCP+4y5aiV0= +github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240108125548-2ca5bfdab0a8 h1:KcfVoYWuf1xZwgDIhS1/H0Yc1Uft3AMg6FCu/MHt5YQ= +github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240108125548-2ca5bfdab0a8/go.mod h1:v/xPmnqCyxBxe7u8XTBg3oJz43uKsIlFLk6DgYEpApY= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 h1:CDSn4hgiGwoOSSLmajgOvjdoRxfJSXjEu/CfXiqihwo= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216/go.mod h1:h87SKR/p66XP0Er2Mx2KfjzS6mLmW6l3tDWyO1oNr94= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 h1:7r2zQiAfqGjN7U8j5obXIoRSh+vnoupBhxBgQGUA2ck= From 62959560647c54f43a0411da2e78008bbe4dbb9e Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 15:11:16 +0200 Subject: [PATCH 573/958] FIX: After merge in stakingV4 15 --- .../bootstrap/shardStorageHandler_test.go | 20 ------------------- epochStart/metachain/systemSCs_test.go | 6 +----- vm/systemSmartContracts/eei.go | 10 ++++++++-- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/epochStart/bootstrap/shardStorageHandler_test.go b/epochStart/bootstrap/shardStorageHandler_test.go index 8443fe27bba..018bc4b99b8 100644 --- a/epochStart/bootstrap/shardStorageHandler_test.go +++ b/epochStart/bootstrap/shardStorageHandler_test.go @@ -13,15 +13,9 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-core-go/data/typeConverters" - "github.com/multiversx/mx-chain-core-go/hashing" - "github.com/multiversx/mx-chain-core-go/marshal" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" - "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/storage" epochStartMocks "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks/epochStart" @@ -1046,20 +1040,6 @@ func Test_getShardHeaderAndMetaHashes(t *testing.T) { require.Equal(t, metaHashes, headers[shardHdrKey].(data.ShardHeaderHandler).GetMetaBlockHashes()) } -type shardStorageArgs struct { - generalConfig config.Config - prefsConfig config.PreferencesConfig - shardCoordinator sharding.Coordinator - pathManagerHandler storage.PathManagerHandler - marshalizer marshal.Marshalizer - hasher hashing.Hasher - currentEpoch uint32 - uint64Converter typeConverters.Uint64ByteSliceConverter - nodeTypeProvider core.NodeTypeProviderHandler - nodeProcessingMode common.NodeProcessingMode - managedPeersHolder common.ManagedPeersHolder -} - func createDefaultEpochStartShardData(lastFinishedMetaBlockHash []byte, shardHeaderHash []byte) []block.EpochStartShardData { return []block.EpochStartShardData{ { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 954f149ce07..0d2f5e65407 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2091,11 +2091,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar args.MaxNodesChangeConfigProvider = nodesConfigProvider args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { - if flag == common.StakingV2Flag { - return true - } - - return false + return flag == common.StakingV2Flag }, } validatorsInfoMap := state.NewShardValidatorsInfoMap() diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index d4c242cf47c..c56b2019d69 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -465,7 +465,10 @@ func (host *vmContext) DeploySystemSC( callInput := createDirectCallInput(newAddress, ownerAddress, value, initFunction, input) - host.transferBeforeInternalExec(callInput, host.scAddress, "DeploySmartContract") + err := host.transferBeforeInternalExec(callInput, host.scAddress, "DeploySmartContract") + if err != nil { + return vmcommon.ExecutionFailed, err + } contract, err := host.systemContracts.Get(baseContract) if err != nil { @@ -519,7 +522,10 @@ func (host *vmContext) ExecuteOnDestContext(destination []byte, sender []byte, v return nil, err } - host.transferBeforeInternalExec(callInput, sender, "ExecuteOnDestContext") + err = host.transferBeforeInternalExec(callInput, sender, "ExecuteOnDestContext") + if err != nil { + return nil, err + } vmOutput := &vmcommon.VMOutput{ReturnCode: vmcommon.UserError} currContext := host.copyToNewContext() From cd60f0d5473da9b91d8537873c57c82a99a069f8 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 15:19:57 +0200 Subject: [PATCH 574/958] FIX: After merge in stakingV4 16 --- node/metrics/metrics_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/metrics/metrics_test.go b/node/metrics/metrics_test.go index 9588957ed55..c7b5a6ccdaa 100644 --- a/node/metrics/metrics_test.go +++ b/node/metrics/metrics_test.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" @@ -359,7 +360,7 @@ func TestInitMetrics(t *testing.T) { return 0 }, } - nodesSetup := &testscommon.NodesSetupStub{ + nodesSetup := &genesisMocks.NodesSetupStub{ GetShardConsensusGroupSizeCalled: func() uint32 { return 63 }, From 3af6793fa988e15838744dbc8b7b8319f149552e Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 15:23:46 +0200 Subject: [PATCH 575/958] FIX: After merge in stakingV4 17 --- integrationTests/vm/staking/stakingV4_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index f8dcfe76b6a..1bf48bf404f 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1171,6 +1171,8 @@ func TestStakingV4_DifferentEdgeCasesWithNotEnoughNodesInWaitingShouldSendShuffl } func TestStakingV4_NewlyStakedNodesInStakingV4Step2ShouldBeSentToWaitingIfListIsTooLow(t *testing.T) { + t.Parallel() + pubKeys := generateAddresses(0, 20) owner1 := "owner1" From b4a3cce37e7c8eb171078f414b2e89904e627475 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Mon, 8 Jan 2024 15:42:01 +0200 Subject: [PATCH 576/958] update tests for metablock requests --- process/block/export_test.go | 24 +- process/block/metablock_request_test.go | 456 +++++++++++++++---- testscommon/dataRetriever/poolsHolderMock.go | 4 + testscommon/pool/headersPoolStub.go | 105 +++++ 4 files changed, 498 insertions(+), 91 deletions(-) create mode 100644 testscommon/pool/headersPoolStub.go diff --git a/process/block/export_test.go b/process/block/export_test.go index 76326c5c3d7..917b52ba80c 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/scheduled" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" @@ -564,26 +565,19 @@ func (bp *baseProcessor) SetNonceOfFirstCommittedBlock(nonce uint64) { bp.setNonceOfFirstCommittedBlock(nonce) } -// HdrForBlock - -type HdrForBlock interface { - InitMaps() - Clone() *hdrForBlock - SetNumMissingHdrs(num uint32) - SetNumMissingFinalityAttestingHdrs(num uint32) - SetHighestHdrNonce(shardId uint32, nonce uint64) - SetHdrHashAndInfo(hash string, info *HdrInfo) - GetHdrHashMap() map[string]data.HeaderHandler - GetHighestHdrNonce() map[uint32]uint64 - GetMissingHdrs() uint32 - GetMissingFinalityAttestingHdrs() uint32 - GetHdrHashAndInfo() map[string]*HdrInfo -} - // GetHdrForBlock - func (mp *metaProcessor) GetHdrForBlock() *hdrForBlock { return mp.hdrsForCurrBlock } +func (mp *metaProcessor) ChannelReceiveAllHeaders() chan bool { + return mp.chRcvAllHdrs +} + +func (mp *metaProcessor) ComputeExistingAndRequestMissingShardHeaders(metaBlock *block.MetaBlock) (uint32, uint32) { + return mp.computeExistingAndRequestMissingShardHeaders(metaBlock) +} + // InitMaps - func (hfb *hdrForBlock) InitMaps() { hfb.initMaps() diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go index 363aef3adac..77331ed30e5 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablock_request_test.go @@ -1,93 +1,119 @@ package block_test import ( + "bytes" + "errors" + "fmt" + "sync" "sync/atomic" "testing" "time" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/multiversx/mx-chain-go/dataRetriever" blockProcess "github.com/multiversx/mx-chain-go/process/block" "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" + "github.com/multiversx/mx-chain-go/testscommon/pool" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) -func createMetaProcessorArguments(t *testing.T, noOfShards uint32) *blockProcess.ArgMetaProcessor { - pool := dataRetrieverMock.NewPoolsHolderMock() - pool.Headers() - coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() - coreComponents.Hash = &hashingMocks.HasherMock{} - dataComponents.DataPool = pool - dataComponents.Storage = initStore() - bootstrapComponents.Coordinator = mock.NewMultiShardsCoordinatorMock(noOfShards) - arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) - arguments.AccountsDB[state.UserAccountsState] = &stateMock.AccountsStub{ - RevertToSnapshotCalled: func(snapshot int) error { - assert.Fail(t, "revert should have not been called") - return nil - }, - JournalLenCalled: func() int { - return 0 - }, - } +func TestMetaProcessor_computeExistingAndRequestMissingShardHeaders(t *testing.T) { + t.Parallel() - startHeaders := createGenesisBlocks(bootstrapComponents.ShardCoordinator()) - arguments.BlockTracker = mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders) - arguments.ArgBaseProcessor.RequestHandler = &testscommon.RequestHandlerStub{ - RequestShardHeaderByNonceCalled: func(shardID uint32, nonce uint64) { - require.Fail(t, "should not have been called") - }, - RequestMetaHeaderByNonceCalled: func(nonce uint64) { - require.Fail(t, "should not have been called") - }, + noOfShards := uint32(2) + td := createTestData() - RequestShardHeaderCalled: func(shardID uint32, hash []byte) { - require.Fail(t, "should not have been called") - }, - RequestMetaHeaderCalled: func(hash []byte) { - require.Fail(t, "should not have been called") - }, - } + t.Run("all referenced shard headers missing", func(t *testing.T) { + t.Parallel() + referencedHeaders := []*shardHeaderData{td[0].referencedHeaderData, td[1].referencedHeaderData} + shardInfo := createShardInfo(referencedHeaders) + metaBlock := &block.MetaBlock{ + ShardInfo: shardInfo, + } - return &arguments + numCallsMissingAttestation := atomic.Uint32{} + numCallsMissingHeaders := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() + if nonce != attestationNonce { + require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) + } + numCallsMissingAttestation.Add(1) + } + requestHandler.RequestShardHeaderCalled = func(shardID uint32, hash []byte) { + for _, sh := range metaBlock.ShardInfo { + if bytes.Equal(sh.HeaderHash, hash) && sh.ShardID == shardID { + numCallsMissingHeaders.Add(1) + return + } + } + + require.Fail(t, fmt.Sprintf("header hash %s not found in meta block", hash)) + } + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + headersForBlock := mp.GetHdrForBlock() + numMissing, numAttestationMissing := mp.ComputeExistingAndRequestMissingShardHeaders(metaBlock) + time.Sleep(100 * time.Millisecond) + require.Equal(t, uint32(2), numMissing) + require.Equal(t, uint32(2), headersForBlock.GetMissingHdrs()) + // before receiving all missing headers referenced in metaBlock, the number of missing attestations is not updated + require.Equal(t, uint32(0), numAttestationMissing) + require.Equal(t, uint32(0), headersForBlock.GetMissingFinalityAttestingHdrs()) + require.Len(t, headersForBlock.GetHdrHashAndInfo(), 2) + require.Equal(t, uint32(0), numCallsMissingAttestation.Load()) + require.Equal(t, uint32(2), numCallsMissingHeaders.Load()) + }) + t.Run("one referenced shard header present and one missing", func(t *testing.T) { + t.Parallel() + + }) + t.Run("all referenced shard headers present, all attestation headers missing", func(t *testing.T) { + t.Parallel() + + }) + t.Run("all referenced shard headers present, one attestation header missing", func(t *testing.T) { + t.Parallel() + + }) + t.Run("all referenced shard headers present, all attestation headers present", func(t *testing.T) { + t.Parallel() + + }) } func TestMetaProcessor_receivedShardHeader(t *testing.T) { - noOfShards := uint32(5) - header1Hash := []byte("testHash1") - header2Hash := []byte("testHash2") - - header1 := &block.HeaderV2{ - Header: &block.Header{ - ShardID: 0, - Round: 100, - Nonce: 100, - }, - } - - header2 := &block.HeaderV2{ - Header: &block.Header{ - ShardID: 0, - Round: 101, - Nonce: 101, - PrevHash: header1Hash, - }, - } + t.Parallel() + noOfShards := uint32(2) + td := createTestData() t.Run("receiving the last used in block shard header", func(t *testing.T) { + t.Parallel() + numCalls := atomic.Uint32{} arguments := createMetaProcessorArguments(t, noOfShards) requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) require.True(t, ok) requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { - if nonce != 101 { - require.Fail(t, "nonce should have been 101") + attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() + if nonce != attestationNonce { + require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) } numCalls.Add(1) } @@ -99,13 +125,13 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { hdrsForBlock := mp.GetHdrForBlock() hdrsForBlock.SetNumMissingHdrs(1) hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) - hdrsForBlock.SetHighestHdrNonce(0, 99) - hdrsForBlock.SetHdrHashAndInfo(string(header1Hash), &blockProcess.HdrInfo{ + hdrsForBlock.SetHighestHdrNonce(0, td[0].referencedHeaderData.header.GetNonce()-1) + hdrsForBlock.SetHdrHashAndInfo(string(td[0].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ UsedInBlock: true, Hdr: nil, }) - mp.ReceivedShardHeader(header1, header1Hash) + mp.ReceivedShardHeader(td[0].referencedHeaderData.header, td[0].referencedHeaderData.headerHash) time.Sleep(100 * time.Millisecond) require.Nil(t, err) @@ -115,6 +141,8 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { }) t.Run("shard header used in block received, not latest", func(t *testing.T) { + t.Parallel() + numCalls := atomic.Uint32{} arguments := createMetaProcessorArguments(t, noOfShards) requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) @@ -122,8 +150,9 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { // for requesting attestation header requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { - if nonce != 101 { - require.Fail(t, "nonce should have been 101") + attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() + if nonce != attestationNonce { + require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) } numCalls.Add(1) } @@ -135,13 +164,13 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { hdrsForBlock := mp.GetHdrForBlock() hdrsForBlock.SetNumMissingHdrs(2) hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) - hdrsForBlock.SetHighestHdrNonce(0, 99) - hdrsForBlock.SetHdrHashAndInfo(string(header1Hash), &blockProcess.HdrInfo{ + hdrsForBlock.SetHighestHdrNonce(0, td[1].referencedHeaderData.header.GetNonce()-1) + hdrsForBlock.SetHdrHashAndInfo(string(td[1].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ UsedInBlock: true, Hdr: nil, }) - mp.ReceivedShardHeader(header1, header1Hash) + mp.ReceivedShardHeader(td[1].referencedHeaderData.header, td[1].referencedHeaderData.headerHash) time.Sleep(100 * time.Millisecond) require.Nil(t, err) @@ -151,17 +180,25 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { // not yet computed require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) }) - t.Run("shard attestation header received", func(t *testing.T) { + t.Run("all needed shard attestation headers received", func(t *testing.T) { + t.Parallel() + numCalls := atomic.Uint32{} arguments := createMetaProcessorArguments(t, noOfShards) - arguments.DataComponents + + poolsHolder, ok := arguments.DataComponents.Datapool().(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) require.True(t, ok) // for requesting attestation header requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { - if nonce != 101 { - require.Fail(t, "nonce should have been 101") + attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() + if nonce != attestationNonce { + require.Fail(t, "nonce should have been %d", attestationNonce) } numCalls.Add(1) } @@ -173,14 +210,16 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { hdrsForBlock := mp.GetHdrForBlock() hdrsForBlock.SetNumMissingHdrs(1) hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) - hdrsForBlock.SetHighestHdrNonce(0, 99) - hdrsForBlock.SetHdrHashAndInfo(string(header1Hash), &blockProcess.HdrInfo{ + hdrsForBlock.SetHighestHdrNonce(0, td[0].referencedHeaderData.header.GetNonce()-1) + hdrsForBlock.SetHdrHashAndInfo(string(td[0].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ UsedInBlock: true, Hdr: nil, }) + // receive the missing header headersPool := mp.GetDataPool().Headers() - // mp.ReceivedShardHeader(header1, header1Hash) is called through the headersPool.AddHeader callback + headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) + mp.ReceivedShardHeader(td[0].referencedHeaderData.header, td[0].referencedHeaderData.headerHash) time.Sleep(100 * time.Millisecond) require.Nil(t, err) @@ -188,10 +227,275 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { require.Equal(t, uint32(1), numCalls.Load()) require.Equal(t, uint32(1), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + // needs to be done before receiving the last header otherwise it will + // be blocked waiting on writing to the channel + wg := &sync.WaitGroup{} + wg.Add(1) + go func(w *sync.WaitGroup) { + receivedAllHeaders := checkReceivedAllHeaders(mp.ChannelReceiveAllHeaders()) + require.True(t, receivedAllHeaders) + wg.Done() + }(wg) + // receive also the attestation header - headersPool.AddHeader(header2Hash, header2) - // mp.ReceivedShardHeader(header2, header2Hash) is called through the headersPool.AddHeader callback + headersPool.AddHeader(td[0].attestationHeaderData.headerHash, td[0].attestationHeaderData.header) + mp.ReceivedShardHeader(td[0].attestationHeaderData.header, td[0].attestationHeaderData.headerHash) + wg.Wait() + require.Equal(t, uint32(1), numCalls.Load()) require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) }) + t.Run("all needed shard attestation headers received, when multiple shards headers missing", func(t *testing.T) { + t.Parallel() + + numCalls := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + + poolsHolder, ok := arguments.DataComponents.Datapool().(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + + // for requesting attestation header + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() + if nonce != td[shardID].attestationHeaderData.header.GetNonce() { + require.Fail(t, fmt.Sprintf("requested nonce for shard %d should have been %d", shardID, attestationNonce)) + } + numCalls.Add(1) + } + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + hdrsForBlock := mp.GetHdrForBlock() + hdrsForBlock.SetNumMissingHdrs(2) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(0, 99) + hdrsForBlock.SetHighestHdrNonce(1, 97) + hdrsForBlock.SetHdrHashAndInfo(string(td[0].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + hdrsForBlock.SetHdrHashAndInfo(string(td[1].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + + // receive the missing header for shard 0 + headersPool := mp.GetDataPool().Headers() + headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) + mp.ReceivedShardHeader(td[0].referencedHeaderData.header, td[0].referencedHeaderData.headerHash) + + time.Sleep(100 * time.Millisecond) + require.Nil(t, err) + require.NotNil(t, mp) + // the attestation header for shard 0 is not requested as the attestation header for shard 1 is missing + // TODO: refactor request logic to request missing attestation headers as soon as possible + require.Equal(t, uint32(0), numCalls.Load()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + + // receive the missing header for shard 1 + headersPool.AddHeader(td[1].referencedHeaderData.headerHash, td[1].referencedHeaderData.header) + mp.ReceivedShardHeader(td[1].referencedHeaderData.header, td[1].referencedHeaderData.headerHash) + + time.Sleep(100 * time.Millisecond) + require.Nil(t, err) + require.NotNil(t, mp) + require.Equal(t, uint32(2), numCalls.Load()) + require.Equal(t, uint32(2), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + + // needs to be done before receiving the last header otherwise it will + // be blocked writing to a channel no one is reading from + wg := &sync.WaitGroup{} + wg.Add(1) + go func(w *sync.WaitGroup) { + receivedAllHeaders := checkReceivedAllHeaders(mp.ChannelReceiveAllHeaders()) + require.True(t, receivedAllHeaders) + wg.Done() + }(wg) + + // receive also the attestation header + headersPool.AddHeader(td[0].attestationHeaderData.headerHash, td[0].attestationHeaderData.header) + mp.ReceivedShardHeader(td[0].attestationHeaderData.header, td[0].attestationHeaderData.headerHash) + + headersPool.AddHeader(td[1].attestationHeaderData.headerHash, td[1].attestationHeaderData.header) + mp.ReceivedShardHeader(td[1].attestationHeaderData.header, td[1].attestationHeaderData.headerHash) + wg.Wait() + + require.Equal(t, uint32(2), numCalls.Load()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + }) +} + +func checkReceivedAllHeaders(channelReceiveAllHeaders chan bool) bool { + select { + case <-time.After(100 * time.Millisecond): + return false + case <-channelReceiveAllHeaders: + return true + } +} + +func createPoolsHolderForHeaderRequests() dataRetriever.HeadersPool { + headersInPool := make(map[string]data.HeaderHandler) + mutHeadersInPool := sync.RWMutex{} + errNotFound := errors.New("header not found") + + return &pool.HeadersCacherStub{ + AddCalled: func(headerHash []byte, header data.HeaderHandler) { + mutHeadersInPool.Lock() + headersInPool[string(headerHash)] = header + mutHeadersInPool.Unlock() + }, + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + mutHeadersInPool.RLock() + defer mutHeadersInPool.RUnlock() + if h, ok := headersInPool[string(hash)]; ok { + return h, nil + } + return nil, errNotFound + }, + GetHeaderByNonceAndShardIdCalled: func(hdrNonce uint64, shardId uint32) ([]data.HeaderHandler, [][]byte, error) { + mutHeadersInPool.RLock() + defer mutHeadersInPool.RUnlock() + for hash, h := range headersInPool { + if h.GetNonce() == hdrNonce && h.GetShardID() == shardId { + return []data.HeaderHandler{h}, [][]byte{[]byte(hash)}, nil + } + } + return nil, nil, errNotFound + }, + } +} + +func createMetaProcessorArguments(t *testing.T, noOfShards uint32) *blockProcess.ArgMetaProcessor { + poolMock := dataRetrieverMock.NewPoolsHolderMock() + poolMock.Headers() + coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders() + coreComponents.Hash = &hashingMocks.HasherMock{} + dataComponents.DataPool = poolMock + dataComponents.Storage = initStore() + bootstrapComponents.Coordinator = mock.NewMultiShardsCoordinatorMock(noOfShards) + arguments := createMockMetaArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) + arguments.AccountsDB[state.UserAccountsState] = &stateMock.AccountsStub{ + RevertToSnapshotCalled: func(snapshot int) error { + assert.Fail(t, "revert should have not been called") + return nil + }, + JournalLenCalled: func() int { + return 0 + }, + } + + startHeaders := createGenesisBlocks(bootstrapComponents.ShardCoordinator()) + arguments.BlockTracker = mock.NewBlockTrackerMock(bootstrapComponents.ShardCoordinator(), startHeaders) + arguments.ArgBaseProcessor.RequestHandler = &testscommon.RequestHandlerStub{ + RequestShardHeaderByNonceCalled: func(shardID uint32, nonce uint64) { + require.Fail(t, "should not have been called") + }, + RequestMetaHeaderByNonceCalled: func(nonce uint64) { + require.Fail(t, "should not have been called") + }, + + RequestShardHeaderCalled: func(shardID uint32, hash []byte) { + require.Fail(t, "should not have been called") + }, + RequestMetaHeaderCalled: func(hash []byte) { + require.Fail(t, "should not have been called") + }, + } + + return &arguments +} + +type shardHeaderData struct { + header *block.HeaderV2 + headerHash []byte +} + +type shardTestData struct { + referencedHeaderData *shardHeaderData + attestationHeaderData *shardHeaderData +} + +func createTestData() map[uint32]*shardTestData { + shard0Header1Hash := []byte("sh0TestHash1") + shard0header2Hash := []byte("sh0TestHash2") + shard1Header1Hash := []byte("sh1TestHash1") + shard1header2Hash := []byte("sh1TestHash2") + shard0ReferencedNonce := uint64(100) + shard1ReferencedNonce := uint64(98) + shard0AttestationNonce := shard0ReferencedNonce + 1 + shard1AttestationNonce := shard1ReferencedNonce + 1 + + shardsTestData := map[uint32]*shardTestData{ + 0: { + referencedHeaderData: &shardHeaderData{ + header: &block.HeaderV2{ + Header: &block.Header{ + ShardID: 0, + Round: 100, + Nonce: shard0ReferencedNonce, + }, + }, + headerHash: shard0Header1Hash, + }, + attestationHeaderData: &shardHeaderData{ + header: &block.HeaderV2{ + Header: &block.Header{ + ShardID: 0, + Round: 101, + Nonce: shard0AttestationNonce, + PrevHash: shard0Header1Hash, + }, + }, + headerHash: shard0header2Hash, + }, + }, + 1: { + referencedHeaderData: &shardHeaderData{ + header: &block.HeaderV2{ + Header: &block.Header{ + ShardID: 1, + Round: 100, + Nonce: shard1ReferencedNonce, + }, + }, + headerHash: shard1Header1Hash, + }, + attestationHeaderData: &shardHeaderData{ + header: &block.HeaderV2{ + Header: &block.Header{ + ShardID: 1, + Round: 101, + Nonce: shard1AttestationNonce, + PrevHash: shard1Header1Hash, + }, + }, + headerHash: shard1header2Hash, + }, + }, + } + + return shardsTestData +} + +func createShardInfo(referencedHeaders []*shardHeaderData) []block.ShardData { + shardData := make([]block.ShardData, len(referencedHeaders)) + for i, h := range referencedHeaders { + shardData[i] = block.ShardData{ + HeaderHash: h.headerHash, + Round: h.header.GetRound(), + PrevHash: h.header.GetPrevHash(), + Nonce: h.header.GetNonce(), + ShardID: h.header.GetShardID(), + } + } + + return shardData } diff --git a/testscommon/dataRetriever/poolsHolderMock.go b/testscommon/dataRetriever/poolsHolderMock.go index 5c711addbb0..f04528bc28c 100644 --- a/testscommon/dataRetriever/poolsHolderMock.go +++ b/testscommon/dataRetriever/poolsHolderMock.go @@ -142,6 +142,10 @@ func (holder *PoolsHolderMock) Headers() dataRetriever.HeadersPool { return holder.headers } +func(holder *PoolsHolderMock) SetHeadersPool(headersPool dataRetriever.HeadersPool) { + holder.headers = headersPool +} + // MiniBlocks - func (holder *PoolsHolderMock) MiniBlocks() storage.Cacher { return holder.miniBlocks diff --git a/testscommon/pool/headersPoolStub.go b/testscommon/pool/headersPoolStub.go new file mode 100644 index 00000000000..c43943cc8c5 --- /dev/null +++ b/testscommon/pool/headersPoolStub.go @@ -0,0 +1,105 @@ +package pool + +import ( + "errors" + + "github.com/multiversx/mx-chain-core-go/data" +) + +// HeadersCacherStub - +type HeadersCacherStub struct { + AddCalled func(headerHash []byte, header data.HeaderHandler) + RemoveHeaderByHashCalled func(headerHash []byte) + RemoveHeaderByNonceAndShardIdCalled func(hdrNonce uint64, shardId uint32) + GetHeaderByNonceAndShardIdCalled func(hdrNonce uint64, shardId uint32) ([]data.HeaderHandler, [][]byte, error) + GetHeaderByHashCalled func(hash []byte) (data.HeaderHandler, error) + ClearCalled func() + RegisterHandlerCalled func(handler func(header data.HeaderHandler, shardHeaderHash []byte)) + NoncesCalled func(shardId uint32) []uint64 + LenCalled func() int + MaxSizeCalled func() int + GetNumHeadersCalled func(shardId uint32) int +} + +// AddHeader - +func (hcs *HeadersCacherStub) AddHeader(headerHash []byte, header data.HeaderHandler) { + if hcs.AddCalled != nil { + hcs.AddCalled(headerHash, header) + } +} + +// RemoveHeaderByHash - +func (hcs *HeadersCacherStub) RemoveHeaderByHash(headerHash []byte) { + if hcs.RemoveHeaderByHashCalled != nil { + hcs.RemoveHeaderByHashCalled(headerHash) + } +} + +// RemoveHeaderByNonceAndShardId - +func (hcs *HeadersCacherStub) RemoveHeaderByNonceAndShardId(hdrNonce uint64, shardId uint32) { + if hcs.RemoveHeaderByNonceAndShardIdCalled != nil { + hcs.RemoveHeaderByNonceAndShardIdCalled(hdrNonce, shardId) + } +} + +// GetHeadersByNonceAndShardId - +func (hcs *HeadersCacherStub) GetHeadersByNonceAndShardId(hdrNonce uint64, shardId uint32) ([]data.HeaderHandler, [][]byte, error) { + if hcs.GetHeaderByNonceAndShardIdCalled != nil { + return hcs.GetHeaderByNonceAndShardIdCalled(hdrNonce, shardId) + } + return nil, nil, errors.New("err") +} + +// GetHeaderByHash - +func (hcs *HeadersCacherStub) GetHeaderByHash(hash []byte) (data.HeaderHandler, error) { + if hcs.GetHeaderByHashCalled != nil { + return hcs.GetHeaderByHashCalled(hash) + } + return nil, nil +} + +// Clear - +func (hcs *HeadersCacherStub) Clear() { + if hcs.ClearCalled != nil { + hcs.ClearCalled() + } +} + +// RegisterHandler - +func (hcs *HeadersCacherStub) RegisterHandler(handler func(header data.HeaderHandler, shardHeaderHash []byte)) { + if hcs.RegisterHandlerCalled != nil { + hcs.RegisterHandlerCalled(handler) + } +} + +// Nonces - +func (hcs *HeadersCacherStub) Nonces(shardId uint32) []uint64 { + if hcs.NoncesCalled != nil { + return hcs.NoncesCalled(shardId) + } + return nil +} + +// Len - +func (hcs *HeadersCacherStub) Len() int { + return 0 +} + +// MaxSize - +func (hcs *HeadersCacherStub) MaxSize() int { + return 100 +} + +// IsInterfaceNil - +func (hcs *HeadersCacherStub) IsInterfaceNil() bool { + return hcs == nil +} + +// GetNumHeaders - +func (hcs *HeadersCacherStub) GetNumHeaders(shardId uint32) int { + if hcs.GetNumHeadersCalled != nil { + return hcs.GetNumHeadersCalled(shardId) + } + + return 0 +} From bb950ff1ffe00a21fd64637513a1616f224301bb Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 15:48:43 +0200 Subject: [PATCH 577/958] FIX: After merge in stakingV4 18 --- sharding/nodesCoordinator/hashValidatorShuffler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index a0f49807993..70fd019cb9d 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -209,7 +209,7 @@ func (rhs *randHashShuffler) UpdateNodeLists(args ArgsUpdateNodes) (*ResUpdateNo nbShards: args.NbShards, distributor: rhs.validatorDistributor, maxNodesToSwapPerShard: rhs.activeNodesConfig.NodesToShufflePerShard, - flagBalanceWaitingLists: rhs.flagBalanceWaitingLists.IsSet(), + flagBalanceWaitingLists: rhs.enableEpochsHandler.IsFlagEnabledInEpoch(common.BalanceWaitingListsFlag, args.Epoch), flagStakingV4Step2: rhs.flagStakingV4Step2.IsSet(), flagStakingV4Step3: rhs.flagStakingV4Step3.IsSet(), maxNumNodes: rhs.activeNodesConfig.MaxNumNodes, From 173eb13b7ee9b9a6bc4f5073a925fa362d88e270 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 16:00:05 +0200 Subject: [PATCH 578/958] FIX: After merge in stakingV4 19 with go fmt --- .../presenter/presenterStatusHandler.go | 2 +- cmd/termui/view/termuic/interface.go | 2 +- .../termuiRenders/drawableContainer.go | 2 +- common/validatorInfo/validatorInfoUtils.go | 2 +- config/ratingsConfig.go | 2 +- config/systemSmartContractsConfig.go | 6 ++- consensus/spos/bls/blsWorker.go | 41 ++++++++-------- consensus/spos/consensusCore.go | 6 +-- dataRetriever/chainStorer.go | 2 +- .../epochproviders/arithmeticEpochProvider.go | 2 +- debug/handler/interceptorDebugHandler.go | 2 +- epochStart/metachain/economicsDataProvider.go | 4 +- factory/processing/processComponents.go | 2 +- genesis/interface.go | 2 +- integrationTests/testProcessorNode.go | 6 +-- integrationTests/testSyncNode.go | 16 +++---- integrationTests/vm/esdt/common.go | 2 +- integrationTests/vm/txsFee/scCalls_test.go | 4 +- node/nodeTesting.go | 2 +- node/node_test.go | 2 +- .../postprocess/intermediateResults_test.go | 18 +++---- .../block/preprocess/transactionsV2_test.go | 2 +- process/coordinator/process_test.go | 34 ++++++------- ...rmediateProcessorsContainerFactory_test.go | 16 +++---- ...rmediateProcessorsContainerFactory_test.go | 16 +++---- process/headerCheck/headerSignatureVerify.go | 2 +- process/peer/ratingReader.go | 4 +- process/rating/chance.go | 6 +-- process/rating/disabledRatingReader.go | 6 +-- .../indexHashedNodesCoordinatorWithRater.go | 2 +- testscommon/state/accountAdapterStub.go | 6 +-- testscommon/state/accountWrapperMock.go | 2 +- .../storageManager/storageManagerStub.go | 48 +++++++++---------- testscommon/txDataBuilder/builder.go | 2 +- testscommon/vmcommonMocks/userAccountStub.go | 2 +- update/genesis/export.go | 26 +++++----- 36 files changed, 152 insertions(+), 149 deletions(-) diff --git a/cmd/termui/presenter/presenterStatusHandler.go b/cmd/termui/presenter/presenterStatusHandler.go index 6ad88f98e4d..1722eedbcb4 100644 --- a/cmd/termui/presenter/presenterStatusHandler.go +++ b/cmd/termui/presenter/presenterStatusHandler.go @@ -6,7 +6,7 @@ import ( "sync" ) -//maxLogLines is used to specify how many lines of logs need to store in slice +// maxLogLines is used to specify how many lines of logs need to store in slice var maxLogLines = 100 // PresenterStatusHandler is the AppStatusHandler impl that is able to process and store received data diff --git a/cmd/termui/view/termuic/interface.go b/cmd/termui/view/termuic/interface.go index ecc3e618da6..63384792e6b 100644 --- a/cmd/termui/view/termuic/interface.go +++ b/cmd/termui/view/termuic/interface.go @@ -1,6 +1,6 @@ package termuic -//TermuiRender defines the actions which should be handled by a render +// TermuiRender defines the actions which should be handled by a render type TermuiRender interface { // RefreshData method is used to refresh data that are displayed on a grid RefreshData(numMillisecondsRefreshTime int) diff --git a/cmd/termui/view/termuic/termuiRenders/drawableContainer.go b/cmd/termui/view/termuic/termuiRenders/drawableContainer.go index 4964c9d6a85..f21472b2185 100644 --- a/cmd/termui/view/termuic/termuiRenders/drawableContainer.go +++ b/cmd/termui/view/termuic/termuiRenders/drawableContainer.go @@ -17,7 +17,7 @@ type DrawableContainer struct { maxHeight int } -//NewDrawableContainer method is used to return a new NewDrawableContainer structure +// NewDrawableContainer method is used to return a new NewDrawableContainer structure func NewDrawableContainer() *DrawableContainer { dc := DrawableContainer{} return &dc diff --git a/common/validatorInfo/validatorInfoUtils.go b/common/validatorInfo/validatorInfoUtils.go index 80e5ba86173..20f4e97897a 100644 --- a/common/validatorInfo/validatorInfoUtils.go +++ b/common/validatorInfo/validatorInfoUtils.go @@ -25,7 +25,7 @@ func WasLeavingEligibleInCurrentEpoch(valInfo state.ValidatorInfoHandler) bool { } // WasJailedEligibleInCurrentEpoch returns true if the validator was jailed in the epoch but also active/eligible due to not enough -//nodes in shard. +// nodes in shard. func WasJailedEligibleInCurrentEpoch(valInfo state.ValidatorInfoHandler) bool { if valInfo == nil { return false diff --git a/config/ratingsConfig.go b/config/ratingsConfig.go index 3558a32f446..a4c243cd51b 100644 --- a/config/ratingsConfig.go +++ b/config/ratingsConfig.go @@ -27,7 +27,7 @@ type MetaChain struct { RatingSteps } -//RatingValue will hold different rating options with increase and decrease steps +// RatingValue will hold different rating options with increase and decrease steps type RatingValue struct { Name string Value int32 diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index fce1b3a47ca..9d04725acc0 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -35,7 +35,8 @@ type ESDTSystemSCConfig struct { } // GovernanceSystemSCConfigV1 holds the initial set of values that were used to initialise the -// governance system smart contract at genesis time +// +// governance system smart contract at genesis time type GovernanceSystemSCConfigV1 struct { NumNodes int64 ProposalCost string @@ -45,7 +46,8 @@ type GovernanceSystemSCConfigV1 struct { } // GovernanceSystemSCConfigActive defines the set of configuration values used by the governance -// system smart contract once it activates +// +// system smart contract once it activates type GovernanceSystemSCConfigActive struct { ProposalCost string LostProposalFee string diff --git a/consensus/spos/bls/blsWorker.go b/consensus/spos/bls/blsWorker.go index 8a5eabe6b5a..456d4e8b1d8 100644 --- a/consensus/spos/bls/blsWorker.go +++ b/consensus/spos/bls/blsWorker.go @@ -7,12 +7,13 @@ import ( // peerMaxMessagesPerSec defines how many messages can be propagated by a pid in a round. The value was chosen by // following the next premises: -// 1. a leader can propagate as maximum as 3 messages per round: proposed header block + proposed body + final info; -// 2. due to the fact that a delayed signature of the proposer (from previous round) can be received in the current round -// adds an extra 1 to the total value, reaching value 4; -// 3. Because the leader might be selected in the next round and might have an empty data pool, it can send the newly -// empty proposed block at the very beginning of the next round. One extra message here, yielding to a total of 5. -// 4. If we consider the forks that can appear on the system wee need to add one more to the value. +// 1. a leader can propagate as maximum as 3 messages per round: proposed header block + proposed body + final info; +// 2. due to the fact that a delayed signature of the proposer (from previous round) can be received in the current round +// adds an extra 1 to the total value, reaching value 4; +// 3. Because the leader might be selected in the next round and might have an empty data pool, it can send the newly +// empty proposed block at the very beginning of the next round. One extra message here, yielding to a total of 5. +// 4. If we consider the forks that can appear on the system wee need to add one more to the value. +// // Validators only send one signature message in a round, treating the edge case of a delayed message, will need at most // 2 messages per round (which is ok as it is below the set value of 5) const peerMaxMessagesPerSec = uint32(6) @@ -36,7 +37,7 @@ func NewConsensusService() (*worker, error) { return &wrk, nil } -//InitReceivedMessages initializes the MessagesType map for all messages for the current ConsensusService +// InitReceivedMessages initializes the MessagesType map for all messages for the current ConsensusService func (wrk *worker) InitReceivedMessages() map[consensus.MessageType][]*consensus.Message { receivedMessages := make(map[consensus.MessageType][]*consensus.Message) receivedMessages[MtBlockBodyAndHeader] = make([]*consensus.Message, 0) @@ -54,47 +55,47 @@ func (wrk *worker) GetMaxMessagesInARoundPerPeer() uint32 { return peerMaxMessagesPerSec } -//GetStringValue gets the name of the messageType +// GetStringValue gets the name of the messageType func (wrk *worker) GetStringValue(messageType consensus.MessageType) string { return getStringValue(messageType) } -//GetSubroundName gets the subround name for the subround id provided +// GetSubroundName gets the subround name for the subround id provided func (wrk *worker) GetSubroundName(subroundId int) string { return getSubroundName(subroundId) } -//IsMessageWithBlockBodyAndHeader returns if the current messageType is about block body and header +// IsMessageWithBlockBodyAndHeader returns if the current messageType is about block body and header func (wrk *worker) IsMessageWithBlockBodyAndHeader(msgType consensus.MessageType) bool { return msgType == MtBlockBodyAndHeader } -//IsMessageWithBlockBody returns if the current messageType is about block body +// IsMessageWithBlockBody returns if the current messageType is about block body func (wrk *worker) IsMessageWithBlockBody(msgType consensus.MessageType) bool { return msgType == MtBlockBody } -//IsMessageWithBlockHeader returns if the current messageType is about block header +// IsMessageWithBlockHeader returns if the current messageType is about block header func (wrk *worker) IsMessageWithBlockHeader(msgType consensus.MessageType) bool { return msgType == MtBlockHeader } -//IsMessageWithSignature returns if the current messageType is about signature +// IsMessageWithSignature returns if the current messageType is about signature func (wrk *worker) IsMessageWithSignature(msgType consensus.MessageType) bool { return msgType == MtSignature } -//IsMessageWithFinalInfo returns if the current messageType is about header final info +// IsMessageWithFinalInfo returns if the current messageType is about header final info func (wrk *worker) IsMessageWithFinalInfo(msgType consensus.MessageType) bool { return msgType == MtBlockHeaderFinalInfo } -//IsMessageWithInvalidSigners returns if the current messageType is about invalid signers +// IsMessageWithInvalidSigners returns if the current messageType is about invalid signers func (wrk *worker) IsMessageWithInvalidSigners(msgType consensus.MessageType) bool { return msgType == MtInvalidSigners } -//IsMessageTypeValid returns if the current messageType is valid +// IsMessageTypeValid returns if the current messageType is valid func (wrk *worker) IsMessageTypeValid(msgType consensus.MessageType) bool { isMessageTypeValid := msgType == MtBlockBodyAndHeader || msgType == MtBlockBody || @@ -106,17 +107,17 @@ func (wrk *worker) IsMessageTypeValid(msgType consensus.MessageType) bool { return isMessageTypeValid } -//IsSubroundSignature returns if the current subround is about signature +// IsSubroundSignature returns if the current subround is about signature func (wrk *worker) IsSubroundSignature(subroundId int) bool { return subroundId == SrSignature } -//IsSubroundStartRound returns if the current subround is about start round +// IsSubroundStartRound returns if the current subround is about start round func (wrk *worker) IsSubroundStartRound(subroundId int) bool { return subroundId == SrStartRound } -//GetMessageRange provides the MessageType range used in checks by the consensus +// GetMessageRange provides the MessageType range used in checks by the consensus func (wrk *worker) GetMessageRange() []consensus.MessageType { var v []consensus.MessageType @@ -127,7 +128,7 @@ func (wrk *worker) GetMessageRange() []consensus.MessageType { return v } -//CanProceed returns if the current messageType can proceed further if previous subrounds finished +// CanProceed returns if the current messageType can proceed further if previous subrounds finished func (wrk *worker) CanProceed(consensusState *spos.ConsensusState, msgType consensus.MessageType) bool { switch msgType { case MtBlockBodyAndHeader: diff --git a/consensus/spos/consensusCore.go b/consensus/spos/consensusCore.go index 1edfb09b5fc..2cf7ca369d6 100644 --- a/consensus/spos/consensusCore.go +++ b/consensus/spos/consensusCore.go @@ -14,7 +14,7 @@ import ( ) // ConsensusCore implements ConsensusCoreHandler and provides access to common functionality -// for the rest of the consensus structures +// for the rest of the consensus structures type ConsensusCore struct { blockChain data.ChainHandler blockProcessor process.BlockProcessor @@ -148,7 +148,7 @@ func (cc *ConsensusCore) MultiSignerContainer() cryptoCommon.MultiSignerContaine return cc.multiSignerContainer } -//RoundHandler gets the RoundHandler stored in the ConsensusCore +// RoundHandler gets the RoundHandler stored in the ConsensusCore func (cc *ConsensusCore) RoundHandler() consensus.RoundHandler { return cc.roundHandler } @@ -158,7 +158,7 @@ func (cc *ConsensusCore) ShardCoordinator() sharding.Coordinator { return cc.shardCoordinator } -//SyncTimer gets the SyncTimer stored in the ConsensusCore +// SyncTimer gets the SyncTimer stored in the ConsensusCore func (cc *ConsensusCore) SyncTimer() ntp.SyncTimer { return cc.syncTimer } diff --git a/dataRetriever/chainStorer.go b/dataRetriever/chainStorer.go index 88541d10077..933d4b97a51 100644 --- a/dataRetriever/chainStorer.go +++ b/dataRetriever/chainStorer.go @@ -10,7 +10,7 @@ import ( var _ StorageService = (*ChainStorer)(nil) // ChainStorer is a StorageService implementation that can hold multiple storages -// grouped by storage unit type +// grouped by storage unit type type ChainStorer struct { lock sync.RWMutex chain map[UnitType]storage.Storer diff --git a/dataRetriever/resolvers/epochproviders/arithmeticEpochProvider.go b/dataRetriever/resolvers/epochproviders/arithmeticEpochProvider.go index a0d6963ad14..675ebd6f276 100644 --- a/dataRetriever/resolvers/epochproviders/arithmeticEpochProvider.go +++ b/dataRetriever/resolvers/epochproviders/arithmeticEpochProvider.go @@ -9,7 +9,7 @@ import ( ) // deltaEpochActive represents how many epochs behind the current computed epoch are to be considered "active" and -//cause the requests to be sent to all peers regardless of being full observers or not. Usually, a node will have +// cause the requests to be sent to all peers regardless of being full observers or not. Usually, a node will have // [config.toml].[StoragePruning].NumActivePersisters opened persisters but to the fact that a shorter epoch can happen, // that value is lowered at a maximum 1. const deltaEpochActive = uint32(1) diff --git a/debug/handler/interceptorDebugHandler.go b/debug/handler/interceptorDebugHandler.go index 9c5b2cb361a..a00f7b878b9 100644 --- a/debug/handler/interceptorDebugHandler.go +++ b/debug/handler/interceptorDebugHandler.go @@ -202,7 +202,7 @@ func (idh *interceptorDebugHandler) incrementNumOfPrints() { } } -//TODO replace this with a call to Query(search) when a suitable conditional parser will be used. Also replace config parameters +// TODO replace this with a call to Query(search) when a suitable conditional parser will be used. Also replace config parameters // with a query string so it will be more extensible func (idh *interceptorDebugHandler) getStringEvents(maxNumPrints int) []string { acceptEvent := func(ev *event) bool { diff --git a/epochStart/metachain/economicsDataProvider.go b/epochStart/metachain/economicsDataProvider.go index c39eb917521..ec165ffe80a 100644 --- a/epochStart/metachain/economicsDataProvider.go +++ b/epochStart/metachain/economicsDataProvider.go @@ -53,7 +53,7 @@ func (es *epochEconomicsStatistics) SetLeadersFees(fees *big.Int) { } // SetRewardsToBeDistributed sets the rewards to be distributed at the end of the epoch (includes the rewards per block, -//the block producers fees, protocol sustainability rewards and developer fees) +// the block producers fees, protocol sustainability rewards and developer fees) func (es *epochEconomicsStatistics) SetRewardsToBeDistributed(rewards *big.Int) { es.mutEconomicsStatistics.Lock() defer es.mutEconomicsStatistics.Unlock() @@ -99,7 +99,7 @@ func (es *epochEconomicsStatistics) LeaderFees() *big.Int { } // RewardsToBeDistributed returns the rewards to be distributed at the end of epoch (includes rewards for produced -//blocks, protocol sustainability rewards, block producer fees and developer fees) +// blocks, protocol sustainability rewards, block producer fees and developer fees) func (es *epochEconomicsStatistics) RewardsToBeDistributed() *big.Int { es.mutEconomicsStatistics.RLock() defer es.mutEconomicsStatistics.RUnlock() diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 00352842964..f2eb4fb5a20 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -213,7 +213,7 @@ func NewProcessComponentsFactory(args ProcessComponentsFactoryArgs) (*processCom epochConfig: args.EpochConfig, prefConfigs: args.PrefConfigs, importDBConfig: args.ImportDBConfig, - economicsConfig: args.EconomicsConfig, + economicsConfig: args.EconomicsConfig, accountsParser: args.AccountsParser, smartContractParser: args.SmartContractParser, gasSchedule: args.GasSchedule, diff --git a/genesis/interface.go b/genesis/interface.go index 1a618a44efe..7b5a4960470 100644 --- a/genesis/interface.go +++ b/genesis/interface.go @@ -84,7 +84,7 @@ type InitialSmartContractHandler interface { } // InitialSmartContractParser contains the parsed genesis initial smart contracts -//json file and has some functionality regarding processed data +// json file and has some functionality regarding processed data type InitialSmartContractParser interface { InitialSmartContractsSplitOnOwnersShards(shardCoordinator sharding.Coordinator) (map[uint32][]InitialSmartContractHandler, error) GetDeployedSCAddresses(scType string) (map[string]struct{}, error) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index b1d41fbb60b..8464f56f542 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -3533,9 +3533,9 @@ func GetDefaultEnableEpochsConfig() *config.EnableEpochs { MiniBlockPartialExecutionEnableEpoch: UnreachableEpoch, FailExecutionOnEveryAPIErrorEnableEpoch: UnreachableEpoch, DynamicGasCostForDataTrieStorageLoadEnableEpoch: UnreachableEpoch, - StakingV4Step1EnableEpoch: UnreachableEpoch, - StakingV4Step2EnableEpoch: UnreachableEpoch, - StakingV4Step3EnableEpoch: UnreachableEpoch, + StakingV4Step1EnableEpoch: UnreachableEpoch, + StakingV4Step2EnableEpoch: UnreachableEpoch, + StakingV4Step3EnableEpoch: UnreachableEpoch, } } diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index 3dfa2efd7cd..bdcc1f26615 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -111,19 +111,19 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { argumentsBase.ForkDetector = tpn.ForkDetector argumentsBase.TxCoordinator = &mock.TransactionCoordinatorMock{} arguments := block.ArgMetaProcessor{ - ArgBaseProcessor: argumentsBase, - SCToProtocol: &mock.SCToProtocolStub{}, - PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, - EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, - EpochEconomics: &mock.EpochEconomicsStub{}, - EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, - EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, + ArgBaseProcessor: argumentsBase, + SCToProtocol: &mock.SCToProtocolStub{}, + PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, + EpochStartDataCreator: &mock.EpochStartDataCreatorStub{}, + EpochEconomics: &mock.EpochEconomicsStub{}, + EpochRewardsCreator: &testscommon.RewardsCreatorStub{}, + EpochValidatorInfoCreator: &testscommon.EpochValidatorInfoCreatorStub{}, ValidatorStatisticsProcessor: &testscommon.ValidatorStatisticsProcessorStub{ UpdatePeerStateCalled: func(header data.MetaHeaderHandler) ([]byte, error) { return []byte("validator stats root hash"), nil }, }, - EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, + EpochSystemSCProcessor: &testscommon.EpochStartSystemSCStub{}, } tpn.BlockProcessor, err = block.NewMetaProcessor(arguments) diff --git a/integrationTests/vm/esdt/common.go b/integrationTests/vm/esdt/common.go index 3287641d0e6..0a6b26ed7e5 100644 --- a/integrationTests/vm/esdt/common.go +++ b/integrationTests/vm/esdt/common.go @@ -338,7 +338,7 @@ func CheckForwarderRawSavedCallbackArgs( } } -/// ForwarderRawSavedPaymentInfo contains token data to be checked in the forwarder-raw contract. +// ForwarderRawSavedPaymentInfo contains token data to be checked in the forwarder-raw contract. type ForwarderRawSavedPaymentInfo struct { TokenId string Nonce uint64 diff --git a/integrationTests/vm/txsFee/scCalls_test.go b/integrationTests/vm/txsFee/scCalls_test.go index e4a742fd331..f247475e015 100644 --- a/integrationTests/vm/txsFee/scCalls_test.go +++ b/integrationTests/vm/txsFee/scCalls_test.go @@ -59,10 +59,10 @@ func prepareTestContextForEpoch836(tb testing.TB) (*vm.VMTestContext, []byte) { testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGasAndRoundConfig( config.EnableEpochs{ - GovernanceEnableEpoch: unreachableEpoch, + GovernanceEnableEpoch: unreachableEpoch, SetSenderInEeiOutputTransferEnableEpoch: unreachableEpoch, RefactorPeersMiniBlocksEnableEpoch: unreachableEpoch, - MaxBlockchainHookCountersEnableEpoch: unreachableEpoch,DynamicGasCostForDataTrieStorageLoadEnableEpoch: unreachableEpoch, + MaxBlockchainHookCountersEnableEpoch: unreachableEpoch, DynamicGasCostForDataTrieStorageLoadEnableEpoch: unreachableEpoch, }, mock.NewMultiShardsCoordinatorMock(2), db, diff --git a/node/nodeTesting.go b/node/nodeTesting.go index 29683432508..bcd15052e21 100644 --- a/node/nodeTesting.go +++ b/node/nodeTesting.go @@ -264,7 +264,7 @@ func (n *Node) generateAndSignTxBuffArray( return tx, signedMarshalizedTx, nil } -//GenerateTransaction generates a new transaction with sender, receiver, amount and code +// GenerateTransaction generates a new transaction with sender, receiver, amount and code func (n *Node) GenerateTransaction(senderHex string, receiverHex string, value *big.Int, transactionData string, privateKey crypto.PrivateKey, chainID []byte, minTxVersion uint32) (*transaction.Transaction, error) { if check.IfNil(n.coreComponents.AddressPubKeyConverter()) { return nil, ErrNilPubkeyConverter diff --git a/node/node_test.go b/node/node_test.go index 28e812d0587..2cde11d08a0 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -56,8 +56,8 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" factoryTests "github.com/multiversx/mx-chain-go/testscommon/factory" - "github.com/multiversx/mx-chain-go/testscommon/guardianMocks" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" + "github.com/multiversx/mx-chain-go/testscommon/guardianMocks" "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" diff --git a/process/block/postprocess/intermediateResults_test.go b/process/block/postprocess/intermediateResults_test.go index d659730575a..b9a0a8e8f83 100644 --- a/process/block/postprocess/intermediateResults_test.go +++ b/process/block/postprocess/intermediateResults_test.go @@ -35,15 +35,15 @@ func createMockPubkeyConverter() *testscommon.PubkeyConverterMock { func createMockArgsNewIntermediateResultsProcessor() ArgsNewIntermediateResultsProcessor { args := ArgsNewIntermediateResultsProcessor{ - Hasher: &hashingMocks.HasherMock{}, - Marshalizer: &mock.MarshalizerMock{}, - Coordinator: mock.NewMultiShardsCoordinatorMock(5), - PubkeyConv: createMockPubkeyConverter(), - Store: &storage.ChainStorerStub{}, - BlockType: block.SmartContractResultBlock, - CurrTxs: &mock.TxForCurrentBlockStub{}, - EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), + Hasher: &hashingMocks.HasherMock{}, + Marshalizer: &mock.MarshalizerMock{}, + Coordinator: mock.NewMultiShardsCoordinatorMock(5), + PubkeyConv: createMockPubkeyConverter(), + Store: &storage.ChainStorerStub{}, + BlockType: block.SmartContractResultBlock, + CurrTxs: &mock.TxForCurrentBlockStub{}, + EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), TxExecutionOrderHandler: &txExecOrderStub.TxExecutionOrderHandlerStub{}, } diff --git a/process/block/preprocess/transactionsV2_test.go b/process/block/preprocess/transactionsV2_test.go index 50203a1a5ae..9d4fb1cf686 100644 --- a/process/block/preprocess/transactionsV2_test.go +++ b/process/block/preprocess/transactionsV2_test.go @@ -15,9 +15,9 @@ import ( "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/storage/txcache" "github.com/multiversx/mx-chain-go/testscommon" + commonMocks "github.com/multiversx/mx-chain-go/testscommon/common" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" - commonMocks "github.com/multiversx/mx-chain-go/testscommon/common" "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" diff --git a/process/coordinator/process_test.go b/process/coordinator/process_test.go index 0508620283e..e23c8f8f1ec 100644 --- a/process/coordinator/process_test.go +++ b/process/coordinator/process_test.go @@ -566,14 +566,14 @@ func createPreProcessorContainer() process.PreProcessorsContainer { func createInterimProcessorContainer() process.IntermediateProcessorContainer { argsFactory := shard.ArgsNewIntermediateProcessorsContainerFactory{ - ShardCoordinator: mock.NewMultiShardsCoordinatorMock(5), - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - PubkeyConverter: createMockPubkeyConverter(), - Store: initStore(), - PoolsHolder: initDataPool([]byte("test_hash1")), - EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), + ShardCoordinator: mock.NewMultiShardsCoordinatorMock(5), + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + PubkeyConverter: createMockPubkeyConverter(), + Store: initStore(), + PoolsHolder: initDataPool([]byte("test_hash1")), + EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), TxExecutionOrderHandler: &commonMock.TxExecutionOrderHandlerStub{}, } preFactory, _ := shard.NewIntermediateProcessorsContainerFactory(argsFactory) @@ -2210,14 +2210,14 @@ func TestTransactionCoordinator_VerifyCreatedBlockTransactionsNilOrMiss(t *testi tdp := initDataPool(txHash) shardCoordinator := mock.NewMultiShardsCoordinatorMock(5) argsFactory := shard.ArgsNewIntermediateProcessorsContainerFactory{ - ShardCoordinator: shardCoordinator, - Marshalizer: &mock.MarshalizerMock{}, - Hasher: &hashingMocks.HasherMock{}, - PubkeyConverter: createMockPubkeyConverter(), - Store: &storageStubs.ChainStorerStub{}, - PoolsHolder: tdp, - EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), + ShardCoordinator: shardCoordinator, + Marshalizer: &mock.MarshalizerMock{}, + Hasher: &hashingMocks.HasherMock{}, + PubkeyConverter: createMockPubkeyConverter(), + Store: &storageStubs.ChainStorerStub{}, + PoolsHolder: tdp, + EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), TxExecutionOrderHandler: &commonMock.TxExecutionOrderHandlerStub{}, } preFactory, _ := shard.NewIntermediateProcessorsContainerFactory(argsFactory) @@ -2278,7 +2278,7 @@ func TestTransactionCoordinator_VerifyCreatedBlockTransactionsOk(t *testing.T) { return MaxGasLimitPerBlock }, }, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), TxExecutionOrderHandler: &commonMock.TxExecutionOrderHandlerStub{}, } interFactory, _ := shard.NewIntermediateProcessorsContainerFactory(argsFactory) diff --git a/process/factory/metachain/intermediateProcessorsContainerFactory_test.go b/process/factory/metachain/intermediateProcessorsContainerFactory_test.go index 79861ced4bd..f58b8e41f72 100644 --- a/process/factory/metachain/intermediateProcessorsContainerFactory_test.go +++ b/process/factory/metachain/intermediateProcessorsContainerFactory_test.go @@ -23,14 +23,14 @@ func createMockPubkeyConverter() *testscommon.PubkeyConverterMock { func createMockArgsNewIntermediateProcessorsFactory() metachain.ArgsNewIntermediateProcessorsContainerFactory { args := metachain.ArgsNewIntermediateProcessorsContainerFactory{ - Hasher: &hashingMocks.HasherMock{}, - Marshalizer: &mock.MarshalizerMock{}, - ShardCoordinator: mock.NewMultiShardsCoordinatorMock(5), - PubkeyConverter: createMockPubkeyConverter(), - Store: &storageStubs.ChainStorerStub{}, - PoolsHolder: dataRetrieverMock.NewPoolsHolderMock(), - EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), + Hasher: &hashingMocks.HasherMock{}, + Marshalizer: &mock.MarshalizerMock{}, + ShardCoordinator: mock.NewMultiShardsCoordinatorMock(5), + PubkeyConverter: createMockPubkeyConverter(), + Store: &storageStubs.ChainStorerStub{}, + PoolsHolder: dataRetrieverMock.NewPoolsHolderMock(), + EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), TxExecutionOrderHandler: &txExecOrderStub.TxExecutionOrderHandlerStub{}, } return args diff --git a/process/factory/shard/intermediateProcessorsContainerFactory_test.go b/process/factory/shard/intermediateProcessorsContainerFactory_test.go index 2f2cc7a9c52..5835a7361ac 100644 --- a/process/factory/shard/intermediateProcessorsContainerFactory_test.go +++ b/process/factory/shard/intermediateProcessorsContainerFactory_test.go @@ -57,14 +57,14 @@ func createMockPubkeyConverter() *testscommon.PubkeyConverterMock { func createMockArgsNewIntermediateProcessorsFactory() shard.ArgsNewIntermediateProcessorsContainerFactory { args := shard.ArgsNewIntermediateProcessorsContainerFactory{ - Hasher: &hashingMocks.HasherMock{}, - Marshalizer: &mock.MarshalizerMock{}, - ShardCoordinator: mock.NewMultiShardsCoordinatorMock(5), - PubkeyConverter: createMockPubkeyConverter(), - Store: &storageStubs.ChainStorerStub{}, - PoolsHolder: createDataPools(), - EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, - EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), + Hasher: &hashingMocks.HasherMock{}, + Marshalizer: &mock.MarshalizerMock{}, + ShardCoordinator: mock.NewMultiShardsCoordinatorMock(5), + PubkeyConverter: createMockPubkeyConverter(), + Store: &storageStubs.ChainStorerStub{}, + PoolsHolder: createDataPools(), + EconomicsFee: &economicsmocks.EconomicsHandlerStub{}, + EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.KeepExecOrderOnCreatedSCRsFlag), TxExecutionOrderHandler: &txExecOrderStub.TxExecutionOrderHandlerStub{}, } return args diff --git a/process/headerCheck/headerSignatureVerify.go b/process/headerCheck/headerSignatureVerify.go index 999bc82e881..d86ac0523c1 100644 --- a/process/headerCheck/headerSignatureVerify.go +++ b/process/headerCheck/headerSignatureVerify.go @@ -30,7 +30,7 @@ type ArgsHeaderSigVerifier struct { FallbackHeaderValidator process.FallbackHeaderValidator } -//HeaderSigVerifier is component used to check if a header is valid +// HeaderSigVerifier is component used to check if a header is valid type HeaderSigVerifier struct { marshalizer marshal.Marshalizer hasher hashing.Hasher diff --git a/process/peer/ratingReader.go b/process/peer/ratingReader.go index 4a8c8f1c5be..83f236b3869 100644 --- a/process/peer/ratingReader.go +++ b/process/peer/ratingReader.go @@ -5,13 +5,13 @@ type RatingReader struct { getRating func(string) uint32 } -//GetRating returns the Rating for the specified public key +// GetRating returns the Rating for the specified public key func (bsr *RatingReader) GetRating(pk string) uint32 { rating := bsr.getRating(pk) return rating } -//IsInterfaceNil checks if the underlying object is nil +// IsInterfaceNil checks if the underlying object is nil func (bsr *RatingReader) IsInterfaceNil() bool { return bsr == nil } diff --git a/process/rating/chance.go b/process/rating/chance.go index 8ad3c092cec..71233ba3d3e 100644 --- a/process/rating/chance.go +++ b/process/rating/chance.go @@ -9,17 +9,17 @@ type selectionChance struct { chancePercentage uint32 } -//GetMaxThreshold returns the maxThreshold until this ChancePercentage holds +// GetMaxThreshold returns the maxThreshold until this ChancePercentage holds func (bsr *selectionChance) GetMaxThreshold() uint32 { return bsr.maxThreshold } -//GetChancePercentage returns the percentage for the RatingChance +// GetChancePercentage returns the percentage for the RatingChance func (bsr *selectionChance) GetChancePercentage() uint32 { return bsr.chancePercentage } -//IsInterfaceNil verifies if the interface is nil +// IsInterfaceNil verifies if the interface is nil func (bsr *selectionChance) IsInterfaceNil() bool { return bsr == nil } diff --git a/process/rating/disabledRatingReader.go b/process/rating/disabledRatingReader.go index 8b7ac6662c1..b57f06b2dca 100644 --- a/process/rating/disabledRatingReader.go +++ b/process/rating/disabledRatingReader.go @@ -10,17 +10,17 @@ func NewDisabledRatingReader(startRating uint32) *disabledRatingReader { return &disabledRatingReader{startRating: startRating} } -//GetRating gets the rating for the public key +// GetRating gets the rating for the public key func (rr *disabledRatingReader) GetRating(string) uint32 { return rr.startRating } -//UpdateRatingFromTempRating sets the new rating to the value of the tempRating +// UpdateRatingFromTempRating sets the new rating to the value of the tempRating func (rr *disabledRatingReader) UpdateRatingFromTempRating([]string) error { return nil } -//IsInterfaceNil verifies if the interface is nil +// IsInterfaceNil verifies if the interface is nil func (rr *disabledRatingReader) IsInterfaceNil() bool { return rr == nil } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater.go index c9e4779e73f..689fe95d341 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater.go @@ -76,7 +76,7 @@ func (ihnc *indexHashedNodesCoordinatorWithRater) ComputeAdditionalLeaving(allVa return extraLeavingNodesMap, nil } -//IsInterfaceNil verifies that the underlying value is nil +// IsInterfaceNil verifies that the underlying value is nil func (ihnc *indexHashedNodesCoordinatorWithRater) IsInterfaceNil() bool { return ihnc == nil } diff --git a/testscommon/state/accountAdapterStub.go b/testscommon/state/accountAdapterStub.go index 433722f7e21..fa9305f8222 100644 --- a/testscommon/state/accountAdapterStub.go +++ b/testscommon/state/accountAdapterStub.go @@ -177,14 +177,14 @@ func (aas *StateUserAccountHandlerStub) ClaimDeveloperRewards(senderAddr []byte) return nil, nil } -//AddToDeveloperReward - +// AddToDeveloperReward - func (aas *StateUserAccountHandlerStub) AddToDeveloperReward(val *big.Int) { if aas.AddToDeveloperRewardCalled != nil { aas.AddToDeveloperRewardCalled(val) } } -//GetDeveloperReward - +// GetDeveloperReward - func (aas *StateUserAccountHandlerStub) GetDeveloperReward() *big.Int { if aas.GetDeveloperRewardCalled != nil { return aas.GetDeveloperRewardCalled() @@ -230,7 +230,7 @@ func (aas *StateUserAccountHandlerStub) GetUserName() []byte { return nil } -//IsGuarded - +// IsGuarded - func (aas *StateUserAccountHandlerStub) IsGuarded() bool { if aas.IsGuardedCalled != nil { return aas.IsGuardedCalled() diff --git a/testscommon/state/accountWrapperMock.go b/testscommon/state/accountWrapperMock.go index 9cbac29d8ce..8f5e794646a 100644 --- a/testscommon/state/accountWrapperMock.go +++ b/testscommon/state/accountWrapperMock.go @@ -205,7 +205,7 @@ func (awm *AccountWrapMock) SetDataTrie(trie common.Trie) { awm.trackableDataTrie.SetDataTrie(trie) } -//IncreaseNonce adds the given value to the current nonce +// IncreaseNonce adds the given value to the current nonce func (awm *AccountWrapMock) IncreaseNonce(val uint64) { awm.nonce = awm.nonce + val } diff --git a/testscommon/storageManager/storageManagerStub.go b/testscommon/storageManager/storageManagerStub.go index b14d6c460a6..60e10541da6 100644 --- a/testscommon/storageManager/storageManagerStub.go +++ b/testscommon/storageManager/storageManagerStub.go @@ -7,30 +7,30 @@ import ( // StorageManagerStub - type StorageManagerStub struct { - PutCalled func([]byte, []byte) error - PutInEpochCalled func([]byte, []byte, uint32) error - PutInEpochWithoutCacheCalled func([]byte, []byte, uint32) error - GetCalled func([]byte) ([]byte, error) - GetFromCurrentEpochCalled func([]byte) ([]byte, error) - TakeSnapshotCalled func(string, []byte, []byte, *common.TrieIteratorChannels, chan []byte, common.SnapshotStatisticsHandler, uint32) - GetDbThatContainsHashCalled func([]byte) common.BaseStorer - IsPruningEnabledCalled func() bool - IsPruningBlockedCalled func() bool - EnterPruningBufferingModeCalled func() - ExitPruningBufferingModeCalled func() - RemoveFromCurrentEpochCalled func([]byte) error - RemoveCalled func([]byte) error - IsInterfaceNilCalled func() bool - SetEpochForPutOperationCalled func(uint32) - ShouldTakeSnapshotCalled func() bool - GetLatestStorageEpochCalled func() (uint32, error) - IsClosedCalled func() bool - GetBaseTrieStorageManagerCalled func() common.StorageManager - GetIdentifierCalled func() string - CloseCalled func() error - RemoveFromAllActiveEpochsCalled func(hash []byte) error - IsSnapshotSupportedCalled func() bool - GetStateStatsHandlerCalled func() common.StateStatisticsHandler + PutCalled func([]byte, []byte) error + PutInEpochCalled func([]byte, []byte, uint32) error + PutInEpochWithoutCacheCalled func([]byte, []byte, uint32) error + GetCalled func([]byte) ([]byte, error) + GetFromCurrentEpochCalled func([]byte) ([]byte, error) + TakeSnapshotCalled func(string, []byte, []byte, *common.TrieIteratorChannels, chan []byte, common.SnapshotStatisticsHandler, uint32) + GetDbThatContainsHashCalled func([]byte) common.BaseStorer + IsPruningEnabledCalled func() bool + IsPruningBlockedCalled func() bool + EnterPruningBufferingModeCalled func() + ExitPruningBufferingModeCalled func() + RemoveFromCurrentEpochCalled func([]byte) error + RemoveCalled func([]byte) error + IsInterfaceNilCalled func() bool + SetEpochForPutOperationCalled func(uint32) + ShouldTakeSnapshotCalled func() bool + GetLatestStorageEpochCalled func() (uint32, error) + IsClosedCalled func() bool + GetBaseTrieStorageManagerCalled func() common.StorageManager + GetIdentifierCalled func() string + CloseCalled func() error + RemoveFromAllActiveEpochsCalled func(hash []byte) error + IsSnapshotSupportedCalled func() bool + GetStateStatsHandlerCalled func() common.StateStatisticsHandler } // Put - diff --git a/testscommon/txDataBuilder/builder.go b/testscommon/txDataBuilder/builder.go index c44c41f9013..3198792ac57 100644 --- a/testscommon/txDataBuilder/builder.go +++ b/testscommon/txDataBuilder/builder.go @@ -177,7 +177,7 @@ func (builder *TxDataBuilder) TransferESDT(token string, value int64) *TxDataBui return builder.Func(core.BuiltInFunctionESDTTransfer).Str(token).Int64(value) } -//TransferESDTNFT appends to the data string all the elements required to request an ESDT NFT transfer. +// TransferESDTNFT appends to the data string all the elements required to request an ESDT NFT transfer. func (builder *TxDataBuilder) TransferESDTNFT(token string, nonce int, value int64) *TxDataBuilder { return builder.Func(core.BuiltInFunctionESDTNFTTransfer).Str(token).Int(nonce).Int64(value) } diff --git a/testscommon/vmcommonMocks/userAccountStub.go b/testscommon/vmcommonMocks/userAccountStub.go index 6fb0b1f4d85..8f1eabf8a7f 100644 --- a/testscommon/vmcommonMocks/userAccountStub.go +++ b/testscommon/vmcommonMocks/userAccountStub.go @@ -159,7 +159,7 @@ func (uas *UserAccountStub) GetNonce() uint64 { return 0 } -//IsInterfaceNil - +// IsInterfaceNil - func (uas *UserAccountStub) IsInterfaceNil() bool { return uas == nil } diff --git a/update/genesis/export.go b/update/genesis/export.go index e1d7f206c47..ba4e678a0f8 100644 --- a/update/genesis/export.go +++ b/update/genesis/export.go @@ -449,19 +449,19 @@ func (se *stateExport) exportNodesSetupJson(validators state.ShardValidatorsInfo for _, validator := range validators.GetAllValidatorsInfo() { if shouldExportValidator(validator, acceptedListsForExport) { - pubKey, err := se.validatorPubKeyConverter.Encode(validator.GetPublicKey()) - if err != nil { - return nil - } - - rewardAddress, err := se.addressPubKeyConverter.Encode(validator.GetRewardAddress()) - if err != nil { - return nil - } - - initialNodes = append(initialNodes, &sharding.InitialNode{ - PubKey: pubKey, - Address: rewardAddress, + pubKey, err := se.validatorPubKeyConverter.Encode(validator.GetPublicKey()) + if err != nil { + return nil + } + + rewardAddress, err := se.addressPubKeyConverter.Encode(validator.GetRewardAddress()) + if err != nil { + return nil + } + + initialNodes = append(initialNodes, &sharding.InitialNode{ + PubKey: pubKey, + Address: rewardAddress, InitialRating: validator.GetRating(), }) } From 7f4d0a0832877a9c6f1d1fd6b5a704892cb4a2fa Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 8 Jan 2024 16:01:42 +0200 Subject: [PATCH 579/958] FIX: After merge in stakingV4 20 with go proto generate --- state/accounts/peerAccountData.pb.go | 121 ++++++++++++--------------- 1 file changed, 53 insertions(+), 68 deletions(-) diff --git a/state/accounts/peerAccountData.pb.go b/state/accounts/peerAccountData.pb.go index 4fa4115b6ff..eb0a6ef69d9 100644 --- a/state/accounts/peerAccountData.pb.go +++ b/state/accounts/peerAccountData.pb.go @@ -276,74 +276,59 @@ func init() { func init() { proto.RegisterFile("peerAccountData.proto", fileDescriptor_26bd0314afcce126) } var fileDescriptor_26bd0314afcce126 = []byte{ - // 1063 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0xdb, 0x46, - 0x17, 0x15, 0x13, 0xcb, 0x3f, 0x63, 0xc9, 0xb2, 0xc7, 0x76, 0x22, 0xf9, 0x8b, 0x39, 0x8e, 0x82, - 0x2f, 0xf5, 0xa2, 0xb6, 0xd1, 0x1f, 0xa0, 0x40, 0x0b, 0xb4, 0x35, 0xd3, 0xa4, 0x50, 0xeb, 0xb8, - 0xc6, 0x28, 0x2d, 0x82, 0x16, 0x28, 0x30, 0x22, 0xc7, 0x34, 0x1b, 0x8a, 0x14, 0x86, 0x43, 0xd5, - 0xde, 0xf5, 0x11, 0xf2, 0x04, 0x5d, 0x17, 0x7d, 0x92, 0x2c, 0xbd, 0xf4, 0x6a, 0x5a, 0xcb, 0x8b, - 0x16, 0xb3, 0xca, 0x23, 0x14, 0x1c, 0x91, 0x36, 0x29, 0x92, 0x72, 0x56, 0x16, 0xef, 0x39, 0xf7, - 0xcc, 0x9d, 0xb9, 0x77, 0xce, 0x18, 0xac, 0x0f, 0x28, 0x65, 0xfb, 0xa6, 0xe9, 0x87, 0x1e, 0xff, - 0x8a, 0x70, 0xb2, 0x3b, 0x60, 0x3e, 0xf7, 0x61, 0x55, 0xfd, 0xd9, 0xd8, 0xb1, 0x1d, 0x7e, 0x12, - 0xf6, 0x76, 0x4d, 0xbf, 0xbf, 0x67, 0xfb, 0xb6, 0xbf, 0xa7, 0xc2, 0xbd, 0xf0, 0x58, 0x7d, 0xa9, - 0x0f, 0xf5, 0x6b, 0x9c, 0xd5, 0xfe, 0x06, 0xcc, 0x77, 0x1d, 0xdb, 0xc3, 0x84, 0x53, 0xa8, 0x03, - 0x70, 0x18, 0xf6, 0xbb, 0xa1, 0x69, 0xd2, 0x20, 0x68, 0x6a, 0x5b, 0xda, 0x76, 0x1d, 0xa7, 0x22, - 0x31, 0xfe, 0x8c, 0x38, 0x6e, 0xc8, 0x68, 0xf3, 0xce, 0x35, 0x1e, 0x47, 0xda, 0xff, 0xcc, 0x83, - 0xb5, 0x1f, 0x88, 0xeb, 0x58, 0x84, 0xfb, 0x6c, 0x7f, 0xe0, 0x60, 0x1a, 0x0c, 0x7c, 0x2f, 0xa0, - 0x70, 0x17, 0x80, 0x17, 0xb4, 0x3f, 0xc0, 0x84, 0x3b, 0x9e, 0xad, 0x84, 0xef, 0x18, 0x4b, 0x52, - 0x20, 0xc0, 0xaf, 0xa3, 0x38, 0xc5, 0x80, 0x5f, 0x82, 0xe5, 0xc3, 0xb0, 0x7f, 0x40, 0x89, 0x45, - 0x59, 0x52, 0x8e, 0x5a, 0xce, 0x58, 0x93, 0x02, 0x2d, 0x7b, 0x13, 0x18, 0xce, 0xb1, 0x33, 0x0a, - 0x49, 0xc1, 0x77, 0x0b, 0x14, 0x62, 0x0c, 0xe7, 0xd8, 0xb0, 0x03, 0x56, 0x0f, 0xc3, 0xfe, 0xf5, - 0x76, 0x92, 0x32, 0x66, 0x94, 0xc8, 0x7d, 0x29, 0xd0, 0xaa, 0x97, 0x87, 0x71, 0x51, 0xce, 0xa4, - 0x54, 0x52, 0x4f, 0xb5, 0x58, 0x2a, 0x29, 0xa9, 0x28, 0x07, 0xda, 0x60, 0x33, 0x1d, 0xee, 0xd8, - 0x9e, 0xcf, 0xa8, 0x15, 0x75, 0x90, 0xf0, 0x90, 0xd1, 0xa0, 0x39, 0xab, 0x44, 0x1f, 0x4a, 0x81, - 0x36, 0xbd, 0x69, 0x44, 0x3c, 0x5d, 0x07, 0xb6, 0xc1, 0x6c, 0xdc, 0xae, 0x39, 0xd5, 0x2e, 0x20, - 0x05, 0x9a, 0x65, 0xe3, 0x56, 0xc5, 0x08, 0xfc, 0x14, 0x2c, 0x8d, 0x7f, 0x3d, 0xf7, 0x2d, 0xe7, - 0xd8, 0xa1, 0xac, 0x39, 0xaf, 0xb8, 0x50, 0x0a, 0xb4, 0xc4, 0x32, 0x08, 0x9e, 0x60, 0xc2, 0xef, - 0xc0, 0xfa, 0x0b, 0x9f, 0x13, 0x37, 0xd7, 0xe7, 0x05, 0xb5, 0x81, 0x96, 0x14, 0x68, 0x9d, 0x17, - 0x11, 0x70, 0x71, 0x5e, 0x5e, 0x30, 0x39, 0x66, 0x50, 0x26, 0x98, 0x1c, 0x74, 0x71, 0x1e, 0x7c, - 0x09, 0x9a, 0x09, 0x90, 0x9b, 0x82, 0x45, 0xa5, 0xf9, 0x40, 0x0a, 0xd4, 0xe4, 0x25, 0x1c, 0x5c, - 0x9a, 0x5d, 0xa8, 0x9c, 0x54, 0x5b, 0x9b, 0xa2, 0x9c, 0x14, 0x5c, 0x9a, 0x0d, 0x87, 0xa0, 0x9d, - 0xc3, 0xf2, 0x33, 0x52, 0x57, 0x6b, 0x3c, 0x96, 0x02, 0xb5, 0xf9, 0xad, 0x6c, 0xfc, 0x0e, 0x8a, - 0xf0, 0xff, 0x60, 0xae, 0x7b, 0x42, 0x98, 0xd5, 0xb1, 0x9a, 0x4b, 0x4a, 0x7c, 0x51, 0x0a, 0x34, - 0x17, 0x8c, 0x43, 0x38, 0xc1, 0xe0, 0xd7, 0xa0, 0x71, 0x73, 0x18, 0x9c, 0xf0, 0x30, 0x68, 0x36, - 0xb6, 0xb4, 0xed, 0x05, 0x63, 0x53, 0x0a, 0xd4, 0x1a, 0x66, 0xa1, 0xf7, 0xfd, 0xbe, 0x13, 0xf9, - 0x03, 0x3f, 0xc3, 0x93, 0x59, 0xed, 0xdf, 0x6b, 0xa0, 0x71, 0x94, 0x75, 0x41, 0xf8, 0x31, 0xa8, - 0x19, 0x07, 0xdd, 0xa3, 0xb0, 0xe7, 0x3a, 0xe6, 0xb7, 0xf4, 0x4c, 0xd9, 0x4c, 0xcd, 0x58, 0x96, - 0x02, 0xd5, 0x7a, 0x6e, 0x70, 0x1d, 0xc7, 0x19, 0x16, 0xdc, 0x07, 0x75, 0x4c, 0x7f, 0x25, 0xcc, - 0xda, 0xb7, 0x2c, 0x96, 0xf8, 0x4c, 0xcd, 0xf8, 0x9f, 0x14, 0xe8, 0x3e, 0x4b, 0x03, 0xa9, 0x72, - 0xb2, 0x19, 0xe9, 0xcd, 0xdf, 0x9d, 0xb2, 0x79, 0x92, 0x32, 0xc7, 0x64, 0x46, 0x08, 0xa7, 0xca, - 0x51, 0x16, 0x3f, 0x6c, 0x8c, 0xfd, 0x78, 0x37, 0x31, 0x63, 0xe3, 0xc1, 0x1b, 0x81, 0x2a, 0x52, - 0xa0, 0xb5, 0x61, 0x41, 0x12, 0x2e, 0x94, 0x82, 0x2f, 0xc1, 0x4a, 0xf6, 0xae, 0x44, 0xfa, 0xd5, - 0x62, 0xfd, 0x56, 0xac, 0xbf, 0xe2, 0x4e, 0x66, 0xe0, 0xbc, 0x08, 0xfc, 0x05, 0xe8, 0x53, 0x46, - 0x24, 0x5a, 0x66, 0x6c, 0x3c, 0x6d, 0x29, 0x90, 0x3e, 0x9c, 0xca, 0xc4, 0xb7, 0x28, 0x4d, 0x58, - 0x4f, 0xbd, 0xd0, 0x7a, 0xb2, 0x2f, 0xca, 0xbc, 0xe2, 0x4d, 0x7b, 0x51, 0x5e, 0x6b, 0xa0, 0xb1, - 0x6f, 0x9a, 0x61, 0x3f, 0x74, 0x09, 0xa7, 0xd6, 0x33, 0x4a, 0xc7, 0x4e, 0x53, 0x33, 0x8e, 0xa3, - 0xd1, 0x23, 0x59, 0xe8, 0xa6, 0xd7, 0x7f, 0xfe, 0x85, 0x9e, 0xf6, 0x09, 0x3f, 0xd9, 0xeb, 0x39, - 0xf6, 0x6e, 0xc7, 0xe3, 0x9f, 0xa5, 0x5e, 0xd7, 0x7e, 0xe8, 0x72, 0x67, 0x48, 0x59, 0x70, 0xba, - 0xd7, 0x3f, 0xdd, 0x31, 0x4f, 0x88, 0xe3, 0xed, 0x98, 0x3e, 0xa3, 0x3b, 0xb6, 0xbf, 0x67, 0x45, - 0xef, 0xb2, 0xe1, 0xd8, 0x1d, 0x8f, 0x3f, 0x21, 0x01, 0xa7, 0x0c, 0x4f, 0x2e, 0x0f, 0x7f, 0x06, - 0x1b, 0xd1, 0xdb, 0x4a, 0x5d, 0x6a, 0x72, 0x6a, 0x75, 0xbc, 0xf8, 0xb8, 0x0d, 0xd7, 0x37, 0x5f, - 0x05, 0xb1, 0x6b, 0xe9, 0x52, 0xa0, 0x0d, 0xaf, 0x94, 0x85, 0xa7, 0x28, 0xc0, 0x0f, 0xc0, 0x62, - 0xc7, 0xb3, 0xe8, 0x69, 0xc7, 0x3b, 0x70, 0x02, 0x1e, 0x5b, 0x56, 0x43, 0x0a, 0xb4, 0xe8, 0xdc, - 0x84, 0x71, 0x9a, 0x03, 0x1f, 0x83, 0x19, 0xc5, 0xad, 0xa9, 0x4b, 0xa9, 0x6c, 0xdc, 0x75, 0x02, - 0x9e, 0x1a, 0x7d, 0x85, 0xc3, 0x9f, 0x40, 0xeb, 0x49, 0xf4, 0xb0, 0x9b, 0x61, 0x74, 0x00, 0x47, - 0xcc, 0x1f, 0xf8, 0x01, 0x65, 0xcf, 0x9d, 0x20, 0xb8, 0x76, 0x17, 0x75, 0xa3, 0xcd, 0x32, 0x12, - 0x2e, 0xcf, 0x87, 0x03, 0xd0, 0x52, 0x8e, 0x53, 0x78, 0x59, 0x96, 0x8a, 0x87, 0xf9, 0x61, 0x3c, - 0xcc, 0x2d, 0x5e, 0x96, 0x89, 0xcb, 0x45, 0xa1, 0x0d, 0xee, 0x29, 0x30, 0x7f, 0x77, 0x1a, 0xc5, - 0xcb, 0xe9, 0xf1, 0x72, 0xf7, 0x78, 0x61, 0x1a, 0x2e, 0x91, 0x83, 0x67, 0xe0, 0x51, 0xb6, 0x8a, - 0xe2, 0xab, 0xb4, 0xac, 0x4e, 0xf0, 0x3d, 0x29, 0xd0, 0x23, 0x7e, 0x3b, 0x1d, 0xbf, 0x8b, 0x26, - 0x44, 0xa0, 0x7a, 0xe8, 0x7b, 0x26, 0x6d, 0xae, 0x6c, 0x69, 0xdb, 0x33, 0xc6, 0x82, 0x14, 0xa8, - 0xea, 0x45, 0x01, 0x3c, 0x8e, 0xc3, 0x4f, 0x40, 0xfd, 0x7b, 0xaf, 0xcb, 0xc9, 0x2b, 0x6a, 0x3d, - 0x1d, 0xf8, 0xe6, 0x49, 0x13, 0xaa, 0x2a, 0x56, 0xa4, 0x40, 0xf5, 0x30, 0x0d, 0xe0, 0x2c, 0x0f, - 0x7e, 0x0e, 0x6a, 0x47, 0x8c, 0x0e, 0x1d, 0x3f, 0x0c, 0xd4, 0xf0, 0xac, 0xaa, 0xe1, 0xd9, 0x88, - 0x8e, 0x67, 0x90, 0x8a, 0xa7, 0x86, 0x28, 0xc3, 0x87, 0x5d, 0xb0, 0x9a, 0x7c, 0xa7, 0xe7, 0x75, - 0xed, 0xe6, 0x1f, 0x99, 0x41, 0x1e, 0x4e, 0xa9, 0x15, 0x65, 0x1b, 0x5f, 0x9c, 0x5f, 0xea, 0x95, - 0x8b, 0x4b, 0xbd, 0xf2, 0xf6, 0x52, 0xd7, 0x7e, 0x1b, 0xe9, 0xda, 0x1f, 0x23, 0x5d, 0x7b, 0x33, - 0xd2, 0xb5, 0xf3, 0x91, 0xae, 0x5d, 0x8c, 0x74, 0xed, 0xef, 0x91, 0xae, 0xfd, 0x3b, 0xd2, 0x2b, - 0x6f, 0x47, 0xba, 0xf6, 0xfa, 0x4a, 0xaf, 0x9c, 0x5f, 0xe9, 0x95, 0x8b, 0x2b, 0xbd, 0xf2, 0x63, - 0x35, 0xe0, 0x84, 0xd3, 0xde, 0xac, 0x6a, 0xf9, 0x47, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xdd, - 0x14, 0xe4, 0x72, 0x6d, 0x0b, 0x00, 0x00, + // 822 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4f, 0x6f, 0xdb, 0x36, + 0x1c, 0xb5, 0xba, 0xfc, 0xa5, 0xed, 0xb8, 0x61, 0xb3, 0x4e, 0xce, 0x56, 0x32, 0x4d, 0xb1, 0x2d, + 0x87, 0xc5, 0xc6, 0xfe, 0x00, 0x3b, 0x0c, 0x18, 0x10, 0x75, 0x2d, 0xe0, 0x2d, 0x2b, 0x02, 0xba, + 0x1b, 0x86, 0x0d, 0x18, 0x40, 0x4b, 0xac, 0xcc, 0x55, 0x12, 0x05, 0x92, 0xca, 0x92, 0xdb, 0x3e, + 0x42, 0x3f, 0xc1, 0xce, 0xc3, 0x3e, 0x49, 0x8f, 0x39, 0xe6, 0xc4, 0x2d, 0xce, 0x65, 0xd0, 0xa9, + 0x1f, 0x61, 0x10, 0xad, 0xb8, 0x72, 0x23, 0xb7, 0x3d, 0xd9, 0x7c, 0xef, 0xfd, 0xde, 0x8f, 0xfc, + 0xf1, 0x11, 0x02, 0xef, 0xa6, 0x8c, 0xc9, 0x03, 0xdf, 0x17, 0x59, 0xa2, 0xbf, 0xa1, 0x9a, 0xf6, + 0x52, 0x29, 0xb4, 0x80, 0xcb, 0xf6, 0x67, 0x7b, 0x3f, 0xe4, 0x7a, 0x9c, 0x8d, 0x7a, 0xbe, 0x88, + 0xfb, 0xa1, 0x08, 0x45, 0xdf, 0xc2, 0xa3, 0xec, 0x89, 0x5d, 0xd9, 0x85, 0xfd, 0x37, 0xad, 0xda, + 0xfd, 0x16, 0xac, 0x0d, 0x79, 0x98, 0x10, 0xaa, 0x19, 0x44, 0x00, 0x3c, 0xca, 0xe2, 0x61, 0xe6, + 0xfb, 0x4c, 0x29, 0xd7, 0xd9, 0x71, 0xf6, 0xda, 0xa4, 0x82, 0x94, 0xfc, 0x43, 0xca, 0xa3, 0x4c, + 0x32, 0xf7, 0xc6, 0x8c, 0x2f, 0x91, 0xdd, 0x3f, 0x5b, 0xa0, 0x73, 0x34, 0xbf, 0x37, 0xf8, 0x05, + 0x68, 0x79, 0x87, 0xc3, 0xa3, 0x6c, 0x14, 0x71, 0xff, 0x3b, 0x76, 0x6a, 0x5d, 0x5b, 0xde, 0xcd, + 0xdc, 0xe0, 0xd6, 0x28, 0x52, 0x33, 0x9c, 0xcc, 0xa9, 0xe0, 0x01, 0x68, 0x13, 0xf6, 0x3b, 0x95, + 0xc1, 0x41, 0x10, 0xc8, 0x62, 0x33, 0x37, 0x6c, 0xd9, 0xfb, 0xb9, 0xc1, 0xef, 0xc9, 0x2a, 0xf1, + 0x89, 0x88, 0xb9, 0x66, 0x71, 0xaa, 0x4f, 0xc9, 0x7c, 0x05, 0xfc, 0x10, 0xac, 0x0e, 0xc7, 0x54, + 0x06, 0x83, 0xc0, 0x7d, 0xa7, 0xd8, 0xa9, 0xd7, 0xcc, 0x0d, 0x5e, 0x55, 0x53, 0x88, 0x5c, 0x71, + 0x90, 0x82, 0xad, 0x1f, 0x69, 0xc4, 0x03, 0xaa, 0x85, 0x2c, 0xcf, 0x59, 0xcc, 0xc2, 0x5d, 0xda, + 0x71, 0xf6, 0x9a, 0x9f, 0x75, 0xa6, 0x53, 0xea, 0x5d, 0x8d, 0xc8, 0xfb, 0xe0, 0xb9, 0xc1, 0x8d, + 0xdc, 0xe0, 0xad, 0xe3, 0x9a, 0x22, 0x52, 0x6b, 0x05, 0x7f, 0x02, 0x9b, 0x87, 0x8c, 0x06, 0x6c, + 0xce, 0x7f, 0xb9, 0xde, 0xbf, 0x5b, 0xfa, 0x6f, 0x46, 0xaf, 0x56, 0x90, 0xeb, 0x26, 0xf0, 0x37, + 0x80, 0x66, 0x1d, 0x07, 0x61, 0x22, 0x24, 0x0b, 0x0a, 0x27, 0xaa, 0x33, 0xc9, 0xa6, 0x6d, 0x56, + 0xec, 0xd1, 0x77, 0x73, 0x83, 0xd1, 0xf1, 0x6b, 0x95, 0xe4, 0x0d, 0x4e, 0x70, 0x17, 0xac, 0x10, + 0xaa, 0x79, 0x12, 0xba, 0xab, 0xd6, 0x13, 0xe4, 0x06, 0xaf, 0x48, 0x8b, 0x90, 0x92, 0x81, 0x3d, + 0x00, 0x1e, 0xb3, 0x38, 0x2d, 0x75, 0x6b, 0x56, 0xb7, 0x91, 0x1b, 0x0c, 0xf4, 0x0c, 0x25, 0x15, + 0x05, 0x7c, 0xe6, 0x80, 0xce, 0x81, 0xef, 0x67, 0x71, 0x16, 0x51, 0xcd, 0x82, 0x87, 0x8c, 0x29, + 0x77, 0xdd, 0xde, 0xf4, 0x93, 0xdc, 0xe0, 0x2e, 0x9d, 0xa7, 0x5e, 0xde, 0xf5, 0xdf, 0xff, 0xe0, + 0x07, 0x31, 0xd5, 0xe3, 0xfe, 0x88, 0x87, 0xbd, 0x41, 0xa2, 0xbf, 0xaa, 0x64, 0x3e, 0xce, 0x22, + 0xcd, 0x8f, 0x99, 0x54, 0x27, 0xfd, 0xf8, 0x64, 0xdf, 0x1f, 0x53, 0x9e, 0xec, 0xfb, 0x42, 0xb2, + 0xfd, 0x50, 0xf4, 0x83, 0xe2, 0xb5, 0x78, 0x3c, 0x1c, 0x24, 0xfa, 0x3e, 0x55, 0x9a, 0x49, 0xf2, + 0x6a, 0x7b, 0xf8, 0x2b, 0xd8, 0x2e, 0x12, 0xcf, 0x22, 0xe6, 0x6b, 0x16, 0x0c, 0x92, 0x72, 0xdc, + 0x5e, 0x24, 0xfc, 0xa7, 0xca, 0x05, 0xf6, 0x48, 0x28, 0x37, 0x78, 0x3b, 0x59, 0xa8, 0x22, 0xaf, + 0x71, 0x80, 0x9f, 0x82, 0xe6, 0x20, 0x09, 0xd8, 0xc9, 0x20, 0x39, 0xe4, 0x4a, 0xbb, 0x4d, 0x6b, + 0xd8, 0xc9, 0x0d, 0x6e, 0xf2, 0x97, 0x30, 0xa9, 0x6a, 0xe0, 0x47, 0x60, 0xc9, 0x6a, 0x5b, 0x3b, + 0xce, 0xde, 0xba, 0x07, 0x73, 0x83, 0x37, 0x22, 0xae, 0x74, 0x25, 0xfa, 0x96, 0x87, 0xbf, 0x80, + 0xee, 0x7d, 0x91, 0x28, 0xe6, 0x67, 0xc5, 0x00, 0x8e, 0xa4, 0x48, 0x85, 0x62, 0xf2, 0x7b, 0xae, + 0x14, 0x53, 0x6e, 0xdb, 0x36, 0xba, 0x53, 0x8c, 0xd5, 0x5f, 0x24, 0x22, 0x8b, 0xeb, 0x61, 0x0a, + 0xba, 0x8f, 0x85, 0xa6, 0x51, 0xed, 0x63, 0xd9, 0xa8, 0x0f, 0xf3, 0xdd, 0x32, 0xcc, 0x5d, 0xbd, + 0xa8, 0x92, 0x2c, 0x36, 0x85, 0x21, 0xb8, 0x6d, 0xc9, 0xeb, 0x6f, 0xa7, 0x53, 0xdf, 0x0e, 0x95, + 0xed, 0x6e, 0xeb, 0xda, 0x32, 0xb2, 0xc0, 0x0e, 0x9e, 0x82, 0x7b, 0xf3, 0xbb, 0xa8, 0x7f, 0x4a, + 0x37, 0xed, 0x04, 0x3f, 0xce, 0x0d, 0xbe, 0xa7, 0xdf, 0x2c, 0x27, 0x6f, 0xe3, 0x09, 0x31, 0x58, + 0x7e, 0x24, 0x12, 0x9f, 0xb9, 0x9b, 0x3b, 0xce, 0xde, 0x92, 0xb7, 0x9e, 0x1b, 0xbc, 0x9c, 0x14, + 0x00, 0x99, 0xe2, 0xf0, 0x4b, 0xd0, 0xfe, 0x21, 0x19, 0x6a, 0xfa, 0x94, 0x05, 0x0f, 0x52, 0xe1, + 0x8f, 0x5d, 0x68, 0x77, 0xb1, 0x99, 0x1b, 0xdc, 0xce, 0xaa, 0x04, 0x99, 0xd7, 0xc1, 0xaf, 0x41, + 0xeb, 0x48, 0xb2, 0x63, 0x2e, 0x32, 0x65, 0xc3, 0x73, 0xcb, 0x86, 0x67, 0xbb, 0x18, 0x4f, 0x5a, + 0xc1, 0x2b, 0x21, 0x9a, 0xd3, 0xc3, 0x21, 0xb8, 0x75, 0xb5, 0xae, 0xe6, 0x75, 0xcb, 0xb6, 0xbf, + 0x9b, 0x1b, 0x7c, 0x27, 0xbd, 0x4e, 0x57, 0xdc, 0xea, 0xaa, 0x3d, 0xef, 0xec, 0x02, 0x35, 0xce, + 0x2f, 0x50, 0xe3, 0xc5, 0x05, 0x72, 0xfe, 0x98, 0x20, 0xe7, 0xaf, 0x09, 0x72, 0x9e, 0x4f, 0x90, + 0x73, 0x36, 0x41, 0xce, 0xf9, 0x04, 0x39, 0xff, 0x4e, 0x90, 0xf3, 0xdf, 0x04, 0x35, 0x5e, 0x4c, + 0x90, 0xf3, 0xec, 0x12, 0x35, 0xce, 0x2e, 0x51, 0xe3, 0xfc, 0x12, 0x35, 0x7e, 0x5e, 0xa3, 0xd3, + 0x6f, 0x8a, 0x1a, 0xad, 0xd8, 0x5b, 0xff, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x40, + 0xd1, 0x9b, 0x06, 0x07, 0x00, 0x00, } func (this *SignRate) Equal(that interface{}) bool { From 1e4a2d676015a0e412f429ef28f7235fe2c1983a Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Mon, 8 Jan 2024 16:16:37 +0200 Subject: [PATCH 580/958] update tests for compute existing and request missing headers --- process/block/metablock_request_test.go | 185 +++++++++++++++++++++--- 1 file changed, 165 insertions(+), 20 deletions(-) diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go index 77331ed30e5..2457ff04e97 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablock_request_test.go @@ -42,26 +42,7 @@ func TestMetaProcessor_computeExistingAndRequestMissingShardHeaders(t *testing.T numCallsMissingAttestation := atomic.Uint32{} numCallsMissingHeaders := atomic.Uint32{} arguments := createMetaProcessorArguments(t, noOfShards) - requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) - require.True(t, ok) - - requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { - attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() - if nonce != attestationNonce { - require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) - } - numCallsMissingAttestation.Add(1) - } - requestHandler.RequestShardHeaderCalled = func(shardID uint32, hash []byte) { - for _, sh := range metaBlock.ShardInfo { - if bytes.Equal(sh.HeaderHash, hash) && sh.ShardID == shardID { - numCallsMissingHeaders.Add(1) - return - } - } - - require.Fail(t, fmt.Sprintf("header hash %s not found in meta block", hash)) - } + updateRequestsHandlerForCountingRequests(t, arguments, td, metaBlock, &numCallsMissingHeaders, &numCallsMissingAttestation) mp, err := blockProcess.NewMetaProcessor(*arguments) require.Nil(t, err) @@ -81,19 +62,154 @@ func TestMetaProcessor_computeExistingAndRequestMissingShardHeaders(t *testing.T }) t.Run("one referenced shard header present and one missing", func(t *testing.T) { t.Parallel() + referencedHeaders := []*shardHeaderData{td[0].referencedHeaderData, td[1].referencedHeaderData} + shardInfo := createShardInfo(referencedHeaders) + metaBlock := &block.MetaBlock{ + ShardInfo: shardInfo, + } + + numCallsMissingAttestation := atomic.Uint32{} + numCallsMissingHeaders := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + poolsHolder, ok := arguments.DataComponents.Datapool().(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) + updateRequestsHandlerForCountingRequests(t, arguments, td, metaBlock, &numCallsMissingHeaders, &numCallsMissingAttestation) + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + headersPool := mp.GetDataPool().Headers() + // adding the existing header + headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) + numMissing, numAttestationMissing := mp.ComputeExistingAndRequestMissingShardHeaders(metaBlock) + time.Sleep(100 * time.Millisecond) + headersForBlock := mp.GetHdrForBlock() + require.Equal(t, uint32(1), numMissing) + require.Equal(t, uint32(1), headersForBlock.GetMissingHdrs()) + // before receiving all missing headers referenced in metaBlock, the number of missing attestations is not updated + require.Equal(t, uint32(0), numAttestationMissing) + require.Equal(t, uint32(0), headersForBlock.GetMissingFinalityAttestingHdrs()) + require.Len(t, headersForBlock.GetHdrHashAndInfo(), 2) + require.Equal(t, uint32(0), numCallsMissingAttestation.Load()) + require.Equal(t, uint32(1), numCallsMissingHeaders.Load()) }) t.Run("all referenced shard headers present, all attestation headers missing", func(t *testing.T) { t.Parallel() + referencedHeaders := []*shardHeaderData{td[0].referencedHeaderData, td[1].referencedHeaderData} + shardInfo := createShardInfo(referencedHeaders) + metaBlock := &block.MetaBlock{ + ShardInfo: shardInfo, + } + + numCallsMissingAttestation := atomic.Uint32{} + numCallsMissingHeaders := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + poolsHolder, ok := arguments.DataComponents.Datapool().(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) + updateRequestsHandlerForCountingRequests(t, arguments, td, metaBlock, &numCallsMissingHeaders, &numCallsMissingAttestation) + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + headersPool := mp.GetDataPool().Headers() + // adding the existing headers + headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) + headersPool.AddHeader(td[1].referencedHeaderData.headerHash, td[1].referencedHeaderData.header) + numMissing, numAttestationMissing := mp.ComputeExistingAndRequestMissingShardHeaders(metaBlock) + time.Sleep(100 * time.Millisecond) + headersForBlock := mp.GetHdrForBlock() + require.Equal(t, uint32(0), numMissing) + require.Equal(t, uint32(0), headersForBlock.GetMissingHdrs()) + require.Equal(t, uint32(2), numAttestationMissing) + require.Equal(t, uint32(2), headersForBlock.GetMissingFinalityAttestingHdrs()) + require.Len(t, headersForBlock.GetHdrHashAndInfo(), 2) + require.Equal(t, uint32(2), numCallsMissingAttestation.Load()) + require.Equal(t, uint32(0), numCallsMissingHeaders.Load()) }) t.Run("all referenced shard headers present, one attestation header missing", func(t *testing.T) { t.Parallel() + referencedHeaders := []*shardHeaderData{td[0].referencedHeaderData, td[1].referencedHeaderData} + shardInfo := createShardInfo(referencedHeaders) + metaBlock := &block.MetaBlock{ + ShardInfo: shardInfo, + } + + numCallsMissingAttestation := atomic.Uint32{} + numCallsMissingHeaders := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + poolsHolder, ok := arguments.DataComponents.Datapool().(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) + updateRequestsHandlerForCountingRequests(t, arguments, td, metaBlock, &numCallsMissingHeaders, &numCallsMissingAttestation) + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + headersPool := mp.GetDataPool().Headers() + // adding the existing headers + headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) + headersPool.AddHeader(td[1].referencedHeaderData.headerHash, td[1].referencedHeaderData.header) + headersPool.AddHeader(td[0].attestationHeaderData.headerHash, td[0].attestationHeaderData.header) + numMissing, numAttestationMissing := mp.ComputeExistingAndRequestMissingShardHeaders(metaBlock) + time.Sleep(100 * time.Millisecond) + headersForBlock := mp.GetHdrForBlock() + require.Equal(t, uint32(0), numMissing) + require.Equal(t, uint32(0), headersForBlock.GetMissingHdrs()) + require.Equal(t, uint32(1), numAttestationMissing) + require.Equal(t, uint32(1), headersForBlock.GetMissingFinalityAttestingHdrs()) + require.Len(t, headersForBlock.GetHdrHashAndInfo(), 3) + require.Equal(t, uint32(1), numCallsMissingAttestation.Load()) + require.Equal(t, uint32(0), numCallsMissingHeaders.Load()) }) t.Run("all referenced shard headers present, all attestation headers present", func(t *testing.T) { t.Parallel() + referencedHeaders := []*shardHeaderData{td[0].referencedHeaderData, td[1].referencedHeaderData} + shardInfo := createShardInfo(referencedHeaders) + metaBlock := &block.MetaBlock{ + ShardInfo: shardInfo, + } + numCallsMissingAttestation := atomic.Uint32{} + numCallsMissingHeaders := atomic.Uint32{} + arguments := createMetaProcessorArguments(t, noOfShards) + poolsHolder, ok := arguments.DataComponents.Datapool().(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) + updateRequestsHandlerForCountingRequests(t, arguments, td, metaBlock, &numCallsMissingHeaders, &numCallsMissingAttestation) + + mp, err := blockProcess.NewMetaProcessor(*arguments) + require.Nil(t, err) + require.NotNil(t, mp) + + headersPool := mp.GetDataPool().Headers() + // adding the existing headers + headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) + headersPool.AddHeader(td[1].referencedHeaderData.headerHash, td[1].referencedHeaderData.header) + headersPool.AddHeader(td[0].attestationHeaderData.headerHash, td[0].attestationHeaderData.header) + headersPool.AddHeader(td[1].attestationHeaderData.headerHash, td[1].attestationHeaderData.header) + numMissing, numAttestationMissing := mp.ComputeExistingAndRequestMissingShardHeaders(metaBlock) + time.Sleep(100 * time.Millisecond) + headersForBlock := mp.GetHdrForBlock() + require.Equal(t, uint32(0), numMissing) + require.Equal(t, uint32(0), headersForBlock.GetMissingHdrs()) + require.Equal(t, uint32(0), numAttestationMissing) + require.Equal(t, uint32(0), headersForBlock.GetMissingFinalityAttestingHdrs()) + require.Len(t, headersForBlock.GetHdrHashAndInfo(), 4) + require.Equal(t, uint32(0), numCallsMissingAttestation.Load()) + require.Equal(t, uint32(0), numCallsMissingHeaders.Load()) }) } @@ -499,3 +615,32 @@ func createShardInfo(referencedHeaders []*shardHeaderData) []block.ShardData { return shardData } + +func updateRequestsHandlerForCountingRequests( + t *testing.T, + arguments *blockProcess.ArgMetaProcessor, + td map[uint32]*shardTestData, + metaBlock *block.MetaBlock, + numCallsMissingHeaders, numCallsMissingAttestation *atomic.Uint32, +) { + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() + if nonce != attestationNonce { + require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) + } + numCallsMissingAttestation.Add(1) + } + requestHandler.RequestShardHeaderCalled = func(shardID uint32, hash []byte) { + for _, sh := range metaBlock.ShardInfo { + if bytes.Equal(sh.HeaderHash, hash) && sh.ShardID == shardID { + numCallsMissingHeaders.Add(1) + return + } + } + + require.Fail(t, fmt.Sprintf("header hash %s not found in meta block", hash)) + } +} From 5bd43e1c7448001e032e3dcaa0fb5c26ff1ad7bb Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Mon, 8 Jan 2024 16:51:44 +0200 Subject: [PATCH 581/958] fix unit test --- process/block/metablock_request_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go index 2457ff04e97..406c2b9d001 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablock_request_test.go @@ -443,7 +443,10 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { mp.ReceivedShardHeader(td[1].attestationHeaderData.header, td[1].attestationHeaderData.headerHash) wg.Wait() - require.Equal(t, uint32(2), numCalls.Load()) + time.Sleep(100 * time.Millisecond) + // the receive of an attestation header, if not the last one, will trigger a new request of missing attestation headers + // TODO: refactor request logic to not request recently already requested headers + require.Equal(t, uint32(3), numCalls.Load()) require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) }) } From 8a3ca4ec778f545ba6eb833614b73bcab1a751ba Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 8 Jan 2024 18:48:49 +0200 Subject: [PATCH 582/958] - fixed ChangeUsernameEnableEpoch --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index ec45ce07a0b..539aaa4fcdc 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -264,7 +264,7 @@ MultiClaimOnDelegationEnableEpoch = 1 # ChangeUsernameEnableEpoch represents the epoch when changing username is enabled - ChangeUsernameEnableEpoch = 10 + ChangeUsernameEnableEpoch = 4 # ConsistentTokensValuesLengthCheckEnableEpoch represents the epoch when the consistent tokens values length check is enabled ConsistentTokensValuesLengthCheckEnableEpoch = 1 From 9d3898d6f86707278fb53ded7b8e92c2cdb65826 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 9 Jan 2024 10:18:56 +0200 Subject: [PATCH 583/958] FIX: After review --- config/systemSmartContractsConfig.go | 6 ++---- epochStart/metachain/systemSCs.go | 2 ++ epochStart/metachain/systemSCs_test.go | 6 +----- factory/api/apiResolverFactory.go | 3 ++- integrationTests/vm/txsFee/scCalls_test.go | 9 +++++---- state/interface.go | 3 +-- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index 9d04725acc0..eb32d9451b4 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -35,8 +35,7 @@ type ESDTSystemSCConfig struct { } // GovernanceSystemSCConfigV1 holds the initial set of values that were used to initialise the -// -// governance system smart contract at genesis time +// governance system smart contract at genesis time type GovernanceSystemSCConfigV1 struct { NumNodes int64 ProposalCost string @@ -46,8 +45,7 @@ type GovernanceSystemSCConfigV1 struct { } // GovernanceSystemSCConfigActive defines the set of configuration values used by the governance -// -// system smart contract once it activates +// system smart contract once it activates type GovernanceSystemSCConfigActive struct { ProposalCost string LostProposalFee string diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index f5cf8e29302..cfbefbd8bcd 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -77,6 +77,8 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr common.ESDTFlagInSpecificEpochOnly, common.GovernanceFlag, common.SaveJailedAlwaysFlag, + common.StakingV4Step1Flag, + common.StakingV4Step2Flag, }) if err != nil { return nil, err diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 0d2f5e65407..d5f4254856f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2089,11 +2089,7 @@ func TestSystemSCProcessor_LegacyEpochConfirmedCorrectMaxNumNodesAfterNodeRestar nodesConfigEpoch6, }) args.MaxNodesChangeConfigProvider = nodesConfigProvider - args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ - IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { - return flag == common.StakingV2Flag - }, - } + args.EnableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.StakingV2Flag) validatorsInfoMap := state.NewShardValidatorsInfoMap() s, _ := NewSystemSCProcessor(args) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 5f46ccc028e..221219ac115 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -470,7 +470,8 @@ func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBl Marshalizer: args.coreComponents.InternalMarshalizer(), SystemSCConfig: args.systemSCConfig, ValidatorAccountsDB: args.stateComponents.PeerAccounts(), - UserAccountsDB: args.stateComponents.AccountsAdapterAPI(), ChanceComputer: args.coreComponents.Rater(), + UserAccountsDB: args.stateComponents.AccountsAdapterAPI(), + ChanceComputer: args.coreComponents.Rater(), ShardCoordinator: args.processComponents.ShardCoordinator(), EnableEpochsHandler: args.coreComponents.EnableEpochsHandler(), NodesCoordinator: args.processComponents.NodesCoordinator(), diff --git a/integrationTests/vm/txsFee/scCalls_test.go b/integrationTests/vm/txsFee/scCalls_test.go index f247475e015..86a6c966f7c 100644 --- a/integrationTests/vm/txsFee/scCalls_test.go +++ b/integrationTests/vm/txsFee/scCalls_test.go @@ -59,10 +59,11 @@ func prepareTestContextForEpoch836(tb testing.TB) (*vm.VMTestContext, []byte) { testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGasAndRoundConfig( config.EnableEpochs{ - GovernanceEnableEpoch: unreachableEpoch, - SetSenderInEeiOutputTransferEnableEpoch: unreachableEpoch, - RefactorPeersMiniBlocksEnableEpoch: unreachableEpoch, - MaxBlockchainHookCountersEnableEpoch: unreachableEpoch, DynamicGasCostForDataTrieStorageLoadEnableEpoch: unreachableEpoch, + GovernanceEnableEpoch: unreachableEpoch, + SetSenderInEeiOutputTransferEnableEpoch: unreachableEpoch, + RefactorPeersMiniBlocksEnableEpoch: unreachableEpoch, + MaxBlockchainHookCountersEnableEpoch: unreachableEpoch, + DynamicGasCostForDataTrieStorageLoadEnableEpoch: unreachableEpoch, }, mock.NewMultiShardsCoordinatorMock(2), db, diff --git a/state/interface.go b/state/interface.go index 2776889473c..e5dd0b3f9d8 100644 --- a/state/interface.go +++ b/state/interface.go @@ -24,8 +24,7 @@ type Updater interface { } // PeerAccountHandler models a peer state account, which can journalize a normal account's data -// -// with some extra features like signing statistics or rating information +// with some extra features like signing statistics or rating information type PeerAccountHandler interface { GetBLSPublicKey() []byte SetBLSPublicKey([]byte) error From 024f233d68b4b2d42ec040b00265404765e5f438 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 9 Jan 2024 11:23:42 +0200 Subject: [PATCH 584/958] FIX: Returned error --- cmd/node/main.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/node/main.go b/cmd/node/main.go index a372c172266..8eb0905e97d 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -46,10 +46,13 @@ VERSION: // appVersion should be populated at build time using ldflags // Usage examples: // linux/mac: -// go build -v -ldflags="-X main.appVersion=$(git describe --tags --long --dirty)" +// +// go build -v -ldflags="-X main.appVersion=$(git describe --tags --long --dirty)" +// // windows: -// for /f %i in ('git describe --tags --long --dirty') do set VERS=%i -// go build -v -ldflags="-X main.appVersion=%VERS%" +// +// for /f %i in ('git describe --tags --long --dirty') do set VERS=%i +// go build -v -ldflags="-X main.appVersion=%VERS%" var appVersion = common.UnVersionedAppString func main() { @@ -105,7 +108,7 @@ func startNodeRunner(c *cli.Context, log logger.Logger, baseVersion string, vers errCheckEpochsCfg := config.SanityCheckEnableEpochsStakingV4(cfgs) if errCheckEpochsCfg != nil { - return errCfg + return errCheckEpochsCfg } if !check.IfNil(fileLogging) { From 3ffb1df7fbd9543c46e2a3a673caf884312bda70 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 9 Jan 2024 11:52:31 +0200 Subject: [PATCH 585/958] send invalid signers from leader --- consensus/spos/bls/subroundEndRound.go | 12 +++-- consensus/spos/bls/subroundEndRound_test.go | 49 ++++++++++++++++++++- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index 723fc0bcbf3..a1f96cc8ffc 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -189,7 +189,7 @@ func (sr *subroundEndRound) receivedInvalidSignersInfo(_ context.Context, cnsDta return false } - if sr.IsSelfLeaderInCurrentRound() { + if sr.IsSelfLeaderInCurrentRound() || sr.IsMultiKeyLeaderInCurrentRound() { return false } @@ -589,12 +589,18 @@ func (sr *subroundEndRound) createAndBroadcastHeaderFinalInfo() { } func (sr *subroundEndRound) createAndBroadcastInvalidSigners(invalidSigners []byte) { + leader, errGetLeader := sr.GetLeader() + if errGetLeader != nil { + log.Debug("createAndBroadcastInvalidSigners.GetLeader", "error", errGetLeader) + return + } + cnsMsg := consensus.NewConsensusMessage( sr.GetData(), nil, nil, nil, - []byte(sr.SelfPubKey()), + []byte(leader), nil, int(MtInvalidSigners), sr.RoundHandler().Index(), @@ -602,7 +608,7 @@ func (sr *subroundEndRound) createAndBroadcastInvalidSigners(invalidSigners []by nil, nil, nil, - sr.CurrentPid(), + sr.GetAssociatedPid([]byte(leader)), invalidSigners, ) diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 456277e23fc..3a6c9fa80f6 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -1322,7 +1322,7 @@ func TestSubroundEndRound_ReceivedInvalidSignersInfo(t *testing.T) { assert.False(t, res) }) - t.Run("received message for self leader", func(t *testing.T) { + t.Run("received message from self leader should return false", func(t *testing.T) { t.Parallel() container := mock.InitConsensusCore() @@ -1339,6 +1339,53 @@ func TestSubroundEndRound_ReceivedInvalidSignersInfo(t *testing.T) { assert.False(t, res) }) + t.Run("received message from self multikey leader should return false", func(t *testing.T) { + t.Parallel() + + container := mock.InitConsensusCore() + keysHandler := &testscommon.KeysHandlerStub{ + IsKeyManagedByCurrentNodeCalled: func(pkBytes []byte) bool { + return string(pkBytes) == "A" + }, + } + ch := make(chan bool, 1) + consensusState := initConsensusStateWithKeysHandler(keysHandler) + sr, _ := spos.NewSubround( + bls.SrSignature, + bls.SrEndRound, + -1, + int64(85*roundTimeDuration/100), + int64(95*roundTimeDuration/100), + "(END_ROUND)", + consensusState, + ch, + executeStoredMessages, + container, + chainID, + currentPid, + &statusHandler.AppStatusHandlerStub{}, + ) + + srEndRound, _ := bls.NewSubroundEndRound( + sr, + extend, + bls.ProcessingThresholdPercent, + displayStatistics, + &statusHandler.AppStatusHandlerStub{}, + &mock.SentSignatureTrackerStub{}, + ) + + srEndRound.SetSelfPubKey("A") + + cnsData := consensus.Message{ + BlockHeaderHash: []byte("X"), + PubKey: []byte("A"), + } + + res := srEndRound.ReceivedInvalidSignersInfo(&cnsData) + assert.False(t, res) + }) + t.Run("received hash does not match the hash from current consensus state", func(t *testing.T) { t.Parallel() From aaa62e11cc1c52e6abdc2d0390cc598e6ef95b8c Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 9 Jan 2024 12:06:58 +0200 Subject: [PATCH 586/958] redundancy node should not send invalid signers --- consensus/spos/bls/subroundEndRound.go | 5 ++ consensus/spos/bls/subroundEndRound_test.go | 63 +++++++++++++++------ 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index a1f96cc8ffc..c9d1a8a62db 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -589,6 +589,11 @@ func (sr *subroundEndRound) createAndBroadcastHeaderFinalInfo() { } func (sr *subroundEndRound) createAndBroadcastInvalidSigners(invalidSigners []byte) { + isSelfLeader := sr.IsSelfLeaderInCurrentRound() && sr.ShouldConsiderSelfKeyInConsensus() + if !isSelfLeader && !sr.IsMultiKeyLeaderInCurrentRound() { + return + } + leader, errGetLeader := sr.GetLeader() if errGetLeader != nil { log.Debug("createAndBroadcastInvalidSigners.GetLeader", "error", errGetLeader) diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 3a6c9fa80f6..d6966a5e870 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -1603,29 +1603,56 @@ func TestVerifyInvalidSigners(t *testing.T) { func TestSubroundEndRound_CreateAndBroadcastInvalidSigners(t *testing.T) { t.Parallel() - wg := &sync.WaitGroup{} - wg.Add(1) + t.Run("redundancy node should not send", func(t *testing.T) { + t.Parallel() - expectedInvalidSigners := []byte("invalid signers") + expectedInvalidSigners := []byte("invalid signers") - wasCalled := false - container := mock.InitConsensusCore() - messenger := &mock.BroadcastMessengerMock{ - BroadcastConsensusMessageCalled: func(message *consensus.Message) error { - wg.Done() - assert.Equal(t, expectedInvalidSigners, message.InvalidSigners) - wasCalled = true - return nil - }, - } - container.SetBroadcastMessenger(messenger) - sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{}) + container := mock.InitConsensusCore() + nodeRedundancy := &mock.NodeRedundancyHandlerStub{ + IsRedundancyNodeCalled: func() bool { + return true + }, + } + container.SetNodeRedundancyHandler(nodeRedundancy) + messenger := &mock.BroadcastMessengerMock{ + BroadcastConsensusMessageCalled: func(message *consensus.Message) error { + assert.Fail(t, "should have not been called") + return nil + }, + } + container.SetBroadcastMessenger(messenger) + sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{}) - sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners) + sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + wg := &sync.WaitGroup{} + wg.Add(1) + + expectedInvalidSigners := []byte("invalid signers") + + wasCalled := false + container := mock.InitConsensusCore() + messenger := &mock.BroadcastMessengerMock{ + BroadcastConsensusMessageCalled: func(message *consensus.Message) error { + wg.Done() + assert.Equal(t, expectedInvalidSigners, message.InvalidSigners) + wasCalled = true + return nil + }, + } + container.SetBroadcastMessenger(messenger) + sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{}) + + sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners) - wg.Wait() + wg.Wait() - require.True(t, wasCalled) + require.True(t, wasCalled) + }) } func TestGetFullMessagesForInvalidSigners(t *testing.T) { From 53ad9b31e08ebd5bb86bb962e7ad047fd3f85553 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 9 Jan 2024 13:09:02 +0200 Subject: [PATCH 587/958] fixed tests --- consensus/spos/bls/subroundEndRound_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index d6966a5e870..0c5ac3f2284 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -1646,6 +1646,7 @@ func TestSubroundEndRound_CreateAndBroadcastInvalidSigners(t *testing.T) { } container.SetBroadcastMessenger(messenger) sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{}) + sr.SetSelfPubKey("A") sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners) From 2508b0309b53a152148514a2b24d45c45a8f9077 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Tue, 9 Jan 2024 13:43:25 +0200 Subject: [PATCH 588/958] new vm 1.5.23 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index efea0bc83be..bf8abd182a5 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.9 - github.com/multiversx/mx-chain-vm-go v1.5.22 + github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109113949-d40e35a87257 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 diff --git a/go.sum b/go.sum index a609d6be13b..5fe37137e5f 100644 --- a/go.sum +++ b/go.sum @@ -400,8 +400,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0Oab github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.9 h1:PnGimbMScV5WXFjumzAmcAcnWrw5e9PQABuIcKKUgZw= github.com/multiversx/mx-chain-vm-common-go v1.5.9/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= -github.com/multiversx/mx-chain-vm-go v1.5.22 h1:MDMMMIu67CAyohnIBuizbFQUJJSzNgXiLKww99j1zyA= -github.com/multiversx/mx-chain-vm-go v1.5.22/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= +github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109113949-d40e35a87257 h1:vWk+2Uz5uIQ8DzprFsSVh5VCM4bznquWJkF9lR7SL9o= +github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109113949-d40e35a87257/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64/go.mod h1:MUO2E4aEIu3siDkvjraO/WaBh/FxVeQyPWfsrZE+MTU= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 h1:H0Duuoz6lR6KapqLqMspWTojaVtQRiLA5lIm6XV9H04= From 2d253dc6f0c3ff4363e3f40268fd65de2a3237c3 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Tue, 9 Jan 2024 14:33:15 +0200 Subject: [PATCH 589/958] new vm 1.5.23 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bf8abd182a5..a8a2a3fc990 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.9 - github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109113949-d40e35a87257 + github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109115804-b7fa5b5a10e1 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 diff --git a/go.sum b/go.sum index 5fe37137e5f..f8251b80ac0 100644 --- a/go.sum +++ b/go.sum @@ -400,8 +400,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0Oab github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.9 h1:PnGimbMScV5WXFjumzAmcAcnWrw5e9PQABuIcKKUgZw= github.com/multiversx/mx-chain-vm-common-go v1.5.9/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109113949-d40e35a87257 h1:vWk+2Uz5uIQ8DzprFsSVh5VCM4bznquWJkF9lR7SL9o= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109113949-d40e35a87257/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= +github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109115804-b7fa5b5a10e1 h1:tHTngw3UR4NALykWbDzZi/Fz5W3KZDhs6qSu1lbV5SA= +github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109115804-b7fa5b5a10e1/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64/go.mod h1:MUO2E4aEIu3siDkvjraO/WaBh/FxVeQyPWfsrZE+MTU= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 h1:H0Duuoz6lR6KapqLqMspWTojaVtQRiLA5lIm6XV9H04= From 2b34ce7fe019b211ecb98e9cd45a3d76cbc7aa61 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 9 Jan 2024 16:16:57 +0200 Subject: [PATCH 590/958] fix after review --- consensus/spos/bls/subroundEndRound_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 0c5ac3f2284..70992e7aec5 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -1603,7 +1603,7 @@ func TestVerifyInvalidSigners(t *testing.T) { func TestSubroundEndRound_CreateAndBroadcastInvalidSigners(t *testing.T) { t.Parallel() - t.Run("redundancy node should not send", func(t *testing.T) { + t.Run("redundancy node should not send while main is active", func(t *testing.T) { t.Parallel() expectedInvalidSigners := []byte("invalid signers") @@ -1613,6 +1613,9 @@ func TestSubroundEndRound_CreateAndBroadcastInvalidSigners(t *testing.T) { IsRedundancyNodeCalled: func() bool { return true }, + IsMainMachineActiveCalled: func() bool { + return true + }, } container.SetNodeRedundancyHandler(nodeRedundancy) messenger := &mock.BroadcastMessengerMock{ From 034fb5924330177051a30253bffacd3936a581a6 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 10 Jan 2024 09:49:15 +0200 Subject: [PATCH 591/958] - fixed assessment tool --- cmd/assessment/testdata/cpucalculate.wasm | Bin 609 -> 621 bytes cmd/assessment/testdata/storage100.wasm | Bin 1647 -> 1455 bytes 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 cmd/assessment/testdata/cpucalculate.wasm mode change 100644 => 100755 cmd/assessment/testdata/storage100.wasm diff --git a/cmd/assessment/testdata/cpucalculate.wasm b/cmd/assessment/testdata/cpucalculate.wasm old mode 100644 new mode 100755 index 1dc0dc303892156beb49647d558d7d9123191ff6..8f04b918eaa60babaf1b355344eee45d7ffffaf4 GIT binary patch delta 97 zcmaFJ@|IVndPc{F4i;{9NhY@3 p)ZF}{N+t%LluybiIX6BqT=kLEyf8zA@g%m=_g8jm|;U#ZgSly=(R>iX0mv6JL zJ6G4IXYJ?wY71df?peE|uFu|Fv@bhC+Kz2mmXnaLq?8F;3M-kCH&Wexa@@YEle}nO zTwTAjgmZp*-Vs*H=(QX5y0G2&^Yr>mIGHbL+ZMk2)se?HrCVNtgvyhIfP6_7ta3N0 z1lh1)2g0|Sc2i}@fmIVeCDd<8NhFZe)Q3Jw!J#x#NVh1XB)Q1I)s#i{BqyVeoayk8 zgQv+?KLq9BBOg+KR4$nE016n;G>Ad;2jcc4+ls0~tT~J!42Lwren!|&R=6(P8|82` zw)b7oSkzE7a^omsT+;+5XcA*Ig-J}cXqvTvX+RT!{`#9S9VN`5q^YdF37SP2vmsR? z!8uc&#~kK0EnoqaKz#1`tFq=Is#pwZi486F{M9(D#r`t19I34swK`T%*VI6RR&!;>)6n=iA}brx^ti{9{vN>-IKNzpEQW1c6bQ8*u_pDKJ^Ukadsd3*bBt3 zZgvX~u#F(!z1CvXdca#Xae!t>ifyXcb)F76JPhdwM-d0U`_qxn{zVG!=_qD{n-d|^ zkz_O+^yNPozIac=k$1;Y%2@CyZ3dA+8X3*dxJ*ona>ydrB9Gnq@Zf7kC4YBM9`&1! z0{T(VG+;Oy!~h0E8j1vmO?d>v7}3neD2DEFj67+vDj@ zMsia|ZW>dV)(j1pm`R!eVWveT)+(cfvSw6f|N5(#jyY5?r)l1Bw19amgj9_L7fpEy zi&)ZBLk-n?9C@_Nnk!hwO2~9rsQ3IeIBdlJG7L<2d}~H+9cx(E49x};vr1do#8!)0 zk+f|tT{9^`kE0#tX!nkzJ;Twyk@D$)Z?6f)ArK#9jyzJFJ;b45;~rf{oIS=djso$s z_wNa3AL1cSV&--j%RTJhW6q;TY^#MwXod8ckMuY`VV<6F_#~vKcp5Y3zL!GXrreJB G59<$@>hcW$ literal 1647 zcmchXu}Z^G6o&tEZ(3`kSR9>dD{g{Lf-W8xAHWx|LnuVrN?QeSNZfRD6Wm;U1YbhX zHxLAI5gqgeJZbDbBIv~o-XZxDzWYPC-w9fS4gsK9yAvd`DA_TiD_|Cljk*U@gJG}V zYDe30i-7D^*p7zWZ|`@a?hs_HF(xR{9ubu+!IUeM5T~a>IMKA_PSol34-G0=PqebU z3=@uHtKWvLK3C0oK$I}%!Qj_>TF1#rn##lG)9vNW)yu{83s#Y4@9ah$e3qqH!UN(p zKmx@L@FTXS5lRKt@SYcB@pKeNySbY06||Ph!ko~gv_v0ml$PkDtSi($09Qd@aF7fTVM_=svRjK^DzS{M3{m(^CF|dkPq{!I^Rws)TIWfVi zYmp-7ELcr0Qsi_7tK>zBoatcozetfA0!AV4a#j7s;U1;(T(#@QA=^B^=6M H|KHaKHmA1} From 197287b851327ed1b0f2f19076658b1471803adc Mon Sep 17 00:00:00 2001 From: robertsasu Date: Wed, 10 Jan 2024 10:55:31 +0200 Subject: [PATCH 592/958] new vm 1.5.23 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a8a2a3fc990..2d667980760 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.9 - github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109115804-b7fa5b5a10e1 + github.com/multiversx/mx-chain-vm-go v1.5.23 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 diff --git a/go.sum b/go.sum index f8251b80ac0..11ce63d1c90 100644 --- a/go.sum +++ b/go.sum @@ -400,8 +400,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0Oab github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.9 h1:PnGimbMScV5WXFjumzAmcAcnWrw5e9PQABuIcKKUgZw= github.com/multiversx/mx-chain-vm-common-go v1.5.9/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109115804-b7fa5b5a10e1 h1:tHTngw3UR4NALykWbDzZi/Fz5W3KZDhs6qSu1lbV5SA= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20240109115804-b7fa5b5a10e1/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= +github.com/multiversx/mx-chain-vm-go v1.5.23 h1:FNkEstebRtQWQNlyQbR2yGSpgGTpiwCMnl4MYVYEy2Q= +github.com/multiversx/mx-chain-vm-go v1.5.23/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64/go.mod h1:MUO2E4aEIu3siDkvjraO/WaBh/FxVeQyPWfsrZE+MTU= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 h1:H0Duuoz6lR6KapqLqMspWTojaVtQRiLA5lIm6XV9H04= From 1ec1783df621ecb51a51724172bf0e987ee44b7c Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 10 Jan 2024 13:51:47 +0200 Subject: [PATCH 593/958] FIX: Linter --- sharding/nodesCoordinator/hashValidatorShuffler.go | 1 - sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 1 - 2 files changed, 2 deletions(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index 70fd019cb9d..b918b5cc980 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -72,7 +72,6 @@ type randHashShuffler struct { availableNodesConfigs []config.MaxNodesChangeConfig mutShufflerParams sync.RWMutex validatorDistributor ValidatorsDistributor - flagBalanceWaitingLists atomic.Flag enableEpochsHandler common.EnableEpochsHandler stakingV4Step2EnableEpoch uint32 flagStakingV4Step2 atomic.Flag diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 0f4c5545030..1b0b87ef342 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -98,7 +98,6 @@ type indexHashedNodesCoordinator struct { enableEpochsHandler common.EnableEpochsHandler validatorInfoCacher epochStart.ValidatorInfoCacher genesisNodesSetupHandler GenesisNodesSetupHandler - stakingV4Step2EnableEpoch uint32 flagStakingV4Step2 atomicFlags.Flag nodesCoordinatorRegistryFactory NodesCoordinatorRegistryFactory flagStakingV4Started atomicFlags.Flag From 2f2744b3fe194f10eb86a577fee5e7593b5e1fa0 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 10 Jan 2024 18:01:25 +0200 Subject: [PATCH 594/958] FIX: Remove enforced config protections --- config/configChecker.go | 45 ++----------- config/configChecker_test.go | 123 +++++++++++++++-------------------- config/errors.go | 4 -- config/interface.go | 4 -- 4 files changed, 58 insertions(+), 118 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index a438957e9e0..589f31528b1 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -35,12 +35,12 @@ func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards u if idx == 0 { return fmt.Errorf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, but %w ", enableEpochsCfg.StakingV4Step3EnableEpoch, errNoMaxNodesConfigBeforeStakingV4) - } else { - prevMaxNodesChange := maxNodesChangeCfg[idx-1] - err := checkMaxNodesChangedCorrectly(prevMaxNodesChange, currMaxNodesChangeCfg, numOfShards) - if err != nil { - return err - } + } + + prevMaxNodesChange := maxNodesChangeCfg[idx-1] + err := checkMaxNodesChangedCorrectly(prevMaxNodesChange, currMaxNodesChangeCfg, numOfShards) + if err != nil { + return err } break @@ -100,38 +100,5 @@ func checkMaxNodesConfig( errInvalidMaxMinNodes, maxNumNodes, minNumNodesWithHysteresis) } - numShards := nodesSetup.NumberOfShards() - waitingListPerShard := (maxNumNodes - minNumNodesWithHysteresis) / (numShards + 1) - if nodesToShufflePerShard > waitingListPerShard { - return fmt.Errorf("%w, nodesToShufflePerShard: %d, waitingListPerShard: %d", - errInvalidNodesToShuffle, nodesToShufflePerShard, waitingListPerShard) - } - - if minNumNodesWithHysteresis > nodesSetup.MinNumberOfNodes() { - return checkHysteresis(nodesSetup, nodesToShufflePerShard) - } - - return nil -} - -func checkHysteresis(nodesSetup NodesSetupHandler, numToShufflePerShard uint32) error { - hysteresis := nodesSetup.GetHysteresis() - - forcedWaitingListNodesPerShard := getHysteresisNodes(nodesSetup.MinNumberOfShardNodes(), hysteresis) - if numToShufflePerShard > forcedWaitingListNodesPerShard { - return fmt.Errorf("%w per shard for numToShufflePerShard: %d, forcedWaitingListNodesPerShard: %d", - errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesPerShard) - } - - forcedWaitingListNodesInMeta := getHysteresisNodes(nodesSetup.MinNumberOfMetaNodes(), hysteresis) - if numToShufflePerShard > forcedWaitingListNodesInMeta { - return fmt.Errorf("%w in metachain for numToShufflePerShard: %d, forcedWaitingListNodesInMeta: %d", - errInvalidNodesToShuffleWithHysteresis, numToShufflePerShard, forcedWaitingListNodesInMeta) - } - return nil } - -func getHysteresisNodes(minNumNodes uint32, hysteresis float32) uint32 { - return uint32(float32(minNumNodes) * hysteresis) -} diff --git a/config/configChecker_test.go b/config/configChecker_test.go index c4f4724f7f3..a6dc964a524 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -227,6 +227,58 @@ func TestSanityCheckNodesConfig(t *testing.T) { } err = SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) + + cfg = []MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + }, + { + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + } + nodesSetup = &nodesSetupMock.NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0, + MinNumberOfMetaNodesField: 3, + MinNumberOfShardNodesField: 3, + } + err = SanityCheckNodesConfig(nodesSetup, cfg) + require.Nil(t, err) + + cfg = []MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + }, + { + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + } + nodesSetup = &nodesSetupMock.NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 7, + MinNumberOfShardNodesField: 7, + } + err = SanityCheckNodesConfig(nodesSetup, cfg) + require.Nil(t, err) }) t.Run("zero nodes to shuffle per shard, should return error", func(t *testing.T) { @@ -273,75 +325,4 @@ func TestSanityCheckNodesConfig(t *testing.T) { require.True(t, strings.Contains(err.Error(), "maxNumNodes: 1900")) require.True(t, strings.Contains(err.Error(), "minNumNodesWithHysteresis: 1920")) }) - - t.Run("invalid nodes to shuffle per shard, should return error ", func(t *testing.T) { - t.Parallel() - - cfg := []MaxNodesChangeConfig{ - { - EpochEnable: 3, - MaxNumNodes: 2240, - NodesToShufflePerShard: 81, - }, - } - nodesSetup := &nodesSetupMock.NodesSetupMock{ - NumberOfShardsField: numShards, - HysteresisField: 0.2, - MinNumberOfMetaNodesField: 400, - MinNumberOfShardNodesField: 400, - } - err := SanityCheckNodesConfig(nodesSetup, cfg) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffle.Error())) - require.True(t, strings.Contains(err.Error(), "nodesToShufflePerShard: 81")) - require.True(t, strings.Contains(err.Error(), "waitingListPerShard: 80")) - }) - - t.Run("invalid nodes to shuffle per shard with hysteresis, should return error ", func(t *testing.T) { - t.Parallel() - - cfg := []MaxNodesChangeConfig{ - { - EpochEnable: 1, - MaxNumNodes: 1600, - NodesToShufflePerShard: 80, - }, - } - nodesSetup := &nodesSetupMock.NodesSetupMock{ - NumberOfShardsField: 1, - HysteresisField: 0.2, - MinNumberOfMetaNodesField: 500, - MinNumberOfShardNodesField: 300, - } - err := SanityCheckNodesConfig(nodesSetup, cfg) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffleWithHysteresis.Error())) - require.True(t, strings.Contains(err.Error(), "per shard")) - require.True(t, strings.Contains(err.Error(), "numToShufflePerShard: 80")) - require.True(t, strings.Contains(err.Error(), "forcedWaitingListNodesPerShard: 60")) - }) - - t.Run("invalid nodes to shuffle in metachain with hysteresis, should return error ", func(t *testing.T) { - t.Parallel() - - cfg := []MaxNodesChangeConfig{ - { - EpochEnable: 1, - MaxNumNodes: 1600, - NodesToShufflePerShard: 80, - }, - } - nodesSetup := &nodesSetupMock.NodesSetupMock{ - NumberOfShardsField: 1, - HysteresisField: 0.2, - MinNumberOfMetaNodesField: 300, - MinNumberOfShardNodesField: 500, - } - err := SanityCheckNodesConfig(nodesSetup, cfg) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), errInvalidNodesToShuffleWithHysteresis.Error())) - require.True(t, strings.Contains(err.Error(), "in metachain")) - require.True(t, strings.Contains(err.Error(), "numToShufflePerShard: 80")) - require.True(t, strings.Contains(err.Error(), "forcedWaitingListNodesInMeta: 60")) - }) } diff --git a/config/errors.go b/config/errors.go index 348f03d1a8a..f0cfa93c4c5 100644 --- a/config/errors.go +++ b/config/errors.go @@ -15,7 +15,3 @@ var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableE var errZeroNodesToShufflePerShard = errors.New("zero nodes to shuffle per shard found in config") var errInvalidMaxMinNodes = errors.New("number of min nodes with hysteresis > number of max nodes") - -var errInvalidNodesToShuffle = errors.New("number of nodes to shuffle per shard > waiting list size per shard") - -var errInvalidNodesToShuffleWithHysteresis = errors.New("number of nodes to shuffle per shard > forced waiting list size per shard with hysteresis") diff --git a/config/interface.go b/config/interface.go index f28661ee925..859e845c434 100644 --- a/config/interface.go +++ b/config/interface.go @@ -3,9 +3,5 @@ package config // NodesSetupHandler provides nodes setup information type NodesSetupHandler interface { MinNumberOfNodesWithHysteresis() uint32 - MinNumberOfNodes() uint32 - MinNumberOfShardNodes() uint32 - MinNumberOfMetaNodes() uint32 - GetHysteresis() float32 NumberOfShards() uint32 } From fcbcee2c88e97961bef9cbef2b9101cdab23ce03 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 11 Jan 2024 14:17:17 +0200 Subject: [PATCH 595/958] CLN: Extra cleaning on config checker --- cmd/node/main.go | 5 -- config/configChecker.go | 75 ++++++++++---------- config/configChecker_test.go | 130 +++++++++++++++++------------------ node/nodeRunner.go | 5 +- 4 files changed, 103 insertions(+), 112 deletions(-) diff --git a/cmd/node/main.go b/cmd/node/main.go index 8eb0905e97d..1ed63d4364e 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -106,11 +106,6 @@ func startNodeRunner(c *cli.Context, log logger.Logger, baseVersion string, vers return errCfgOverride } - errCheckEpochsCfg := config.SanityCheckEnableEpochsStakingV4(cfgs) - if errCheckEpochsCfg != nil { - return errCheckEpochsCfg - } - if !check.IfNil(fileLogging) { timeLogLifeSpan := time.Second * time.Duration(cfgs.GeneralConfig.Logs.LogFileLifeSpanInSec) sizeLogLifeSpanInMB := uint64(cfgs.GeneralConfig.Logs.LogFileLifeSpanInMB) diff --git a/config/configChecker.go b/config/configChecker.go index 589f31528b1..e72957265f7 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -4,14 +4,47 @@ import ( "fmt" ) -// SanityCheckEnableEpochsStakingV4 checks if the enable epoch configs for stakingV4 are set correctly -func SanityCheckEnableEpochsStakingV4(cfg *Configs) error { - enableEpochsCfg := cfg.EpochConfig.EnableEpochs +// SanityCheckNodesConfig checks if the nodes limit setup is set correctly +func SanityCheckNodesConfig( + nodesSetup NodesSetupHandler, + cfg EnableEpochs, +) error { + maxNodesChange := cfg.MaxNodesChangeEnableEpoch + for _, maxNodesConfig := range maxNodesChange { + err := checkMaxNodesConfig(nodesSetup, maxNodesConfig) + if err != nil { + return fmt.Errorf("%w in MaxNodesChangeConfig at EpochEnable = %d", err, maxNodesConfig.EpochEnable) + } + } + + return sanityCheckEnableEpochsStakingV4(cfg, nodesSetup.NumberOfShards()) +} + +func checkMaxNodesConfig( + nodesSetup NodesSetupHandler, + maxNodesConfig MaxNodesChangeConfig, +) error { + nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard + if nodesToShufflePerShard == 0 { + return errZeroNodesToShufflePerShard + } + + maxNumNodes := maxNodesConfig.MaxNumNodes + minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() + if maxNumNodes < minNumNodesWithHysteresis { + return fmt.Errorf("%w, maxNumNodes: %d, minNumNodesWithHysteresis: %d", + errInvalidMaxMinNodes, maxNumNodes, minNumNodesWithHysteresis) + } + + return nil +} + +// sanityCheckEnableEpochsStakingV4 checks if the enable epoch configs for stakingV4 are set correctly +func sanityCheckEnableEpochsStakingV4(enableEpochsCfg EnableEpochs, numOfShards uint32) error { if !areStakingV4StepsInOrder(enableEpochsCfg) { return errStakingV4StepsNotInOrder } - numOfShards := cfg.GeneralConfig.GeneralSettings.GenesisMaxNumberOfShards return checkStakingV4MaxNodesChangeCfg(enableEpochsCfg, numOfShards) } @@ -68,37 +101,3 @@ func checkMaxNodesChangedCorrectly(prevMaxNodesChange MaxNodesChangeConfig, curr return nil } - -// SanityCheckNodesConfig checks if the nodes limit setup is set correctly -func SanityCheckNodesConfig( - nodesSetup NodesSetupHandler, - maxNodesChange []MaxNodesChangeConfig, -) error { - for _, maxNodesConfig := range maxNodesChange { - err := checkMaxNodesConfig(nodesSetup, maxNodesConfig) - if err != nil { - return fmt.Errorf("%w in MaxNodesChangeConfig at EpochEnable = %d", err, maxNodesConfig.EpochEnable) - } - } - - return nil -} - -func checkMaxNodesConfig( - nodesSetup NodesSetupHandler, - maxNodesConfig MaxNodesChangeConfig, -) error { - nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard - if nodesToShufflePerShard == 0 { - return errZeroNodesToShufflePerShard - } - - maxNumNodes := maxNodesConfig.MaxNumNodes - minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() - if maxNumNodes < minNumNodesWithHysteresis { - return fmt.Errorf("%w, maxNumNodes: %d, minNumNodesWithHysteresis: %d", - errInvalidMaxMinNodes, maxNumNodes, minNumNodesWithHysteresis) - } - - return nil -} diff --git a/config/configChecker_test.go b/config/configChecker_test.go index a6dc964a524..492e1a4db91 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -8,35 +8,28 @@ import ( "github.com/stretchr/testify/require" ) -func generateCorrectConfig() *Configs { - return &Configs{ - EpochConfig: &EpochConfig{ - EnableEpochs: EnableEpochs{ - StakingV4Step1EnableEpoch: 4, - StakingV4Step2EnableEpoch: 5, - StakingV4Step3EnableEpoch: 6, - MaxNodesChangeEnableEpoch: []MaxNodesChangeConfig{ - { - EpochEnable: 0, - MaxNumNodes: 36, - NodesToShufflePerShard: 4, - }, - { - EpochEnable: 1, - MaxNumNodes: 56, - NodesToShufflePerShard: 2, - }, - { - EpochEnable: 6, - MaxNumNodes: 48, - NodesToShufflePerShard: 2, - }, - }, +const numOfShards = 3 + +func generateCorrectConfig() EnableEpochs { + return EnableEpochs{ + StakingV4Step1EnableEpoch: 4, + StakingV4Step2EnableEpoch: 5, + StakingV4Step3EnableEpoch: 6, + MaxNodesChangeEnableEpoch: []MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, }, - }, - GeneralConfig: &Config{ - GeneralSettings: GeneralSettingsConfig{ - GenesisMaxNumberOfShards: 3, + { + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, }, }, } @@ -49,7 +42,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - err := SanityCheckEnableEpochsStakingV4(cfg) + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Nil(t, err) }) @@ -57,15 +50,15 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 5 - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 - err := SanityCheckEnableEpochsStakingV4(cfg) + cfg.StakingV4Step1EnableEpoch = 5 + cfg.StakingV4Step2EnableEpoch = 5 + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Equal(t, errStakingV4StepsNotInOrder, err) cfg = generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - err = SanityCheckEnableEpochsStakingV4(cfg) + cfg.StakingV4Step2EnableEpoch = 5 + cfg.StakingV4Step3EnableEpoch = 4 + err = sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Equal(t, errStakingV4StepsNotInOrder, err) }) @@ -74,22 +67,22 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 - err := SanityCheckEnableEpochsStakingV4(cfg) + cfg.StakingV4Step1EnableEpoch = 1 + cfg.StakingV4Step2EnableEpoch = 3 + cfg.StakingV4Step3EnableEpoch = 6 + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Equal(t, errStakingV4StepsNotInOrder, err) - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 2 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 - err = SanityCheckEnableEpochsStakingV4(cfg) + cfg.StakingV4Step1EnableEpoch = 1 + cfg.StakingV4Step2EnableEpoch = 2 + cfg.StakingV4Step3EnableEpoch = 6 + err = sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Equal(t, errStakingV4StepsNotInOrder, err) - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 1 - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 5 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 6 - err = SanityCheckEnableEpochsStakingV4(cfg) + cfg.StakingV4Step1EnableEpoch = 1 + cfg.StakingV4Step2EnableEpoch = 5 + cfg.StakingV4Step3EnableEpoch = 6 + err = sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Equal(t, errStakingV4StepsNotInOrder, err) }) @@ -97,7 +90,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 6, MaxNumNodes: 48, @@ -105,7 +98,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { }, } - err := SanityCheckEnableEpochsStakingV4(cfg) + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.Equal(t, errNotEnoughMaxNodesChanges, err) }) @@ -113,7 +106,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 1, MaxNumNodes: 56, @@ -126,7 +119,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { }, } - err := SanityCheckEnableEpochsStakingV4(cfg) + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), errNoMaxNodesConfigChangeForStakingV4.Error())) require.True(t, strings.Contains(err.Error(), "6")) @@ -136,9 +129,9 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { - EpochEnable: cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch, + EpochEnable: cfg.StakingV4Step3EnableEpoch, MaxNumNodes: 48, NodesToShufflePerShard: 2, }, @@ -149,7 +142,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { }, } - err := SanityCheckEnableEpochsStakingV4(cfg) + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.NotNil(t, err) require.ErrorIs(t, err, errNoMaxNodesConfigBeforeStakingV4) }) @@ -158,10 +151,10 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[1].NodesToShufflePerShard = 2 - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].NodesToShufflePerShard = 4 + cfg.MaxNodesChangeEnableEpoch[1].NodesToShufflePerShard = 2 + cfg.MaxNodesChangeEnableEpoch[2].NodesToShufflePerShard = 4 - err := SanityCheckEnableEpochsStakingV4(cfg) + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.ErrorIs(t, err, errMismatchNodesToShuffle) }) @@ -169,9 +162,9 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].MaxNumNodes = 56 + cfg.MaxNodesChangeEnableEpoch[2].MaxNumNodes = 56 - err := SanityCheckEnableEpochsStakingV4(cfg) + err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), "expected")) require.True(t, strings.Contains(err.Error(), "48")) @@ -187,7 +180,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { t.Run("should work", func(t *testing.T) { t.Parallel() - cfg := generateCorrectConfig().EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch + cfg := generateCorrectConfig() nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, HysteresisField: 0, @@ -197,7 +190,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { err := SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) - cfg = []MaxNodesChangeConfig{ + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 1, MaxNumNodes: 3200, @@ -218,6 +211,11 @@ func TestSanityCheckNodesConfig(t *testing.T) { MaxNumNodes: 2240, NodesToShufflePerShard: 40, }, + { + EpochEnable: 6, + MaxNumNodes: 2080, + NodesToShufflePerShard: 40, + }, } nodesSetup = &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, @@ -228,7 +226,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { err = SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) - cfg = []MaxNodesChangeConfig{ + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 0, MaxNumNodes: 36, @@ -254,7 +252,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { err = SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) - cfg = []MaxNodesChangeConfig{ + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 0, MaxNumNodes: 36, @@ -284,7 +282,8 @@ func TestSanityCheckNodesConfig(t *testing.T) { t.Run("zero nodes to shuffle per shard, should return error", func(t *testing.T) { t.Parallel() - cfg := []MaxNodesChangeConfig{ + cfg := generateCorrectConfig() + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 4, MaxNumNodes: 3200, @@ -306,7 +305,8 @@ func TestSanityCheckNodesConfig(t *testing.T) { t.Run("maxNumNodes < minNumNodesWithHysteresis, should return error ", func(t *testing.T) { t.Parallel() - cfg := []MaxNodesChangeConfig{ + cfg := generateCorrectConfig() + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ { EpochEnable: 4, MaxNumNodes: 1900, diff --git a/node/nodeRunner.go b/node/nodeRunner.go index cfdc8d2788f..db53e2298c9 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -287,10 +287,7 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( return true, err } - err = config.SanityCheckNodesConfig( - managedCoreComponents.GenesisNodesSetup(), - configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch, - ) + err = config.SanityCheckNodesConfig(managedCoreComponents.GenesisNodesSetup(), configs.EpochConfig.EnableEpochs) if err != nil { return true, err } From 564f5bb9de7e210661a0ab8bbfebb19d8352ffc9 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 11 Jan 2024 14:43:10 +0200 Subject: [PATCH 596/958] FIX: Enable epoch --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index f82eb5f763e..47bd0336b91 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -309,7 +309,7 @@ # - Enable epoch = StakingV4Step3EnableEpoch # - NodesToShufflePerShard = same as previous entry in MaxNodesChangeEnableEpoch # - MaxNumNodes = (MaxNumNodesFromPreviousEpochEnable - (numOfShards+1)*NodesToShufflePerShard) - { EpochEnable = 6, MaxNumNodes = 48, NodesToShufflePerShard = 2 }, + { EpochEnable = 6, MaxNumNodes = 50, NodesToShufflePerShard = 2 }, ] [GasSchedule] From 2b89371356927cedf050a292257d8901bb16c811 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 11 Jan 2024 17:27:16 +0200 Subject: [PATCH 597/958] FIX: MaxNumNodes in enable epochs --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 47bd0336b91..f82eb5f763e 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -309,7 +309,7 @@ # - Enable epoch = StakingV4Step3EnableEpoch # - NodesToShufflePerShard = same as previous entry in MaxNodesChangeEnableEpoch # - MaxNumNodes = (MaxNumNodesFromPreviousEpochEnable - (numOfShards+1)*NodesToShufflePerShard) - { EpochEnable = 6, MaxNumNodes = 50, NodesToShufflePerShard = 2 }, + { EpochEnable = 6, MaxNumNodes = 48, NodesToShufflePerShard = 2 }, ] [GasSchedule] From cc4330286fca2ed05147021b8fc8c501ae17e800 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 12 Jan 2024 09:50:45 +0200 Subject: [PATCH 598/958] - fixed the redundancy metric to include the multikey status - added a new metric that contains the reason of step-in, in case the node is not main node and the main node failed --- common/constants.go | 3 + common/interface.go | 1 + consensus/interface.go | 1 + consensus/spos/consensusState.go | 5 ++ consensus/spos/consensusState_test.go | 35 ++++++++ consensus/spos/export_test.go | 13 +++ consensus/spos/worker.go | 16 +++- consensus/spos/worker_test.go | 97 +++++++++++++++++++++- keysManagement/export_test.go | 6 ++ keysManagement/keysHandler.go | 5 ++ keysManagement/keysHandler_test.go | 15 ++++ keysManagement/managedPeersHolder.go | 25 ++++++ keysManagement/managedPeersHolder_test.go | 63 +++++++++++++- node/nodeRunner.go | 1 + testscommon/keysHandlerSingleSignerMock.go | 5 ++ testscommon/keysHandlerStub.go | 10 +++ testscommon/managedPeersHolderStub.go | 10 +++ 17 files changed, 305 insertions(+), 6 deletions(-) diff --git a/common/constants.go b/common/constants.go index 223dcebd189..487166299a6 100644 --- a/common/constants.go +++ b/common/constants.go @@ -307,6 +307,9 @@ const MetricRedundancyLevel = "erd_redundancy_level" // MetricRedundancyIsMainActive is the metric that specifies data about the redundancy main machine const MetricRedundancyIsMainActive = "erd_redundancy_is_main_active" +// MetricRedundancyStepInReason is the metric that specifies why the back-up machine stepped in +const MetricRedundancyStepInReason = "erd_redundancy_step_in_reason" + // MetricValueNA represents the value to be used when a metric is not available/applicable const MetricValueNA = "N/A" diff --git a/common/interface.go b/common/interface.go index 9bc3e8c5090..d6099536d69 100644 --- a/common/interface.go +++ b/common/interface.go @@ -421,6 +421,7 @@ type ManagedPeersHolder interface { GetNextPeerAuthenticationTime(pkBytes []byte) (time.Time, error) SetNextPeerAuthenticationTime(pkBytes []byte, nextTime time.Time) IsMultiKeyMode() bool + GetRedundancyStepInReason() string IsInterfaceNil() bool } diff --git a/consensus/interface.go b/consensus/interface.go index 97292269a99..aa8d9057bc4 100644 --- a/consensus/interface.go +++ b/consensus/interface.go @@ -190,5 +190,6 @@ type KeysHandler interface { GetAssociatedPid(pkBytes []byte) core.PeerID IsOriginalPublicKeyOfTheNode(pkBytes []byte) bool ResetRoundsWithoutReceivedMessages(pkBytes []byte, pid core.PeerID) + GetRedundancyStepInReason() string IsInterfaceNil() bool } diff --git a/consensus/spos/consensusState.go b/consensus/spos/consensusState.go index c3f48919d83..564b3def852 100644 --- a/consensus/spos/consensusState.go +++ b/consensus/spos/consensusState.go @@ -380,6 +380,11 @@ func (cns *ConsensusState) IsMultiKeyJobDone(currentSubroundId int) bool { return true } +// GetMultikeyRedundancyStepInReason returns the reason if the current node stepped in as a multikey redundancy node +func (cns *ConsensusState) GetMultikeyRedundancyStepInReason() string { + return cns.keysHandler.GetRedundancyStepInReason() +} + // ResetRoundsWithoutReceivedMessages will reset the rounds received without a message for a specified public key by // providing also the peer ID from the received message func (cns *ConsensusState) ResetRoundsWithoutReceivedMessages(pkBytes []byte, pid core.PeerID) { diff --git a/consensus/spos/consensusState_test.go b/consensus/spos/consensusState_test.go index 74c8426f197..554c9c0c755 100644 --- a/consensus/spos/consensusState_test.go +++ b/consensus/spos/consensusState_test.go @@ -5,6 +5,7 @@ import ( "errors" "testing" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos" @@ -582,3 +583,37 @@ func TestConsensusState_IsMultiKeyJobDone(t *testing.T) { assert.True(t, cns.IsMultiKeyJobDone(0)) }) } + +func TestConsensusState_GetMultikeyRedundancyStepInReason(t *testing.T) { + t.Parallel() + + expectedString := "expected string" + keysHandler := &testscommon.KeysHandlerStub{ + GetRedundancyStepInReasonCalled: func() string { + return expectedString + }, + } + cns := internalInitConsensusStateWithKeysHandler(keysHandler) + + assert.Equal(t, expectedString, cns.GetMultikeyRedundancyStepInReason()) +} + +func TestConsensusState_ResetRoundsWithoutReceivedMessages(t *testing.T) { + t.Parallel() + + resetRoundsWithoutReceivedMessagesCalled := false + testPkBytes := []byte("pk bytes") + testPid := core.PeerID("pid") + + keysHandler := &testscommon.KeysHandlerStub{ + ResetRoundsWithoutReceivedMessagesCalled: func(pkBytes []byte, pid core.PeerID) { + resetRoundsWithoutReceivedMessagesCalled = true + assert.Equal(t, testPkBytes, pkBytes) + assert.Equal(t, testPid, pid) + }, + } + cns := internalInitConsensusStateWithKeysHandler(keysHandler) + + cns.ResetRoundsWithoutReceivedMessages(testPkBytes, testPid) + assert.True(t, resetRoundsWithoutReceivedMessagesCalled) +} diff --git a/consensus/spos/export_test.go b/consensus/spos/export_test.go index 3a02e7b27fb..39d19de6e30 100644 --- a/consensus/spos/export_test.go +++ b/consensus/spos/export_test.go @@ -10,6 +10,9 @@ import ( "github.com/multiversx/mx-chain-go/process" ) +// RedundancySingleKeySteppedIn exposes the redundancySingleKeySteppedIn constant +const RedundancySingleKeySteppedIn = redundancySingleKeySteppedIn + type RoundConsensus struct { *roundConsensus } @@ -173,6 +176,16 @@ func (wrk *Worker) CheckSelfState(cnsDta *consensus.Message) error { return wrk.checkSelfState(cnsDta) } +// SetRedundancyHandler - +func (wrk *Worker) SetRedundancyHandler(redundancyHandler consensus.NodeRedundancyHandler) { + wrk.nodeRedundancyHandler = redundancyHandler +} + +// SetKeysHandler - +func (wrk *Worker) SetKeysHandler(keysHandler consensus.KeysHandler) { + wrk.consensusState.keysHandler = keysHandler +} + // EligibleList - func (rcns *RoundConsensus) EligibleList() map[string]struct{} { return rcns.eligibleNodes diff --git a/consensus/spos/worker.go b/consensus/spos/worker.go index 8fdcca4686f..f7159454f2a 100644 --- a/consensus/spos/worker.go +++ b/consensus/spos/worker.go @@ -31,6 +31,7 @@ var _ closing.Closer = (*Worker)(nil) // sleepTime defines the time in milliseconds between each iteration made in checkChannels method const sleepTime = 5 * time.Millisecond +const redundancySingleKeySteppedIn = "single-key node stepped in" // Worker defines the data needed by spos to communicate between nodes which are in the validators group type Worker struct { @@ -545,7 +546,20 @@ func (wrk *Worker) processReceivedHeaderMetric(cnsDta *consensus.Message) { } percent := sinceRoundStart * 100 / wrk.roundHandler.TimeDuration() wrk.appStatusHandler.SetUInt64Value(common.MetricReceivedProposedBlock, uint64(percent)) - wrk.appStatusHandler.SetStringValue(common.MetricRedundancyIsMainActive, strconv.FormatBool(wrk.nodeRedundancyHandler.IsMainMachineActive())) + + isMainMachineActive, redundancyReason := wrk.computeRedundancyMetrics() + wrk.appStatusHandler.SetStringValue(common.MetricRedundancyIsMainActive, strconv.FormatBool(isMainMachineActive)) + wrk.appStatusHandler.SetStringValue(common.MetricRedundancyStepInReason, redundancyReason) +} + +func (wrk *Worker) computeRedundancyMetrics() (bool, string) { + if !wrk.nodeRedundancyHandler.IsMainMachineActive() { + return false, redundancySingleKeySteppedIn + } + + reason := wrk.consensusState.GetMultikeyRedundancyStepInReason() + + return len(reason) == 0, reason } func (wrk *Worker) checkSelfState(cnsDta *consensus.Message) error { diff --git a/consensus/spos/worker_test.go b/consensus/spos/worker_test.go index 37cc36f33c1..59d155e2117 100644 --- a/consensus/spos/worker_test.go +++ b/consensus/spos/worker_test.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "math/big" + "strconv" "sync/atomic" "testing" "time" @@ -628,13 +629,21 @@ func TestWorker_ProcessReceivedMessageComputeReceivedProposedBlockMetric(t *test delay := time.Millisecond * 430 roundStartTimeStamp := time.Now() - receivedValue := testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric(roundStartTimeStamp, delay, roundDuration) + receivedValue, redundancyReason, redundancyStatus := testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( + t, + roundStartTimeStamp, + delay, + roundDuration, + &mock.NodeRedundancyHandlerStub{}, + &testscommon.KeysHandlerStub{}) minimumExpectedValue := uint64(delay * 100 / roundDuration) assert.True(t, receivedValue >= minimumExpectedValue, fmt.Sprintf("minimum expected was %d, got %d", minimumExpectedValue, receivedValue), ) + assert.Empty(t, redundancyReason) + assert.True(t, redundancyStatus) }) t.Run("time.Since returns negative value", func(t *testing.T) { // test the edgecase when the returned NTP time stored in the round handler is @@ -645,23 +654,101 @@ func TestWorker_ProcessReceivedMessageComputeReceivedProposedBlockMetric(t *test delay := time.Millisecond * 430 roundStartTimeStamp := time.Now().Add(time.Minute) - receivedValue := testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric(roundStartTimeStamp, delay, roundDuration) + receivedValue, redundancyReason, redundancyStatus := testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( + t, + roundStartTimeStamp, + delay, + roundDuration, + &mock.NodeRedundancyHandlerStub{}, + &testscommon.KeysHandlerStub{}) assert.Zero(t, receivedValue) + assert.Empty(t, redundancyReason) + assert.True(t, redundancyStatus) + }) + t.Run("normal operation as a single-key redundancy node", func(t *testing.T) { + t.Parallel() + + roundDuration := time.Millisecond * 1000 + delay := time.Millisecond * 430 + roundStartTimeStamp := time.Now() + + receivedValue, redundancyReason, redundancyStatus := testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( + t, + roundStartTimeStamp, + delay, + roundDuration, + &mock.NodeRedundancyHandlerStub{ + IsMainMachineActiveCalled: func() bool { + return false + }, + }, + &testscommon.KeysHandlerStub{}) + + minimumExpectedValue := uint64(delay * 100 / roundDuration) + assert.True(t, + receivedValue >= minimumExpectedValue, + fmt.Sprintf("minimum expected was %d, got %d", minimumExpectedValue, receivedValue), + ) + assert.Equal(t, spos.RedundancySingleKeySteppedIn, redundancyReason) + assert.False(t, redundancyStatus) + }) + t.Run("normal operation as a multikey-key redundancy node", func(t *testing.T) { + t.Parallel() + + roundDuration := time.Millisecond * 1000 + delay := time.Millisecond * 430 + roundStartTimeStamp := time.Now() + + multikeyReason := "multikey step in reason" + receivedValue, redundancyReason, redundancyStatus := testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( + t, + roundStartTimeStamp, + delay, + roundDuration, + &mock.NodeRedundancyHandlerStub{}, + &testscommon.KeysHandlerStub{ + GetRedundancyStepInReasonCalled: func() string { + return multikeyReason + }, + }) + + minimumExpectedValue := uint64(delay * 100 / roundDuration) + assert.True(t, + receivedValue >= minimumExpectedValue, + fmt.Sprintf("minimum expected was %d, got %d", minimumExpectedValue, receivedValue), + ) + assert.Equal(t, multikeyReason, redundancyReason) + assert.False(t, redundancyStatus) }) } func testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( + t *testing.T, roundStartTimeStamp time.Time, delay time.Duration, roundDuration time.Duration, -) uint64 { + redundancyHandler consensus.NodeRedundancyHandler, + keysHandler consensus.KeysHandler, +) (uint64, string, bool) { marshaller := mock.MarshalizerMock{} receivedValue := uint64(0) + redundancyReason := "" + redundancyStatus := false wrk := *initWorker(&statusHandlerMock.AppStatusHandlerStub{ SetUInt64ValueHandler: func(key string, value uint64) { receivedValue = value }, + SetStringValueHandler: func(key string, value string) { + if key == common.MetricRedundancyIsMainActive { + var err error + redundancyStatus, err = strconv.ParseBool(value) + assert.Nil(t, err) + } + if key == common.MetricRedundancyStepInReason { + redundancyReason = value + } + }, }) wrk.SetBlockProcessor(&testscommon.BlockProcessorStub{ DecodeBlockHeaderCalled: func(dta []byte) data.HeaderHandler { @@ -686,6 +773,8 @@ func testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( return roundStartTimeStamp }, }) + wrk.SetRedundancyHandler(redundancyHandler) + wrk.SetKeysHandler(keysHandler) hdr := &block.Header{ ChainID: chainID, PrevHash: []byte("prev hash"), @@ -725,7 +814,7 @@ func testWorkerProcessReceivedMessageComputeReceivedProposedBlockMetric( } _ = wrk.ProcessReceivedMessage(msg, "", &p2pmocks.MessengerStub{}) - return receivedValue + return receivedValue, redundancyReason, redundancyStatus } func TestWorker_ProcessReceivedMessageInconsistentChainIDInConsensusMessageShouldErr(t *testing.T) { diff --git a/keysManagement/export_test.go b/keysManagement/export_test.go index b9e80ddcc66..42d1ee00317 100644 --- a/keysManagement/export_test.go +++ b/keysManagement/export_test.go @@ -6,6 +6,12 @@ import ( "github.com/multiversx/mx-chain-go/common" ) +// exported constants +const ( + RedundancyReasonForOneKey = redundancyReasonForOneKey + RedundancyReasonForMultipleKeys = redundancyReasonForMultipleKeys +) + // GetRoundsOfInactivity - func (pInfo *peerInfo) GetRoundsOfInactivity() int { pInfo.mutChangeableData.RLock() diff --git a/keysManagement/keysHandler.go b/keysManagement/keysHandler.go index 109b05fc712..1b4b83c2e6f 100644 --- a/keysManagement/keysHandler.go +++ b/keysManagement/keysHandler.go @@ -120,6 +120,11 @@ func (handler *keysHandler) ResetRoundsWithoutReceivedMessages(pkBytes []byte, p handler.managedPeersHolder.ResetRoundsWithoutReceivedMessages(pkBytes, pid) } +// GetRedundancyStepInReason returns the reason if the current node stepped in as a redundancy node +func (handler *keysHandler) GetRedundancyStepInReason() string { + return handler.managedPeersHolder.GetRedundancyStepInReason() +} + // IsInterfaceNil returns true if there is no value under the interface func (handler *keysHandler) IsInterfaceNil() bool { return handler == nil diff --git a/keysManagement/keysHandler_test.go b/keysManagement/keysHandler_test.go index fecfddf3a29..886053a1b94 100644 --- a/keysManagement/keysHandler_test.go +++ b/keysManagement/keysHandler_test.go @@ -268,3 +268,18 @@ func TestKeysHandler_ResetRoundsWithoutReceivedMessages(t *testing.T) { assert.Equal(t, 1, len(mapResetCalled)) assert.Equal(t, 1, mapResetCalled[string(randomPublicKeyBytes)]) } + +func TestKeysHandler_GetRedundancyStepInReason(t *testing.T) { + t.Parallel() + + expectedString := "expected string" + args := createMockArgsKeysHandler() + args.ManagedPeersHolder = &testscommon.ManagedPeersHolderStub{ + GetRedundancyStepInReasonCalled: func() string { + return expectedString + }, + } + + handler, _ := keysManagement.NewKeysHandler(args) + assert.Equal(t, expectedString, handler.GetRedundancyStepInReason()) +} diff --git a/keysManagement/managedPeersHolder.go b/keysManagement/managedPeersHolder.go index 93e48fa2e30..a347f4f2a53 100644 --- a/keysManagement/managedPeersHolder.go +++ b/keysManagement/managedPeersHolder.go @@ -19,6 +19,11 @@ import ( var log = logger.GetOrCreate("keysManagement") +const ( + redundancyReasonForOneKey = "multikey node stepped in with one key" + redundancyReasonForMultipleKeys = "multikey node stepped in with %d keys" +) + type managedPeersHolder struct { mut sync.RWMutex defaultPeerInfoCurrentIndex int @@ -369,6 +374,26 @@ func (holder *managedPeersHolder) IsMultiKeyMode() bool { return len(holder.data) > 0 } +// GetRedundancyStepInReason returns the reason if the current node stepped in as a redundancy node +// Returns empty string if the current node is the main multikey machine, the machine is not running in multikey mode +// or the machine is acting as a backup but the main machine is acting accordingly +func (holder *managedPeersHolder) GetRedundancyStepInReason() string { + if holder.isMainMachine { + return "" + } + + numManagedKeys := len(holder.GetManagedKeysByCurrentNode()) + if numManagedKeys == 0 { + return "" + } + + if numManagedKeys == 1 { + return redundancyReasonForOneKey + } + + return fmt.Sprintf(redundancyReasonForMultipleKeys, numManagedKeys) +} + // IsInterfaceNil returns true if there is no value under the interface func (holder *managedPeersHolder) IsInterfaceNil() bool { return holder == nil diff --git a/keysManagement/managedPeersHolder_test.go b/keysManagement/managedPeersHolder_test.go index 7c2d278f9cd..81f0dfff86b 100644 --- a/keysManagement/managedPeersHolder_test.go +++ b/keysManagement/managedPeersHolder_test.go @@ -935,6 +935,65 @@ func TestManagedPeersHolder_IsMultiKeyMode(t *testing.T) { }) } +func TestManagedPeersHolder_GetRedundancyStepInReason(t *testing.T) { + t.Parallel() + + t.Run("main machine mode", func(t *testing.T) { + args := createMockArgsManagedPeersHolder() + holder, _ := keysManagement.NewManagedPeersHolder(args) + assert.Empty(t, holder.GetRedundancyStepInReason()) + }) + t.Run("redundancy machine mode but no managed keys", func(t *testing.T) { + args := createMockArgsManagedPeersHolder() + args.MaxRoundsOfInactivity = 2 + holder, _ := keysManagement.NewManagedPeersHolder(args) + assert.Empty(t, holder.GetRedundancyStepInReason()) + }) + t.Run("redundancy machine mode with one managed key, main active", func(t *testing.T) { + args := createMockArgsManagedPeersHolder() + args.MaxRoundsOfInactivity = 2 + holder, _ := keysManagement.NewManagedPeersHolder(args) + _ = holder.AddManagedPeer(skBytes0) + + assert.Empty(t, holder.GetRedundancyStepInReason()) + }) + t.Run("redundancy machine mode with one managed key, main inactive", func(t *testing.T) { + args := createMockArgsManagedPeersHolder() + args.MaxRoundsOfInactivity = 2 + holder, _ := keysManagement.NewManagedPeersHolder(args) + _ = holder.AddManagedPeer(skBytes0) + for i := 0; i < args.MaxRoundsOfInactivity+1; i++ { + holder.IncrementRoundsWithoutReceivedMessages(pkBytes0) + } + + assert.Equal(t, keysManagement.RedundancyReasonForOneKey, holder.GetRedundancyStepInReason()) + }) + t.Run("redundancy machine mode with 2 managed keys, main active", func(t *testing.T) { + args := createMockArgsManagedPeersHolder() + args.MaxRoundsOfInactivity = 2 + holder, _ := keysManagement.NewManagedPeersHolder(args) + _ = holder.AddManagedPeer(skBytes0) + _ = holder.AddManagedPeer(skBytes1) + + assert.Empty(t, holder.GetRedundancyStepInReason()) + }) + t.Run("redundancy machine mode with 2 managed keys, main inactive", func(t *testing.T) { + args := createMockArgsManagedPeersHolder() + args.MaxRoundsOfInactivity = 2 + holder, _ := keysManagement.NewManagedPeersHolder(args) + _ = holder.AddManagedPeer(skBytes0) + _ = holder.AddManagedPeer(skBytes1) + + for i := 0; i < args.MaxRoundsOfInactivity+1; i++ { + holder.IncrementRoundsWithoutReceivedMessages(pkBytes0) + holder.IncrementRoundsWithoutReceivedMessages(pkBytes1) + } + + expectedReason := fmt.Sprintf(keysManagement.RedundancyReasonForMultipleKeys, 2) + assert.Equal(t, expectedReason, holder.GetRedundancyStepInReason()) + }) +} + func TestManagedPeersHolder_ParallelOperationsShouldNotPanic(t *testing.T) { defer func() { r := recover() @@ -984,10 +1043,12 @@ func TestManagedPeersHolder_ParallelOperationsShouldNotPanic(t *testing.T) { _, _ = holder.GetNextPeerAuthenticationTime(pkBytes0) case 13: holder.SetNextPeerAuthenticationTime(pkBytes0, time.Now()) + case 14: + _ = holder.GetRedundancyStepInReason() } wg.Done() - }(i % 14) + }(i % 15) } wg.Wait() diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 61fe217d574..11bc7eea435 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -808,6 +808,7 @@ func (nr *nodeRunner) createMetrics( metrics.SaveStringMetric(statusCoreComponents.AppStatusHandler(), common.MetricNodeDisplayName, nr.configs.PreferencesConfig.Preferences.NodeDisplayName) metrics.SaveStringMetric(statusCoreComponents.AppStatusHandler(), common.MetricRedundancyLevel, fmt.Sprintf("%d", nr.configs.PreferencesConfig.Preferences.RedundancyLevel)) metrics.SaveStringMetric(statusCoreComponents.AppStatusHandler(), common.MetricRedundancyIsMainActive, common.MetricValueNA) + metrics.SaveStringMetric(statusCoreComponents.AppStatusHandler(), common.MetricRedundancyStepInReason, "") metrics.SaveStringMetric(statusCoreComponents.AppStatusHandler(), common.MetricChainId, coreComponents.ChainID()) metrics.SaveUint64Metric(statusCoreComponents.AppStatusHandler(), common.MetricGasPerDataByte, coreComponents.EconomicsData().GasPerDataByte()) metrics.SaveUint64Metric(statusCoreComponents.AppStatusHandler(), common.MetricMinGasPrice, coreComponents.EconomicsData().MinGasPrice()) diff --git a/testscommon/keysHandlerSingleSignerMock.go b/testscommon/keysHandlerSingleSignerMock.go index 9235a5a2abe..afc38cbfab5 100644 --- a/testscommon/keysHandlerSingleSignerMock.go +++ b/testscommon/keysHandlerSingleSignerMock.go @@ -67,6 +67,11 @@ func (mock *keysHandlerSingleSignerMock) IsOriginalPublicKeyOfTheNode(pkBytes [] func (mock *keysHandlerSingleSignerMock) ResetRoundsWithoutReceivedMessages(_ []byte, _ core.PeerID) { } +// GetRedundancyStepInReason - +func (mock *keysHandlerSingleSignerMock) GetRedundancyStepInReason() string { + return "" +} + // IsInterfaceNil - func (mock *keysHandlerSingleSignerMock) IsInterfaceNil() bool { return mock == nil diff --git a/testscommon/keysHandlerStub.go b/testscommon/keysHandlerStub.go index 8549de432f3..5821f305654 100644 --- a/testscommon/keysHandlerStub.go +++ b/testscommon/keysHandlerStub.go @@ -15,6 +15,7 @@ type KeysHandlerStub struct { GetAssociatedPidCalled func(pkBytes []byte) core.PeerID IsOriginalPublicKeyOfTheNodeCalled func(pkBytes []byte) bool ResetRoundsWithoutReceivedMessagesCalled func(pkBytes []byte, pid core.PeerID) + GetRedundancyStepInReasonCalled func() string } // GetHandledPrivateKey - @@ -76,6 +77,15 @@ func (stub *KeysHandlerStub) ResetRoundsWithoutReceivedMessages(pkBytes []byte, } } +// GetRedundancyStepInReason - +func (stub *KeysHandlerStub) GetRedundancyStepInReason() string { + if stub.GetRedundancyStepInReasonCalled != nil { + return stub.GetRedundancyStepInReasonCalled() + } + + return "" +} + // IsInterfaceNil - func (stub *KeysHandlerStub) IsInterfaceNil() bool { return stub == nil diff --git a/testscommon/managedPeersHolderStub.go b/testscommon/managedPeersHolderStub.go index 1cbd397debc..0bd1948d813 100644 --- a/testscommon/managedPeersHolderStub.go +++ b/testscommon/managedPeersHolderStub.go @@ -25,6 +25,7 @@ type ManagedPeersHolderStub struct { GetNextPeerAuthenticationTimeCalled func(pkBytes []byte) (time.Time, error) SetNextPeerAuthenticationTimeCalled func(pkBytes []byte, nextTime time.Time) IsMultiKeyModeCalled func() bool + GetRedundancyStepInReasonCalled func() string } // AddManagedPeer - @@ -151,6 +152,15 @@ func (stub *ManagedPeersHolderStub) IsMultiKeyMode() bool { return false } +// GetRedundancyStepInReason - +func (stub *ManagedPeersHolderStub) GetRedundancyStepInReason() string { + if stub.GetRedundancyStepInReasonCalled != nil { + return stub.GetRedundancyStepInReasonCalled() + } + + return "" +} + // IsInterfaceNil - func (stub *ManagedPeersHolderStub) IsInterfaceNil() bool { return stub == nil From a0fcccba40b8d688f4b1e658feda641e6485aaa9 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 12 Jan 2024 12:45:31 +0200 Subject: [PATCH 599/958] change indexer version --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index efea0bc83be..3c78ab7c4d6 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/multiversx/mx-chain-communication-go v1.0.12 github.com/multiversx/mx-chain-core-go v1.2.18 github.com/multiversx/mx-chain-crypto-go v1.2.9 - github.com/multiversx/mx-chain-es-indexer-go v1.4.17 + github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20240112103055-0aaca2e304fe github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 diff --git a/go.sum b/go.sum index a609d6be13b..2cdbe151f1a 100644 --- a/go.sum +++ b/go.sum @@ -390,8 +390,8 @@ github.com/multiversx/mx-chain-core-go v1.2.18 h1:fnub2eFL7XYOLrKKVZAPPsaM1TWEna github.com/multiversx/mx-chain-core-go v1.2.18/go.mod h1:BILOGHUOIG5dNNX8cgkzCNfDaVtoYrJRYcPnpxRMH84= github.com/multiversx/mx-chain-crypto-go v1.2.9 h1:OEfF2kOQrtzUl273Z3DEcshjlTVUfPpJMd0R0SvTrlU= github.com/multiversx/mx-chain-crypto-go v1.2.9/go.mod h1:fkaWKp1rbQN9wPKya5jeoRyC+c/SyN/NfggreyeBw+8= -github.com/multiversx/mx-chain-es-indexer-go v1.4.17 h1:XeUp+H6ZhHfOZiegpmH/Xo6t5c6xz2Rlx0j5k/dA2Ko= -github.com/multiversx/mx-chain-es-indexer-go v1.4.17/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= +github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20240112103055-0aaca2e304fe h1:1SV3MEZ6KHh8AM5qIDF++jKGXO+3QIgfxUryJwsfOsI= +github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20240112103055-0aaca2e304fe/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= github.com/multiversx/mx-chain-logger-go v1.0.13 h1:eru/TETo0MkO4ZTnXsQDKf4PBRpAXmqjT02klNT/JnY= github.com/multiversx/mx-chain-logger-go v1.0.13/go.mod h1:MZJhTAtZTJxT+yK2EHc4ZW3YOHUc1UdjCD0iahRNBZk= github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIMWwuNBtAZlgR4cSMA= From fd01919432476824d61091eeb0e62e06aae7d17a Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 12 Jan 2024 16:58:54 +0200 Subject: [PATCH 600/958] FIX: Remove errNoMaxNodesConfigBeforeStakingV4 error --- config/configChecker.go | 9 +++++++-- config/configChecker_test.go | 5 ++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index e72957265f7..34146ca94f4 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -2,8 +2,12 @@ package config import ( "fmt" + + logger "github.com/multiversx/mx-chain-logger-go" ) +var log = logger.GetOrCreate("config-checker") + // SanityCheckNodesConfig checks if the nodes limit setup is set correctly func SanityCheckNodesConfig( nodesSetup NodesSetupHandler, @@ -66,8 +70,9 @@ func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards u maxNodesConfigAdaptedForStakingV4 = true if idx == 0 { - return fmt.Errorf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, but %w ", - enableEpochsCfg.StakingV4Step3EnableEpoch, errNoMaxNodesConfigBeforeStakingV4) + log.Warn(fmt.Errorf("found config change in MaxNodesChangeEnableEpoch for StakingV4Step3EnableEpoch = %d, but %w ", + enableEpochsCfg.StakingV4Step3EnableEpoch, errNoMaxNodesConfigBeforeStakingV4).Error()) + break } prevMaxNodesChange := maxNodesChangeCfg[idx-1] diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 492e1a4db91..7af720879fa 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -125,7 +125,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { require.True(t, strings.Contains(err.Error(), "6")) }) - t.Run("max nodes config change for StakingV4Step3EnableEpoch has no previous config change, should return error", func(t *testing.T) { + t.Run("max nodes config change for StakingV4Step3EnableEpoch has no previous config change, should not error", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() @@ -143,8 +143,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { } err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) - require.NotNil(t, err) - require.ErrorIs(t, err, errNoMaxNodesConfigBeforeStakingV4) + require.Nil(t, err) }) t.Run("stakingV4 config for max nodes changed with different nodes to shuffle, should return error", func(t *testing.T) { From 0897fbf6d85db7f99357bd9d14d18a6374cf0256 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 12 Jan 2024 16:59:19 +0200 Subject: [PATCH 601/958] FEAT: Support in testnet scripts to updateConfigsForStakingV4 --- scripts/testnet/include/config.sh | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/scripts/testnet/include/config.sh b/scripts/testnet/include/config.sh index 56d792dc7ed..e87b97eed3e 100644 --- a/scripts/testnet/include/config.sh +++ b/scripts/testnet/include/config.sh @@ -131,10 +131,49 @@ updateNodeConfig() { sed -i '/\[Antiflood\]/,/\[Logger\]/ s/true/false/' config_observer.toml fi + updateConfigsForStakingV4 + echo "Updated configuration for Nodes." popd } +updateConfigsForStakingV4() { + config=$(cat enableEpochs.toml) + + echo "Updating staking v4 configs" + + # Get the StakingV4Step3EnableEpoch value + staking_enable_epoch=$(echo "$config" | awk -F '=' '/ StakingV4Step3EnableEpoch/{gsub(/^[ \t]+|[ \t]+$/,"", $2); print $2; exit}') + # Count the number of entries in MaxNodesChangeEnableEpoch + entry_count=$(echo "$config" | awk '/MaxNodesChangeEnableEpoch/,/\]/{if ($0 ~ /\{/) {count++}} END {print count}') + + # Check if entry_count is less than 2 + if [ "$entry_count" -lt 2 ]; then + echo "Not enough entries found to update" + else + # Find all entries in MaxNodesChangeEnableEpoch + all_entries=$(awk '/MaxNodesChangeEnableEpoch/,/\]/{if ($0 ~ /^[[:space:]]*\{/) {p=1}; if (p) print; if ($0 ~ /\]/) p=0}' enableEpochs.toml | grep -vE '^\s*#' | sed '/^\s*$/d') + + # Get the index of the entry with EpochEnable equal to StakingV4Step3EnableEpoch + index=$(echo "$all_entries" | grep -n "EpochEnable = $staking_enable_epoch" | cut -d: -f1) + + prev_entry=$(echo "$all_entries" | sed -n "$((index-1))p") + curr_entry=$(echo "$all_entries" | sed -n "$((index))p") + + # Extract the value of MaxNumNodes & NodesToShufflePerShard from prev_entry + max_nodes_from_prev_epoch=$(echo "$prev_entry" | awk -F 'MaxNumNodes = ' '{print $2}' | cut -d ',' -f1) + nodes_to_shuffle_per_shard=$(echo "$prev_entry" | awk -F 'NodesToShufflePerShard = ' '{gsub(/[^0-9]+/, "", $2); print $2}') + + # Calculate the new MaxNumNodes value based on the formula + new_max_nodes=$((max_nodes_from_prev_epoch - (SHARDCOUNT + 1) * nodes_to_shuffle_per_shard)) + curr_entry_updated=$(echo "$curr_entry" | awk -v new_max_nodes="$new_max_nodes" '{gsub(/MaxNumNodes = [0-9]+,/, "MaxNumNodes = " new_max_nodes ",")}1') + + echo "Updating entry in MaxNodesChangeEnableEpoch from $curr_entry to $curr_entry_updated" + + sed -i "/$staking_enable_epoch/,/$staking_enable_epoch/ s|.*$curr_entry.*|$curr_entry_updated|" enableEpochs.toml + fi +} + copyProxyConfig() { pushd $TESTNETDIR From 103c36cf09aab2fa3f62acee48bec9103b28d93a Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 12 Jan 2024 18:07:42 +0200 Subject: [PATCH 602/958] - put back mutex protection --- trie/patriciaMerkleTrie.go | 12 +++++++ trie/patriciaMerkleTrie_test.go | 59 +++++++++++++++------------------ 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/trie/patriciaMerkleTrie.go b/trie/patriciaMerkleTrie.go index 485b01bf199..0f875999bd1 100644 --- a/trie/patriciaMerkleTrie.go +++ b/trie/patriciaMerkleTrie.go @@ -399,6 +399,12 @@ func (tr *patriciaMerkleTrie) recreateFromDb(rootHash []byte, tsm common.Storage // GetSerializedNode returns the serialized node (if existing) provided the node's hash func (tr *patriciaMerkleTrie) GetSerializedNode(hash []byte) ([]byte, error) { + // TODO: investigate if we can move the critical section behavior in the trie node resolver as this call will compete with a normal trie.Get operation + // which might occur during processing. + // warning: A critical section here or on the trie node resolver must be kept as to not overwhelm the node with requests that affects the block processing flow + tr.mutOperation.Lock() + defer tr.mutOperation.Unlock() + log.Trace("GetSerializedNode", "hash", hash) return tr.trieStorage.Get(hash) @@ -406,6 +412,12 @@ func (tr *patriciaMerkleTrie) GetSerializedNode(hash []byte) ([]byte, error) { // GetSerializedNodes returns a batch of serialized nodes from the trie, starting from the given hash func (tr *patriciaMerkleTrie) GetSerializedNodes(rootHash []byte, maxBuffToSend uint64) ([][]byte, uint64, error) { + // TODO: investigate if we can move the critical section behavior in the trie node resolver as this call will compete with a normal trie.Get operation + // which might occur during processing. + // warning: A critical section here or on the trie node resolver must be kept as to not overwhelm the node with requests that affects the block processing flow + tr.mutOperation.Lock() + defer tr.mutOperation.Unlock() + log.Trace("GetSerializedNodes", "rootHash", rootHash) size := uint64(0) diff --git a/trie/patriciaMerkleTrie_test.go b/trie/patriciaMerkleTrie_test.go index 900d1b66002..501539a3e54 100644 --- a/trie/patriciaMerkleTrie_test.go +++ b/trie/patriciaMerkleTrie_test.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "testing" "time" @@ -22,7 +23,7 @@ import ( errorsCommon "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/state/parsers" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" - "github.com/multiversx/mx-chain-go/testscommon/storage" + "github.com/multiversx/mx-chain-go/testscommon/storageManager" trieMock "github.com/multiversx/mx-chain-go/testscommon/trie" "github.com/multiversx/mx-chain-go/trie" "github.com/multiversx/mx-chain-go/trie/keyBuilder" @@ -492,17 +493,17 @@ func TestPatriciaMerkleTrie_GetSerializedNodesGetFromCheckpoint(t *testing.T) { _ = tr.Commit() rootHash, _ := tr.RootHash() - storageManager := tr.GetStorageManager() + storageManagerInstance := tr.GetStorageManager() dirtyHashes := trie.GetDirtyHashes(tr) - storageManager.AddDirtyCheckpointHashes(rootHash, dirtyHashes) + storageManagerInstance.AddDirtyCheckpointHashes(rootHash, dirtyHashes) iteratorChannels := &common.TrieIteratorChannels{ LeavesChan: nil, ErrChan: errChan.NewErrChanWrapper(), } - storageManager.SetCheckpoint(rootHash, make([]byte, 0), iteratorChannels, nil, &trieMock.MockStatistics{}) - trie.WaitForOperationToComplete(storageManager) + storageManagerInstance.SetCheckpoint(rootHash, make([]byte, 0), iteratorChannels, nil, &trieMock.MockStatistics{}) + trie.WaitForOperationToComplete(storageManagerInstance) - err := storageManager.Remove(rootHash) + err := storageManagerInstance.Remove(rootHash) assert.Nil(t, err) maxBuffToSend := uint64(500) @@ -1085,64 +1086,56 @@ func TestPatriciaMerkleTrie_ConcurrentOperations(t *testing.T) { wg.Wait() } -func TestPatriciaMerkleTrie_GetSerializedNodesClose(t *testing.T) { +func TestPatriciaMerkleTrie_GetSerializedNodesShouldSerializeTheCalls(t *testing.T) { t.Parallel() args := trie.GetDefaultTrieStorageManagerParameters() - args.MainStorer = &storage.StorerStub{ - GetCalled: func(key []byte) ([]byte, error) { - // gets take a long time + numConcurrentCalls := int32(0) + testTrieStorageManager := &storageManager.StorageManagerStub{ + GetCalled: func(bytes []byte) ([]byte, error) { + newValue := atomic.AddInt32(&numConcurrentCalls, 1) + defer atomic.AddInt32(&numConcurrentCalls, -1) + + assert.Equal(t, int32(1), newValue) + + // get takes a long time time.Sleep(time.Millisecond * 10) - return key, nil + + return bytes, nil }, } - trieStorageManager, _ := trie.NewTrieStorageManager(args) - tr, _ := trie.NewTrie(trieStorageManager, args.Marshalizer, args.Hasher, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, 5) - numGoRoutines := 1000 - wgStart := sync.WaitGroup{} - wgStart.Add(numGoRoutines) - wgEnd := sync.WaitGroup{} - wgEnd.Add(numGoRoutines) + tr, _ := trie.NewTrie(testTrieStorageManager, args.Marshalizer, args.Hasher, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, 5) + numGoRoutines := 100 + wg := sync.WaitGroup{} + wg.Add(numGoRoutines) for i := 0; i < numGoRoutines; i++ { if i%2 == 0 { go func() { time.Sleep(time.Millisecond * 100) - wgStart.Done() - _, _, _ = tr.GetSerializedNodes([]byte("dog"), 1024) - wgEnd.Done() + wg.Done() }() } else { go func() { time.Sleep(time.Millisecond * 100) - wgStart.Done() - _, _ = tr.GetSerializedNode([]byte("dog")) - wgEnd.Done() + wg.Done() }() } } - wgStart.Wait() + wg.Wait() chanClosed := make(chan struct{}) go func() { _ = tr.Close() close(chanClosed) }() - chanGetsEnded := make(chan struct{}) - go func() { - wgEnd.Wait() - close(chanGetsEnded) - }() - timeout := time.Second * 10 select { case <-chanClosed: // ok - case <-chanGetsEnded: - assert.Fail(t, "trie should have been closed before all gets ended") case <-time.After(timeout): assert.Fail(t, "timeout waiting for trie to be closed") } From a60027fe56dee4b1a175ae0eba6c52b407273d8c Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 12 Jan 2024 19:33:48 +0200 Subject: [PATCH 603/958] FIX: Remove returning error on 0 nodes to shuffle or less than 2 entries --- config/configChecker.go | 7 +------ config/configChecker_test.go | 15 +++++++++------ config/errors.go | 4 ---- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/config/configChecker.go b/config/configChecker.go index 34146ca94f4..11ddc7eff9a 100644 --- a/config/configChecker.go +++ b/config/configChecker.go @@ -28,11 +28,6 @@ func checkMaxNodesConfig( nodesSetup NodesSetupHandler, maxNodesConfig MaxNodesChangeConfig, ) error { - nodesToShufflePerShard := maxNodesConfig.NodesToShufflePerShard - if nodesToShufflePerShard == 0 { - return errZeroNodesToShufflePerShard - } - maxNumNodes := maxNodesConfig.MaxNumNodes minNumNodesWithHysteresis := nodesSetup.MinNumberOfNodesWithHysteresis() if maxNumNodes < minNumNodesWithHysteresis { @@ -60,7 +55,7 @@ func areStakingV4StepsInOrder(enableEpochsCfg EnableEpochs) bool { func checkStakingV4MaxNodesChangeCfg(enableEpochsCfg EnableEpochs, numOfShards uint32) error { maxNodesChangeCfg := enableEpochsCfg.MaxNodesChangeEnableEpoch if len(maxNodesChangeCfg) <= 1 { - return errNotEnoughMaxNodesChanges + return nil } maxNodesConfigAdaptedForStakingV4 := false diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 7af720879fa..caa5461b144 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -86,7 +86,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { require.Equal(t, errStakingV4StepsNotInOrder, err) }) - t.Run("no previous config for max nodes change, should return error", func(t *testing.T) { + t.Run("no previous config for max nodes change with one entry, should not return error", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() @@ -99,7 +99,7 @@ func TestSanityCheckEnableEpochsStakingV4(t *testing.T) { } err := sanityCheckEnableEpochsStakingV4(cfg, numOfShards) - require.Equal(t, errNotEnoughMaxNodesChanges, err) + require.Nil(t, err) }) t.Run("no max nodes config change for StakingV4Step3EnableEpoch, should return error", func(t *testing.T) { @@ -278,7 +278,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { require.Nil(t, err) }) - t.Run("zero nodes to shuffle per shard, should return error", func(t *testing.T) { + t.Run("zero nodes to shuffle per shard, should not return error", func(t *testing.T) { t.Parallel() cfg := generateCorrectConfig() @@ -288,6 +288,11 @@ func TestSanityCheckNodesConfig(t *testing.T) { MaxNumNodes: 3200, NodesToShufflePerShard: 0, }, + { + EpochEnable: 6, + MaxNumNodes: 3200, + NodesToShufflePerShard: 0, + }, } nodesSetup := &nodesSetupMock.NodesSetupMock{ NumberOfShardsField: numShards, @@ -296,9 +301,7 @@ func TestSanityCheckNodesConfig(t *testing.T) { MinNumberOfShardNodesField: 400, } err := SanityCheckNodesConfig(nodesSetup, cfg) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), errZeroNodesToShufflePerShard.Error())) - require.True(t, strings.Contains(err.Error(), "at EpochEnable = 4")) + require.Nil(t, err) }) t.Run("maxNumNodes < minNumNodesWithHysteresis, should return error ", func(t *testing.T) { diff --git a/config/errors.go b/config/errors.go index f0cfa93c4c5..6161ef4c168 100644 --- a/config/errors.go +++ b/config/errors.go @@ -4,14 +4,10 @@ import "errors" var errStakingV4StepsNotInOrder = errors.New("staking v4 enable epoch steps should be in cardinal order(e.g.: StakingV4Step1EnableEpoch = 2, StakingV4Step2EnableEpoch = 3, StakingV4Step3EnableEpoch = 4)") -var errNotEnoughMaxNodesChanges = errors.New("not enough entries in MaxNodesChangeEnableEpoch config; expected one entry before stakingV4 and another one starting StakingV4Step3EnableEpoch") - var errNoMaxNodesConfigBeforeStakingV4 = errors.New("no previous config change entry in MaxNodesChangeEnableEpoch before entry with EpochEnable = StakingV4Step3EnableEpoch") var errMismatchNodesToShuffle = errors.New("previous MaxNodesChangeEnableEpoch.NodesToShufflePerShard != MaxNodesChangeEnableEpoch.NodesToShufflePerShard with EnableEpoch = StakingV4Step3EnableEpoch") var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch") -var errZeroNodesToShufflePerShard = errors.New("zero nodes to shuffle per shard found in config") - var errInvalidMaxMinNodes = errors.New("number of min nodes with hysteresis > number of max nodes") From c7e7898a2647c171f1fc910a5fe3a5abab5473df Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 15 Jan 2024 11:24:02 +0200 Subject: [PATCH 604/958] FIX: Edge case StakingV4Step3EnableEpoch does not exist in MaxNodesChangeEnableEpoch --- scripts/testnet/include/config.sh | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/scripts/testnet/include/config.sh b/scripts/testnet/include/config.sh index e87b97eed3e..d52ce33c385 100644 --- a/scripts/testnet/include/config.sh +++ b/scripts/testnet/include/config.sh @@ -157,20 +157,24 @@ updateConfigsForStakingV4() { # Get the index of the entry with EpochEnable equal to StakingV4Step3EnableEpoch index=$(echo "$all_entries" | grep -n "EpochEnable = $staking_enable_epoch" | cut -d: -f1) - prev_entry=$(echo "$all_entries" | sed -n "$((index-1))p") - curr_entry=$(echo "$all_entries" | sed -n "$((index))p") + if [[ -z "${index// }" ]]; then + echo -e "\033[1;33mWarning: MaxNodesChangeEnableEpoch does not contain an entry enable epoch for StakingV4Step3EnableEpoch, nodes might fail to start...\033[0m" + else + prev_entry=$(echo "$all_entries" | sed -n "$((index-1))p") + curr_entry=$(echo "$all_entries" | sed -n "$((index))p") - # Extract the value of MaxNumNodes & NodesToShufflePerShard from prev_entry - max_nodes_from_prev_epoch=$(echo "$prev_entry" | awk -F 'MaxNumNodes = ' '{print $2}' | cut -d ',' -f1) - nodes_to_shuffle_per_shard=$(echo "$prev_entry" | awk -F 'NodesToShufflePerShard = ' '{gsub(/[^0-9]+/, "", $2); print $2}') + # Extract the value of MaxNumNodes & NodesToShufflePerShard from prev_entry + max_nodes_from_prev_epoch=$(echo "$prev_entry" | awk -F 'MaxNumNodes = ' '{print $2}' | cut -d ',' -f1) + nodes_to_shuffle_per_shard=$(echo "$prev_entry" | awk -F 'NodesToShufflePerShard = ' '{gsub(/[^0-9]+/, "", $2); print $2}') - # Calculate the new MaxNumNodes value based on the formula - new_max_nodes=$((max_nodes_from_prev_epoch - (SHARDCOUNT + 1) * nodes_to_shuffle_per_shard)) - curr_entry_updated=$(echo "$curr_entry" | awk -v new_max_nodes="$new_max_nodes" '{gsub(/MaxNumNodes = [0-9]+,/, "MaxNumNodes = " new_max_nodes ",")}1') + # Calculate the new MaxNumNodes value based on the formula + new_max_nodes=$((max_nodes_from_prev_epoch - (SHARDCOUNT + 1) * nodes_to_shuffle_per_shard)) + curr_entry_updated=$(echo "$curr_entry" | awk -v new_max_nodes="$new_max_nodes" '{gsub(/MaxNumNodes = [0-9]+,/, "MaxNumNodes = " new_max_nodes ",")}1') - echo "Updating entry in MaxNodesChangeEnableEpoch from $curr_entry to $curr_entry_updated" + echo "Updating entry in MaxNodesChangeEnableEpoch from $curr_entry to $curr_entry_updated" - sed -i "/$staking_enable_epoch/,/$staking_enable_epoch/ s|.*$curr_entry.*|$curr_entry_updated|" enableEpochs.toml + sed -i "/$staking_enable_epoch/,/$staking_enable_epoch/ s|.*$curr_entry.*|$curr_entry_updated|" enableEpochs.toml + fi fi } From 3121214b4dd961fa5aa684c6f72caa8797f03bbc Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 15 Jan 2024 12:37:45 +0200 Subject: [PATCH 605/958] fixes after review --- consensus/spos/bls/subroundEndRound.go | 2 +- consensus/spos/bls/subroundEndRound_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index c9d1a8a62db..26c845511b5 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -590,7 +590,7 @@ func (sr *subroundEndRound) createAndBroadcastHeaderFinalInfo() { func (sr *subroundEndRound) createAndBroadcastInvalidSigners(invalidSigners []byte) { isSelfLeader := sr.IsSelfLeaderInCurrentRound() && sr.ShouldConsiderSelfKeyInConsensus() - if !isSelfLeader && !sr.IsMultiKeyLeaderInCurrentRound() { + if !(isSelfLeader || sr.IsMultiKeyLeaderInCurrentRound()) { return } diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 70992e7aec5..b6556b8ad70 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -1641,9 +1641,9 @@ func TestSubroundEndRound_CreateAndBroadcastInvalidSigners(t *testing.T) { container := mock.InitConsensusCore() messenger := &mock.BroadcastMessengerMock{ BroadcastConsensusMessageCalled: func(message *consensus.Message) error { - wg.Done() assert.Equal(t, expectedInvalidSigners, message.InvalidSigners) wasCalled = true + wg.Done() return nil }, } From 96d32fb1ca6b27d1c2365899d12587b556a96b8a Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Mon, 15 Jan 2024 17:45:36 +0200 Subject: [PATCH 606/958] verify header hash --- consensus/spos/errors.go | 3 ++ consensus/spos/worker.go | 12 +++++++ consensus/spos/worker_test.go | 63 +++++++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/consensus/spos/errors.go b/consensus/spos/errors.go index c8b5cede565..f5f069d3394 100644 --- a/consensus/spos/errors.go +++ b/consensus/spos/errors.go @@ -243,3 +243,6 @@ var ErrNilSentSignatureTracker = errors.New("nil sent signature tracker") // ErrNilFunctionHandler signals that a nil function handler was provided var ErrNilFunctionHandler = errors.New("nil function handler") + +// ErrWrongHashForHeader signals that the hash of the header is not the expected one +var ErrWrongHashForHeader = errors.New("wrong hash for header") diff --git a/consensus/spos/worker.go b/consensus/spos/worker.go index 8fdcca4686f..940d04ab8e9 100644 --- a/consensus/spos/worker.go +++ b/consensus/spos/worker.go @@ -1,6 +1,7 @@ package spos import ( + "bytes" "context" "encoding/hex" "errors" @@ -17,6 +18,7 @@ import ( "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" errorsErd "github.com/multiversx/mx-chain-go/errors" @@ -484,6 +486,11 @@ func (wrk *Worker) doJobOnMessageWithHeader(cnsMsg *consensus.Message) error { "nbTxs", header.GetTxCount(), "val stats root hash", valStatsRootHash) + if !wrk.verifyHeaderHash(headerHash, cnsMsg.Header) { + return fmt.Errorf("%w : received header from consensus with wrong hash", + ErrWrongHashForHeader) + } + err = wrk.headerIntegrityVerifier.Verify(header) if err != nil { return fmt.Errorf("%w : verify header integrity from consensus topic failed", err) @@ -508,6 +515,11 @@ func (wrk *Worker) doJobOnMessageWithHeader(cnsMsg *consensus.Message) error { return nil } +func (wrk *Worker) verifyHeaderHash(hash []byte, marshalledHeader []byte) bool { + computedHash := wrk.hasher.Compute(string(marshalledHeader)) + return bytes.Equal(hash, computedHash) +} + func (wrk *Worker) doJobOnMessageWithSignature(cnsMsg *consensus.Message, p2pMsg p2p.MessageP2P) { wrk.mutDisplayHashConsensusMessage.Lock() defer wrk.mutDisplayHashConsensusMessage.Unlock() diff --git a/consensus/spos/worker_test.go b/consensus/spos/worker_test.go index 37cc36f33c1..935f8ce59b3 100644 --- a/consensus/spos/worker_test.go +++ b/consensus/spos/worker_test.go @@ -15,6 +15,9 @@ import ( "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/mock" @@ -26,8 +29,6 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const roundTimeDuration = 100 * time.Millisecond @@ -1163,6 +1164,64 @@ func TestWorker_ProcessReceivedMessageWithABadOriginatorShouldErr(t *testing.T) assert.True(t, errors.Is(err, spos.ErrOriginatorMismatch)) } +func TestWorker_ProcessReceivedMessageWithHeaderAndWrongHash(t *testing.T) { + t.Parallel() + + workerArgs := createDefaultWorkerArgs(&statusHandlerMock.AppStatusHandlerStub{}) + wrk, _ := spos.NewWorker(workerArgs) + + wrk.SetBlockProcessor( + &testscommon.BlockProcessorStub{ + DecodeBlockHeaderCalled: func(dta []byte) data.HeaderHandler { + return &testscommon.HeaderHandlerStub{ + CheckChainIDCalled: func(reference []byte) error { + return nil + }, + GetPrevHashCalled: func() []byte { + return make([]byte, 0) + }, + } + }, + RevertCurrentBlockCalled: func() { + }, + DecodeBlockBodyCalled: func(dta []byte) data.BodyHandler { + return nil + }, + }, + ) + + hdr := &block.Header{ChainID: chainID} + hdrHash := make([]byte, 32) // wrong hash + hdrStr, _ := mock.MarshalizerMock{}.Marshal(hdr) + cnsMsg := consensus.NewConsensusMessage( + hdrHash, + nil, + nil, + hdrStr, + []byte(wrk.ConsensusState().ConsensusGroup()[0]), + signature, + int(bls.MtBlockHeader), + 0, + chainID, + nil, + nil, + nil, + currentPid, + nil, + ) + buff, _ := wrk.Marshalizer().Marshal(cnsMsg) + msg := &p2pmocks.P2PMessageMock{ + DataField: buff, + PeerField: currentPid, + SignatureField: []byte("signature"), + } + err := wrk.ProcessReceivedMessage(msg, fromConnectedPeerId, &p2pmocks.MessengerStub{}) + time.Sleep(time.Second) + + assert.Equal(t, 0, len(wrk.ReceivedMessages()[bls.MtBlockHeader])) + assert.ErrorIs(t, err, spos.ErrWrongHashForHeader) +} + func TestWorker_ProcessReceivedMessageOkValsShouldWork(t *testing.T) { t.Parallel() From 5f981bc5e1a16e1a6652d67f61cd8624df6c3efa Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 16 Jan 2024 10:10:38 +0200 Subject: [PATCH 607/958] proper tag --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6c9c5257153..074a5b37e0f 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/multiversx/mx-chain-communication-go v1.0.12 github.com/multiversx/mx-chain-core-go v1.2.18 github.com/multiversx/mx-chain-crypto-go v1.2.9 - github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20240112103055-0aaca2e304fe + github.com/multiversx/mx-chain-es-indexer-go v1.4.18 github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 diff --git a/go.sum b/go.sum index b105c0dfefc..557ea8c7b0a 100644 --- a/go.sum +++ b/go.sum @@ -390,8 +390,8 @@ github.com/multiversx/mx-chain-core-go v1.2.18 h1:fnub2eFL7XYOLrKKVZAPPsaM1TWEna github.com/multiversx/mx-chain-core-go v1.2.18/go.mod h1:BILOGHUOIG5dNNX8cgkzCNfDaVtoYrJRYcPnpxRMH84= github.com/multiversx/mx-chain-crypto-go v1.2.9 h1:OEfF2kOQrtzUl273Z3DEcshjlTVUfPpJMd0R0SvTrlU= github.com/multiversx/mx-chain-crypto-go v1.2.9/go.mod h1:fkaWKp1rbQN9wPKya5jeoRyC+c/SyN/NfggreyeBw+8= -github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20240112103055-0aaca2e304fe h1:1SV3MEZ6KHh8AM5qIDF++jKGXO+3QIgfxUryJwsfOsI= -github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20240112103055-0aaca2e304fe/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= +github.com/multiversx/mx-chain-es-indexer-go v1.4.18 h1:rCA+/mn/77MyB7c8FjtabdQemfxNquustHLmqIYk7TE= +github.com/multiversx/mx-chain-es-indexer-go v1.4.18/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= github.com/multiversx/mx-chain-logger-go v1.0.13 h1:eru/TETo0MkO4ZTnXsQDKf4PBRpAXmqjT02klNT/JnY= github.com/multiversx/mx-chain-logger-go v1.0.13/go.mod h1:MZJhTAtZTJxT+yK2EHc4ZW3YOHUc1UdjCD0iahRNBZk= github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIMWwuNBtAZlgR4cSMA= From e8bccc0c1063081cde6aba87208285071fd26691 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 16 Jan 2024 15:30:12 +0200 Subject: [PATCH 608/958] - fixed wrong backup machine step-in by correctly resetting counters at commit block time. --- consensus/spos/bls/blsSubroundsFactory.go | 3 +- .../spos/bls/blsSubroundsFactory_test.go | 38 +++++----- consensus/spos/bls/subroundEndRound.go | 6 +- consensus/spos/bls/subroundEndRound_test.go | 35 ++++------ consensus/spos/bls/subroundSignature.go | 3 +- consensus/spos/bls/subroundSignature_test.go | 25 +++---- consensus/spos/bls/subroundStartRound.go | 3 +- consensus/spos/bls/subroundStartRound_test.go | 27 +++---- consensus/spos/errors.go | 3 - consensus/spos/interface.go | 1 - .../spos/sposFactory/sposFactory_test.go | 6 +- errors/errors.go | 4 +- factory/consensus/consensusComponents.go | 7 +- factory/consensus/consensusComponents_test.go | 1 + factory/interface.go | 1 + factory/mock/processComponentsStub.go | 6 ++ factory/processing/blockProcessorCreator.go | 7 ++ .../processing/blockProcessorCreator_test.go | 2 + factory/processing/export_test.go | 2 + factory/processing/processComponents.go | 8 +++ .../processing/processComponentsHandler.go | 17 ++++- .../processComponentsHandler_test.go | 2 + factory/processing/processComponents_test.go | 1 + .../mock/processComponentsStub.go | 6 ++ integrationTests/testConsensusNode.go | 1 + integrationTests/testProcessorNode.go | 1 + integrationTests/testSyncNode.go | 1 + process/block/argProcessor.go | 1 + process/block/baseProcess.go | 21 ++++++ process/block/baseProcess_test.go | 55 ++++++++++++++- process/block/export_test.go | 5 ++ process/block/metablock.go | 6 ++ process/block/metablock_test.go | 8 +++ process/block/shardblock.go | 8 ++- process/block/shardblock_test.go | 7 ++ process/errors.go | 3 + process/headerCheck/common.go | 19 +++++ process/headerCheck/common_test.go | 70 +++++++++++++++++++ process/headerCheck/headerSignatureVerify.go | 12 +--- process/interface.go | 8 +++ process/track/errors.go | 3 + process/track/interface.go | 8 +++ .../track}/sentSignaturesTracker.go | 20 +++--- .../track}/sentSignaturesTracker_test.go | 34 ++++----- .../sentSignatureTrackerStub.go | 16 ++--- 45 files changed, 385 insertions(+), 136 deletions(-) create mode 100644 process/headerCheck/common.go create mode 100644 process/headerCheck/common_test.go rename {consensus/spos => process/track}/sentSignaturesTracker.go (64%) rename {consensus/spos => process/track}/sentSignaturesTracker_test.go (73%) rename {consensus/mock => testscommon}/sentSignatureTrackerStub.go (52%) diff --git a/consensus/spos/bls/blsSubroundsFactory.go b/consensus/spos/bls/blsSubroundsFactory.go index 81a09e71009..f68e35e570f 100644 --- a/consensus/spos/bls/blsSubroundsFactory.go +++ b/consensus/spos/bls/blsSubroundsFactory.go @@ -6,6 +6,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-go/consensus/spos" + "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/outport" ) @@ -80,7 +81,7 @@ func checkNewFactoryParams( return spos.ErrNilAppStatusHandler } if check.IfNil(sentSignaturesTracker) { - return spos.ErrNilSentSignatureTracker + return errors.ErrNilSentSignatureTracker } if len(chainID) == 0 { return spos.ErrInvalidChainID diff --git a/consensus/spos/bls/blsSubroundsFactory_test.go b/consensus/spos/bls/blsSubroundsFactory_test.go index a0cf949d366..936b765e951 100644 --- a/consensus/spos/bls/blsSubroundsFactory_test.go +++ b/consensus/spos/bls/blsSubroundsFactory_test.go @@ -12,7 +12,9 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" + "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/outport" + "github.com/multiversx/mx-chain-go/testscommon" testscommonOutport "github.com/multiversx/mx-chain-go/testscommon/outport" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" "github.com/stretchr/testify/assert" @@ -76,7 +78,7 @@ func initFactoryWithContainer(container *mock.ConsensusCoreMock) bls.Factory { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) return fct @@ -125,7 +127,7 @@ func TestFactory_NewFactoryNilContainerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -145,7 +147,7 @@ func TestFactory_NewFactoryNilConsensusStateShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -167,7 +169,7 @@ func TestFactory_NewFactoryNilBlockchainShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -189,7 +191,7 @@ func TestFactory_NewFactoryNilBlockProcessorShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -211,7 +213,7 @@ func TestFactory_NewFactoryNilBootstrapperShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -233,7 +235,7 @@ func TestFactory_NewFactoryNilChronologyHandlerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -255,7 +257,7 @@ func TestFactory_NewFactoryNilHasherShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -277,7 +279,7 @@ func TestFactory_NewFactoryNilMarshalizerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -299,7 +301,7 @@ func TestFactory_NewFactoryNilMultiSignerContainerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -321,7 +323,7 @@ func TestFactory_NewFactoryNilRoundHandlerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -343,7 +345,7 @@ func TestFactory_NewFactoryNilShardCoordinatorShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -365,7 +367,7 @@ func TestFactory_NewFactoryNilSyncTimerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -387,7 +389,7 @@ func TestFactory_NewFactoryNilValidatorGroupSelectorShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -407,7 +409,7 @@ func TestFactory_NewFactoryNilWorkerShouldFail(t *testing.T) { chainID, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -428,7 +430,7 @@ func TestFactory_NewFactoryNilAppStatusHandlerShouldFail(t *testing.T) { chainID, currentPid, nil, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) @@ -453,7 +455,7 @@ func TestFactory_NewFactoryNilSignaturesTrackerShouldFail(t *testing.T) { ) assert.Nil(t, fct) - assert.Equal(t, spos.ErrNilSentSignatureTracker, err) + assert.Equal(t, errors.ErrNilSentSignatureTracker, err) } func TestFactory_NewFactoryShouldWork(t *testing.T) { @@ -478,7 +480,7 @@ func TestFactory_NewFactoryEmptyChainIDShouldFail(t *testing.T) { nil, currentPid, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, fct) diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index 723fc0bcbf3..dab059526d1 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -14,6 +14,7 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos" + "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/p2p" ) @@ -48,7 +49,7 @@ func NewSubroundEndRound( return nil, spos.ErrNilAppStatusHandler } if check.IfNil(sentSignatureTracker) { - return nil, spos.ErrNilSentSignatureTracker + return nil, errors.ErrNilSentSignatureTracker } srEndRound := subroundEndRound{ @@ -120,9 +121,6 @@ func (sr *subroundEndRound) receivedBlockHeaderFinalInfo(_ context.Context, cnsD "AggregateSignature", cnsDta.AggregateSignature, "LeaderSignature", cnsDta.LeaderSignature) - signers := computeSignersPublicKeys(sr.ConsensusGroup(), cnsDta.PubKeysBitmap) - sr.sentSignatureTracker.ReceivedActualSigners(signers) - sr.PeerHonestyHandler().ChangeScore( node, spos.GetConsensusTopicID(sr.ShardCoordinator()), diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 456277e23fc..e539282e1eb 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -17,6 +17,7 @@ import ( "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" + mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/p2p" "github.com/multiversx/mx-chain-go/p2p/factory" "github.com/multiversx/mx-chain-go/testscommon" @@ -55,7 +56,7 @@ func initSubroundEndRoundWithContainer( bls.ProcessingThresholdPercent, displayStatistics, appStatusHandler, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) return srEndRound @@ -97,7 +98,7 @@ func TestNewSubroundEndRound(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srEndRound) @@ -112,7 +113,7 @@ func TestNewSubroundEndRound(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srEndRound) @@ -127,7 +128,7 @@ func TestNewSubroundEndRound(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, nil, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srEndRound) @@ -146,7 +147,7 @@ func TestNewSubroundEndRound(t *testing.T) { ) assert.Nil(t, srEndRound) - assert.Equal(t, spos.ErrNilSentSignatureTracker, err) + assert.Equal(t, mxErrors.ErrNilSentSignatureTracker, err) }) } @@ -179,7 +180,7 @@ func TestSubroundEndRound_NewSubroundEndRoundNilBlockChainShouldFail(t *testing. bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srEndRound)) @@ -215,7 +216,7 @@ func TestSubroundEndRound_NewSubroundEndRoundNilBlockProcessorShouldFail(t *test bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srEndRound)) @@ -252,7 +253,7 @@ func TestSubroundEndRound_NewSubroundEndRoundNilConsensusStateShouldFail(t *test bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srEndRound)) @@ -288,7 +289,7 @@ func TestSubroundEndRound_NewSubroundEndRoundNilMultiSignerContainerShouldFail(t bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srEndRound)) @@ -324,7 +325,7 @@ func TestSubroundEndRound_NewSubroundEndRoundNilRoundHandlerShouldFail(t *testin bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srEndRound)) @@ -360,7 +361,7 @@ func TestSubroundEndRound_NewSubroundEndRoundNilSyncTimerShouldFail(t *testing.T bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srEndRound)) @@ -396,7 +397,7 @@ func TestSubroundEndRound_NewSubroundEndRoundShouldWork(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.False(t, check.IfNil(srEndRound)) @@ -902,16 +903,8 @@ func TestSubroundEndRound_ReceivedBlockHeaderFinalInfoShouldWork(t *testing.T) { PubKey: []byte("A"), } - sentTrackerInterface := sr.GetSentSignatureTracker() - sentTracker := sentTrackerInterface.(*mock.SentSignatureTrackerStub) - receivedActualSignersCalled := false - sentTracker.ReceivedActualSignersCalled = func(signersPks []string) { - receivedActualSignersCalled = true - } - res := sr.ReceivedBlockHeaderFinalInfo(&cnsData) assert.True(t, res) - assert.True(t, receivedActualSignersCalled) } func TestSubroundEndRound_ReceivedBlockHeaderFinalInfoShouldReturnFalseWhenFinalInfoIsNotValid(t *testing.T) { @@ -1665,7 +1658,7 @@ func TestSubroundEndRound_getMinConsensusGroupIndexOfManagedKeys(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) t.Run("no managed keys from consensus group", func(t *testing.T) { diff --git a/consensus/spos/bls/subroundSignature.go b/consensus/spos/bls/subroundSignature.go index 84892d660fe..07d5ddd3fe9 100644 --- a/consensus/spos/bls/subroundSignature.go +++ b/consensus/spos/bls/subroundSignature.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos" + "github.com/multiversx/mx-chain-go/errors" ) type subroundSignature struct { @@ -39,7 +40,7 @@ func NewSubroundSignature( return nil, spos.ErrNilAppStatusHandler } if check.IfNil(sentSignatureTracker) { - return nil, spos.ErrNilSentSignatureTracker + return nil, errors.ErrNilSentSignatureTracker } srSignature := subroundSignature{ diff --git a/consensus/spos/bls/subroundSignature_test.go b/consensus/spos/bls/subroundSignature_test.go index d12e00b52c0..2002e9d6a66 100644 --- a/consensus/spos/bls/subroundSignature_test.go +++ b/consensus/spos/bls/subroundSignature_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" + mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/testscommon" consensusMocks "github.com/multiversx/mx-chain-go/testscommon/consensus" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" @@ -41,7 +42,7 @@ func initSubroundSignatureWithContainer(container *mock.ConsensusCoreMock) bls.S sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) return srSignature @@ -82,7 +83,7 @@ func TestNewSubroundSignature(t *testing.T) { nil, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srSignature) @@ -95,7 +96,7 @@ func TestNewSubroundSignature(t *testing.T) { sr, nil, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srSignature) @@ -108,7 +109,7 @@ func TestNewSubroundSignature(t *testing.T) { sr, extend, nil, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srSignature) @@ -125,7 +126,7 @@ func TestNewSubroundSignature(t *testing.T) { ) assert.Nil(t, srSignature) - assert.Equal(t, spos.ErrNilSentSignatureTracker, err) + assert.Equal(t, mxErrors.ErrNilSentSignatureTracker, err) }) } @@ -157,7 +158,7 @@ func TestSubroundSignature_NewSubroundSignatureNilConsensusStateShouldFail(t *te sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srSignature)) @@ -191,7 +192,7 @@ func TestSubroundSignature_NewSubroundSignatureNilHasherShouldFail(t *testing.T) sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srSignature)) @@ -225,7 +226,7 @@ func TestSubroundSignature_NewSubroundSignatureNilMultiSignerContainerShouldFail sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srSignature)) @@ -260,7 +261,7 @@ func TestSubroundSignature_NewSubroundSignatureNilRoundHandlerShouldFail(t *test sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srSignature)) @@ -294,7 +295,7 @@ func TestSubroundSignature_NewSubroundSignatureNilSyncTimerShouldFail(t *testing sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.True(t, check.IfNil(srSignature)) @@ -328,7 +329,7 @@ func TestSubroundSignature_NewSubroundSignatureShouldWork(t *testing.T) { sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.False(t, check.IfNil(srSignature)) @@ -411,7 +412,7 @@ func TestSubroundSignature_DoSignatureJobWithMultikey(t *testing.T) { sr, extend, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{ + &testscommon.SentSignatureTrackerStub{ SignatureSentCalled: func(pkBytes []byte) { signatureSentForPks[string(pkBytes)] = struct{}{} }, diff --git a/consensus/spos/bls/subroundStartRound.go b/consensus/spos/bls/subroundStartRound.go index 6a799928769..735e2eb770d 100644 --- a/consensus/spos/bls/subroundStartRound.go +++ b/consensus/spos/bls/subroundStartRound.go @@ -13,6 +13,7 @@ import ( outportcore "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus/spos" + "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/outport" "github.com/multiversx/mx-chain-go/outport/disabled" ) @@ -54,7 +55,7 @@ func NewSubroundStartRound( return nil, fmt.Errorf("%w for resetConsensusMessages function", spos.ErrNilFunctionHandler) } if check.IfNil(sentSignatureTracker) { - return nil, spos.ErrNilSentSignatureTracker + return nil, errors.ErrNilSentSignatureTracker } srStartRound := subroundStartRound{ diff --git a/consensus/spos/bls/subroundStartRound_test.go b/consensus/spos/bls/subroundStartRound_test.go index 583861032d1..62307d99b2d 100644 --- a/consensus/spos/bls/subroundStartRound_test.go +++ b/consensus/spos/bls/subroundStartRound_test.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" + mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -23,7 +24,7 @@ func defaultSubroundStartRoundFromSubround(sr *spos.Subround) (bls.SubroundStart bls.ProcessingThresholdPercent, executeStoredMessages, resetConsensusMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) return startRound, err @@ -36,7 +37,7 @@ func defaultWithoutErrorSubroundStartRoundFromSubround(sr *spos.Subround) bls.Su bls.ProcessingThresholdPercent, executeStoredMessages, resetConsensusMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) return startRound @@ -75,7 +76,7 @@ func initSubroundStartRoundWithContainer(container spos.ConsensusCoreHandler) bl bls.ProcessingThresholdPercent, executeStoredMessages, resetConsensusMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) return srStartRound @@ -117,7 +118,7 @@ func TestNewSubroundStartRound(t *testing.T) { bls.ProcessingThresholdPercent, executeStoredMessages, resetConsensusMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srStartRound) @@ -132,7 +133,7 @@ func TestNewSubroundStartRound(t *testing.T) { bls.ProcessingThresholdPercent, executeStoredMessages, resetConsensusMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srStartRound) @@ -148,7 +149,7 @@ func TestNewSubroundStartRound(t *testing.T) { bls.ProcessingThresholdPercent, nil, resetConsensusMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srStartRound) @@ -164,7 +165,7 @@ func TestNewSubroundStartRound(t *testing.T) { bls.ProcessingThresholdPercent, executeStoredMessages, nil, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) assert.Nil(t, srStartRound) @@ -184,7 +185,7 @@ func TestNewSubroundStartRound(t *testing.T) { ) assert.Nil(t, srStartRound) - assert.Equal(t, spos.ErrNilSentSignatureTracker, err) + assert.Equal(t, mxErrors.ErrNilSentSignatureTracker, err) }) } @@ -366,7 +367,7 @@ func TestSubroundStartRound_DoStartRoundConsensusCheckShouldReturnTrueWhenInitCu sr := *initSubroundStartRoundWithContainer(container) sentTrackerInterface := sr.GetSentSignatureTracker() - sentTracker := sentTrackerInterface.(*mock.SentSignatureTrackerStub) + sentTracker := sentTrackerInterface.(*testscommon.SentSignatureTrackerStub) startRoundCalled := false sentTracker.StartRoundCalled = func() { startRoundCalled = true @@ -561,7 +562,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldMetrics(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, executeStoredMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) srStartRound.Check() assert.True(t, wasCalled) @@ -604,7 +605,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldMetrics(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, executeStoredMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) srStartRound.Check() assert.True(t, wasCalled) @@ -667,7 +668,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldMetrics(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, executeStoredMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) srStartRound.Check() assert.True(t, wasMetricConsensusStateCalled) @@ -734,7 +735,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldMetrics(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, executeStoredMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) srStartRound.Check() assert.True(t, wasMetricConsensusStateCalled) diff --git a/consensus/spos/errors.go b/consensus/spos/errors.go index c8b5cede565..ea3b504b93f 100644 --- a/consensus/spos/errors.go +++ b/consensus/spos/errors.go @@ -238,8 +238,5 @@ var ErrNilSigningHandler = errors.New("nil signing handler") // ErrNilKeysHandler signals that a nil keys handler was provided var ErrNilKeysHandler = errors.New("nil keys handler") -// ErrNilSentSignatureTracker defines the error for setting a nil SentSignatureTracker -var ErrNilSentSignatureTracker = errors.New("nil sent signature tracker") - // ErrNilFunctionHandler signals that a nil function handler was provided var ErrNilFunctionHandler = errors.New("nil function handler") diff --git a/consensus/spos/interface.go b/consensus/spos/interface.go index 235c139d2fb..0ca771d30e5 100644 --- a/consensus/spos/interface.go +++ b/consensus/spos/interface.go @@ -175,6 +175,5 @@ type PeerBlackListCacher interface { type SentSignaturesTracker interface { StartRound() SignatureSent(pkBytes []byte) - ReceivedActualSigners(signersPks []string) IsInterfaceNil() bool } diff --git a/consensus/spos/sposFactory/sposFactory_test.go b/consensus/spos/sposFactory/sposFactory_test.go index 090f5b19f0a..4a672a3343f 100644 --- a/consensus/spos/sposFactory/sposFactory_test.go +++ b/consensus/spos/sposFactory/sposFactory_test.go @@ -52,7 +52,7 @@ func TestGetSubroundsFactory_BlsNilConsensusCoreShouldErr(t *testing.T) { consensusType, statusHandler, indexer, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, chainID, currentPid, ) @@ -76,7 +76,7 @@ func TestGetSubroundsFactory_BlsNilStatusHandlerShouldErr(t *testing.T) { consensusType, nil, indexer, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, chainID, currentPid, ) @@ -101,7 +101,7 @@ func TestGetSubroundsFactory_BlsShouldWork(t *testing.T) { consensusType, statusHandler, indexer, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, chainID, currentPid, ) diff --git a/errors/errors.go b/errors/errors.go index 81f547d8bea..771c65adc07 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -593,5 +593,5 @@ var ErrEmptyAddress = errors.New("empty Address") // ErrInvalidNodeOperationMode signals that an invalid node operation mode has been provided var ErrInvalidNodeOperationMode = errors.New("invalid node operation mode") -// ErrNilTxExecutionOrderHandler signals that a nil tx execution order handler has been provided -var ErrNilTxExecutionOrderHandler = errors.New("nil tx execution order handler") +// ErrNilSentSignatureTracker defines the error for setting a nil SentSignatureTracker +var ErrNilSentSignatureTracker = errors.New("nil sent signature tracker") diff --git a/factory/consensus/consensusComponents.go b/factory/consensus/consensusComponents.go index a2dc7a3e1bf..decdb7c85fa 100644 --- a/factory/consensus/consensusComponents.go +++ b/factory/consensus/consensusComponents.go @@ -261,11 +261,6 @@ func (ccf *consensusComponentsFactory) Create() (*consensusComponents, error) { return nil, err } - sentSignaturesHandler, err := spos.NewSentSignaturesTracker(ccf.cryptoComponents.KeysHandler()) - if err != nil { - return nil, err - } - fct, err := sposFactory.GetSubroundsFactory( consensusDataContainer, consensusState, @@ -273,7 +268,7 @@ func (ccf *consensusComponentsFactory) Create() (*consensusComponents, error) { ccf.config.Consensus.Type, ccf.statusCoreComponents.AppStatusHandler(), ccf.statusComponents.OutportHandler(), - sentSignaturesHandler, + ccf.processComponents.SentSignaturesTracker(), []byte(ccf.coreComponents.ChainID()), ccf.networkComponents.NetworkMessenger().ID(), ) diff --git a/factory/consensus/consensusComponents_test.go b/factory/consensus/consensusComponents_test.go index 67f551acf1d..f3ffa602ba1 100644 --- a/factory/consensus/consensusComponents_test.go +++ b/factory/consensus/consensusComponents_test.go @@ -139,6 +139,7 @@ func createMockConsensusComponentsFactoryArgs() consensusComp.ConsensusComponent HeaderSigVerif: &testsMocks.HeaderSigVerifierStub{}, HeaderIntegrVerif: &mock.HeaderIntegrityVerifierStub{}, FallbackHdrValidator: &testscommon.FallBackHeaderValidatorStub{}, + SentSignaturesTrackerInternal: &testscommon.SentSignatureTrackerStub{}, }, StateComponents: &factoryMocks.StateComponentsMock{ StorageManagers: map[string]common.StorageManager{ diff --git a/factory/interface.go b/factory/interface.go index 28eb2a72bcb..ae1bbb791be 100644 --- a/factory/interface.go +++ b/factory/interface.go @@ -308,6 +308,7 @@ type ProcessComponentsHolder interface { ESDTDataStorageHandlerForAPI() vmcommon.ESDTNFTStorageHandler AccountsParser() genesis.AccountsParser ReceiptsRepository() ReceiptsRepository + SentSignaturesTracker() process.SentSignaturesTracker IsInterfaceNil() bool } diff --git a/factory/mock/processComponentsStub.go b/factory/mock/processComponentsStub.go index 51265a22997..e646958281c 100644 --- a/factory/mock/processComponentsStub.go +++ b/factory/mock/processComponentsStub.go @@ -56,6 +56,7 @@ type ProcessComponentsMock struct { ESDTDataStorageHandlerForAPIInternal vmcommon.ESDTNFTStorageHandler AccountsParserInternal genesis.AccountsParser ReceiptsRepositoryInternal factory.ReceiptsRepository + SentSignaturesTrackerInternal process.SentSignaturesTracker } // Create - @@ -278,6 +279,11 @@ func (pcm *ProcessComponentsMock) ReceiptsRepository() factory.ReceiptsRepositor return pcm.ReceiptsRepositoryInternal } +// SentSignaturesTracker - +func (pcm *ProcessComponentsMock) SentSignaturesTracker() process.SentSignaturesTracker { + return pcm.SentSignaturesTrackerInternal +} + // IsInterfaceNil - func (pcm *ProcessComponentsMock) IsInterfaceNil() bool { return pcm == nil diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index f07ef302059..5c3e4270273 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -65,6 +65,7 @@ func (pcf *processComponentsFactory) newBlockProcessor( receiptsRepository mainFactory.ReceiptsRepository, blockCutoffProcessingHandler cutoff.BlockProcessingCutoffHandler, missingTrieNodesNotifier common.MissingTrieNodesNotifier, + sentSignaturesTracker process.SentSignaturesTracker, ) (*blockProcessorAndVmFactories, error) { shardCoordinator := pcf.bootstrapComponents.ShardCoordinator() if shardCoordinator.SelfId() < shardCoordinator.NumberOfShards() { @@ -82,6 +83,7 @@ func (pcf *processComponentsFactory) newBlockProcessor( receiptsRepository, blockCutoffProcessingHandler, missingTrieNodesNotifier, + sentSignaturesTracker, ) } if shardCoordinator.SelfId() == core.MetachainShardId { @@ -99,6 +101,7 @@ func (pcf *processComponentsFactory) newBlockProcessor( processedMiniBlocksTracker, receiptsRepository, blockCutoffProcessingHandler, + sentSignaturesTracker, ) } @@ -121,6 +124,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( receiptsRepository mainFactory.ReceiptsRepository, blockProcessingCutoffHandler cutoff.BlockProcessingCutoffHandler, missingTrieNodesNotifier common.MissingTrieNodesNotifier, + sentSignaturesTracker process.SentSignaturesTracker, ) (*blockProcessorAndVmFactories, error) { argsParser := smartContract.NewArgumentParser() @@ -432,6 +436,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( OutportDataProvider: outportDataProvider, BlockProcessingCutoffHandler: blockProcessingCutoffHandler, ManagedPeersHolder: pcf.crypto.ManagedPeersHolder(), + SentSignaturesTracker: sentSignaturesTracker, } arguments := block.ArgShardProcessor{ ArgBaseProcessor: argumentsBaseProcessor, @@ -467,6 +472,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( processedMiniBlocksTracker process.ProcessedMiniBlocksTracker, receiptsRepository mainFactory.ReceiptsRepository, blockProcessingCutoffhandler cutoff.BlockProcessingCutoffHandler, + sentSignaturesTracker process.SentSignaturesTracker, ) (*blockProcessorAndVmFactories, error) { builtInFuncFactory, err := pcf.createBuiltInFunctionContainer(pcf.state.AccountsAdapter(), make(map[string]struct{})) if err != nil { @@ -852,6 +858,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( OutportDataProvider: outportDataProvider, BlockProcessingCutoffHandler: blockProcessingCutoffhandler, ManagedPeersHolder: pcf.crypto.ManagedPeersHolder(), + SentSignaturesTracker: sentSignaturesTracker, } esdtOwnerAddress, err := pcf.coreData.AddressPubKeyConverter().Decode(pcf.systemSCConfig.ESDTSystemSCConfig.OwnerAddress) diff --git a/factory/processing/blockProcessorCreator_test.go b/factory/processing/blockProcessorCreator_test.go index f989bad2571..8c0fc36430e 100644 --- a/factory/processing/blockProcessorCreator_test.go +++ b/factory/processing/blockProcessorCreator_test.go @@ -54,6 +54,7 @@ func Test_newBlockProcessorCreatorForShard(t *testing.T) { &testscommon.ReceiptsRepositoryStub{}, &testscommon.BlockProcessingCutoffStub{}, &testscommon.MissingTrieNodesNotifierStub{}, + &testscommon.SentSignatureTrackerStub{}, ) require.NoError(t, err) @@ -180,6 +181,7 @@ func Test_newBlockProcessorCreatorForMeta(t *testing.T) { &testscommon.ReceiptsRepositoryStub{}, &testscommon.BlockProcessingCutoffStub{}, &testscommon.MissingTrieNodesNotifierStub{}, + &testscommon.SentSignatureTrackerStub{}, ) require.NoError(t, err) diff --git a/factory/processing/export_test.go b/factory/processing/export_test.go index 3187bd729b1..50c5123634c 100644 --- a/factory/processing/export_test.go +++ b/factory/processing/export_test.go @@ -24,6 +24,7 @@ func (pcf *processComponentsFactory) NewBlockProcessor( receiptsRepository factory.ReceiptsRepository, blockProcessingCutoff cutoff.BlockProcessingCutoffHandler, missingTrieNodesNotifier common.MissingTrieNodesNotifier, + sentSignaturesTracker process.SentSignaturesTracker, ) (process.BlockProcessor, error) { blockProcessorComponents, err := pcf.newBlockProcessor( requestHandler, @@ -40,6 +41,7 @@ func (pcf *processComponentsFactory) NewBlockProcessor( receiptsRepository, blockProcessingCutoff, missingTrieNodesNotifier, + sentSignaturesTracker, ) if err != nil { return nil, err diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 9cc0cd96341..f36eee4e29e 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -130,6 +130,7 @@ type processComponents struct { esdtDataStorageForApi vmcommon.ESDTNFTStorageHandler accountsParser genesis.AccountsParser receiptsRepository mainFactory.ReceiptsRepository + sentSignaturesTracker process.SentSignaturesTracker } // ProcessComponentsFactoryArgs holds the arguments needed to create a process components factory @@ -606,6 +607,11 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { return nil, err } + sentSignaturesTracker, err := track.NewSentSignaturesTracker(pcf.crypto.KeysHandler()) + if err != nil { + return nil, fmt.Errorf("%w when assembling components for the sent signatures tracker", err) + } + blockProcessorComponents, err := pcf.newBlockProcessor( requestHandler, forkDetector, @@ -621,6 +627,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { receiptsRepository, blockCutoffProcessingHandler, pcf.state.MissingTrieNodesNotifier(), + sentSignaturesTracker, ) if err != nil { return nil, err @@ -734,6 +741,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { esdtDataStorageForApi: pcf.esdtNftStorage, accountsParser: pcf.accountsParser, receiptsRepository: receiptsRepository, + sentSignaturesTracker: sentSignaturesTracker, }, nil } diff --git a/factory/processing/processComponentsHandler.go b/factory/processing/processComponentsHandler.go index b544ba901ef..a5b71ca3b28 100644 --- a/factory/processing/processComponentsHandler.go +++ b/factory/processing/processComponentsHandler.go @@ -55,7 +55,7 @@ func (m *managedProcessComponents) Create() error { return nil } -// Close will close all underlying sub-components +// Close will close all underlying subcomponents func (m *managedProcessComponents) Close() error { m.mutProcessComponents.Lock() defer m.mutProcessComponents.Unlock() @@ -174,6 +174,9 @@ func (m *managedProcessComponents) CheckSubcomponents() error { if check.IfNil(m.processComponents.esdtDataStorageForApi) { return errors.ErrNilESDTDataStorage } + if check.IfNil(m.processComponents.sentSignaturesTracker) { + return errors.ErrNilSentSignatureTracker + } return nil } @@ -658,6 +661,18 @@ func (m *managedProcessComponents) ReceiptsRepository() factory.ReceiptsReposito return m.processComponents.receiptsRepository } +// SentSignaturesTracker returns the signature tracker +func (m *managedProcessComponents) SentSignaturesTracker() process.SentSignaturesTracker { + m.mutProcessComponents.RLock() + defer m.mutProcessComponents.RUnlock() + + if m.processComponents == nil { + return nil + } + + return m.processComponents.sentSignaturesTracker +} + // IsInterfaceNil returns true if the interface is nil func (m *managedProcessComponents) IsInterfaceNil() bool { return m == nil diff --git a/factory/processing/processComponentsHandler_test.go b/factory/processing/processComponentsHandler_test.go index 152b7637dc6..36638afacfd 100644 --- a/factory/processing/processComponentsHandler_test.go +++ b/factory/processing/processComponentsHandler_test.go @@ -92,6 +92,7 @@ func TestManagedProcessComponents_Create(t *testing.T) { require.True(t, check.IfNil(managedProcessComponents.ReceiptsRepository())) require.True(t, check.IfNil(managedProcessComponents.FullArchivePeerShardMapper())) require.True(t, check.IfNil(managedProcessComponents.FullArchiveInterceptorsContainer())) + require.True(t, check.IfNil(managedProcessComponents.SentSignaturesTracker())) err := managedProcessComponents.Create() require.NoError(t, err) @@ -135,6 +136,7 @@ func TestManagedProcessComponents_Create(t *testing.T) { require.False(t, check.IfNil(managedProcessComponents.ReceiptsRepository())) require.False(t, check.IfNil(managedProcessComponents.FullArchivePeerShardMapper())) require.False(t, check.IfNil(managedProcessComponents.FullArchiveInterceptorsContainer())) + require.False(t, check.IfNil(managedProcessComponents.SentSignaturesTracker())) require.Equal(t, factory.ProcessComponentsName, managedProcessComponents.String()) }) diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index bb629016728..9bb6e4800a6 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -215,6 +215,7 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto PeerSignHandler: &cryptoMocks.PeerSignatureHandlerStub{}, MsgSigVerifier: &testscommon.MessageSignVerifierMock{}, ManagedPeersHolderField: &testscommon.ManagedPeersHolderStub{}, + KeysHandlerField: &testscommon.KeysHandlerStub{}, }, Network: &testsMocks.NetworkComponentsStub{ Messenger: &p2pmocks.MessengerStub{}, diff --git a/integrationTests/mock/processComponentsStub.go b/integrationTests/mock/processComponentsStub.go index e5a94dd78c1..e0407b5d6f9 100644 --- a/integrationTests/mock/processComponentsStub.go +++ b/integrationTests/mock/processComponentsStub.go @@ -59,6 +59,7 @@ type ProcessComponentsStub struct { ProcessedMiniBlocksTrackerInternal process.ProcessedMiniBlocksTracker ReceiptsRepositoryInternal factory.ReceiptsRepository ESDTDataStorageHandlerForAPIInternal vmcommon.ESDTNFTStorageHandler + SentSignaturesTrackerInternal process.SentSignaturesTracker } // Create - @@ -290,6 +291,11 @@ func (pcs *ProcessComponentsStub) ESDTDataStorageHandlerForAPI() vmcommon.ESDTNF return pcs.ESDTDataStorageHandlerForAPIInternal } +// SentSignaturesTracker - +func (pcs *ProcessComponentsStub) SentSignaturesTracker() process.SentSignaturesTracker { + return pcs.SentSignaturesTrackerInternal +} + // IsInterfaceNil - func (pcs *ProcessComponentsStub) IsInterfaceNil() bool { return pcs == nil diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 650f54a5058..f56720fd0a3 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -320,6 +320,7 @@ func (tcn *TestConsensusNode) initNode(args ArgsTestConsensusNode) { processComponents.RoundHandlerField = roundHandler processComponents.ScheduledTxsExecutionHandlerInternal = &testscommon.ScheduledTxsExecutionStub{} processComponents.ProcessedMiniBlocksTrackerInternal = &testscommon.ProcessedMiniBlocksTrackerStub{} + processComponents.SentSignaturesTrackerInternal = &testscommon.SentSignatureTrackerStub{} dataComponents := GetDefaultDataComponents() dataComponents.BlockChain = tcn.ChainHandler diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 9e599debbd7..875f2bb3cec 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2225,6 +2225,7 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { OutportDataProvider: &outport.OutportDataProviderStub{}, BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, + SentSignaturesTracker: &testscommon.SentSignatureTrackerStub{}, } if check.IfNil(tpn.EpochStartNotifier) { diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index ee4d95a0c63..1dfea4958b2 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -104,6 +104,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { OutportDataProvider: &outport.OutportDataProviderStub{}, BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, + SentSignaturesTracker: &testscommon.SentSignatureTrackerStub{}, } if tpn.ShardCoordinator.SelfId() == core.MetachainShardId { diff --git a/process/block/argProcessor.go b/process/block/argProcessor.go index 703d6326b40..df929214829 100644 --- a/process/block/argProcessor.go +++ b/process/block/argProcessor.go @@ -93,6 +93,7 @@ type ArgBaseProcessor struct { ReceiptsRepository receiptsRepository BlockProcessingCutoffHandler cutoff.BlockProcessingCutoffHandler ManagedPeersHolder common.ManagedPeersHolder + SentSignaturesTracker process.SentSignaturesTracker } // ArgShardProcessor holds all dependencies required by the process data factory in order to create diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 31a4629a6ac..72bdc5b7cca 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -35,6 +35,7 @@ import ( "github.com/multiversx/mx-chain-go/process/block/bootstrapStorage" "github.com/multiversx/mx-chain-go/process/block/cutoff" "github.com/multiversx/mx-chain-go/process/block/processedMb" + "github.com/multiversx/mx-chain-go/process/headerCheck" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" @@ -89,6 +90,7 @@ type baseProcessor struct { processDebugger process.Debugger processStatusHandler common.ProcessStatusHandler managedPeersHolder common.ManagedPeersHolder + sentSignaturesTracker process.SentSignaturesTracker versionedHeaderFactory nodeFactory.VersionedHeaderFactory headerIntegrityVerifier process.HeaderIntegrityVerifier @@ -551,6 +553,9 @@ func checkProcessorParameters(arguments ArgBaseProcessor) error { if check.IfNil(arguments.ManagedPeersHolder) { return process.ErrNilManagedPeersHolder } + if check.IfNil(arguments.SentSignaturesTracker) { + return process.ErrNilSentSignatureTracker + } return nil } @@ -2110,3 +2115,19 @@ func (bp *baseProcessor) setNonceOfFirstCommittedBlock(nonce uint64) { bp.nonceOfFirstCommittedBlock.HasValue = true bp.nonceOfFirstCommittedBlock.Value = nonce } + +func (bp *baseProcessor) checkSentSignaturesBeforeCommitting(header data.HeaderHandler) error { + validatorsGroup, err := headerCheck.ComputeConsensusGroup(header, bp.nodesCoordinator) + if err != nil { + return err + } + + validatorsPKs := make([][]byte, 0, len(validatorsGroup)) + for _, validator := range validatorsGroup { + validatorsPKs = append(validatorsPKs, validator.PubKey()) + } + + bp.sentSignaturesTracker.ResetCountersManagedBlockSigners(validatorsPKs) + + return nil +} diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 77bcf2ac770..4c4e4b1b0a3 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -34,6 +34,7 @@ import ( "github.com/multiversx/mx-chain-go/process/block/processedMb" "github.com/multiversx/mx-chain-go/process/coordinator" "github.com/multiversx/mx-chain-go/process/mock" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/storage/database" @@ -73,7 +74,7 @@ func createArgBaseProcessor( bootstrapComponents *mock.BootstrapComponentsMock, statusComponents *mock.StatusComponentsMock, ) blproc.ArgBaseProcessor { - nodesCoordinator := shardingMocks.NewNodesCoordinatorMock() + nodesCoordinatorInstance := shardingMocks.NewNodesCoordinatorMock() argsHeaderValidator := blproc.ArgsHeaderValidator{ Hasher: &hashingMocks.HasherMock{}, Marshalizer: &mock.MarshalizerMock{}, @@ -102,7 +103,7 @@ func createArgBaseProcessor( Config: config.Config{}, AccountsDB: accountsDb, ForkDetector: &mock.ForkDetectorMock{}, - NodesCoordinator: nodesCoordinator, + NodesCoordinator: nodesCoordinatorInstance, FeeHandler: &mock.FeeAccumulatorStub{}, RequestHandler: &testscommon.RequestHandlerStub{}, BlockChainHook: &testscommon.BlockChainHookStub{}, @@ -126,6 +127,7 @@ func createArgBaseProcessor( ReceiptsRepository: &testscommon.ReceiptsRepositoryStub{}, BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, + SentSignaturesTracker: &testscommon.SentSignatureTrackerStub{}, } } @@ -3128,3 +3130,52 @@ func TestBaseProcessor_ConcurrentCallsNonceOfFirstCommittedBlock(t *testing.T) { assert.True(t, len(values) <= 1) // we can have the situation when all reads are done before the first set assert.Equal(t, numCalls/2, values[lastValRead]+noValues) } + +func TestBaseProcessor_CheckSentSignaturesBeforeCommitting(t *testing.T) { + t.Parallel() + + expectedErr := errors.New("expected error") + t.Run("nodes coordinator errors, should return error", func(t *testing.T) { + nodesCoordinatorInstance := shardingMocks.NewNodesCoordinatorMock() + nodesCoordinatorInstance.ComputeValidatorsGroupCalled = func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + return nil, expectedErr + } + + arguments := CreateMockArguments(createComponentHolderMocks()) + arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ + ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { + assert.Fail(t, "should have not called ResetCountersManagedBlockSigners") + }, + } + arguments.NodesCoordinator = nodesCoordinatorInstance + bp, _ := blproc.NewShardProcessor(arguments) + + err := bp.CheckSentSignaturesBeforeCommitting(&block.Header{}) + assert.Equal(t, expectedErr, err) + }) + t.Run("should work", func(t *testing.T) { + validator0, _ := nodesCoordinator.NewValidator([]byte("pk0"), 0, 0) + validator1, _ := nodesCoordinator.NewValidator([]byte("pk1"), 1, 1) + validator2, _ := nodesCoordinator.NewValidator([]byte("pk2"), 2, 2) + + nodesCoordinatorInstance := shardingMocks.NewNodesCoordinatorMock() + nodesCoordinatorInstance.ComputeValidatorsGroupCalled = func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + return []nodesCoordinator.Validator{validator0, validator1, validator2}, nil + } + + resetCountersCalled := make([][]byte, 0) + arguments := CreateMockArguments(createComponentHolderMocks()) + arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ + ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { + resetCountersCalled = append(resetCountersCalled, signersPKs...) + }, + } + arguments.NodesCoordinator = nodesCoordinatorInstance + bp, _ := blproc.NewShardProcessor(arguments) + + err := bp.CheckSentSignaturesBeforeCommitting(&block.Header{}) + assert.Nil(t, err) + + assert.Equal(t, [][]byte{validator0.PubKey(), validator1.PubKey(), validator2.PubKey()}, resetCountersCalled) + }) +} diff --git a/process/block/export_test.go b/process/block/export_test.go index 00c67190fea..11171d27edd 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -167,6 +167,7 @@ func NewShardProcessorEmptyWith3shards( ReceiptsRepository: &testscommon.ReceiptsRepositoryStub{}, BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, + SentSignaturesTracker: &testscommon.SentSignatureTrackerStub{}, }, } shardProc, err := NewShardProcessor(arguments) @@ -559,3 +560,7 @@ func (mp *metaProcessor) GetAllMarshalledTxs(body *block.Body) map[string][][]by func (bp *baseProcessor) SetNonceOfFirstCommittedBlock(nonce uint64) { bp.setNonceOfFirstCommittedBlock(nonce) } + +func (bp *baseProcessor) CheckSentSignaturesBeforeCommitting(header data.HeaderHandler) error { + return bp.checkSentSignaturesBeforeCommitting(header) +} diff --git a/process/block/metablock.go b/process/block/metablock.go index 8808fa218ff..86cfe0af68c 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -136,6 +136,7 @@ func NewMetaProcessor(arguments ArgMetaProcessor) (*metaProcessor, error) { processStatusHandler: arguments.CoreComponents.ProcessStatusHandler(), blockProcessingCutoffHandler: arguments.BlockProcessingCutoffHandler, managedPeersHolder: arguments.ManagedPeersHolder, + sentSignaturesTracker: arguments.SentSignaturesTracker, } mp := metaProcessor{ @@ -1237,6 +1238,11 @@ func (mp *metaProcessor) CommitBlock( mp.setNonceOfFirstCommittedBlock(headerHandler.GetNonce()) mp.updateLastCommittedInDebugger(headerHandler.GetRound()) + errNotCritical := mp.checkSentSignaturesBeforeCommitting(headerHandler) + if errNotCritical != nil { + log.Debug("checkSentSignaturesBeforeCommitting", "error", errNotCritical.Error()) + } + notarizedHeadersHashes, errNotCritical := mp.updateCrossShardInfo(header) if errNotCritical != nil { log.Debug("updateCrossShardInfo", "error", errNotCritical.Error()) diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 101e8b8f4c6..313dda0f606 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -149,6 +149,7 @@ func createMockMetaArguments( OutportDataProvider: &outport.OutportDataProviderStub{}, BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, + SentSignaturesTracker: &testscommon.SentSignatureTrackerStub{}, }, SCToProtocol: &mock.SCToProtocolStub{}, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, @@ -1041,6 +1042,12 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { return &block.Header{}, []byte("hash"), nil } arguments.BlockTracker = blockTrackerMock + resetCountersManagedBlockSignersCalled := false + arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ + ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { + resetCountersManagedBlockSignersCalled = true + }, + } mp, _ := blproc.NewMetaProcessor(arguments) @@ -1082,6 +1089,7 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.Nil(t, err) assert.True(t, forkDetectorAddCalled) assert.True(t, debuggerMethodWasCalled) + assert.True(t, resetCountersManagedBlockSignersCalled) // this should sleep as there is an async call to display current header and block in CommitBlock time.Sleep(time.Second) } diff --git a/process/block/shardblock.go b/process/block/shardblock.go index ffc736db370..c2f56dfec9d 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -121,6 +121,7 @@ func NewShardProcessor(arguments ArgShardProcessor) (*shardProcessor, error) { processStatusHandler: arguments.CoreComponents.ProcessStatusHandler(), blockProcessingCutoffHandler: arguments.BlockProcessingCutoffHandler, managedPeersHolder: arguments.ManagedPeersHolder, + sentSignaturesTracker: arguments.SentSignaturesTracker, } sp := shardProcessor{ @@ -987,7 +988,12 @@ func (sp *shardProcessor) CommitBlock( sp.updateLastCommittedInDebugger(headerHandler.GetRound()) - errNotCritical := sp.updateCrossShardInfo(processedMetaHdrs) + errNotCritical := sp.checkSentSignaturesBeforeCommitting(headerHandler) + if errNotCritical != nil { + log.Debug("checkSentSignaturesBeforeCommitting", "error", errNotCritical.Error()) + } + + errNotCritical = sp.updateCrossShardInfo(processedMetaHdrs) if errNotCritical != nil { log.Debug("updateCrossShardInfo", "error", errNotCritical.Error()) } diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index ff1e1e3e10f..cbda7fe4ceb 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -2121,6 +2121,12 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { return &block.MetaBlock{}, []byte("hash"), nil } arguments.BlockTracker = blockTrackerMock + resetCountersManagedBlockSignersCalled := false + arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ + ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { + resetCountersManagedBlockSignersCalled = true + }, + } sp, _ := blproc.NewShardProcessor(arguments) debuggerMethodWasCalled := false @@ -2144,6 +2150,7 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.True(t, forkDetectorAddCalled) assert.Equal(t, hdrHash, blkc.GetCurrentBlockHeaderHash()) assert.True(t, debuggerMethodWasCalled) + assert.True(t, resetCountersManagedBlockSignersCalled) // this should sleep as there is an async call to display current hdr and block in CommitBlock time.Sleep(time.Second) } diff --git a/process/errors.go b/process/errors.go index 6ae40412109..52fcfd95a18 100644 --- a/process/errors.go +++ b/process/errors.go @@ -1226,3 +1226,6 @@ var ErrNilStorageService = errors.New("nil storage service") // ErrInvalidAsyncArguments signals that invalid arguments were given for async/callBack processing var ErrInvalidAsyncArguments = errors.New("invalid arguments to process async/callback function") + +// ErrNilSentSignatureTracker defines the error for setting a nil SentSignatureTracker +var ErrNilSentSignatureTracker = errors.New("nil sent signature tracker") diff --git a/process/headerCheck/common.go b/process/headerCheck/common.go new file mode 100644 index 00000000000..6b3b9960428 --- /dev/null +++ b/process/headerCheck/common.go @@ -0,0 +1,19 @@ +package headerCheck + +import ( + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" +) + +// ComputeConsensusGroup will compute the consensus group that assembled the provided block +func ComputeConsensusGroup(header data.HeaderHandler, nodesCoordinator nodesCoordinator.NodesCoordinator) (validatorsGroup []nodesCoordinator.Validator, err error) { + prevRandSeed := header.GetPrevRandSeed() + + // TODO: change here with an activation flag if start of epoch block needs to be validated by the new epoch nodes + epoch := header.GetEpoch() + if header.IsStartOfEpochBlock() && epoch > 0 { + epoch = epoch - 1 + } + + return nodesCoordinator.ComputeConsensusGroup(prevRandSeed, header.GetRound(), header.GetShardID(), epoch) +} diff --git a/process/headerCheck/common_test.go b/process/headerCheck/common_test.go new file mode 100644 index 00000000000..9f349c47d8b --- /dev/null +++ b/process/headerCheck/common_test.go @@ -0,0 +1,70 @@ +package headerCheck + +import ( + "testing" + + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/stretchr/testify/assert" +) + +func TestComputeConsensusGroup(t *testing.T) { + t.Parallel() + + t.Run("should work for a random block", func(t *testing.T) { + header := &block.Header{ + Epoch: 1123, + Round: 37373, + Nonce: 38383, + ShardID: 2, + PrevRandSeed: []byte("prev rand seed"), + } + + validator1, _ := nodesCoordinator.NewValidator([]byte("pk1"), 1, 1) + validator2, _ := nodesCoordinator.NewValidator([]byte("pk2"), 1, 2) + + validatorGroup := []nodesCoordinator.Validator{validator1, validator2} + nodesCoordinatorInstance := shardingMocks.NewNodesCoordinatorMock() + nodesCoordinatorInstance.ComputeValidatorsGroupCalled = func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + assert.Equal(t, header.PrevRandSeed, randomness) + assert.Equal(t, header.Round, round) + assert.Equal(t, header.ShardID, shardId) + assert.Equal(t, header.Epoch, epoch) + + return validatorGroup, nil + } + + vGroup, err := ComputeConsensusGroup(header, nodesCoordinatorInstance) + assert.Nil(t, err) + assert.Equal(t, validatorGroup, vGroup) + }) + t.Run("should work for a start of epoch block", func(t *testing.T) { + header := &block.Header{ + Epoch: 1123, + Round: 37373, + Nonce: 38383, + ShardID: 2, + PrevRandSeed: []byte("prev rand seed"), + EpochStartMetaHash: []byte("epoch start metahash"), + } + + validator1, _ := nodesCoordinator.NewValidator([]byte("pk1"), 1, 1) + validator2, _ := nodesCoordinator.NewValidator([]byte("pk2"), 1, 2) + + validatorGroup := []nodesCoordinator.Validator{validator1, validator2} + nodesCoordinatorInstance := shardingMocks.NewNodesCoordinatorMock() + nodesCoordinatorInstance.ComputeValidatorsGroupCalled = func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + assert.Equal(t, header.PrevRandSeed, randomness) + assert.Equal(t, header.Round, round) + assert.Equal(t, header.ShardID, shardId) + assert.Equal(t, header.Epoch-1, epoch) + + return validatorGroup, nil + } + + vGroup, err := ComputeConsensusGroup(header, nodesCoordinatorInstance) + assert.Nil(t, err) + assert.Equal(t, validatorGroup, vGroup) + }) +} diff --git a/process/headerCheck/headerSignatureVerify.go b/process/headerCheck/headerSignatureVerify.go index 999bc82e881..308af919366 100644 --- a/process/headerCheck/headerSignatureVerify.go +++ b/process/headerCheck/headerSignatureVerify.go @@ -30,7 +30,7 @@ type ArgsHeaderSigVerifier struct { FallbackHeaderValidator process.FallbackHeaderValidator } -//HeaderSigVerifier is component used to check if a header is valid +// HeaderSigVerifier is component used to check if a header is valid type HeaderSigVerifier struct { marshalizer marshal.Marshalizer hasher hashing.Hasher @@ -301,15 +301,7 @@ func (hsv *HeaderSigVerifier) verifyLeaderSignature(leaderPubKey crypto.PublicKe } func (hsv *HeaderSigVerifier) getLeader(header data.HeaderHandler) (crypto.PublicKey, error) { - prevRandSeed := header.GetPrevRandSeed() - - // TODO: remove if start of epoch block needs to be validated by the new epoch nodes - epoch := header.GetEpoch() - if header.IsStartOfEpochBlock() && epoch > 0 { - epoch = epoch - 1 - } - - headerConsensusGroup, err := hsv.nodesCoordinator.ComputeConsensusGroup(prevRandSeed, header.GetRound(), header.GetShardID(), epoch) + headerConsensusGroup, err := ComputeConsensusGroup(header, hsv.nodesCoordinator) if err != nil { return nil, err } diff --git a/process/interface.go b/process/interface.go index 9dfb58b9460..24ae59b9afe 100644 --- a/process/interface.go +++ b/process/interface.go @@ -1340,3 +1340,11 @@ type Debugger interface { Close() error IsInterfaceNil() bool } + +// SentSignaturesTracker defines a component able to handle sent signature from self +type SentSignaturesTracker interface { + StartRound() + SignatureSent(pkBytes []byte) + ResetCountersManagedBlockSigners(signersPKs [][]byte) + IsInterfaceNil() bool +} diff --git a/process/track/errors.go b/process/track/errors.go index 2a0c2e57672..2c9a3a5c297 100644 --- a/process/track/errors.go +++ b/process/track/errors.go @@ -30,3 +30,6 @@ var ErrNotarizedHeaderOffsetIsOutOfBound = errors.New("requested offset of the n // ErrNilRoundHandler signals that a nil roundHandler has been provided var ErrNilRoundHandler = errors.New("nil roundHandler") + +// ErrNilKeysHandler signals that a nil keys handler was provided +var ErrNilKeysHandler = errors.New("nil keys handler") diff --git a/process/track/interface.go b/process/track/interface.go index 7d7966060da..1dbfa2caa2c 100644 --- a/process/track/interface.go +++ b/process/track/interface.go @@ -1,6 +1,7 @@ package track import ( + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data" ) @@ -47,3 +48,10 @@ type blockBalancerHandler interface { SetLastShardProcessedMetaNonce(shardID uint32, nonce uint64) IsInterfaceNil() bool } + +// KeysHandler defines the operations implemented by a component that will manage all keys, +// including the single signer keys or the set of multi-keys +type KeysHandler interface { + ResetRoundsWithoutReceivedMessages(pkBytes []byte, pid core.PeerID) + IsInterfaceNil() bool +} diff --git a/consensus/spos/sentSignaturesTracker.go b/process/track/sentSignaturesTracker.go similarity index 64% rename from consensus/spos/sentSignaturesTracker.go rename to process/track/sentSignaturesTracker.go index de7ecd69543..91f0bed00eb 100644 --- a/consensus/spos/sentSignaturesTracker.go +++ b/process/track/sentSignaturesTracker.go @@ -1,11 +1,10 @@ -package spos +package track import ( "sync" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-go/consensus" ) // externalPeerID is just a marker so the ResetRoundsWithoutReceivedMessages will know it is not an owned peer ID @@ -15,11 +14,11 @@ const externalPeerID = core.PeerID("external peer id") type sentSignaturesTracker struct { mut sync.RWMutex sentFromSelf map[string]struct{} - keysHandler consensus.KeysHandler + keysHandler KeysHandler } // NewSentSignaturesTracker will create a new instance of a tracker able to record if a signature was sent from self -func NewSentSignaturesTracker(keysHandler consensus.KeysHandler) (*sentSignaturesTracker, error) { +func NewSentSignaturesTracker(keysHandler KeysHandler) (*sentSignaturesTracker, error) { if check.IfNil(keysHandler) { return nil, ErrNilKeysHandler } @@ -44,20 +43,19 @@ func (tracker *sentSignaturesTracker) SignatureSent(pkBytes []byte) { tracker.mut.Unlock() } -// ReceivedActualSigners is called whenever a final info is received. If a signer public key did not send a signature -// from the current host, it will call the reset rounds without received message. This is the case when another instance of a -// multikey node (possibly running as main) broadcast only the final info as it contained the leader + a few signers -func (tracker *sentSignaturesTracker) ReceivedActualSigners(signersPks []string) { +// ResetCountersManagedBlockSigners is called at commit time and will call the reset rounds without received messages +// for each managed key that actually signed a block +func (tracker *sentSignaturesTracker) ResetCountersManagedBlockSigners(signersPKs [][]byte) { tracker.mut.RLock() defer tracker.mut.RUnlock() - for _, signerPk := range signersPks { - _, isSentFromSelf := tracker.sentFromSelf[signerPk] + for _, signerPk := range signersPKs { + _, isSentFromSelf := tracker.sentFromSelf[string(signerPk)] if isSentFromSelf { continue } - tracker.keysHandler.ResetRoundsWithoutReceivedMessages([]byte(signerPk), externalPeerID) + tracker.keysHandler.ResetRoundsWithoutReceivedMessages(signerPk, externalPeerID) } } diff --git a/consensus/spos/sentSignaturesTracker_test.go b/process/track/sentSignaturesTracker_test.go similarity index 73% rename from consensus/spos/sentSignaturesTracker_test.go rename to process/track/sentSignaturesTracker_test.go index a0ecc275e68..2c57dc5880a 100644 --- a/consensus/spos/sentSignaturesTracker_test.go +++ b/process/track/sentSignaturesTracker_test.go @@ -1,4 +1,4 @@ -package spos +package track import ( "testing" @@ -37,13 +37,13 @@ func TestSentSignaturesTracker_IsInterfaceNil(t *testing.T) { assert.False(t, tracker.IsInterfaceNil()) } -func TestSentSignaturesTracker_ReceivedActualSigners(t *testing.T) { +func TestSentSignaturesTracker_ResetCountersManagedBlockSigners(t *testing.T) { t.Parallel() - pk1 := "pk1" - pk2 := "pk2" - pk3 := "pk3" - pk4 := "pk4" + pk1 := []byte("pk1") + pk2 := []byte("pk2") + pk3 := []byte("pk3") + pk4 := []byte("pk4") t.Run("empty map should call remove", func(t *testing.T) { t.Parallel() @@ -56,11 +56,11 @@ func TestSentSignaturesTracker_ReceivedActualSigners(t *testing.T) { }, } - signers := []string{pk1, pk2} + signers := [][]byte{pk1, pk2} tracker, _ := NewSentSignaturesTracker(keysHandler) - tracker.ReceivedActualSigners(signers) + tracker.ResetCountersManagedBlockSigners(signers) - assert.Equal(t, [][]byte{[]byte(pk1), []byte(pk2)}, pkBytesSlice) + assert.Equal(t, [][]byte{pk1, pk2}, pkBytesSlice) }) t.Run("should call remove only for the public keys that did not sent signatures from self", func(t *testing.T) { t.Parallel() @@ -73,21 +73,21 @@ func TestSentSignaturesTracker_ReceivedActualSigners(t *testing.T) { }, } - signers := []string{pk1, pk2, pk3, pk4} + signers := [][]byte{pk1, pk2, pk3, pk4} tracker, _ := NewSentSignaturesTracker(keysHandler) - tracker.SignatureSent([]byte(pk1)) - tracker.SignatureSent([]byte(pk3)) + tracker.SignatureSent(pk1) + tracker.SignatureSent(pk3) - tracker.ReceivedActualSigners(signers) - assert.Equal(t, [][]byte{[]byte("pk2"), []byte("pk4")}, pkBytesSlice) + tracker.ResetCountersManagedBlockSigners(signers) + assert.Equal(t, [][]byte{pk2, pk4}, pkBytesSlice) t.Run("after reset, all should be called", func(t *testing.T) { tracker.StartRound() - tracker.ReceivedActualSigners(signers) + tracker.ResetCountersManagedBlockSigners(signers) assert.Equal(t, [][]byte{ - []byte("pk2"), []byte("pk4"), // from the previous test - []byte("pk1"), []byte("pk2"), []byte("pk3"), []byte("pk4"), // from this call + pk2, pk4, // from the previous test + pk1, pk2, pk3, pk4, // from this call }, pkBytesSlice) }) }) diff --git a/consensus/mock/sentSignatureTrackerStub.go b/testscommon/sentSignatureTrackerStub.go similarity index 52% rename from consensus/mock/sentSignatureTrackerStub.go rename to testscommon/sentSignatureTrackerStub.go index f61bcf2e778..13e399c4aa1 100644 --- a/consensus/mock/sentSignatureTrackerStub.go +++ b/testscommon/sentSignatureTrackerStub.go @@ -1,10 +1,10 @@ -package mock +package testscommon // SentSignatureTrackerStub - type SentSignatureTrackerStub struct { - StartRoundCalled func() - SignatureSentCalled func(pkBytes []byte) - ReceivedActualSignersCalled func(signersPks []string) + StartRoundCalled func() + SignatureSentCalled func(pkBytes []byte) + ResetCountersManagedBlockSignersCalled func(signersPKs [][]byte) } // StartRound - @@ -21,10 +21,10 @@ func (stub *SentSignatureTrackerStub) SignatureSent(pkBytes []byte) { } } -// ReceivedActualSigners - -func (stub *SentSignatureTrackerStub) ReceivedActualSigners(signersPks []string) { - if stub.ReceivedActualSignersCalled != nil { - stub.ReceivedActualSignersCalled(signersPks) +// ResetCountersManagedBlockSigners - +func (stub *SentSignatureTrackerStub) ResetCountersManagedBlockSigners(signersPKs [][]byte) { + if stub.ResetCountersManagedBlockSignersCalled != nil { + stub.ResetCountersManagedBlockSignersCalled(signersPKs) } } From 504232816312b8378982d0554d1c5d019a0d031c Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 16 Jan 2024 16:25:21 +0200 Subject: [PATCH 609/958] - fix after merge --- consensus/spos/bls/subroundEndRound_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 6b74aa8b924..8a932e5e074 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -1365,7 +1365,7 @@ func TestSubroundEndRound_ReceivedInvalidSignersInfo(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, &statusHandler.AppStatusHandlerStub{}, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) srEndRound.SetSelfPubKey("A") From cd71db69aa0193fd9c981de97dd31bf3b8d5f542 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 16 Jan 2024 19:17:30 +0200 Subject: [PATCH 610/958] - new vm common --- cmd/node/config/enableEpochs.toml | 3 +++ common/enablers/enableEpochsHandler.go | 1 + common/enablers/enableEpochsHandler_test.go | 16 ++++++++++++++++ common/enablers/epochFlags.go | 7 +++++++ common/interface.go | 1 + config/epochConfig.go | 1 + config/tomlConfig_test.go | 4 ++++ go.mod | 4 ++-- go.sum | 8 ++++---- .../enableEpochsHandlerStub.go | 9 +++++++++ 10 files changed, 48 insertions(+), 6 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 539aaa4fcdc..e5b6efe99f3 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -257,6 +257,9 @@ # AutoBalanceDataTriesEnableEpoch represents the epoch when the data tries are automatically balanced by inserting at the hashed key instead of the normal key AutoBalanceDataTriesEnableEpoch = 1 + # MigrateDataTrieEnableEpoch represents the epoch when the data tries migration is enabled + MigrateDataTrieEnableEpoch = 999999 + # KeepExecOrderOnCreatedSCRsEnableEpoch represents the epoch when the execution order of created SCRs is ensured KeepExecOrderOnCreatedSCRsEnableEpoch = 1 diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 41e4d45e033..8e52fe54adb 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -133,6 +133,7 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.NFTStopCreateEnableEpoch, handler.nftStopCreateFlag, "nftStopCreateFlag", epoch, handler.enableEpochsConfig.NFTStopCreateEnableEpoch) handler.setFlagValue(epoch >= handler.enableEpochsConfig.ChangeOwnerAddressCrossShardThroughSCEnableEpoch, handler.changeOwnerAddressCrossShardThroughSCFlag, "changeOwnerAddressCrossShardThroughSCFlag", epoch, handler.enableEpochsConfig.ChangeOwnerAddressCrossShardThroughSCEnableEpoch) handler.setFlagValue(epoch >= handler.enableEpochsConfig.FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch, handler.fixGasRemainingForSaveKeyValueFlag, "fixGasRemainingForSaveKeyValueFlag", epoch, handler.enableEpochsConfig.FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch) + handler.setFlagValue(epoch >= handler.enableEpochsConfig.MigrateDataTrieEnableEpoch, handler.migrateDataTrieFlag, "migrateDataTrieFlag", epoch, handler.enableEpochsConfig.MigrateDataTrieEnableEpoch) } func (handler *enableEpochsHandler) setFlagValue(value bool, flag *atomic.Flag, flagName string, epoch uint32, flagEpoch uint32) { diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 7f412524538..ced326d41ba 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -106,6 +106,7 @@ func createEnableEpochsConfig() config.EnableEpochs { ScToScLogEventEnableEpoch: 88, NFTStopCreateEnableEpoch: 89, FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch: 90, + MigrateDataTrieEnableEpoch: 91, } } @@ -251,6 +252,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.FixDelegationChangeOwnerOnAccountEnabled()) assert.True(t, handler.NFTStopCreateEnabled()) assert.True(t, handler.FixGasRemainingForSaveKeyValueBuiltinFunctionEnabled()) + assert.True(t, handler.IsMigrateDataTrieEnabled()) }) t.Run("flags with == condition should not be set, the ones with >= should be set", func(t *testing.T) { t.Parallel() @@ -372,6 +374,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.FixDelegationChangeOwnerOnAccountEnabled()) assert.True(t, handler.NFTStopCreateEnabled()) assert.True(t, handler.FixGasRemainingForSaveKeyValueBuiltinFunctionEnabled()) + assert.True(t, handler.IsMigrateDataTrieEnabled()) }) t.Run("flags with < should be set", func(t *testing.T) { t.Parallel() @@ -488,6 +491,19 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.FixDelegationChangeOwnerOnAccountEnabled()) assert.False(t, handler.NFTStopCreateEnabled()) assert.False(t, handler.FixGasRemainingForSaveKeyValueBuiltinFunctionEnabled()) + assert.False(t, handler.IsMigrateDataTrieEnabled()) + }) + t.Run("test for migrate data tries", func(t *testing.T) { + t.Parallel() + + epoch := uint32(90) + cfg := createEnableEpochsConfig() + handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) + + handler.EpochConfirmed(epoch, 0) + + assert.True(t, handler.IsAutoBalanceDataTriesEnabled()) + assert.False(t, handler.IsMigrateDataTrieEnabled()) }) } diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index 84abad52647..05269dee2f2 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -100,6 +100,7 @@ type epochFlagsHolder struct { changeUsernameFlag *atomic.Flag consistentTokensValuesCheckFlag *atomic.Flag autoBalanceDataTriesFlag *atomic.Flag + migrateDataTrieFlag *atomic.Flag fixDelegationChangeOwnerOnAccountFlag *atomic.Flag dynamicGasCostForDataTrieStorageLoadFlag *atomic.Flag nftStopCreateFlag *atomic.Flag @@ -209,6 +210,7 @@ func newEpochFlagsHolder() *epochFlagsHolder { nftStopCreateFlag: &atomic.Flag{}, changeOwnerAddressCrossShardThroughSCFlag: &atomic.Flag{}, fixGasRemainingForSaveKeyValueFlag: &atomic.Flag{}, + migrateDataTrieFlag: &atomic.Flag{}, } } @@ -740,6 +742,11 @@ func (holder *epochFlagsHolder) IsAutoBalanceDataTriesEnabled() bool { return holder.autoBalanceDataTriesFlag.IsSet() } +// IsMigrateDataTrieEnabled returns true if the migrateDataTrieFlag is enabled +func (holder *epochFlagsHolder) IsMigrateDataTrieEnabled() bool { + return holder.migrateDataTrieFlag.IsSet() +} + // FixDelegationChangeOwnerOnAccountEnabled returns true if the fix for the delegation change owner on account is enabled func (holder *epochFlagsHolder) FixDelegationChangeOwnerOnAccountEnabled() bool { return holder.fixDelegationChangeOwnerOnAccountFlag.IsSet() diff --git a/common/interface.go b/common/interface.go index 9bc3e8c5090..55dbecddc10 100644 --- a/common/interface.go +++ b/common/interface.go @@ -394,6 +394,7 @@ type EnableEpochsHandler interface { IsChangeUsernameEnabled() bool IsConsistentTokensValuesLengthCheckEnabled() bool IsAutoBalanceDataTriesEnabled() bool + IsMigrateDataTrieEnabled() bool IsDynamicGasCostForDataTrieStorageLoadEnabled() bool FixDelegationChangeOwnerOnAccountEnabled() bool NFTStopCreateEnabled() bool diff --git a/config/epochConfig.go b/config/epochConfig.go index c591b17c97b..b23c5a33825 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -102,6 +102,7 @@ type EnableEpochs struct { MultiClaimOnDelegationEnableEpoch uint32 ChangeUsernameEnableEpoch uint32 AutoBalanceDataTriesEnableEpoch uint32 + MigrateDataTrieEnableEpoch uint32 ConsistentTokensValuesLengthCheckEnableEpoch uint32 FixDelegationChangeOwnerOnAccountEnableEpoch uint32 DynamicGasCostForDataTrieStorageLoadEnableEpoch uint32 diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 6e1af87c39b..5b8fa879f6e 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -842,6 +842,9 @@ func TestEnableEpochConfig(t *testing.T) { # FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch represents the epoch when the fix for the remaining gas in the SaveKeyValue builtin function is enabled FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch = 91 + + # MigrateDataTrieEnableEpoch represents the epoch when the data tries migration is enabled + MigrateDataTrieEnableEpoch = 92 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ @@ -954,6 +957,7 @@ func TestEnableEpochConfig(t *testing.T) { NFTStopCreateEnableEpoch: 89, ChangeOwnerAddressCrossShardThroughSCEnableEpoch: 90, FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch: 91, + MigrateDataTrieEnableEpoch: 92, MaxNodesChangeEnableEpoch: []MaxNodesChangeConfig{ { EpochEnable: 44, diff --git a/go.mod b/go.mod index 2d667980760..45d438fc803 100644 --- a/go.mod +++ b/go.mod @@ -20,8 +20,8 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 - github.com/multiversx/mx-chain-vm-common-go v1.5.9 - github.com/multiversx/mx-chain-vm-go v1.5.23 + github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240116165528-e13d057575c2 + github.com/multiversx/mx-chain-vm-go v1.5.24-0.20240116171344-b97ba9e3078e github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 diff --git a/go.sum b/go.sum index 11ce63d1c90..7c47eb5a4b1 100644 --- a/go.sum +++ b/go.sum @@ -398,10 +398,10 @@ github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIM github.com/multiversx/mx-chain-scenario-go v1.2.1/go.mod h1:EuZY7DpNFHVNSxJR8dKE1z2I8gBYfEFFPSwNUOXptqE= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= -github.com/multiversx/mx-chain-vm-common-go v1.5.9 h1:PnGimbMScV5WXFjumzAmcAcnWrw5e9PQABuIcKKUgZw= -github.com/multiversx/mx-chain-vm-common-go v1.5.9/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= -github.com/multiversx/mx-chain-vm-go v1.5.23 h1:FNkEstebRtQWQNlyQbR2yGSpgGTpiwCMnl4MYVYEy2Q= -github.com/multiversx/mx-chain-vm-go v1.5.23/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= +github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240116165528-e13d057575c2 h1:Gzq8OEYp8JTqj7Mfs9/kUQuS5ANS9W3hQ8r5r6cBmYk= +github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240116165528-e13d057575c2/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= +github.com/multiversx/mx-chain-vm-go v1.5.24-0.20240116171344-b97ba9e3078e h1:Nl4JmMDPIMnT4L4C394b6z6jt1R5WhLa1tcednFXE5k= +github.com/multiversx/mx-chain-vm-go v1.5.24-0.20240116171344-b97ba9e3078e/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64/go.mod h1:MUO2E4aEIu3siDkvjraO/WaBh/FxVeQyPWfsrZE+MTU= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 h1:H0Duuoz6lR6KapqLqMspWTojaVtQRiLA5lIm6XV9H04= diff --git a/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go index 43d4139a500..755bdaa10e1 100644 --- a/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerMock/enableEpochsHandlerStub.go @@ -129,6 +129,7 @@ type EnableEpochsHandlerStub struct { IsChangeUsernameEnabledField bool IsConsistentTokensValuesLengthCheckEnabledField bool IsAutoBalanceDataTriesEnabledField bool + IsMigrateDataTrieEnabledField bool FixDelegationChangeOwnerOnAccountEnabledField bool IsDynamicGasCostForDataTrieStorageLoadEnabledField bool IsNFTStopCreateEnabledField bool @@ -1119,6 +1120,14 @@ func (stub *EnableEpochsHandlerStub) IsAutoBalanceDataTriesEnabled() bool { return stub.IsAutoBalanceDataTriesEnabledField } +// IsMigrateDataTrieEnabled - +func (stub *EnableEpochsHandlerStub) IsMigrateDataTrieEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsMigrateDataTrieEnabledField +} + // FixDelegationChangeOwnerOnAccountEnabled - func (stub *EnableEpochsHandlerStub) FixDelegationChangeOwnerOnAccountEnabled() bool { stub.RLock() From bc3bb4b75108a9053698637a1ec0fa6594118cf0 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 16 Jan 2024 19:22:06 +0200 Subject: [PATCH 611/958] - fixed mock --- sharding/mock/enableEpochsHandlerMock.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index e67f7f486ba..93df39fcd2b 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -618,6 +618,11 @@ func (mock *EnableEpochsHandlerMock) IsAutoBalanceDataTriesEnabled() bool { return false } +// IsMigrateDataTrieEnabled - +func (mock *EnableEpochsHandlerMock) IsMigrateDataTrieEnabled() bool { + return false +} + // FixDelegationChangeOwnerOnAccountEnabled - func (mock *EnableEpochsHandlerMock) FixDelegationChangeOwnerOnAccountEnabled() bool { return false From e9ad64cd2720dea8bd70a7adfd1ec530eb954523 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 17 Jan 2024 10:15:41 +0200 Subject: [PATCH 612/958] - fixes after review: renaming + code optimization --- process/block/baseProcess.go | 7 ++---- process/block/baseProcess_test.go | 12 +++++----- process/block/export_test.go | 5 +++-- process/block/metablock.go | 2 +- process/block/metablock_test.go | 8 +++---- process/block/shardblock.go | 2 +- process/block/shardblock_test.go | 8 +++---- process/headerCheck/common.go | 9 ++++++++ process/headerCheck/common_test.go | 25 +++++++++++++++++++++ process/interface.go | 2 +- process/track/sentSignaturesTracker.go | 18 +++++++-------- process/track/sentSignaturesTracker_test.go | 25 +++++++++------------ testscommon/sentSignatureTrackerStub.go | 14 ++++++------ 13 files changed, 82 insertions(+), 55 deletions(-) diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 72bdc5b7cca..c51d7510110 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -2116,18 +2116,15 @@ func (bp *baseProcessor) setNonceOfFirstCommittedBlock(nonce uint64) { bp.nonceOfFirstCommittedBlock.Value = nonce } -func (bp *baseProcessor) checkSentSignaturesBeforeCommitting(header data.HeaderHandler) error { +func (bp *baseProcessor) checkSentSignaturesAtCommitTime(header data.HeaderHandler) error { validatorsGroup, err := headerCheck.ComputeConsensusGroup(header, bp.nodesCoordinator) if err != nil { return err } - validatorsPKs := make([][]byte, 0, len(validatorsGroup)) for _, validator := range validatorsGroup { - validatorsPKs = append(validatorsPKs, validator.PubKey()) + bp.sentSignaturesTracker.ResetCountersForManagedBlockSigner(validator.PubKey()) } - bp.sentSignaturesTracker.ResetCountersManagedBlockSigners(validatorsPKs) - return nil } diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 4c4e4b1b0a3..71737a1b2e4 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -3131,7 +3131,7 @@ func TestBaseProcessor_ConcurrentCallsNonceOfFirstCommittedBlock(t *testing.T) { assert.Equal(t, numCalls/2, values[lastValRead]+noValues) } -func TestBaseProcessor_CheckSentSignaturesBeforeCommitting(t *testing.T) { +func TestBaseProcessor_CheckSentSignaturesAtCommitTime(t *testing.T) { t.Parallel() expectedErr := errors.New("expected error") @@ -3143,14 +3143,14 @@ func TestBaseProcessor_CheckSentSignaturesBeforeCommitting(t *testing.T) { arguments := CreateMockArguments(createComponentHolderMocks()) arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ - ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { + ResetCountersForManagedBlockSignerCalled: func(signerPk []byte) { assert.Fail(t, "should have not called ResetCountersManagedBlockSigners") }, } arguments.NodesCoordinator = nodesCoordinatorInstance bp, _ := blproc.NewShardProcessor(arguments) - err := bp.CheckSentSignaturesBeforeCommitting(&block.Header{}) + err := bp.CheckSentSignaturesAtCommitTime(&block.Header{}) assert.Equal(t, expectedErr, err) }) t.Run("should work", func(t *testing.T) { @@ -3166,14 +3166,14 @@ func TestBaseProcessor_CheckSentSignaturesBeforeCommitting(t *testing.T) { resetCountersCalled := make([][]byte, 0) arguments := CreateMockArguments(createComponentHolderMocks()) arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ - ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { - resetCountersCalled = append(resetCountersCalled, signersPKs...) + ResetCountersForManagedBlockSignerCalled: func(signerPk []byte) { + resetCountersCalled = append(resetCountersCalled, signerPk) }, } arguments.NodesCoordinator = nodesCoordinatorInstance bp, _ := blproc.NewShardProcessor(arguments) - err := bp.CheckSentSignaturesBeforeCommitting(&block.Header{}) + err := bp.CheckSentSignaturesAtCommitTime(&block.Header{}) assert.Nil(t, err) assert.Equal(t, [][]byte{validator0.PubKey(), validator1.PubKey(), validator2.PubKey()}, resetCountersCalled) diff --git a/process/block/export_test.go b/process/block/export_test.go index 11171d27edd..c24513f6fd8 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -561,6 +561,7 @@ func (bp *baseProcessor) SetNonceOfFirstCommittedBlock(nonce uint64) { bp.setNonceOfFirstCommittedBlock(nonce) } -func (bp *baseProcessor) CheckSentSignaturesBeforeCommitting(header data.HeaderHandler) error { - return bp.checkSentSignaturesBeforeCommitting(header) +// CheckSentSignaturesAtCommitTime - +func (bp *baseProcessor) CheckSentSignaturesAtCommitTime(header data.HeaderHandler) error { + return bp.checkSentSignaturesAtCommitTime(header) } diff --git a/process/block/metablock.go b/process/block/metablock.go index 86cfe0af68c..86126bc2c29 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -1238,7 +1238,7 @@ func (mp *metaProcessor) CommitBlock( mp.setNonceOfFirstCommittedBlock(headerHandler.GetNonce()) mp.updateLastCommittedInDebugger(headerHandler.GetRound()) - errNotCritical := mp.checkSentSignaturesBeforeCommitting(headerHandler) + errNotCritical := mp.checkSentSignaturesAtCommitTime(headerHandler) if errNotCritical != nil { log.Debug("checkSentSignaturesBeforeCommitting", "error", errNotCritical.Error()) } diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 313dda0f606..e06611c10f8 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -1042,10 +1042,10 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { return &block.Header{}, []byte("hash"), nil } arguments.BlockTracker = blockTrackerMock - resetCountersManagedBlockSignersCalled := false + resetCountersForManagedBlockSignerCalled := false arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ - ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { - resetCountersManagedBlockSignersCalled = true + ResetCountersForManagedBlockSignerCalled: func(signerPk []byte) { + resetCountersForManagedBlockSignerCalled = true }, } @@ -1089,7 +1089,7 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.Nil(t, err) assert.True(t, forkDetectorAddCalled) assert.True(t, debuggerMethodWasCalled) - assert.True(t, resetCountersManagedBlockSignersCalled) + assert.True(t, resetCountersForManagedBlockSignerCalled) // this should sleep as there is an async call to display current header and block in CommitBlock time.Sleep(time.Second) } diff --git a/process/block/shardblock.go b/process/block/shardblock.go index c2f56dfec9d..8da3e4a07c1 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -988,7 +988,7 @@ func (sp *shardProcessor) CommitBlock( sp.updateLastCommittedInDebugger(headerHandler.GetRound()) - errNotCritical := sp.checkSentSignaturesBeforeCommitting(headerHandler) + errNotCritical := sp.checkSentSignaturesAtCommitTime(headerHandler) if errNotCritical != nil { log.Debug("checkSentSignaturesBeforeCommitting", "error", errNotCritical.Error()) } diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index cbda7fe4ceb..1c967862542 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -2121,10 +2121,10 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { return &block.MetaBlock{}, []byte("hash"), nil } arguments.BlockTracker = blockTrackerMock - resetCountersManagedBlockSignersCalled := false + resetCountersForManagedBlockSignerCalled := false arguments.SentSignaturesTracker = &testscommon.SentSignatureTrackerStub{ - ResetCountersManagedBlockSignersCalled: func(signersPKs [][]byte) { - resetCountersManagedBlockSignersCalled = true + ResetCountersForManagedBlockSignerCalled: func(signerPk []byte) { + resetCountersForManagedBlockSignerCalled = true }, } @@ -2150,7 +2150,7 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.True(t, forkDetectorAddCalled) assert.Equal(t, hdrHash, blkc.GetCurrentBlockHeaderHash()) assert.True(t, debuggerMethodWasCalled) - assert.True(t, resetCountersManagedBlockSignersCalled) + assert.True(t, resetCountersForManagedBlockSignerCalled) // this should sleep as there is an async call to display current hdr and block in CommitBlock time.Sleep(time.Second) } diff --git a/process/headerCheck/common.go b/process/headerCheck/common.go index 6b3b9960428..b25e12c0833 100644 --- a/process/headerCheck/common.go +++ b/process/headerCheck/common.go @@ -1,12 +1,21 @@ package headerCheck import ( + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" ) // ComputeConsensusGroup will compute the consensus group that assembled the provided block func ComputeConsensusGroup(header data.HeaderHandler, nodesCoordinator nodesCoordinator.NodesCoordinator) (validatorsGroup []nodesCoordinator.Validator, err error) { + if check.IfNil(header) { + return nil, process.ErrNilHeaderHandler + } + if check.IfNil(nodesCoordinator) { + return nil, process.ErrNilNodesCoordinator + } + prevRandSeed := header.GetPrevRandSeed() // TODO: change here with an activation flag if start of epoch block needs to be validated by the new epoch nodes diff --git a/process/headerCheck/common_test.go b/process/headerCheck/common_test.go index 9f349c47d8b..3833a7b2d60 100644 --- a/process/headerCheck/common_test.go +++ b/process/headerCheck/common_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/stretchr/testify/assert" @@ -12,6 +13,30 @@ import ( func TestComputeConsensusGroup(t *testing.T) { t.Parallel() + t.Run("nil header should error", func(t *testing.T) { + nodesCoordinatorInstance := shardingMocks.NewNodesCoordinatorMock() + nodesCoordinatorInstance.ComputeValidatorsGroupCalled = func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + assert.Fail(t, "should have not called ComputeValidatorsGroupCalled") + return nil, nil + } + + vGroup, err := ComputeConsensusGroup(nil, nodesCoordinatorInstance) + assert.Equal(t, process.ErrNilHeaderHandler, err) + assert.Nil(t, vGroup) + }) + t.Run("nil nodes coordinator should error", func(t *testing.T) { + header := &block.Header{ + Epoch: 1123, + Round: 37373, + Nonce: 38383, + ShardID: 2, + PrevRandSeed: []byte("prev rand seed"), + } + + vGroup, err := ComputeConsensusGroup(header, nil) + assert.Equal(t, process.ErrNilNodesCoordinator, err) + assert.Nil(t, vGroup) + }) t.Run("should work for a random block", func(t *testing.T) { header := &block.Header{ Epoch: 1123, diff --git a/process/interface.go b/process/interface.go index 24ae59b9afe..fe890b1c569 100644 --- a/process/interface.go +++ b/process/interface.go @@ -1345,6 +1345,6 @@ type Debugger interface { type SentSignaturesTracker interface { StartRound() SignatureSent(pkBytes []byte) - ResetCountersManagedBlockSigners(signersPKs [][]byte) + ResetCountersForManagedBlockSigner(signerPk []byte) IsInterfaceNil() bool } diff --git a/process/track/sentSignaturesTracker.go b/process/track/sentSignaturesTracker.go index 91f0bed00eb..515f56a61f6 100644 --- a/process/track/sentSignaturesTracker.go +++ b/process/track/sentSignaturesTracker.go @@ -43,20 +43,18 @@ func (tracker *sentSignaturesTracker) SignatureSent(pkBytes []byte) { tracker.mut.Unlock() } -// ResetCountersManagedBlockSigners is called at commit time and will call the reset rounds without received messages -// for each managed key that actually signed a block -func (tracker *sentSignaturesTracker) ResetCountersManagedBlockSigners(signersPKs [][]byte) { +// ResetCountersForManagedBlockSigner is called at commit time and will call the reset rounds without received messages +// for the provided key that actually signed a block +func (tracker *sentSignaturesTracker) ResetCountersForManagedBlockSigner(signerPk []byte) { tracker.mut.RLock() defer tracker.mut.RUnlock() - for _, signerPk := range signersPKs { - _, isSentFromSelf := tracker.sentFromSelf[string(signerPk)] - if isSentFromSelf { - continue - } - - tracker.keysHandler.ResetRoundsWithoutReceivedMessages(signerPk, externalPeerID) + _, isSentFromSelf := tracker.sentFromSelf[string(signerPk)] + if isSentFromSelf { + return } + + tracker.keysHandler.ResetRoundsWithoutReceivedMessages(signerPk, externalPeerID) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/process/track/sentSignaturesTracker_test.go b/process/track/sentSignaturesTracker_test.go index 2c57dc5880a..8a60dba37dd 100644 --- a/process/track/sentSignaturesTracker_test.go +++ b/process/track/sentSignaturesTracker_test.go @@ -37,13 +37,11 @@ func TestSentSignaturesTracker_IsInterfaceNil(t *testing.T) { assert.False(t, tracker.IsInterfaceNil()) } -func TestSentSignaturesTracker_ResetCountersManagedBlockSigners(t *testing.T) { +func TestSentSignaturesTracker_ResetCountersForManagedBlockSigner(t *testing.T) { t.Parallel() pk1 := []byte("pk1") pk2 := []byte("pk2") - pk3 := []byte("pk3") - pk4 := []byte("pk4") t.Run("empty map should call remove", func(t *testing.T) { t.Parallel() @@ -56,13 +54,12 @@ func TestSentSignaturesTracker_ResetCountersManagedBlockSigners(t *testing.T) { }, } - signers := [][]byte{pk1, pk2} tracker, _ := NewSentSignaturesTracker(keysHandler) - tracker.ResetCountersManagedBlockSigners(signers) + tracker.ResetCountersForManagedBlockSigner(pk1) - assert.Equal(t, [][]byte{pk1, pk2}, pkBytesSlice) + assert.Equal(t, [][]byte{pk1}, pkBytesSlice) }) - t.Run("should call remove only for the public keys that did not sent signatures from self", func(t *testing.T) { + t.Run("should call remove only for the public key that did not sent signatures from self", func(t *testing.T) { t.Parallel() pkBytesSlice := make([][]byte, 0) @@ -73,21 +70,21 @@ func TestSentSignaturesTracker_ResetCountersManagedBlockSigners(t *testing.T) { }, } - signers := [][]byte{pk1, pk2, pk3, pk4} tracker, _ := NewSentSignaturesTracker(keysHandler) tracker.SignatureSent(pk1) - tracker.SignatureSent(pk3) - tracker.ResetCountersManagedBlockSigners(signers) - assert.Equal(t, [][]byte{pk2, pk4}, pkBytesSlice) + tracker.ResetCountersForManagedBlockSigner(pk1) + tracker.ResetCountersForManagedBlockSigner(pk2) + assert.Equal(t, [][]byte{pk2}, pkBytesSlice) t.Run("after reset, all should be called", func(t *testing.T) { tracker.StartRound() - tracker.ResetCountersManagedBlockSigners(signers) + tracker.ResetCountersForManagedBlockSigner(pk1) + tracker.ResetCountersForManagedBlockSigner(pk2) assert.Equal(t, [][]byte{ - pk2, pk4, // from the previous test - pk1, pk2, pk3, pk4, // from this call + pk2, // from the previous test + pk1, pk2, // from this call }, pkBytesSlice) }) }) diff --git a/testscommon/sentSignatureTrackerStub.go b/testscommon/sentSignatureTrackerStub.go index 13e399c4aa1..c051d0c60a7 100644 --- a/testscommon/sentSignatureTrackerStub.go +++ b/testscommon/sentSignatureTrackerStub.go @@ -2,9 +2,9 @@ package testscommon // SentSignatureTrackerStub - type SentSignatureTrackerStub struct { - StartRoundCalled func() - SignatureSentCalled func(pkBytes []byte) - ResetCountersManagedBlockSignersCalled func(signersPKs [][]byte) + StartRoundCalled func() + SignatureSentCalled func(pkBytes []byte) + ResetCountersForManagedBlockSignerCalled func(signerPk []byte) } // StartRound - @@ -21,10 +21,10 @@ func (stub *SentSignatureTrackerStub) SignatureSent(pkBytes []byte) { } } -// ResetCountersManagedBlockSigners - -func (stub *SentSignatureTrackerStub) ResetCountersManagedBlockSigners(signersPKs [][]byte) { - if stub.ResetCountersManagedBlockSignersCalled != nil { - stub.ResetCountersManagedBlockSignersCalled(signersPKs) +// ResetCountersForManagedBlockSigner - +func (stub *SentSignatureTrackerStub) ResetCountersForManagedBlockSigner(signerPk []byte) { + if stub.ResetCountersForManagedBlockSignerCalled != nil { + stub.ResetCountersForManagedBlockSignerCalled(signerPk) } } From 6e6d2cb41b2b396ced56e1ae991af1eede65d591 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 17 Jan 2024 11:23:33 +0200 Subject: [PATCH 613/958] - proper releases --- go.mod | 9 ++++----- go.sum | 15 ++++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index e8673975c09..135f5d22821 100644 --- a/go.mod +++ b/go.mod @@ -20,8 +20,8 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 - github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240116165528-e13d057575c2 - github.com/multiversx/mx-chain-vm-go v1.5.24-0.20240116171344-b97ba9e3078e + github.com/multiversx/mx-chain-vm-common-go v1.5.10 + github.com/multiversx/mx-chain-vm-go v1.5.24 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 @@ -47,7 +47,7 @@ require ( github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/denisbrodbeck/machineid v1.0.1 // indirect @@ -150,8 +150,7 @@ require ( github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/smartystreets/assertions v1.13.1 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect diff --git a/go.sum b/go.sum index 78064ef029f..7940ab735e0 100644 --- a/go.sum +++ b/go.sum @@ -72,8 +72,9 @@ github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -398,10 +399,10 @@ github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIM github.com/multiversx/mx-chain-scenario-go v1.2.1/go.mod h1:EuZY7DpNFHVNSxJR8dKE1z2I8gBYfEFFPSwNUOXptqE= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240116165528-e13d057575c2 h1:Gzq8OEYp8JTqj7Mfs9/kUQuS5ANS9W3hQ8r5r6cBmYk= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20240116165528-e13d057575c2/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= -github.com/multiversx/mx-chain-vm-go v1.5.24-0.20240116171344-b97ba9e3078e h1:Nl4JmMDPIMnT4L4C394b6z6jt1R5WhLa1tcednFXE5k= -github.com/multiversx/mx-chain-vm-go v1.5.24-0.20240116171344-b97ba9e3078e/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= +github.com/multiversx/mx-chain-vm-common-go v1.5.10 h1:VoqVt9yX1nQUa0ZujMpdT3J3pKSnQcB6WCQLvIW4sqw= +github.com/multiversx/mx-chain-vm-common-go v1.5.10/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= +github.com/multiversx/mx-chain-vm-go v1.5.24 h1:6RhMvf84Ys8DksDovms+su7w6j9TWz3Rtm/PpgV12Yw= +github.com/multiversx/mx-chain-vm-go v1.5.24/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64/go.mod h1:MUO2E4aEIu3siDkvjraO/WaBh/FxVeQyPWfsrZE+MTU= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 h1:H0Duuoz6lR6KapqLqMspWTojaVtQRiLA5lIm6XV9H04= @@ -486,8 +487,9 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -512,7 +514,6 @@ github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= From f69b0fdf19d3c9038e290aeaf60d8c93fba75581 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Wed, 17 Jan 2024 13:33:00 +0200 Subject: [PATCH 614/958] remove suffix when migrating from NotSpecified to AutoBalanceEnabled using the migrate func --- state/accountsDB_test.go | 71 +++++++++++++++++--- state/export_test.go | 6 ++ state/trackableDataTrie/trackableDataTrie.go | 7 +- 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/state/accountsDB_test.go b/state/accountsDB_test.go index 43c82853c65..5286c9bc603 100644 --- a/state/accountsDB_test.go +++ b/state/accountsDB_test.go @@ -6,6 +6,7 @@ import ( "crypto/rand" "errors" "fmt" + "github.com/multiversx/mx-chain-vm-common-go/dataTrieMigrator" mathRand "math/rand" "strings" "sync" @@ -97,19 +98,20 @@ func generateAddressAccountAccountsDB(trie common.Trie) ([]byte, *stateMock.Acco func getDefaultTrieAndAccountsDb() (common.Trie, *state.AccountsDB) { checkpointHashesHolder := hashesHolder.NewCheckpointHashesHolder(10000000, testscommon.HashSize) - adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) return tr, adb } func getDefaultTrieAndAccountsDbWithCustomDB(db common.BaseStorer) (common.Trie, *state.AccountsDB) { checkpointHashesHolder := hashesHolder.NewCheckpointHashesHolder(10000000, testscommon.HashSize) - adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, db) + adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, db, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) return tr, adb } func getDefaultStateComponents( hashesHolder trie.CheckpointHashesHolder, db common.BaseStorer, + enableEpochsHandler common.EnableEpochsHandler, ) (*state.AccountsDB, common.Trie, common.StorageManager) { generalCfg := config.TrieStorageManagerConfig{ PruningBufferLen: 1000, @@ -123,7 +125,7 @@ func getDefaultStateComponents( args.MainStorer = db args.CheckpointHashesHolder = hashesHolder trieStorage, _ := trie.NewTrieStorageManager(args) - tr, _ := trie.NewTrie(trieStorage, marshaller, hasher, &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, 5) + tr, _ := trie.NewTrie(trieStorage, marshaller, hasher, enableEpochsHandler, 5) ewlArgs := evictionWaitingList.MemoryEvictionWaitingListArgs{ RootHashesSize: 100, HashesSize: 10000, @@ -133,7 +135,7 @@ func getDefaultStateComponents( argsAccCreator := factory.ArgsAccountCreator{ Hasher: hasher, Marshaller: marshaller, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + EnableEpochsHandler: enableEpochsHandler, } accCreator, _ := factory.NewAccountCreator(argsAccCreator) @@ -2056,7 +2058,7 @@ func TestAccountsDB_CommitAddsDirtyHashesToCheckpointHashesHolder(t *testing.T) }, } - adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) accountsAddresses := generateAccounts(t, 3, adb) newHashes, _ = tr.GetDirtyHashes() @@ -2099,7 +2101,7 @@ func TestAccountsDB_CommitSetsStateCheckpointIfCheckpointHashesHolderIsFull(t *t }, } - adb, tr, trieStorage := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, tr, trieStorage := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) accountsAddresses := generateAccounts(t, 3, adb) newHashes = modifyDataTries(t, accountsAddresses, adb) @@ -2129,7 +2131,7 @@ func TestAccountsDB_SnapshotStateCleansCheckpointHashesHolder(t *testing.T) { return false }, } - adb, tr, trieStorage := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, tr, trieStorage := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) _ = trieStorage.Put([]byte(common.ActiveDBKey), []byte(common.ActiveDBVal)) accountsAddresses := generateAccounts(t, 3, adb) @@ -2150,7 +2152,7 @@ func TestAccountsDB_SetStateCheckpointCommitsOnlyMissingData(t *testing.T) { t.Parallel() checkpointHashesHolder := hashesHolder.NewCheckpointHashesHolder(100000, testscommon.HashSize) - adb, tr, trieStorage := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, tr, trieStorage := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) accountsAddresses := generateAccounts(t, 3, adb) rootHash, _ := tr.RootHash() @@ -2227,7 +2229,7 @@ func TestAccountsDB_CheckpointHashesHolderReceivesOnly32BytesData(t *testing.T) return false }, } - adb, _, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, _, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) accountsAddresses := generateAccounts(t, 3, adb) _ = modifyDataTries(t, accountsAddresses, adb) @@ -2248,7 +2250,7 @@ func TestAccountsDB_PruneRemovesDataFromCheckpointHashesHolder(t *testing.T) { removeCalled++ }, } - adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock()) + adb, tr, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), &enableEpochsHandlerMock.EnableEpochsHandlerStub{}) accountsAddresses := generateAccounts(t, 3, adb) newHashes, _ = tr.GetDirtyHashes() @@ -3221,6 +3223,55 @@ func testAccountMethodsConcurrency( wg.Wait() } +func TestAccountsDB_MigrateDataTrieWithFunc(t *testing.T) { + t.Parallel() + + checkpointHashesHolder := hashesHolder.NewCheckpointHashesHolder(10000000, testscommon.HashSize) + enabeEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsAutoBalanceDataTriesEnabledField: false, + } + adb, _, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), enabeEpochsHandler) + + addr := []byte("addr") + acc, _ := adb.LoadAccount(addr) + value := []byte("value") + _ = acc.(state.UserAccountHandler).SaveKeyValue([]byte("key"), value) + _ = acc.(state.UserAccountHandler).SaveKeyValue([]byte("key2"), value) + _ = adb.SaveAccount(acc) + + enabeEpochsHandler.IsAutoBalanceDataTriesEnabledField = true + acc, _ = adb.LoadAccount(addr) + + isMigrated, err := acc.(state.AccountHandlerWithDataTrieMigrationStatus).IsDataTrieMigrated() + assert.Nil(t, err) + assert.False(t, isMigrated) + + accWithMigrate := acc.(vmcommon.UserAccountHandler).AccountDataHandler() + dataTrieMig := dataTrieMigrator.NewDataTrieMigrator(dataTrieMigrator.ArgsNewDataTrieMigrator{ + GasProvided: 100000000, + DataTrieGasCost: dataTrieMigrator.DataTrieGasCost{ + TrieLoadPerNode: 1, + TrieStorePerNode: 1, + }, + }) + err = accWithMigrate.MigrateDataTrieLeaves(vmcommon.ArgsMigrateDataTrieLeaves{ + OldVersion: core.NotSpecified, + NewVersion: core.AutoBalanceEnabled, + TrieMigrator: dataTrieMig, + }) + assert.Nil(t, err) + _ = adb.SaveAccount(acc) + + acc, _ = adb.LoadAccount(addr) + retrievedVal, _, err := acc.(state.UserAccountHandler).RetrieveValue([]byte("key")) + assert.Equal(t, value, retrievedVal) + assert.Nil(t, err) + + isMigrated, err = acc.(state.AccountHandlerWithDataTrieMigrationStatus).IsDataTrieMigrated() + assert.Nil(t, err) + assert.True(t, isMigrated) +} + func BenchmarkAccountsDB_GetMethodsInParallel(b *testing.B) { _, adb := getDefaultTrieAndAccountsDb() diff --git a/state/export_test.go b/state/export_test.go index 43810db3749..b9fc6b2f4cd 100644 --- a/state/export_test.go +++ b/state/export_test.go @@ -111,3 +111,9 @@ func (sm *snapshotsManager) WaitForStorageEpochChange(args storageEpochChangeWai func NewNilSnapshotsManager() *snapshotsManager { return nil } + +// AccountHandlerWithDataTrieMigrationStatus - +type AccountHandlerWithDataTrieMigrationStatus interface { + vmcommon.AccountHandler + IsDataTrieMigrated() (bool, error) +} diff --git a/state/trackableDataTrie/trackableDataTrie.go b/state/trackableDataTrie/trackableDataTrie.go index 4f7607a1980..8a2fe8812ef 100644 --- a/state/trackableDataTrie/trackableDataTrie.go +++ b/state/trackableDataTrie/trackableDataTrie.go @@ -127,8 +127,13 @@ func (tdt *trackableDataTrie) MigrateDataTrieLeaves(args vmcommon.ArgsMigrateDat dataToBeMigrated := args.TrieMigrator.GetLeavesToBeMigrated() log.Debug("num leaves to be migrated", "num", len(dataToBeMigrated), "account", tdt.identifier) for _, leafData := range dataToBeMigrated { + val, err := tdt.getValueWithoutMetadata(leafData.Key, leafData) + if err != nil { + return err + } + dataEntry := dirtyData{ - value: leafData.Value, + value: val, newVersion: args.NewVersion, } From ef869b78672960415876d07ed8123685c3d1d709 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Wed, 17 Jan 2024 13:34:22 +0200 Subject: [PATCH 615/958] fix imports --- state/accountsDB_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state/accountsDB_test.go b/state/accountsDB_test.go index 5286c9bc603..95785e9c231 100644 --- a/state/accountsDB_test.go +++ b/state/accountsDB_test.go @@ -6,7 +6,6 @@ import ( "crypto/rand" "errors" "fmt" - "github.com/multiversx/mx-chain-vm-common-go/dataTrieMigrator" mathRand "math/rand" "strings" "sync" @@ -42,6 +41,7 @@ import ( "github.com/multiversx/mx-chain-go/trie" "github.com/multiversx/mx-chain-go/trie/hashesHolder" vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/multiversx/mx-chain-vm-common-go/dataTrieMigrator" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) From d91ac828ec6c05c25fe032beb1472ae06e746792 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 18 Jan 2024 13:15:43 +0200 Subject: [PATCH 616/958] fix tests --- go.mod | 2 +- go.sum | 4 ++-- integrationTests/vm/txsFee/migrateDataTrie_test.go | 10 +++++++++- state/trackableDataTrie/trackableDataTrie_test.go | 12 +++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 135f5d22821..fb8e2d66678 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 - github.com/multiversx/mx-chain-vm-common-go v1.5.10 + github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240118090210-c70b5a1381ed github.com/multiversx/mx-chain-vm-go v1.5.24 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 diff --git a/go.sum b/go.sum index 7940ab735e0..443a1a2d902 100644 --- a/go.sum +++ b/go.sum @@ -399,8 +399,8 @@ github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIM github.com/multiversx/mx-chain-scenario-go v1.2.1/go.mod h1:EuZY7DpNFHVNSxJR8dKE1z2I8gBYfEFFPSwNUOXptqE= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= -github.com/multiversx/mx-chain-vm-common-go v1.5.10 h1:VoqVt9yX1nQUa0ZujMpdT3J3pKSnQcB6WCQLvIW4sqw= -github.com/multiversx/mx-chain-vm-common-go v1.5.10/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= +github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240118090210-c70b5a1381ed h1:a6oJcgeUlOeGZEokII1b1Eb3Av9uMztKmpEkw090+/E= +github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240118090210-c70b5a1381ed/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= github.com/multiversx/mx-chain-vm-go v1.5.24 h1:6RhMvf84Ys8DksDovms+su7w6j9TWz3Rtm/PpgV12Yw= github.com/multiversx/mx-chain-vm-go v1.5.24/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= diff --git a/integrationTests/vm/txsFee/migrateDataTrie_test.go b/integrationTests/vm/txsFee/migrateDataTrie_test.go index a4bc4ad1e0f..9c62a4f30fd 100644 --- a/integrationTests/vm/txsFee/migrateDataTrie_test.go +++ b/integrationTests/vm/txsFee/migrateDataTrie_test.go @@ -215,7 +215,8 @@ func generateDataTrie( for i := 1; i < numLeaves; i++ { key := keyGenerator(i) - err := tr.UpdateWithVersion(key, key, core.NotSpecified) + value := getValWithAppendedData(key, key, accAddr) + err := tr.UpdateWithVersion(key, value, core.NotSpecified) require.Nil(t, err) keys[i] = key @@ -226,6 +227,13 @@ func generateDataTrie( return rootHash, keys } +func getValWithAppendedData(key, val, address []byte) []byte { + suffix := append(key, address...) + val = append(val, suffix...) + + return val +} + func initDataTrie( t *testing.T, testContext *vm.VMTestContext, diff --git a/state/trackableDataTrie/trackableDataTrie_test.go b/state/trackableDataTrie/trackableDataTrie_test.go index 23fc69d7404..42f6ebc4189 100644 --- a/state/trackableDataTrie/trackableDataTrie_test.go +++ b/state/trackableDataTrie/trackableDataTrie_test.go @@ -827,20 +827,22 @@ func TestTrackableDataTrie_MigrateDataTrieLeaves(t *testing.T) { t.Run("leaves that need to be migrated are added to dirty data", func(t *testing.T) { t.Parallel() + expectedValues := [][]byte{[]byte("value1"), []byte("value2"), []byte("value3")} + address := []byte("identifier") leavesToBeMigrated := []core.TrieData{ { Key: []byte("key1"), - Value: []byte("value1"), + Value: append([]byte("value1key1"), address...), Version: core.NotSpecified, }, { Key: []byte("key2"), - Value: []byte("value2"), + Value: append([]byte("value2key2"), address...), Version: core.NotSpecified, }, { Key: []byte("key3"), - Value: []byte("value3"), + Value: append([]byte("value3key3"), address...), Version: core.NotSpecified, }, } @@ -858,7 +860,7 @@ func TestTrackableDataTrie_MigrateDataTrieLeaves(t *testing.T) { IsAutoBalanceDataTriesEnabledField: true, } - tdt, _ := trackableDataTrie.NewTrackableDataTrie([]byte("identifier"), &hashingMocks.HasherMock{}, &marshallerMock.MarshalizerMock{}, enableEpchs) + tdt, _ := trackableDataTrie.NewTrackableDataTrie(address, &hashingMocks.HasherMock{}, &marshallerMock.MarshalizerMock{}, enableEpchs) tdt.SetDataTrie(tr) args := vmcommon.ArgsMigrateDataTrieLeaves{ OldVersion: core.NotSpecified, @@ -872,7 +874,7 @@ func TestTrackableDataTrie_MigrateDataTrieLeaves(t *testing.T) { assert.Equal(t, len(leavesToBeMigrated), len(dirtyData)) for i := range leavesToBeMigrated { d := dirtyData[string(leavesToBeMigrated[i].Key)] - assert.Equal(t, leavesToBeMigrated[i].Value, d.Value) + assert.Equal(t, expectedValues[i], d.Value) assert.Equal(t, core.TrieNodeVersion(100), d.NewVersion) } }) From a54bf8a1aaeb136725c4ba5293522b1b63f0b581 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 18 Jan 2024 14:33:50 +0200 Subject: [PATCH 617/958] initial round --- node/chainSimulator/chainSimulator.go | 5 ++++- node/chainSimulator/chainSimulator_test.go | 5 +++-- node/chainSimulator/components/coreComponents.go | 3 ++- node/chainSimulator/components/manualRoundHandler.go | 3 ++- node/chainSimulator/components/testOnlyProcessingNode.go | 2 ++ node/chainSimulator/process/processor.go | 1 + 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 59511a2c7e4..ed84fad97b8 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -28,6 +28,7 @@ type ArgsChainSimulator struct { MinNodesPerShard uint32 MetaChainMinNodes uint32 GenesisTimestamp int64 + InitialRound int64 RoundDurationInMillis uint64 RoundsPerEpoch core.OptionalUint64 ApiInterface components.APIConfigurator @@ -88,7 +89,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { shardIDStr = "metachain" } - node, errCreate := s.createTestNode(outputConfigs.Configs, shardIDStr, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck) + node, errCreate := s.createTestNode(outputConfigs.Configs, shardIDStr, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck, args.InitialRound) if errCreate != nil { return errCreate } @@ -122,6 +123,7 @@ func (s *simulator) createTestNode( gasScheduleFilename string, apiInterface components.APIConfigurator, bypassTxSignatureCheck bool, + initialRound int64, ) (process.NodeHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Configs: *configs, @@ -132,6 +134,7 @@ func (s *simulator) createTestNode( ShardIDStr: shardIDStr, APIInterface: apiInterface, BypassTxSignatureCheck: bypassTxSignatureCheck, + InitialRound: initialRound, } return components.NewTestOnlyProcessingNode(args) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 73503230edd..cd625e92b37 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -45,7 +45,7 @@ func TestNewChainSimulator(t *testing.T) { } func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { - startTime := time.Now().Unix() + startTime := time.Now().Unix() + 6*200000000 roundDurationInMillis := uint64(6000) chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ BypassTxSignatureCheck: false, @@ -58,13 +58,14 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { ApiInterface: api.NewNoApiInterface(), MinNodesPerShard: 1, MetaChainMinNodes: 1, + InitialRound: 200000000, }) require.Nil(t, err) require.NotNil(t, chainSimulator) time.Sleep(time.Second) - err = chainSimulator.GenerateBlocks(10) + err = chainSimulator.GenerateBlocks(30) require.Nil(t, err) err = chainSimulator.Close() diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 7a3798dc980..0d311e3d103 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -83,6 +83,7 @@ type ArgsCoreComponentsHolder struct { RoundsConfig config.RoundConfig EconomicsConfig config.EconomicsConfig ChanStopNodeProcess chan endProcess.ArgEndProcess + InitialRound int64 NodesSetupPath string GasScheduleFilename string NumShards uint32 @@ -146,7 +147,7 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents } roundDuration := time.Millisecond * time.Duration(instance.genesisNodesSetup.GetRoundDuration()) - instance.roundHandler = NewManualRoundHandler(instance.genesisNodesSetup.GetStartTime(), roundDuration) + instance.roundHandler = NewManualRoundHandler(instance.genesisNodesSetup.GetStartTime(), roundDuration, args.InitialRound) instance.wasmVMChangeLocker = &sync.RWMutex{} instance.txVersionChecker = versioning.NewTxVersionChecker(args.Config.GeneralSettings.MinTransactionVersion) diff --git a/node/chainSimulator/components/manualRoundHandler.go b/node/chainSimulator/components/manualRoundHandler.go index b0503be92fb..3639bf23752 100644 --- a/node/chainSimulator/components/manualRoundHandler.go +++ b/node/chainSimulator/components/manualRoundHandler.go @@ -12,10 +12,11 @@ type manualRoundHandler struct { } // NewManualRoundHandler returns a manual round handler instance -func NewManualRoundHandler(genesisTimeStamp int64, roundDuration time.Duration) *manualRoundHandler { +func NewManualRoundHandler(genesisTimeStamp int64, roundDuration time.Duration, initialRound int64) *manualRoundHandler { return &manualRoundHandler{ genesisTimeStamp: genesisTimeStamp, roundDuration: roundDuration, + index: initialRound, } } diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 36ece2c880e..c33d1999c47 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -38,6 +38,7 @@ type ArgsTestOnlyProcessingNode struct { ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler + InitialRound int64 GasScheduleFilename string NumShards uint32 ShardIDStr string @@ -93,6 +94,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces WorkingDir: args.Configs.FlagsConfig.WorkingDir, GasScheduleFilename: args.GasScheduleFilename, NodesSetupPath: args.Configs.ConfigurationPathsHolder.Nodes, + InitialRound: args.InitialRound, }) if err != nil { return nil, err diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 8ee45be2c52..e47ccb92b50 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -143,6 +143,7 @@ func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prev prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() + round = uint64(creator.nodeHandler.GetCoreComponents().RoundHandler().Index()) - 1 return } From f920a0139f9342539997a47152540e3bcfe98c15 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 18 Jan 2024 17:15:10 +0200 Subject: [PATCH 618/958] refactoring --- node/chainSimulator/chainSimulator.go | 6 +++++- node/chainSimulator/chainSimulator_test.go | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index ed84fad97b8..a9fda865a59 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -69,7 +69,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: args.NumOfShards, OriginalConfigsPath: args.PathToInitialConfig, - GenesisTimeStamp: args.GenesisTimestamp, + GenesisTimeStamp: computeStartTimeBaseOnInitialRound(args), RoundDurationInMillis: args.RoundDurationInMillis, TempDir: args.TempDir, MinNodesPerShard: args.MinNodesPerShard, @@ -117,6 +117,10 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { return nil } +func computeStartTimeBaseOnInitialRound(args ArgsChainSimulator) int64 { + return args.GenesisTimestamp + int64(args.RoundDurationInMillis/1000)*args.InitialRound +} + func (s *simulator) createTestNode( configs *config.Configs, shardIDStr string, diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index cd625e92b37..770c55976a2 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -45,7 +45,7 @@ func TestNewChainSimulator(t *testing.T) { } func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { - startTime := time.Now().Unix() + 6*200000000 + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ BypassTxSignatureCheck: false, From 54775cd6d22581b93de06ba5dc87ee23369e6246 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 18 Jan 2024 18:06:16 +0200 Subject: [PATCH 619/958] move hostParameters to common --- {cmd/assessment => common}/hostParameters/hostInfo.go | 0 {cmd/assessment => common}/hostParameters/hostInfo_test.go | 0 {cmd/assessment => common}/hostParameters/hostParametersGetter.go | 0 .../hostParameters/hostParametersGetter_test.go | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {cmd/assessment => common}/hostParameters/hostInfo.go (100%) rename {cmd/assessment => common}/hostParameters/hostInfo_test.go (100%) rename {cmd/assessment => common}/hostParameters/hostParametersGetter.go (100%) rename {cmd/assessment => common}/hostParameters/hostParametersGetter_test.go (100%) diff --git a/cmd/assessment/hostParameters/hostInfo.go b/common/hostParameters/hostInfo.go similarity index 100% rename from cmd/assessment/hostParameters/hostInfo.go rename to common/hostParameters/hostInfo.go diff --git a/cmd/assessment/hostParameters/hostInfo_test.go b/common/hostParameters/hostInfo_test.go similarity index 100% rename from cmd/assessment/hostParameters/hostInfo_test.go rename to common/hostParameters/hostInfo_test.go diff --git a/cmd/assessment/hostParameters/hostParametersGetter.go b/common/hostParameters/hostParametersGetter.go similarity index 100% rename from cmd/assessment/hostParameters/hostParametersGetter.go rename to common/hostParameters/hostParametersGetter.go diff --git a/cmd/assessment/hostParameters/hostParametersGetter_test.go b/common/hostParameters/hostParametersGetter_test.go similarity index 100% rename from cmd/assessment/hostParameters/hostParametersGetter_test.go rename to common/hostParameters/hostParametersGetter_test.go From 45ba97d9b9b6251547135dde0c0ba2cdd8a87650 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 18 Jan 2024 18:06:43 +0200 Subject: [PATCH 620/958] update assessment --- cmd/assessment/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/assessment/main.go b/cmd/assessment/main.go index 8e61205de2b..47642c03faa 100644 --- a/cmd/assessment/main.go +++ b/cmd/assessment/main.go @@ -12,7 +12,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/cmd/assessment/benchmarks" "github.com/multiversx/mx-chain-go/cmd/assessment/benchmarks/factory" - "github.com/multiversx/mx-chain-go/cmd/assessment/hostParameters" + "github.com/multiversx/mx-chain-go/common/hostParameters" logger "github.com/multiversx/mx-chain-logger-go" "github.com/urfave/cli" ) From 639da41b11ff2de8344a823aeb8987321305fab5 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 18 Jan 2024 18:12:57 +0200 Subject: [PATCH 621/958] cpu flags checks --- cmd/node/config/config.toml | 11 +++++++---- cmd/node/main.go | 28 ++++++++++++++++++++++++++++ config/config.go | 24 +++++++++++++++--------- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index f6b965ec081..72539a298f7 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -35,10 +35,13 @@ # SyncProcessTimeInMillis is the value in milliseconds used when processing blocks while synchronizing blocks SyncProcessTimeInMillis = 12000 - # SetGuardianEpochsDelay represents the delay in epochs between the execution time of the SetGuardian transaction and - # the activation of the configured guardian. - # Make sure that this is greater than the unbonding period! - SetGuardianEpochsDelay = 2 # TODO: for mainnet should be 20, 2 is just for testing + # SetGuardianEpochsDelay represents the delay in epochs between the execution time of the SetGuardian transaction and + # the activation of the configured guardian. + # Make sure that this is greater than the unbonding period! + SetGuardianEpochsDelay = 2 # TODO: for mainnet should be 20, 2 is just for testing + +[HardwareRequirements] + CPUFlags = ["sse4_1", "sse4_2"] [Versions] DefaultVersion = "default" diff --git a/cmd/node/main.go b/cmd/node/main.go index 65fe1165a43..9df3873b1af 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-go/cmd/node/factory" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/hostParameters" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/config/overridableConfig" "github.com/multiversx/mx-chain-go/node" @@ -129,6 +130,11 @@ func startNodeRunner(c *cli.Context, log logger.Logger, baseVersion string, vers cfgs.FlagsConfig.BaseVersion = baseVersion cfgs.FlagsConfig.Version = version + err = checkHardwareRequirements(cfgs.GeneralConfig.HardwareRequirements) + if err != nil { + return fmt.Errorf("Hardware Requirements checks failed: %s", err.Error()) + } + nodeRunner, errRunner := node.NewNodeRunner(cfgs) if errRunner != nil { return errRunner @@ -301,3 +307,25 @@ func attachFileLogger(log logger.Logger, flagsConfig *config.ContextFlagsConfig) return fileLogging, nil } + +func checkHardwareRequirements(cfg config.HardwareRequirementsConfig) error { + hpg := hostParameters.NewHostParameterGetter("") + hostInfo := hpg.GetHostInfo() + + for _, cpuFlag := range cfg.CPUFlags { + if !contains(hostInfo.CPUFlags, cpuFlag) { + return fmt.Errorf("CPU Flag %s not available", cpuFlag) + } + } + + return nil +} + +func contains(list []string, s string) bool { + for _, item := range list { + if item == s { + return true + } + } + return false +} diff --git a/config/config.go b/config/config.go index db0e84bb1cd..b53e46a2201 100644 --- a/config/config.go +++ b/config/config.go @@ -190,15 +190,16 @@ type Config struct { PublicKeyPIDSignature CacheConfig PeerHonesty CacheConfig - Antiflood AntifloodConfig - WebServerAntiflood WebServerAntifloodConfig - ResourceStats ResourceStatsConfig - HeartbeatV2 HeartbeatV2Config - ValidatorStatistics ValidatorStatisticsConfig - GeneralSettings GeneralSettingsConfig - Consensus ConsensusConfig - StoragePruning StoragePruningConfig - LogsAndEvents LogsAndEventsConfig + Antiflood AntifloodConfig + WebServerAntiflood WebServerAntifloodConfig + ResourceStats ResourceStatsConfig + HeartbeatV2 HeartbeatV2Config + ValidatorStatistics ValidatorStatisticsConfig + GeneralSettings GeneralSettingsConfig + Consensus ConsensusConfig + StoragePruning StoragePruningConfig + LogsAndEvents LogsAndEventsConfig + HardwareRequirements HardwareRequirementsConfig NTPConfig NTPConfig HeadersPoolConfig HeadersPoolConfig @@ -285,6 +286,11 @@ type GeneralSettingsConfig struct { SetGuardianEpochsDelay uint32 } +// HardwareRequirementsConfig will hold the hardware requirements config +type HardwareRequirementsConfig struct { + CPUFlags []string +} + // FacadeConfig will hold different configuration option that will be passed to the node facade type FacadeConfig struct { RestApiInterface string From 2bc1c58b8db545e0fb607a8e2eb28ca547cfbe63 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 18 Jan 2024 23:31:53 +0200 Subject: [PATCH 622/958] - fix after review --- consensus/spos/bls/blsSubroundsFactory.go | 3 +-- consensus/spos/bls/blsSubroundsFactory_test.go | 3 +-- consensus/spos/bls/errors.go | 6 ++++++ consensus/spos/bls/subroundEndRound.go | 3 +-- consensus/spos/bls/subroundEndRound_test.go | 3 +-- consensus/spos/bls/subroundSignature.go | 3 +-- consensus/spos/bls/subroundSignature_test.go | 3 +-- consensus/spos/bls/subroundStartRound.go | 3 +-- consensus/spos/bls/subroundStartRound_test.go | 3 +-- 9 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 consensus/spos/bls/errors.go diff --git a/consensus/spos/bls/blsSubroundsFactory.go b/consensus/spos/bls/blsSubroundsFactory.go index f68e35e570f..aeb64a5775a 100644 --- a/consensus/spos/bls/blsSubroundsFactory.go +++ b/consensus/spos/bls/blsSubroundsFactory.go @@ -6,7 +6,6 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-go/consensus/spos" - "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/outport" ) @@ -81,7 +80,7 @@ func checkNewFactoryParams( return spos.ErrNilAppStatusHandler } if check.IfNil(sentSignaturesTracker) { - return errors.ErrNilSentSignatureTracker + return ErrNilSentSignatureTracker } if len(chainID) == 0 { return spos.ErrInvalidChainID diff --git a/consensus/spos/bls/blsSubroundsFactory_test.go b/consensus/spos/bls/blsSubroundsFactory_test.go index 936b765e951..af3267a78cc 100644 --- a/consensus/spos/bls/blsSubroundsFactory_test.go +++ b/consensus/spos/bls/blsSubroundsFactory_test.go @@ -12,7 +12,6 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" - "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/outport" "github.com/multiversx/mx-chain-go/testscommon" testscommonOutport "github.com/multiversx/mx-chain-go/testscommon/outport" @@ -455,7 +454,7 @@ func TestFactory_NewFactoryNilSignaturesTrackerShouldFail(t *testing.T) { ) assert.Nil(t, fct) - assert.Equal(t, errors.ErrNilSentSignatureTracker, err) + assert.Equal(t, bls.ErrNilSentSignatureTracker, err) } func TestFactory_NewFactoryShouldWork(t *testing.T) { diff --git a/consensus/spos/bls/errors.go b/consensus/spos/bls/errors.go new file mode 100644 index 00000000000..b840f9e2c85 --- /dev/null +++ b/consensus/spos/bls/errors.go @@ -0,0 +1,6 @@ +package bls + +import "errors" + +// ErrNilSentSignatureTracker defines the error for setting a nil SentSignatureTracker +var ErrNilSentSignatureTracker = errors.New("nil sent signature tracker") diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index a9a7405d180..3171f806077 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -14,7 +14,6 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos" - "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/p2p" ) @@ -49,7 +48,7 @@ func NewSubroundEndRound( return nil, spos.ErrNilAppStatusHandler } if check.IfNil(sentSignatureTracker) { - return nil, errors.ErrNilSentSignatureTracker + return nil, ErrNilSentSignatureTracker } srEndRound := subroundEndRound{ diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 8a932e5e074..725513b8cb2 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -17,7 +17,6 @@ import ( "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" - mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/p2p" "github.com/multiversx/mx-chain-go/p2p/factory" "github.com/multiversx/mx-chain-go/testscommon" @@ -147,7 +146,7 @@ func TestNewSubroundEndRound(t *testing.T) { ) assert.Nil(t, srEndRound) - assert.Equal(t, mxErrors.ErrNilSentSignatureTracker, err) + assert.Equal(t, bls.ErrNilSentSignatureTracker, err) }) } diff --git a/consensus/spos/bls/subroundSignature.go b/consensus/spos/bls/subroundSignature.go index 07d5ddd3fe9..ac06cc72fdd 100644 --- a/consensus/spos/bls/subroundSignature.go +++ b/consensus/spos/bls/subroundSignature.go @@ -11,7 +11,6 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos" - "github.com/multiversx/mx-chain-go/errors" ) type subroundSignature struct { @@ -40,7 +39,7 @@ func NewSubroundSignature( return nil, spos.ErrNilAppStatusHandler } if check.IfNil(sentSignatureTracker) { - return nil, errors.ErrNilSentSignatureTracker + return nil, ErrNilSentSignatureTracker } srSignature := subroundSignature{ diff --git a/consensus/spos/bls/subroundSignature_test.go b/consensus/spos/bls/subroundSignature_test.go index 2002e9d6a66..9ee8a03ba19 100644 --- a/consensus/spos/bls/subroundSignature_test.go +++ b/consensus/spos/bls/subroundSignature_test.go @@ -10,7 +10,6 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" - mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/testscommon" consensusMocks "github.com/multiversx/mx-chain-go/testscommon/consensus" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" @@ -126,7 +125,7 @@ func TestNewSubroundSignature(t *testing.T) { ) assert.Nil(t, srSignature) - assert.Equal(t, mxErrors.ErrNilSentSignatureTracker, err) + assert.Equal(t, bls.ErrNilSentSignatureTracker, err) }) } diff --git a/consensus/spos/bls/subroundStartRound.go b/consensus/spos/bls/subroundStartRound.go index 735e2eb770d..72176342e49 100644 --- a/consensus/spos/bls/subroundStartRound.go +++ b/consensus/spos/bls/subroundStartRound.go @@ -13,7 +13,6 @@ import ( outportcore "github.com/multiversx/mx-chain-core-go/data/outport" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus/spos" - "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/outport" "github.com/multiversx/mx-chain-go/outport/disabled" ) @@ -55,7 +54,7 @@ func NewSubroundStartRound( return nil, fmt.Errorf("%w for resetConsensusMessages function", spos.ErrNilFunctionHandler) } if check.IfNil(sentSignatureTracker) { - return nil, errors.ErrNilSentSignatureTracker + return nil, ErrNilSentSignatureTracker } srStartRound := subroundStartRound{ diff --git a/consensus/spos/bls/subroundStartRound_test.go b/consensus/spos/bls/subroundStartRound_test.go index 62307d99b2d..cc70bf68737 100644 --- a/consensus/spos/bls/subroundStartRound_test.go +++ b/consensus/spos/bls/subroundStartRound_test.go @@ -9,7 +9,6 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/consensus/spos/bls" - mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" @@ -185,7 +184,7 @@ func TestNewSubroundStartRound(t *testing.T) { ) assert.Nil(t, srStartRound) - assert.Equal(t, mxErrors.ErrNilSentSignatureTracker, err) + assert.Equal(t, bls.ErrNilSentSignatureTracker, err) }) } From 0db2dc0f6f074b47bd5b9704ad2d36b3a4a82b92 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 19 Jan 2024 12:08:55 +0200 Subject: [PATCH 623/958] use cpuid implementation for cpu flags check --- cmd/node/config/config.toml | 3 --- cmd/node/main.go | 24 +++++------------------- config/config.go | 24 +++++++++--------------- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 72539a298f7..be5d2d7bbf6 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -40,9 +40,6 @@ # Make sure that this is greater than the unbonding period! SetGuardianEpochsDelay = 2 # TODO: for mainnet should be 20, 2 is just for testing -[HardwareRequirements] - CPUFlags = ["sse4_1", "sse4_2"] - [Versions] DefaultVersion = "default" VersionsByEpochs = [ diff --git a/cmd/node/main.go b/cmd/node/main.go index 9df3873b1af..1f24976b6e8 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -6,11 +6,11 @@ import ( "runtime" "time" + "github.com/klauspost/cpuid/v2" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-go/cmd/node/factory" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/common/hostParameters" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/config/overridableConfig" "github.com/multiversx/mx-chain-go/node" @@ -130,7 +130,7 @@ func startNodeRunner(c *cli.Context, log logger.Logger, baseVersion string, vers cfgs.FlagsConfig.BaseVersion = baseVersion cfgs.FlagsConfig.Version = version - err = checkHardwareRequirements(cfgs.GeneralConfig.HardwareRequirements) + err = checkHardwareRequirements() if err != nil { return fmt.Errorf("Hardware Requirements checks failed: %s", err.Error()) } @@ -308,24 +308,10 @@ func attachFileLogger(log logger.Logger, flagsConfig *config.ContextFlagsConfig) return fileLogging, nil } -func checkHardwareRequirements(cfg config.HardwareRequirementsConfig) error { - hpg := hostParameters.NewHostParameterGetter("") - hostInfo := hpg.GetHostInfo() - - for _, cpuFlag := range cfg.CPUFlags { - if !contains(hostInfo.CPUFlags, cpuFlag) { - return fmt.Errorf("CPU Flag %s not available", cpuFlag) - } +func checkHardwareRequirements() error { + if !cpuid.CPU.Supports(cpuid.SSE4, cpuid.SSE42) { + return fmt.Errorf("CPU Flags: Streaming SIMD Extensions 4 requied") } return nil } - -func contains(list []string, s string) bool { - for _, item := range list { - if item == s { - return true - } - } - return false -} diff --git a/config/config.go b/config/config.go index b53e46a2201..db0e84bb1cd 100644 --- a/config/config.go +++ b/config/config.go @@ -190,16 +190,15 @@ type Config struct { PublicKeyPIDSignature CacheConfig PeerHonesty CacheConfig - Antiflood AntifloodConfig - WebServerAntiflood WebServerAntifloodConfig - ResourceStats ResourceStatsConfig - HeartbeatV2 HeartbeatV2Config - ValidatorStatistics ValidatorStatisticsConfig - GeneralSettings GeneralSettingsConfig - Consensus ConsensusConfig - StoragePruning StoragePruningConfig - LogsAndEvents LogsAndEventsConfig - HardwareRequirements HardwareRequirementsConfig + Antiflood AntifloodConfig + WebServerAntiflood WebServerAntifloodConfig + ResourceStats ResourceStatsConfig + HeartbeatV2 HeartbeatV2Config + ValidatorStatistics ValidatorStatisticsConfig + GeneralSettings GeneralSettingsConfig + Consensus ConsensusConfig + StoragePruning StoragePruningConfig + LogsAndEvents LogsAndEventsConfig NTPConfig NTPConfig HeadersPoolConfig HeadersPoolConfig @@ -286,11 +285,6 @@ type GeneralSettingsConfig struct { SetGuardianEpochsDelay uint32 } -// HardwareRequirementsConfig will hold the hardware requirements config -type HardwareRequirementsConfig struct { - CPUFlags []string -} - // FacadeConfig will hold different configuration option that will be passed to the node facade type FacadeConfig struct { RestApiInterface string From da2544a4b76ceaa8ed60d00e856d910d01afac96 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 19 Jan 2024 12:09:56 +0200 Subject: [PATCH 624/958] fix typo --- cmd/node/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/main.go b/cmd/node/main.go index 1f24976b6e8..c0470f4826b 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -310,7 +310,7 @@ func attachFileLogger(log logger.Logger, flagsConfig *config.ContextFlagsConfig) func checkHardwareRequirements() error { if !cpuid.CPU.Supports(cpuid.SSE4, cpuid.SSE42) { - return fmt.Errorf("CPU Flags: Streaming SIMD Extensions 4 requied") + return fmt.Errorf("CPU Flags: Streaming SIMD Extensions 4 required") } return nil From c580833da62e7d45c14e799e0552c7f304407b7b Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Fri, 19 Jan 2024 14:56:48 +0200 Subject: [PATCH 625/958] add integration tests --- go.mod | 2 +- go.sum | 4 +- .../startInEpoch/startInEpoch_test.go | 2 +- .../multiShard/hardFork/hardFork_test.go | 4 +- .../node/getAccount/getAccount_test.go | 4 +- .../state/stateTrie/stateTrie_test.go | 218 ++++++++++++++++++ integrationTests/testConsensusNode.go | 2 +- integrationTests/testInitializer.go | 6 +- integrationTests/testProcessorNode.go | 11 +- integrationTests/testSyncNode.go | 2 +- 10 files changed, 236 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index fb8e2d66678..7bd32583cac 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.2.1 github.com/multiversx/mx-chain-storage-go v1.0.14 - github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240118090210-c70b5a1381ed + github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240119120033-6a9321334ec5 github.com/multiversx/mx-chain-vm-go v1.5.24 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 diff --git a/go.sum b/go.sum index 443a1a2d902..aade389db54 100644 --- a/go.sum +++ b/go.sum @@ -399,8 +399,8 @@ github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIM github.com/multiversx/mx-chain-scenario-go v1.2.1/go.mod h1:EuZY7DpNFHVNSxJR8dKE1z2I8gBYfEFFPSwNUOXptqE= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= -github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240118090210-c70b5a1381ed h1:a6oJcgeUlOeGZEokII1b1Eb3Av9uMztKmpEkw090+/E= -github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240118090210-c70b5a1381ed/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= +github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240119120033-6a9321334ec5 h1:ZaxuCVOLL2gtBeUimMUQrIpsBVfoaAW39iW9Px1CeWQ= +github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240119120033-6a9321334ec5/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= github.com/multiversx/mx-chain-vm-go v1.5.24 h1:6RhMvf84Ys8DksDovms+su7w6j9TWz3Rtm/PpgV12Yw= github.com/multiversx/mx-chain-vm-go v1.5.24/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= diff --git a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go index b9492592bd3..86d2070814b 100644 --- a/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go +++ b/integrationTests/multiShard/endOfEpoch/startInEpoch/startInEpoch_test.go @@ -216,7 +216,7 @@ func testNodeStartsInEpoch(t *testing.T, shardID uint32, expectedHighestRound ui cryptoComponents.BlKeyGen = &mock.KeyGenMock{} cryptoComponents.TxKeyGen = &mock.KeyGenMock{} - coreComponents := integrationTests.GetDefaultCoreComponents() + coreComponents := integrationTests.GetDefaultCoreComponents(integrationTests.CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = integrationTests.TestMarshalizer coreComponents.TxMarshalizerField = integrationTests.TestMarshalizer coreComponents.HasherField = integrationTests.TestHasher diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index 0f4f6140854..4172deb9462 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -386,7 +386,7 @@ func hardForkImport( defaults.FillGasMapInternal(gasSchedule, 1) log.Warn("started import process") - coreComponents := integrationTests.GetDefaultCoreComponents() + coreComponents := integrationTests.GetDefaultCoreComponents(integrationTests.CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = integrationTests.TestMarshalizer coreComponents.TxMarshalizerField = integrationTests.TestMarshalizer coreComponents.HasherField = integrationTests.TestHasher @@ -558,7 +558,7 @@ func createHardForkExporter( returnedConfigs[node.ShardCoordinator.SelfId()] = append(returnedConfigs[node.ShardCoordinator.SelfId()], exportConfig) returnedConfigs[node.ShardCoordinator.SelfId()] = append(returnedConfigs[node.ShardCoordinator.SelfId()], keysConfig) - coreComponents := integrationTests.GetDefaultCoreComponents() + coreComponents := integrationTests.GetDefaultCoreComponents(integrationTests.CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = integrationTests.TestMarshalizer coreComponents.TxMarshalizerField = integrationTests.TestTxSignMarshalizer coreComponents.HasherField = integrationTests.TestHasher diff --git a/integrationTests/node/getAccount/getAccount_test.go b/integrationTests/node/getAccount/getAccount_test.go index c3123a41b29..8f24706fff5 100644 --- a/integrationTests/node/getAccount/getAccount_test.go +++ b/integrationTests/node/getAccount/getAccount_test.go @@ -37,7 +37,7 @@ func TestNode_GetAccountAccountDoesNotExistsShouldRetEmpty(t *testing.T) { accDB, _ := integrationTests.CreateAccountsDB(0, trieStorage) rootHash, _ := accDB.Commit() - coreComponents := integrationTests.GetDefaultCoreComponents() + coreComponents := integrationTests.GetDefaultCoreComponents(integrationTests.CreateEnableEpochsConfig()) coreComponents.AddressPubKeyConverterField = integrationTests.TestAddressPubkeyConverter dataComponents := integrationTests.GetDefaultDataComponents() @@ -77,7 +77,7 @@ func TestNode_GetAccountAccountExistsShouldReturn(t *testing.T) { testPubkey := integrationTests.CreateAccount(accDB, testNonce, testBalance) rootHash, _ := accDB.Commit() - coreComponents := integrationTests.GetDefaultCoreComponents() + coreComponents := integrationTests.GetDefaultCoreComponents(integrationTests.CreateEnableEpochsConfig()) coreComponents.AddressPubKeyConverterField = testscommon.RealWorldBech32PubkeyConverter dataComponents := integrationTests.GetDefaultDataComponents() diff --git a/integrationTests/state/stateTrie/stateTrie_test.go b/integrationTests/state/stateTrie/stateTrie_test.go index f8a7bfae8c5..05857d9b87c 100644 --- a/integrationTests/state/stateTrie/stateTrie_test.go +++ b/integrationTests/state/stateTrie/stateTrie_test.go @@ -2,6 +2,7 @@ package stateTrie import ( "bytes" + "context" "encoding/base64" "encoding/binary" "encoding/hex" @@ -24,11 +25,13 @@ import ( "github.com/multiversx/mx-chain-core-go/hashing/sha256" crypto "github.com/multiversx/mx-chain-crypto-go" "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/common/errChan" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/epochStart" "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/mock" + esdtCommon "github.com/multiversx/mx-chain-go/integrationTests/vm/esdt" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/state/factory" @@ -2342,6 +2345,221 @@ func Test_SnapshotStateRemovesLastSnapshotStartedAfterSnapshotFinished(t *testin assert.NotNil(t, err) } +func TestMigrateDataTrieBuiltinFunc(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + t.Run("migrate shard 0 system account", func(t *testing.T) { + shardId := byte(0) + nodes, idxProposers, nonce, round := startNodesAndIssueToken(t, 2, shardId) + defer func() { + for _, n := range nodes { + n.Close() + } + }() + + valuesBeforeMigration := getValuesFromAccount(t, nodes[shardId].AccntState, core.SystemAccountAddress) + migrateDataTrieBuiltInFunc(t, nodes, shardId, core.SystemAccountAddress, nonce, round, idxProposers) + valuesAfterMigration := getValuesFromAccount(t, nodes[shardId].AccntState, core.SystemAccountAddress) + + require.Equal(t, len(valuesBeforeMigration), len(valuesAfterMigration)) + require.True(t, len(valuesAfterMigration) > 0) + for i := range valuesBeforeMigration { + require.Equal(t, valuesBeforeMigration[i], valuesAfterMigration[i]) + } + }) + t.Run("migrate shard 0 user account", func(t *testing.T) { + shardId := byte(0) + nodes, idxProposers, nonce, round := startNodesAndIssueToken(t, 2, shardId) + defer func() { + for _, n := range nodes { + n.Close() + } + }() + + migrationAddress := nodes[shardId].OwnAccount.Address + valuesBeforeMigration := getValuesFromAccount(t, nodes[shardId].AccntState, migrationAddress) + migrateDataTrieBuiltInFunc(t, nodes, shardId, migrationAddress, nonce, round, idxProposers) + valuesAfterMigration := getValuesFromAccount(t, nodes[shardId].AccntState, migrationAddress) + + require.Equal(t, len(valuesBeforeMigration), len(valuesAfterMigration)) + require.True(t, len(valuesAfterMigration) > 0) + for i := range valuesBeforeMigration { + require.Equal(t, valuesBeforeMigration[i], valuesAfterMigration[i]) + } + }) + t.Run("migrate shard 1 system account", func(t *testing.T) { + shardId := byte(1) + nodes, idxProposers, nonce, round := startNodesAndIssueToken(t, 2, shardId) + defer func() { + for _, n := range nodes { + n.Close() + } + }() + + valuesBeforeMigration := getValuesFromAccount(t, nodes[shardId].AccntState, core.SystemAccountAddress) + migrateDataTrieBuiltInFunc(t, nodes, shardId, core.SystemAccountAddress, nonce, round, idxProposers) + valuesAfterMigration := getValuesFromAccount(t, nodes[shardId].AccntState, core.SystemAccountAddress) + + require.Equal(t, len(valuesBeforeMigration), len(valuesAfterMigration)) + require.True(t, len(valuesAfterMigration) > 0) + for i := range valuesBeforeMigration { + require.Equal(t, valuesBeforeMigration[i], valuesAfterMigration[i]) + } + }) + t.Run("migrate shard 1 user account", func(t *testing.T) { + shardId := byte(1) + nodes, idxProposers, nonce, round := startNodesAndIssueToken(t, 2, shardId) + defer func() { + for _, n := range nodes { + n.Close() + } + }() + + migrationAddress := nodes[shardId].OwnAccount.Address + valuesBeforeMigration := getValuesFromAccount(t, nodes[shardId].AccntState, migrationAddress) + migrateDataTrieBuiltInFunc(t, nodes, shardId, nodes[shardId].OwnAccount.Address, nonce, round, idxProposers) + valuesAfterMigration := getValuesFromAccount(t, nodes[shardId].AccntState, migrationAddress) + + require.Equal(t, len(valuesBeforeMigration), len(valuesAfterMigration)) + require.True(t, len(valuesAfterMigration) > 0) + for i := range valuesBeforeMigration { + require.Equal(t, valuesBeforeMigration[i], valuesAfterMigration[i]) + } + }) +} + +func getValuesFromAccount(t *testing.T, adb state.AccountsAdapter, address []byte) [][]byte { + account, err := adb.GetExistingAccount(address) + require.Nil(t, err) + + chLeaves := &common.TrieIteratorChannels{ + LeavesChan: make(chan core.KeyValueHolder, common.TrieLeavesChannelDefaultCapacity), + ErrChan: errChan.NewErrChanWrapper(), + } + err = account.(state.UserAccountHandler).GetAllLeaves(chLeaves, context.Background()) + require.Nil(t, err) + + values := make([][]byte, 0) + for leaf := range chLeaves.LeavesChan { + values = append(values, leaf.Value()) + } + + err = chLeaves.ErrChan.ReadFromChanNonBlocking() + require.Nil(t, err) + + return values +} + +func migrateDataTrieBuiltInFunc( + t *testing.T, + nodes []*integrationTests.TestProcessorNode, + shardId byte, + migrationAddress []byte, + nonce uint64, + round uint64, + idxProposers []int, +) { + require.True(t, nodes[shardId].EnableEpochsHandler.IsAutoBalanceDataTriesEnabled()) + isMigrated := getAddressMigrationStatus(t, nodes[shardId].AccntState, migrationAddress) + require.False(t, isMigrated) + + integrationTests.CreateAndSendTransactionWithSenderAccount(nodes[shardId], nodes, big.NewInt(0), nodes[shardId].OwnAccount, getDestAccountAddress(migrationAddress, shardId), core.BuiltInFunctionMigrateDataTrie, 1000000) + + time.Sleep(time.Second) + nrRoundsToPropagate := 5 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagate, nonce, round, idxProposers) + + isMigrated = getAddressMigrationStatus(t, nodes[shardId].AccntState, migrationAddress) + require.True(t, isMigrated) +} + +func startNodesAndIssueToken( + t *testing.T, + numOfShards int, + issuerShardId byte, +) ([]*integrationTests.TestProcessorNode, []int, uint64, uint64) { + nodesPerShard := 1 + numMetachainNodes := 1 + + enableEpochs := config.EnableEpochs{ + GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, + BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, + OptimizeGasUsedInCrossMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, + MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, + StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + AutoBalanceDataTriesEnableEpoch: 1, + } + nodes := integrationTests.CreateNodesWithEnableEpochs( + numOfShards, + nodesPerShard, + numMetachainNodes, + enableEpochs, + ) + + roundsPerEpoch := uint64(5) + for _, node := range nodes { + node.EpochStartTrigger.SetRoundsPerEpoch(roundsPerEpoch) + } + + idxProposers := make([]int, numOfShards+1) + for i := 0; i < numOfShards; i++ { + idxProposers[i] = i * nodesPerShard + } + idxProposers[numOfShards] = numOfShards * nodesPerShard + + integrationTests.DisplayAndStartNodes(nodes) + + initialVal := int64(10000000000) + integrationTests.MintAllNodes(nodes, big.NewInt(initialVal)) + + round := uint64(0) + nonce := uint64(0) + round = integrationTests.IncrementAndPrintRound(round) + nonce++ + + // send token issue + initialSupply := int64(10000000000) + ticker := "TCK" + esdtCommon.IssueTestTokenWithIssuerAccount(nodes, nodes[issuerShardId].OwnAccount, initialSupply, ticker) + + time.Sleep(time.Second) + nrRoundsToPropagate := 8 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagate, nonce, round, idxProposers) + time.Sleep(time.Second) + + tokenIdentifier := string(integrationTests.GetTokenIdentifier(nodes, []byte(ticker))) + + esdtCommon.CheckAddressHasTokens(t, nodes[issuerShardId].OwnAccount.Address, nodes, []byte(tokenIdentifier), 0, initialSupply) + + return nodes, idxProposers, nonce, round +} + +func getDestAccountAddress(migrationAddress []byte, shardId byte) []byte { + if bytes.Equal(migrationAddress, core.SystemAccountAddress) && shardId == 0 { + systemAccountAddress := bytes.Repeat([]byte{255}, 30) + systemAccountAddress = append(systemAccountAddress, []byte{0, 0}...) + return systemAccountAddress + } + + return migrationAddress +} + +func getAddressMigrationStatus(t *testing.T, adb state.AccountsAdapter, address []byte) bool { + account, err := adb.LoadAccount(address) + require.Nil(t, err) + + userAccount, ok := account.(state.UserAccountHandler) + require.True(t, ok) + + isMigrated, err := userAccount.DataTrie().IsMigratedToLatestVersion() + require.Nil(t, err) + + return isMigrated +} + func addDataTriesForAccountsStartingWithIndex( startIndex uint32, nbAccounts uint32, diff --git a/integrationTests/testConsensusNode.go b/integrationTests/testConsensusNode.go index 650f54a5058..746141dd148 100644 --- a/integrationTests/testConsensusNode.go +++ b/integrationTests/testConsensusNode.go @@ -234,7 +234,7 @@ func (tcn *TestConsensusNode) initNode(args ArgsTestConsensusNode) { tcn.initAccountsDB() - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(CreateEnableEpochsConfig()) coreComponents.SyncTimerField = syncer coreComponents.RoundHandlerField = roundHandler coreComponents.InternalMarshalizerField = TestMarshalizer diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 6a72d118a50..340f6786985 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -643,7 +643,7 @@ func CreateFullGenesisBlocks( gasSchedule := wasmConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(enableEpochsConfig) coreComponents.InternalMarshalizerField = TestMarshalizer coreComponents.TxMarshalizerField = TestTxSignMarshalizer coreComponents.HasherField = TestHasher @@ -759,7 +759,7 @@ func CreateGenesisMetaBlock( gasSchedule := wasmConfig.MakeGasMapForTests() defaults.FillGasMapInternal(gasSchedule, 1) - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(enableEpochsConfig) coreComponents.InternalMarshalizerField = marshalizer coreComponents.HasherField = hasher coreComponents.Uint64ByteSliceConverterField = uint64Converter @@ -2215,7 +2215,7 @@ func generateValidTx( _ = accnts.SaveAccount(acc) _, _ = accnts.Commit() - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = TestMarshalizer coreComponents.TxMarshalizerField = TestTxSignMarshalizer coreComponents.VmMarshalizerField = TestMarshalizer diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 9e599debbd7..7dc403a4afd 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1247,7 +1247,7 @@ func (tpn *TestProcessorNode) initInterceptors(heartbeatPk string) { tpn.EpochStartNotifier = notifier.NewEpochStartSubscriptionHandler() } - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = TestMarshalizer coreComponents.TxMarshalizerField = TestTxSignMarshalizer coreComponents.HasherField = TestHasher @@ -2166,7 +2166,7 @@ func (tpn *TestProcessorNode) initBlockProcessor(stateCheckpointModulus uint) { accountsDb[state.UserAccountsState] = tpn.AccntState accountsDb[state.PeerAccountsState] = tpn.PeerState - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = TestMarshalizer coreComponents.HasherField = TestHasher coreComponents.Uint64ByteSliceConverterField = TestUint64Converter @@ -2438,7 +2438,7 @@ func (tpn *TestProcessorNode) initNode() { AppStatusHandlerField: tpn.AppStatusHandler, } - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = TestMarshalizer coreComponents.VmMarshalizerField = TestVmMarshalizer coreComponents.TxMarshalizerField = TestTxSignMarshalizer @@ -3236,10 +3236,9 @@ func CreateEnableEpochsConfig() config.EnableEpochs { } // GetDefaultCoreComponents - -func GetDefaultCoreComponents() *mock.CoreComponentsStub { - enableEpochsCfg := CreateEnableEpochsConfig() +func GetDefaultCoreComponents(enableEpochsConfig config.EnableEpochs) *mock.CoreComponentsStub { genericEpochNotifier := forking.NewGenericEpochNotifier() - enableEpochsHandler, _ := enablers.NewEnableEpochsHandler(enableEpochsCfg, genericEpochNotifier) + enableEpochsHandler, _ := enablers.NewEnableEpochsHandler(enableEpochsConfig, genericEpochNotifier) return &mock.CoreComponentsStub{ InternalMarshalizerField: TestMarshalizer, diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index ee4d95a0c63..02d5d3cb359 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -44,7 +44,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { accountsDb[state.UserAccountsState] = tpn.AccntState accountsDb[state.PeerAccountsState] = tpn.PeerState - coreComponents := GetDefaultCoreComponents() + coreComponents := GetDefaultCoreComponents(CreateEnableEpochsConfig()) coreComponents.InternalMarshalizerField = TestMarshalizer coreComponents.HasherField = TestHasher coreComponents.Uint64ByteSliceConverterField = TestUint64Converter From f362608ebc340430835c389dd0d6f91be2e5a11f Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Fri, 19 Jan 2024 15:15:56 +0200 Subject: [PATCH 626/958] change enable epoch for migrateDataTrie --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index e5b6efe99f3..5dc78b7a616 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -258,7 +258,7 @@ AutoBalanceDataTriesEnableEpoch = 1 # MigrateDataTrieEnableEpoch represents the epoch when the data tries migration is enabled - MigrateDataTrieEnableEpoch = 999999 + MigrateDataTrieEnableEpoch = 1 # KeepExecOrderOnCreatedSCRsEnableEpoch represents the epoch when the execution order of created SCRs is ensured KeepExecOrderOnCreatedSCRsEnableEpoch = 1 From 685b847fd1912f41f59814b0a08d0f9f47bbf727 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 22 Jan 2024 10:56:29 +0200 Subject: [PATCH 627/958] add cpu flags to config --- cmd/node/config/config.toml | 3 +++ cmd/node/main.go | 28 +++++++++++++++++++++++++--- config/config.go | 24 +++++++++++++++--------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index be5d2d7bbf6..72539a298f7 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -40,6 +40,9 @@ # Make sure that this is greater than the unbonding period! SetGuardianEpochsDelay = 2 # TODO: for mainnet should be 20, 2 is just for testing +[HardwareRequirements] + CPUFlags = ["sse4_1", "sse4_2"] + [Versions] DefaultVersion = "default" VersionsByEpochs = [ diff --git a/cmd/node/main.go b/cmd/node/main.go index c0470f4826b..207c6375083 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -130,7 +130,7 @@ func startNodeRunner(c *cli.Context, log logger.Logger, baseVersion string, vers cfgs.FlagsConfig.BaseVersion = baseVersion cfgs.FlagsConfig.Version = version - err = checkHardwareRequirements() + err = checkHardwareRequirements(cfgs.GeneralConfig.HardwareRequirements) if err != nil { return fmt.Errorf("Hardware Requirements checks failed: %s", err.Error()) } @@ -308,10 +308,32 @@ func attachFileLogger(log logger.Logger, flagsConfig *config.ContextFlagsConfig) return fileLogging, nil } -func checkHardwareRequirements() error { - if !cpuid.CPU.Supports(cpuid.SSE4, cpuid.SSE42) { +func checkHardwareRequirements(cfg config.HardwareRequirementsConfig) error { + cpuFlags, err := parseFeatures(cfg.CPUFlags) + if err != nil { + return err + } + + if !cpuid.CPU.Supports(cpuFlags...) { return fmt.Errorf("CPU Flags: Streaming SIMD Extensions 4 required") } return nil } + +func parseFeatures(features []string) ([]cpuid.FeatureID, error) { + flags := make([]cpuid.FeatureID, 0) + + for _, cpuFlag := range features { + switch cpuFlag { + case "sse4_1": + flags = append(flags, cpuid.SSE4) + case "sse4_2": + flags = append(flags, cpuid.SSE42) + default: + return nil, fmt.Errorf("CPU Flags: cpu flag %s not found", cpuFlag) + } + } + + return flags, nil +} diff --git a/config/config.go b/config/config.go index db0e84bb1cd..b53e46a2201 100644 --- a/config/config.go +++ b/config/config.go @@ -190,15 +190,16 @@ type Config struct { PublicKeyPIDSignature CacheConfig PeerHonesty CacheConfig - Antiflood AntifloodConfig - WebServerAntiflood WebServerAntifloodConfig - ResourceStats ResourceStatsConfig - HeartbeatV2 HeartbeatV2Config - ValidatorStatistics ValidatorStatisticsConfig - GeneralSettings GeneralSettingsConfig - Consensus ConsensusConfig - StoragePruning StoragePruningConfig - LogsAndEvents LogsAndEventsConfig + Antiflood AntifloodConfig + WebServerAntiflood WebServerAntifloodConfig + ResourceStats ResourceStatsConfig + HeartbeatV2 HeartbeatV2Config + ValidatorStatistics ValidatorStatisticsConfig + GeneralSettings GeneralSettingsConfig + Consensus ConsensusConfig + StoragePruning StoragePruningConfig + LogsAndEvents LogsAndEventsConfig + HardwareRequirements HardwareRequirementsConfig NTPConfig NTPConfig HeadersPoolConfig HeadersPoolConfig @@ -285,6 +286,11 @@ type GeneralSettingsConfig struct { SetGuardianEpochsDelay uint32 } +// HardwareRequirementsConfig will hold the hardware requirements config +type HardwareRequirementsConfig struct { + CPUFlags []string +} + // FacadeConfig will hold different configuration option that will be passed to the node facade type FacadeConfig struct { RestApiInterface string From dfd4004da922d7dd99b11bb9b643f1b222979459 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Mon, 22 Jan 2024 11:04:39 +0200 Subject: [PATCH 628/958] do not activate more nodes on stake if too many nodes --- vm/systemSmartContracts/validator.go | 19 ++++++++----------- vm/systemSmartContracts/validator_test.go | 5 +---- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 509ec89b624..1adc60976d2 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -1064,17 +1064,14 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod } } - v.activateStakingFor( - blsKeys, - registrationData, - validatorConfig.NodePrice, - registrationData.RewardAddress, - args.CallerAddr, - ) - - if v.isNumberOfNodesTooHigh(registrationData) { - v.eei.AddReturnMessage("number of nodes is too high") - return vmcommon.UserError + if !v.isNumberOfNodesTooHigh(registrationData) { + v.activateStakingFor( + blsKeys, + registrationData, + validatorConfig.NodePrice, + registrationData.RewardAddress, + args.CallerAddr, + ) } err = v.saveRegistrationData(args.CallerAddr, registrationData) diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 12d66464625..d2504cde21c 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -460,9 +460,6 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { } return nil } - eei.AddReturnMessageCalled = func(msg string) { - assert.Equal(t, msg, "number of nodes is too high") - } key1 := []byte("Key1") key2 := []byte("Key2") @@ -472,7 +469,7 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { arguments.Arguments = [][]byte{big.NewInt(3).Bytes(), key1, []byte("msg1"), key2, []byte("msg2"), key3, []byte("msg3")} errCode := stakingValidatorSc.Execute(arguments) - assert.Equal(t, vmcommon.UserError, errCode) + assert.Equal(t, vmcommon.Ok, errCode) } func TestStakingValidatorSC_ExecuteStakeAddedNewPubKeysShouldWork(t *testing.T) { From 64ca8a0fed8532a6c4ebe637d7ca48531b88f173 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 22 Jan 2024 11:21:53 +0200 Subject: [PATCH 629/958] use ParseFeature func from cpuid --- cmd/node/config/config.toml | 2 +- cmd/node/main.go | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 72539a298f7..184bf0db1ac 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -41,7 +41,7 @@ SetGuardianEpochsDelay = 2 # TODO: for mainnet should be 20, 2 is just for testing [HardwareRequirements] - CPUFlags = ["sse4_1", "sse4_2"] + CPUFlags = ["SSE4", "SSE42"] [Versions] DefaultVersion = "default" diff --git a/cmd/node/main.go b/cmd/node/main.go index 207c6375083..289800252f5 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -325,12 +325,8 @@ func parseFeatures(features []string) ([]cpuid.FeatureID, error) { flags := make([]cpuid.FeatureID, 0) for _, cpuFlag := range features { - switch cpuFlag { - case "sse4_1": - flags = append(flags, cpuid.SSE4) - case "sse4_2": - flags = append(flags, cpuid.SSE42) - default: + featureID := cpuid.ParseFeature(cpuFlag) + if featureID == cpuid.UNKNOWN { return nil, fmt.Errorf("CPU Flags: cpu flag %s not found", cpuFlag) } } From a9a630ab6fc9504371b1f31df2babd1a2acecd3d Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 22 Jan 2024 12:13:01 +0200 Subject: [PATCH 630/958] linter fix --- integrationTests/state/stateTrie/stateTrie_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/state/stateTrie/stateTrie_test.go b/integrationTests/state/stateTrie/stateTrie_test.go index 05857d9b87c..3bc5184767b 100644 --- a/integrationTests/state/stateTrie/stateTrie_test.go +++ b/integrationTests/state/stateTrie/stateTrie_test.go @@ -2469,7 +2469,7 @@ func migrateDataTrieBuiltInFunc( time.Sleep(time.Second) nrRoundsToPropagate := 5 - nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagate, nonce, round, idxProposers) + _, _ = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagate, nonce, round, idxProposers) isMigrated = getAddressMigrationStatus(t, nodes[shardId].AccntState, migrationAddress) require.True(t, isMigrated) From e0566b94007d9eb7b9436661ee812f38bb6b4ee2 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 22 Jan 2024 14:56:37 +0200 Subject: [PATCH 631/958] update go mod --- go.mod | 12 +++++----- go.sum | 24 +++++++++---------- .../vm/wasm/wasmvm/mockContracts.go | 2 +- .../scenariosConverter/scenariosConverter.go | 16 ++++++------- .../scenariosConverterUtils.go | 24 +++++++++---------- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 7bd32583cac..8e918b544a4 100644 --- a/go.mod +++ b/go.mod @@ -18,13 +18,13 @@ require ( github.com/multiversx/mx-chain-crypto-go v1.2.9 github.com/multiversx/mx-chain-es-indexer-go v1.4.18 github.com/multiversx/mx-chain-logger-go v1.0.13 - github.com/multiversx/mx-chain-scenario-go v1.2.1 + github.com/multiversx/mx-chain-scenario-go v1.3.0 github.com/multiversx/mx-chain-storage-go v1.0.14 - github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240119120033-6a9321334ec5 - github.com/multiversx/mx-chain-vm-go v1.5.24 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 + github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240122101533-cc1288fd297e + github.com/multiversx/mx-chain-vm-go v1.5.26-0.20240122101933-32a558e14c8a + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20240122121022-c7d274043a74 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20240122120659-69848278235c + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94-0.20240122102744-2052863f9b5c github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil v3.21.11+incompatible diff --git a/go.sum b/go.sum index aade389db54..bd49ee1ade1 100644 --- a/go.sum +++ b/go.sum @@ -395,20 +395,20 @@ github.com/multiversx/mx-chain-es-indexer-go v1.4.18 h1:rCA+/mn/77MyB7c8FjtabdQe github.com/multiversx/mx-chain-es-indexer-go v1.4.18/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= github.com/multiversx/mx-chain-logger-go v1.0.13 h1:eru/TETo0MkO4ZTnXsQDKf4PBRpAXmqjT02klNT/JnY= github.com/multiversx/mx-chain-logger-go v1.0.13/go.mod h1:MZJhTAtZTJxT+yK2EHc4ZW3YOHUc1UdjCD0iahRNBZk= -github.com/multiversx/mx-chain-scenario-go v1.2.1 h1:9eC6VcOEAKRRKZ7EbSWPLzCdNIMWwuNBtAZlgR4cSMA= -github.com/multiversx/mx-chain-scenario-go v1.2.1/go.mod h1:EuZY7DpNFHVNSxJR8dKE1z2I8gBYfEFFPSwNUOXptqE= +github.com/multiversx/mx-chain-scenario-go v1.3.0 h1:Vm6jYipJuIcJt8kamgXkePtKkwXaF5Lv5DglZjE5o8I= +github.com/multiversx/mx-chain-scenario-go v1.3.0/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= -github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240119120033-6a9321334ec5 h1:ZaxuCVOLL2gtBeUimMUQrIpsBVfoaAW39iW9Px1CeWQ= -github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240119120033-6a9321334ec5/go.mod h1:sqkKMCnwkWl8DURdb9q7pctK8IANghdHY1KJLE0ox2c= -github.com/multiversx/mx-chain-vm-go v1.5.24 h1:6RhMvf84Ys8DksDovms+su7w6j9TWz3Rtm/PpgV12Yw= -github.com/multiversx/mx-chain-vm-go v1.5.24/go.mod h1:T03t+in5jqeTuFZKDt2wH/Sl9MSRczvWhmG+tQEIfec= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64 h1:3BEpSxEQibMMi4LXBjpo2y5vUa1LS7olDC2eDkmUfFQ= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.64/go.mod h1:MUO2E4aEIu3siDkvjraO/WaBh/FxVeQyPWfsrZE+MTU= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65 h1:H0Duuoz6lR6KapqLqMspWTojaVtQRiLA5lIm6XV9H04= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.65/go.mod h1:IZCHU3j/OSKVzdXu+5uZZSq2pVJrAS/KKAvnGrA/IKM= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92 h1:8ZcqnUQoIeM5k1F2IHvqbFzCumGwB4oVilWGuwurxpo= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92/go.mod h1:NyGULyeuEFe7Tb3gavT3Mti2oIFZJiMIf8VJIQnL4E8= +github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240122101533-cc1288fd297e h1:MSZgCSYqwsJ6AyD06b4V00vovP/WhFV//d7Oyea9Tu0= +github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240122101533-cc1288fd297e/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= +github.com/multiversx/mx-chain-vm-go v1.5.26-0.20240122101933-32a558e14c8a h1:qAFxvzeuEbziggn3UYfuwHV0Vgqoq5SPyPx+58R2mCY= +github.com/multiversx/mx-chain-vm-go v1.5.26-0.20240122101933-32a558e14c8a/go.mod h1:UlKI1NbOnUMIF7pmixIR55S01wrPP8kmeM4CY4iY9Vs= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20240122121022-c7d274043a74 h1:7VZq8W+fD45/H4sH5ldin7dEh1UeQWkGJbaUfez4Nb8= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20240122121022-c7d274043a74/go.mod h1:ty8vCeZ6gRWBc1oM8VT5PKVxS0L/61TxMcQwy2lnAcg= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20240122120659-69848278235c h1:3w80/WeldsyNe5v9tg1dT7ZXiS/iDgJYUtxehg1mhYU= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20240122120659-69848278235c/go.mod h1:FxHEUiZeqTJtnlip5EkSATOCzkKUtE9MYfIpccLpIVQ= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94-0.20240122102744-2052863f9b5c h1:DEPBKTjddfB1ZynBwSwv37oFhGrON6nIOJuXfdxBIDE= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94-0.20240122102744-2052863f9b5c/go.mod h1:vBbwc8dOPgUFLEzWVqS62uDRazYKsBVABrl9SFNu25k= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= diff --git a/integrationTests/vm/wasm/wasmvm/mockContracts.go b/integrationTests/vm/wasm/wasmvm/mockContracts.go index 21c6e6cae55..e8478768cbc 100644 --- a/integrationTests/vm/wasm/wasmvm/mockContracts.go +++ b/integrationTests/vm/wasm/wasmvm/mockContracts.go @@ -17,9 +17,9 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" + "github.com/multiversx/mx-chain-scenario-go/worldmock" "github.com/multiversx/mx-chain-vm-go/executor" contextmock "github.com/multiversx/mx-chain-vm-go/mock/context" - worldmock "github.com/multiversx/mx-chain-vm-go/mock/world" "github.com/multiversx/mx-chain-vm-go/testcommon" "github.com/multiversx/mx-chain-vm-go/vmhost" "github.com/stretchr/testify/require" diff --git a/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverter.go b/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverter.go index 64a8bde201f..36a4fb8e51b 100644 --- a/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverter.go +++ b/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverter.go @@ -10,15 +10,15 @@ import ( "github.com/multiversx/mx-chain-go/process/factory" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" - mge "github.com/multiversx/mx-chain-scenario-go/scenario-exporter" - mgutil "github.com/multiversx/mx-chain-scenario-go/util" + "github.com/multiversx/mx-chain-scenario-go/scenario/exporter" + scenmodel "github.com/multiversx/mx-chain-scenario-go/scenario/model" vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) var errReturnCodeNotOk = errors.New("returnCode is not 0(Ok)") // CreateAccountsFromScenariosAccs uses scenariosAccounts to populate the AccountsAdapter -func CreateAccountsFromScenariosAccs(tc *vm.VMTestContext, scenariosUserAccounts []*mge.TestAccount) error { +func CreateAccountsFromScenariosAccs(tc *vm.VMTestContext, scenariosUserAccounts []*exporter.TestAccount) error { for _, scenariosAcc := range scenariosUserAccounts { acc, err := tc.Accounts.LoadAccount(scenariosAcc.GetAddress()) if err != nil { @@ -60,7 +60,7 @@ func CreateAccountsFromScenariosAccs(tc *vm.VMTestContext, scenariosUserAccounts } // CreateTransactionsFromScenariosTxs converts scenarios transactions intro trasnsactions that can be processed by the txProcessor -func CreateTransactionsFromScenariosTxs(scenariosTxs []*mge.Transaction) (transactions []*transaction.Transaction) { +func CreateTransactionsFromScenariosTxs(scenariosTxs []*exporter.Transaction) (transactions []*transaction.Transaction) { var data []byte transactions = make([]*transaction.Transaction, 0) @@ -70,7 +70,7 @@ func CreateTransactionsFromScenariosTxs(scenariosTxs []*mge.Transaction) (transa endpointName := scenariosTx.GetCallFunction() args := scenariosTx.GetCallArguments() if len(esdtTransfers) != 0 { - data = mgutil.CreateMultiTransferData(scenariosTx.GetReceiverAddress(), esdtTransfers, endpointName, args) + data = scenmodel.CreateMultiTransferData(scenariosTx.GetReceiverAddress(), esdtTransfers, endpointName, args) } else { data = createData(endpointName, args) } @@ -92,7 +92,7 @@ func CreateTransactionsFromScenariosTxs(scenariosTxs []*mge.Transaction) (transa } // DeploySCsFromScenariosDeployTxs deploys all smartContracts correspondent to "scDeploy" in a scenarios test, then replaces with the correct computed address in all the transactions. -func DeploySCsFromScenariosDeployTxs(testContext *vm.VMTestContext, deployScenariosTxs []*mge.Transaction) ([][]byte, error) { +func DeploySCsFromScenariosDeployTxs(testContext *vm.VMTestContext, deployScenariosTxs []*exporter.Transaction) ([][]byte, error) { newScAddresses := make([][]byte, 0) for _, deployScenariosTransaction := range deployScenariosTxs { deployedScAddress, err := deploySC(testContext, deployScenariosTransaction) @@ -105,7 +105,7 @@ func DeploySCsFromScenariosDeployTxs(testContext *vm.VMTestContext, deployScenar } // ReplaceScenariosScAddressesWithNewScAddresses corrects the Scenarios SC Addresses, with the new Addresses obtained from deploying the SCs -func ReplaceScenariosScAddressesWithNewScAddresses(deployedScAccounts []*mge.TestAccount, newScAddresses [][]byte, scenariosTxs []*mge.Transaction) { +func ReplaceScenariosScAddressesWithNewScAddresses(deployedScAccounts []*exporter.TestAccount, newScAddresses [][]byte, scenariosTxs []*exporter.Transaction) { for _, newScAddr := range newScAddresses { addressToBeReplaced := deployedScAccounts[0].GetAddress() for _, scenariosTx := range scenariosTxs { @@ -126,7 +126,7 @@ func createData(functionName string, arguments [][]byte) []byte { return builder.ToBytes() } -func deploySC(testContext *vm.VMTestContext, deployScenariosTx *mge.Transaction) (scAddress []byte, err error) { +func deploySC(testContext *vm.VMTestContext, deployScenariosTx *exporter.Transaction) (scAddress []byte, err error) { gasLimit, gasPrice := deployScenariosTx.GetGasLimitAndPrice() ownerAddr := deployScenariosTx.GetSenderAddress() deployData := deployScenariosTx.GetDeployData() diff --git a/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverterUtils.go b/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverterUtils.go index a701d090e95..2d3d15f681d 100644 --- a/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverterUtils.go +++ b/integrationTests/vm/wasm/wasmvm/scenariosConverter/scenariosConverterUtils.go @@ -8,8 +8,8 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/state" logger "github.com/multiversx/mx-chain-logger-go" - mge "github.com/multiversx/mx-chain-scenario-go/scenario-exporter" - mgutil "github.com/multiversx/mx-chain-scenario-go/util" + "github.com/multiversx/mx-chain-scenario-go/scenario/exporter" + scenmodel "github.com/multiversx/mx-chain-scenario-go/scenario/model" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/require" ) @@ -17,7 +17,7 @@ import ( var log = logger.GetOrCreate("scenariosConverter") // CheckAccounts will verify if scenariosAccounts correspond to AccountsAdapter accounts -func CheckAccounts(t *testing.T, accAdapter state.AccountsAdapter, scenariosAccounts []*mge.TestAccount) { +func CheckAccounts(t *testing.T, accAdapter state.AccountsAdapter, scenariosAccounts []*exporter.TestAccount) { for _, scenariosAcc := range scenariosAccounts { accHandler, err := accAdapter.LoadAccount(scenariosAcc.GetAddress()) require.Nil(t, err) @@ -56,7 +56,7 @@ func CheckStorage(t *testing.T, dataTrie state.UserAccountHandler, scenariosAccS } // CheckTransactions checks if the transactions correspond with the scenariosTransactions -func CheckTransactions(t *testing.T, transactions []*transaction.Transaction, scenariosTransactions []*mge.Transaction) { +func CheckTransactions(t *testing.T, transactions []*transaction.Transaction, scenariosTransactions []*exporter.Transaction) { expectedLength := len(scenariosTransactions) require.Equal(t, expectedLength, len(transactions)) for i := 0; i < expectedLength; i++ { @@ -77,7 +77,7 @@ func CheckTransactions(t *testing.T, transactions []*transaction.Transaction, sc var expectedData []byte if len(expectedEsdtTransfers) != 0 { - expectedData = mgutil.CreateMultiTransferData(expectedReceiver, expectedEsdtTransfers, expectedCallFunction, expectedCallArguments) + expectedData = scenmodel.CreateMultiTransferData(expectedReceiver, expectedEsdtTransfers, expectedCallFunction, expectedCallArguments) require.Equal(t, expectedSender, transactions[i].GetRcvAddr()) } else { require.Equal(t, expectedReceiver, transactions[i].GetRcvAddr()) @@ -97,7 +97,7 @@ func BenchmarkScenariosSpecificTx(b *testing.B, scenariosTestPath string) { return } defer testContext.Close() - if benchmarkTxPos == mge.InvalidBenchmarkTxPos { + if benchmarkTxPos == exporter.InvalidBenchmarkTxPos { log.Trace("no transactions marked for benchmarking") } if len(transactions) > 1 { @@ -115,21 +115,21 @@ func BenchmarkScenariosSpecificTx(b *testing.B, scenariosTestPath string) { // SetStateFromScenariosTest recieves path to scenariosTest, returns a VMTestContext with the specified accounts, an array with the specified transactions and an error func SetStateFromScenariosTest(scenariosTestPath string) (testContext *vm.VMTestContext, transactions []*transaction.Transaction, bechmarkTxPos int, err error) { - stateAndBenchmarkInfo, err := mge.GetAccountsAndTransactionsFromScenarios(scenariosTestPath) + stateAndBenchmarkInfo, err := exporter.GetAccountsAndTransactionsFromScenarios(scenariosTestPath) if err != nil { - return nil, nil, mge.InvalidBenchmarkTxPos, err + return nil, nil, exporter.InvalidBenchmarkTxPos, err } testContext, err = vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) if err != nil { - return nil, nil, mge.InvalidBenchmarkTxPos, err + return nil, nil, exporter.InvalidBenchmarkTxPos, err } err = CreateAccountsFromScenariosAccs(testContext, stateAndBenchmarkInfo.Accs) if err != nil { - return nil, nil, mge.InvalidBenchmarkTxPos, err + return nil, nil, exporter.InvalidBenchmarkTxPos, err } newAddresses, err := DeploySCsFromScenariosDeployTxs(testContext, stateAndBenchmarkInfo.DeployTxs) if err != nil { - return nil, nil, mge.InvalidBenchmarkTxPos, err + return nil, nil, exporter.InvalidBenchmarkTxPos, err } ReplaceScenariosScAddressesWithNewScAddresses(stateAndBenchmarkInfo.DeployedAccs, newAddresses, stateAndBenchmarkInfo.Txs) transactions = CreateTransactionsFromScenariosTxs(stateAndBenchmarkInfo.Txs) @@ -138,7 +138,7 @@ func SetStateFromScenariosTest(scenariosTestPath string) (testContext *vm.VMTest // CheckConverter - func CheckConverter(t *testing.T, scenariosTestPath string) { - stateAndBenchmarkInfo, err := mge.GetAccountsAndTransactionsFromScenarios(scenariosTestPath) + stateAndBenchmarkInfo, err := exporter.GetAccountsAndTransactionsFromScenarios(scenariosTestPath) require.Nil(t, err) testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) require.Nil(t, err) From 40d73dd5ce32451004bc0e86ef39bb4dfebd55f1 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Mon, 22 Jan 2024 16:01:12 +0200 Subject: [PATCH 632/958] update enable flags --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 5dc78b7a616..6a9384c8490 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -258,7 +258,7 @@ AutoBalanceDataTriesEnableEpoch = 1 # MigrateDataTrieEnableEpoch represents the epoch when the data tries migration is enabled - MigrateDataTrieEnableEpoch = 1 + MigrateDataTrieEnableEpoch = 2 # KeepExecOrderOnCreatedSCRsEnableEpoch represents the epoch when the execution order of created SCRs is ensured KeepExecOrderOnCreatedSCRsEnableEpoch = 1 From 94244afbca4db253cc76d17d5f9202fc79975084 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Tue, 23 Jan 2024 10:27:17 +0200 Subject: [PATCH 633/958] do not activate more nodes on stake if too many nodes --- vm/systemSmartContracts/delegation.go | 19 +++++++++++++++++++ vm/systemSmartContracts/validator.go | 8 ++++++++ 2 files changed, 27 insertions(+) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index c65afdf6942..e457e9157f2 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1215,6 +1215,12 @@ func (d *delegation) stakeNodes(args *vmcommon.ContractCallInput) vmcommon.Retur return vmOutput.ReturnCode } + allLogs := d.eei.GetLogs() + if tooManyNodesLogs(allLogs) { + d.eei.AddReturnMessage(numberOfNodesTooHigh) + return vmcommon.UserError + } + err = d.updateDelegationStatusAfterStake(status, vmOutput.ReturnData, args.Arguments) if err != nil { d.eei.AddReturnMessage(err.Error()) @@ -1226,6 +1232,19 @@ func (d *delegation) stakeNodes(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.Ok } +func tooManyNodesLogs(logEntries []*vmcommon.LogEntry) bool { + for _, logEntry := range logEntries { + if len(logEntry.Topics) > 1 { + continue + } + if !bytes.Equal(logEntry.Topics[0], []byte(numberOfNodesTooHigh)) { + return true + } + } + + return false +} + func (d *delegation) updateDelegationStatusAfterStake( status *DelegationContractStatus, returnData [][]byte, diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 1adc60976d2..081a1e848f7 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -22,6 +22,7 @@ import ( const unJailedFunds = "unJailFunds" const unStakeUnBondPauseKey = "unStakeUnBondPause" const minPercentage = 0.0001 +const numberOfNodesTooHigh = "number of nodes too high, no new nodes activated" var zero = big.NewInt(0) @@ -1072,6 +1073,13 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod registrationData.RewardAddress, args.CallerAddr, ) + } else { + entry := &vmcommon.LogEntry{ + Identifier: []byte(args.Function), + Address: args.RecipientAddr, + Topics: [][]byte{[]byte(numberOfNodesTooHigh)}, + } + v.eei.AddLogEntry(entry) } err = v.saveRegistrationData(args.CallerAddr, registrationData) From 4f408b0a00f51b0dd729061a01280b0b66ec3516 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Tue, 23 Jan 2024 10:50:49 +0200 Subject: [PATCH 634/958] fixes after review --- vm/systemSmartContracts/delegation.go | 2 +- vm/systemSmartContracts/validator_test.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index e457e9157f2..e1304eca90d 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1234,7 +1234,7 @@ func (d *delegation) stakeNodes(args *vmcommon.ContractCallInput) vmcommon.Retur func tooManyNodesLogs(logEntries []*vmcommon.LogEntry) bool { for _, logEntry := range logEntries { - if len(logEntry.Topics) > 1 { + if len(logEntry.Topics) != 1 { continue } if !bytes.Equal(logEntry.Topics[0], []byte(numberOfNodesTooHigh)) { diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index d2504cde21c..3cb475eb9e2 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -460,6 +460,11 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { } return nil } + called := false + eei.AddLogEntryCalled = func(entry *vmcommon.LogEntry) { + called = true + assert.Equal(t, entry.Topics[0], []byte(numberOfNodesTooHigh)) + } key1 := []byte("Key1") key2 := []byte("Key2") @@ -470,6 +475,7 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { errCode := stakingValidatorSc.Execute(arguments) assert.Equal(t, vmcommon.Ok, errCode) + assert.True(t, called) } func TestStakingValidatorSC_ExecuteStakeAddedNewPubKeysShouldWork(t *testing.T) { From 1ddf0517fa0a0be59c5b683432e53cd808020059 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 23 Jan 2024 20:46:47 +0200 Subject: [PATCH 635/958] - added the possibility to decide if a connected peer is compatible with the seed node --- cmd/seednode/main.go | 15 ++++++++++++--- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cmd/seednode/main.go b/cmd/seednode/main.go index c881fb2a752..ee083fde21d 100644 --- a/cmd/seednode/main.go +++ b/cmd/seednode/main.go @@ -309,12 +309,21 @@ func displayMessengerInfo(messenger p2p.Messenger) { return strings.Compare(mesConnectedAddrs[i], mesConnectedAddrs[j]) < 0 }) - log.Info("known peers", "num peers", len(messenger.Peers())) - headerConnectedAddresses := []string{fmt.Sprintf("Seednode is connected to %d peers:", len(mesConnectedAddrs))} + protocolIDString := "Valid protocol ID?" + log.Info("peers info", "num known peers", len(messenger.Peers()), "num connected peers", len(mesConnectedAddrs)) + headerConnectedAddresses := []string{"Connected peers", protocolIDString} connAddresses := make([]*display.LineData, len(mesConnectedAddrs)) + yesMarker := "yes" + yesMarker = strings.Repeat(" ", (len(protocolIDString)-len(yesMarker))/2) + yesMarker // add padding + noMarker := "!!! no !!!" + noMarker = strings.Repeat(" ", (len(protocolIDString)-len(noMarker))/2) + noMarker // add padding for idx, address := range mesConnectedAddrs { - connAddresses[idx] = display.NewLineData(false, []string{address}) + marker := noMarker + if messenger.HasCompatibleProtocolID(address) { + marker = yesMarker + } + connAddresses[idx] = display.NewLineData(false, []string{address, marker}) } tbl2, _ := display.CreateTableString(headerConnectedAddresses, connAddresses) diff --git a/go.mod b/go.mod index 9f27d2e1ffd..df87ee8d432 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/google/gops v0.3.18 github.com/gorilla/websocket v1.5.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/multiversx/mx-chain-communication-go v1.0.13-0.20231129114230-d280af707381 + github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240123161141-8b8b0259c602 github.com/multiversx/mx-chain-core-go v1.2.19-0.20231214115026-a1e7279b14f1 github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231129101537-ef355850e34b github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20231228064619-e3b0caf29058 diff --git a/go.sum b/go.sum index 0375c025713..d25972f480d 100644 --- a/go.sum +++ b/go.sum @@ -384,8 +384,8 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUYwbO0993uPI= github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o= -github.com/multiversx/mx-chain-communication-go v1.0.13-0.20231129114230-d280af707381 h1:M4JNeubA+zq7NaH2LP5YsWUVeKn9hNL+HgSw2kqwWUc= -github.com/multiversx/mx-chain-communication-go v1.0.13-0.20231129114230-d280af707381/go.mod h1:n4E8BWIV0g3AcNGe1gf+vcjUC8A2QCJ4ARQSbiUDGrI= +github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240123161141-8b8b0259c602 h1:R010kiv1Gp0ULko3TJxAGJmQQz24frgN05y9crLTp/Q= +github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240123161141-8b8b0259c602/go.mod h1:n4E8BWIV0g3AcNGe1gf+vcjUC8A2QCJ4ARQSbiUDGrI= github.com/multiversx/mx-chain-core-go v1.2.19-0.20231214115026-a1e7279b14f1 h1:8rz1ZpRAsWVxSEBy7PJIUStQMKiHs3I4mvpRmHUpsbI= github.com/multiversx/mx-chain-core-go v1.2.19-0.20231214115026-a1e7279b14f1/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231129101537-ef355850e34b h1:TIE6it719ZIW0E1bFgPAgE+U3zPSkPfAloFYEIeOL3U= From f2c718711ea8b6ec98afc0036d71b60cc847db91 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 23 Jan 2024 20:55:13 +0200 Subject: [PATCH 636/958] - fixed stub/disabled component --- p2p/disabled/networkMessenger.go | 5 +++++ testscommon/p2pmocks/messengerStub.go | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/p2p/disabled/networkMessenger.go b/p2p/disabled/networkMessenger.go index 0216ccdd797..1eb767d26c8 100644 --- a/p2p/disabled/networkMessenger.go +++ b/p2p/disabled/networkMessenger.go @@ -190,6 +190,11 @@ func (netMes *networkMessenger) SetDebugger(_ p2p.Debugger) error { return nil } +// HasCompatibleProtocolID returns false as it is disabled +func (netMes *networkMessenger) HasCompatibleProtocolID(_ string) bool { + return false +} + // IsInterfaceNil returns true if there is no value under the interface func (netMes *networkMessenger) IsInterfaceNil() bool { return netMes == nil diff --git a/testscommon/p2pmocks/messengerStub.go b/testscommon/p2pmocks/messengerStub.go index 368b8bdadd5..77d058c71a1 100644 --- a/testscommon/p2pmocks/messengerStub.go +++ b/testscommon/p2pmocks/messengerStub.go @@ -46,6 +46,7 @@ type MessengerStub struct { SignUsingPrivateKeyCalled func(skBytes []byte, payload []byte) ([]byte, error) ProcessReceivedMessageCalled func(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error SetDebuggerCalled func(debugger p2p.Debugger) error + HasCompatibleProtocolIDCalled func(address string) bool } // ID - @@ -369,6 +370,15 @@ func (ms *MessengerStub) SetDebugger(debugger p2p.Debugger) error { return nil } +// HasCompatibleProtocolID - +func (ms *MessengerStub) HasCompatibleProtocolID(address string) bool { + if ms.HasCompatibleProtocolIDCalled != nil { + return ms.HasCompatibleProtocolIDCalled(address) + } + + return false +} + // IsInterfaceNil returns true if there is no value under the interface func (ms *MessengerStub) IsInterfaceNil() bool { return ms == nil From 8fb567dcef7d35b9762e900d8a9f76feab26de4f Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 25 Jan 2024 13:20:38 +0200 Subject: [PATCH 637/958] use proper releases in go mod --- go.mod | 12 ++++++------ go.sum | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 8e918b544a4..fbd61b07d8d 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/gops v0.3.18 github.com/gorilla/websocket v1.5.0 + github.com/klauspost/cpuid/v2 v2.2.5 github.com/mitchellh/mapstructure v1.5.0 github.com/multiversx/mx-chain-communication-go v1.0.12 github.com/multiversx/mx-chain-core-go v1.2.18 @@ -20,11 +21,11 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.13 github.com/multiversx/mx-chain-scenario-go v1.3.0 github.com/multiversx/mx-chain-storage-go v1.0.14 - github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240122101533-cc1288fd297e - github.com/multiversx/mx-chain-vm-go v1.5.26-0.20240122101933-32a558e14c8a - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20240122121022-c7d274043a74 - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20240122120659-69848278235c - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94-0.20240122102744-2052863f9b5c + github.com/multiversx/mx-chain-vm-common-go v1.5.11 + github.com/multiversx/mx-chain-vm-go v1.5.26 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil v3.21.11+incompatible @@ -91,7 +92,6 @@ require ( github.com/jbenet/goprocess v0.1.4 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.5 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect diff --git a/go.sum b/go.sum index bd49ee1ade1..b7cb342ed43 100644 --- a/go.sum +++ b/go.sum @@ -399,16 +399,16 @@ github.com/multiversx/mx-chain-scenario-go v1.3.0 h1:Vm6jYipJuIcJt8kamgXkePtKkwX github.com/multiversx/mx-chain-scenario-go v1.3.0/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= -github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240122101533-cc1288fd297e h1:MSZgCSYqwsJ6AyD06b4V00vovP/WhFV//d7Oyea9Tu0= -github.com/multiversx/mx-chain-vm-common-go v1.5.11-0.20240122101533-cc1288fd297e/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= -github.com/multiversx/mx-chain-vm-go v1.5.26-0.20240122101933-32a558e14c8a h1:qAFxvzeuEbziggn3UYfuwHV0Vgqoq5SPyPx+58R2mCY= -github.com/multiversx/mx-chain-vm-go v1.5.26-0.20240122101933-32a558e14c8a/go.mod h1:UlKI1NbOnUMIF7pmixIR55S01wrPP8kmeM4CY4iY9Vs= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20240122121022-c7d274043a74 h1:7VZq8W+fD45/H4sH5ldin7dEh1UeQWkGJbaUfez4Nb8= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20240122121022-c7d274043a74/go.mod h1:ty8vCeZ6gRWBc1oM8VT5PKVxS0L/61TxMcQwy2lnAcg= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20240122120659-69848278235c h1:3w80/WeldsyNe5v9tg1dT7ZXiS/iDgJYUtxehg1mhYU= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20240122120659-69848278235c/go.mod h1:FxHEUiZeqTJtnlip5EkSATOCzkKUtE9MYfIpccLpIVQ= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94-0.20240122102744-2052863f9b5c h1:DEPBKTjddfB1ZynBwSwv37oFhGrON6nIOJuXfdxBIDE= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94-0.20240122102744-2052863f9b5c/go.mod h1:vBbwc8dOPgUFLEzWVqS62uDRazYKsBVABrl9SFNu25k= +github.com/multiversx/mx-chain-vm-common-go v1.5.11 h1:rAQR00ALKOmWAuNA8XW8hR02M9gmrAE4WZwyJH4dMMU= +github.com/multiversx/mx-chain-vm-common-go v1.5.11/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= +github.com/multiversx/mx-chain-vm-go v1.5.26 h1:ZjUJTG9cO2h5WNRIZ50ZSZNsTEPqXXPGS9Y/SAGyC2A= +github.com/multiversx/mx-chain-vm-go v1.5.26/go.mod h1:gNZ/s4Z6OHg6ZeBsW6aDxWQduXsRS0Bsv4pfkmHeRzs= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 h1:TxFjQH0dXC/ACQxlIgJbO7pVoh00rcqeKSnIjWTDMxg= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 h1:xgrXfHKa0Za4xjFj5W0FcYEivjrQIhLvGEFXXa1uQZU= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66/go.mod h1:mx6IOAqo7zjSinYd8D2YqlpMWsuqFoYXJ6bntnTOeQg= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 h1:MZFEBjDmfwLGB0cZb/pvlLx+qRv/9tO83bEgHUk34is= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94/go.mod h1:uuSbZGe0UwOWQyHA4EeJWhs8UeDdhtmMwlhNaX9ppx0= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From ebfa3730a44f1a99c867b46dbfd661108f58bd80 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Fri, 26 Jan 2024 11:13:23 +0200 Subject: [PATCH 638/958] add some tests for missing attestation metablocks --- process/block/shardblock_request_test.go | 234 +++++++++++++++++++++++ process/block/shardblock_test.go | 22 +-- 2 files changed, 238 insertions(+), 18 deletions(-) create mode 100644 process/block/shardblock_request_test.go diff --git a/process/block/shardblock_request_test.go b/process/block/shardblock_request_test.go new file mode 100644 index 00000000000..43c05428c8d --- /dev/null +++ b/process/block/shardblock_request_test.go @@ -0,0 +1,234 @@ +package block_test + +import ( + "fmt" + "sync/atomic" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/stretchr/testify/require" + + blproc "github.com/multiversx/mx-chain-go/process/block" + "github.com/multiversx/mx-chain-go/testscommon" + dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" +) + +type headerData struct { + hash []byte + header data.HeaderHandler +} + +type shardBlockTestData struct { + headerData *headerData + confirmationHeaderData *headerData +} + +func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { + t.Parallel() + + t.Run("missing attesting meta header", func(t *testing.T) { + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + numCalls := atomic.Uint32{} + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + attestationNonce := testData[core.MetachainShardId].confirmationHeaderData.header.GetNonce() + if nonce != attestationNonce { + require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) + } + numCalls.Add(1) + } + sp, _ := blproc.NewShardProcessor(arguments) + + metaBlockData := testData[core.MetachainShardId].headerData + // not adding the confirmation metaBlock to the headers pool means it will be missing and requested + sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) + res := sp.RequestMissingFinalityAttestingHeaders() + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(1), res) + require.Equal(t, uint32(1), numCalls.Load()) + }) + t.Run("no missing attesting meta header", func(t *testing.T) { + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + require.Fail(t, "should not request meta header by nonce") + } + sp, _ := blproc.NewShardProcessor(arguments) + + headersDataPool := arguments.DataComponents.Datapool().Headers() + require.NotNil(t, headersDataPool) + metaBlockData := testData[core.MetachainShardId].headerData + confirmationMetaBlockData := testData[core.MetachainShardId].confirmationHeaderData + headersDataPool.AddHeader(confirmationMetaBlockData.hash, confirmationMetaBlockData.header) + sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) + res := sp.RequestMissingFinalityAttestingHeaders() + time.Sleep(100 * time.Millisecond) + require.Equal(t, uint32(0), res) + }) +} + +func TestShardProcessor_computeExistingAndRequestMissingMetaHeaders(t *testing.T) { + +} + +func TestShardProcessor_receivedMetaBlock(t *testing.T) { + +} + +func shardBlockRequestTestInit(t *testing.T) (blproc.ArgShardProcessor, *testscommon.RequestHandlerStub) { + coreComponents, dataComponents, bootstrapComponents, statusComponents := createComponentHolderMocks() + poolMock := dataRetrieverMock.NewPoolsHolderMock() + dataComponents.DataPool = poolMock + arguments := CreateMockArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) + poolsHolderAsInterface := arguments.DataComponents.Datapool() + poolsHolder, ok := poolsHolderAsInterface.(*dataRetrieverMock.PoolsHolderMock) + require.True(t, ok) + + headersPoolStub := createPoolsHolderForHeaderRequests() + poolsHolder.SetHeadersPool(headersPoolStub) + + requestHandler, ok := arguments.ArgBaseProcessor.RequestHandler.(*testscommon.RequestHandlerStub) + require.True(t, ok) + return arguments, requestHandler +} + +func createShardProcessorTestData() map[uint32]*shardBlockTestData { + // shard 0 miniblocks + mbHash1 := []byte("mb hash 1") + mbHash2 := []byte("mb hash 2") + mbHash3 := []byte("mb hash 3") + + // shard 1 miniblocks + mbHash4 := []byte("mb hash 4") + mbHash5 := []byte("mb hash 5") + mbHash6 := []byte("mb hash 6") + + metaBlockHash := []byte("meta block hash") + metaConfirmationHash := []byte("confirmation meta block hash") + + shard0Block0Hash := []byte("shard 0 block 0 hash") + shard0Block1Hash := []byte("shard 0 block 1 hash") + shard0Block2Hash := []byte("shard 0 block 2 hash") + + shard1Block0Hash := []byte("shard 1 block 0 hash") + shard1Block1Hash := []byte("shard 1 block 1 hash") + shard1Block2Hash := []byte("shard 1 block 2 hash") + + metaBlock := &block.MetaBlock{ + Nonce: 100, + Round: 100, + ShardInfo: []block.ShardData{ + { + ShardID: 0, + HeaderHash: shard0Block1Hash, + PrevHash: shard0Block0Hash, + ShardMiniBlockHeaders: []block.MiniBlockHeader{ + {Hash: mbHash1, SenderShardID: 0, ReceiverShardID: 1}, + {Hash: mbHash2, SenderShardID: 0, ReceiverShardID: 1}, + {Hash: mbHash3, SenderShardID: 0, ReceiverShardID: 1}, + }, + }, + { + ShardID: 1, + HeaderHash: shard1Block1Hash, + PrevHash: shard1Block0Hash, + ShardMiniBlockHeaders: []block.MiniBlockHeader{ + {Hash: mbHash4, SenderShardID: 1, ReceiverShardID: 0}, + {Hash: mbHash5, SenderShardID: 1, ReceiverShardID: 0}, + {Hash: mbHash6, SenderShardID: 1, ReceiverShardID: 0}, + }, + }, + }, + } + metaConfirmationBlock := &block.MetaBlock{ + Nonce: 101, + Round: 101, + PrevHash: metaBlockHash, + ShardInfo: []block.ShardData{}, + } + + shard0Block1 := &block.Header{ + ShardID: 0, + PrevHash: shard0Block0Hash, + Nonce: 98, + Round: 98, + MiniBlockHeaders: []block.MiniBlockHeader{ + {Hash: mbHash1, SenderShardID: 0, ReceiverShardID: 1}, + {Hash: mbHash2, SenderShardID: 0, ReceiverShardID: 1}, + {Hash: mbHash3, SenderShardID: 0, ReceiverShardID: 1}, + }, + } + + shard0Block2 := &block.Header{ + ShardID: 0, + PrevHash: shard0Block1Hash, + Nonce: 99, + Round: 99, + MiniBlockHeaders: []block.MiniBlockHeader{}, + } + + shar1Block1 := &block.Header{ + ShardID: 1, + PrevHash: shard1Block0Hash, + Nonce: 98, + Round: 98, + MiniBlockHeaders: []block.MiniBlockHeader{ + {Hash: mbHash4, SenderShardID: 0, ReceiverShardID: 1}, + {Hash: mbHash5, SenderShardID: 0, ReceiverShardID: 1}, + {Hash: mbHash6, SenderShardID: 0, ReceiverShardID: 1}, + }, + } + + shard1Block2 := &block.Header{ + ShardID: 1, + PrevHash: shard1Block1Hash, + Nonce: 99, + Round: 99, + MiniBlockHeaders: []block.MiniBlockHeader{}, + } + + sbd := map[uint32]*shardBlockTestData{ + 0: { + headerData: &headerData{ + hash: shard0Block1Hash, + header: shard0Block1, + }, + confirmationHeaderData: &headerData{ + hash: shard0Block2Hash, + header: shard0Block2, + }, + }, + 1: { + headerData: &headerData{ + hash: shard1Block1Hash, + header: shar1Block1, + }, + confirmationHeaderData: &headerData{ + hash: shard1Block2Hash, + header: shard1Block2, + }, + }, + core.MetachainShardId: { + headerData: &headerData{ + hash: metaBlockHash, + header: metaBlock, + }, + confirmationHeaderData: &headerData{ + hash: metaConfirmationHash, + header: metaConfirmationBlock, + }, + }, + } + + return sbd +} diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index ff1e1e3e10f..c6a45381e55 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -22,6 +22,10 @@ import ( "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" @@ -45,9 +49,6 @@ import ( stateMock "github.com/multiversx/mx-chain-go/testscommon/state" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" storageStubs "github.com/multiversx/mx-chain-go/testscommon/storage" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const MaxGasLimitPerBlock = uint64(100000) @@ -1677,21 +1678,6 @@ func TestShardProcessor_CheckAndRequestIfMetaHeadersMissingShouldErr(t *testing. assert.Equal(t, err, process.ErrTimeIsOut) } -// -------- requestMissingFinalityAttestingHeaders -func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { - t.Parallel() - - tdp := dataRetrieverMock.NewPoolsHolderMock() - coreComponents, dataComponents, bootstrapComponents, statusComponents := createComponentHolderMocks() - dataComponents.DataPool = tdp - arguments := CreateMockArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) - sp, _ := blproc.NewShardProcessor(arguments) - - sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, 1) - res := sp.RequestMissingFinalityAttestingHeaders() - assert.Equal(t, res > 0, true) -} - // --------- verifyIncludedMetaBlocksFinality func TestShardProcessor_CheckMetaHeadersValidityAndFinalityShouldPass(t *testing.T) { t.Parallel() From 26f2e33ffd178fe2590202da12f3e40a3daecc20 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 26 Jan 2024 12:51:37 +0200 Subject: [PATCH 639/958] fix tx cost api route --- facade/interface.go | 3 ++- .../processing/txSimulatorProcessComponents.go | 5 +++++ process/mock/transactionSimulatorStub.go | 7 ++++--- .../transactionEvaluator/transactionEvaluator.go | 14 ++++++++++++-- .../transactionEvaluator_test.go | 16 +++++++++------- .../transactionEvaluator/transactionSimulator.go | 11 ++++++++++- .../transactionSimulator_test.go | 7 ++++--- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/facade/interface.go b/facade/interface.go index 4c782e6a574..8ef83d774d1 100644 --- a/facade/interface.go +++ b/facade/interface.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/multiversx/mx-chain-core-go/core" + coreData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/alteredAccount" "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-core-go/data/esdt" @@ -106,7 +107,7 @@ type NodeHandler interface { // TransactionSimulatorProcessor defines the actions which a transaction simulator processor has to implement type TransactionSimulatorProcessor interface { - ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) + ProcessTx(tx *transaction.Transaction, currentHeader coreData.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) IsInterfaceNil() bool } diff --git a/factory/processing/txSimulatorProcessComponents.go b/factory/processing/txSimulatorProcessComponents.go index 2a5e8c5a7a2..257a46af1a5 100644 --- a/factory/processing/txSimulatorProcessComponents.go +++ b/factory/processing/txSimulatorProcessComponents.go @@ -79,6 +79,7 @@ func (pcf *processComponentsFactory) createAPITransactionEvaluator() (factory.Tr Accounts: simulationAccountsDB, ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), + BlockChain: pcf.data.Blockchain(), }) return apiTransactionEvaluator, vmContainerFactory, err @@ -141,6 +142,8 @@ func (pcf *processComponentsFactory) createArgsTxSimulatorProcessorForMeta( return args, nil, nil, err } + args.BlockChainHook = vmContainerFactory.BlockChainHookImpl() + vmContainer, err := vmContainerFactory.Create() if err != nil { return args, nil, nil, err @@ -301,6 +304,8 @@ func (pcf *processComponentsFactory) createArgsTxSimulatorProcessorShard( return args, nil, nil, err } + args.BlockChainHook = vmContainerFactory.BlockChainHookImpl() + err = builtInFuncFactory.SetPayableHandler(vmContainerFactory.BlockChainHookImpl()) if err != nil { return args, nil, nil, err diff --git a/process/mock/transactionSimulatorStub.go b/process/mock/transactionSimulatorStub.go index 70363230936..971cda66d04 100644 --- a/process/mock/transactionSimulatorStub.go +++ b/process/mock/transactionSimulatorStub.go @@ -1,19 +1,20 @@ package mock import ( + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/transaction" txSimData "github.com/multiversx/mx-chain-go/process/transactionEvaluator/data" ) // TransactionSimulatorStub - type TransactionSimulatorStub struct { - ProcessTxCalled func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) + ProcessTxCalled func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) } // ProcessTx - -func (tss *TransactionSimulatorStub) ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { +func (tss *TransactionSimulatorStub) ProcessTx(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { if tss.ProcessTxCalled != nil { - return tss.ProcessTxCalled(tx) + return tss.ProcessTxCalled(tx, currentHeader) } return nil, nil diff --git a/process/transactionEvaluator/transactionEvaluator.go b/process/transactionEvaluator/transactionEvaluator.go index b9184ae3fad..56077c0a498 100644 --- a/process/transactionEvaluator/transactionEvaluator.go +++ b/process/transactionEvaluator/transactionEvaluator.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/facade" @@ -32,6 +33,7 @@ type ArgsApiTransactionEvaluator struct { Accounts state.AccountsAdapterWithClean ShardCoordinator sharding.Coordinator EnableEpochsHandler common.EnableEpochsHandler + BlockChain data.ChainHandler } type apiTransactionEvaluator struct { @@ -41,6 +43,7 @@ type apiTransactionEvaluator struct { feeHandler process.FeeHandler txSimulator facade.TransactionSimulatorProcessor enableEpochsHandler common.EnableEpochsHandler + blockChain data.ChainHandler mutExecution sync.RWMutex } @@ -64,6 +67,9 @@ func NewAPITransactionEvaluator(args ArgsApiTransactionEvaluator) (*apiTransacti if check.IfNil(args.EnableEpochsHandler) { return nil, process.ErrNilEnableEpochsHandler } + if check.IfNil(args.BlockChain) { + return nil, process.ErrNilBlockChain + } err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ common.CleanUpInformativeSCRsFlag, }) @@ -78,6 +84,7 @@ func NewAPITransactionEvaluator(args ArgsApiTransactionEvaluator) (*apiTransacti accounts: args.Accounts, shardCoordinator: args.ShardCoordinator, enableEpochsHandler: args.EnableEpochsHandler, + blockChain: args.BlockChain, } return tce, nil @@ -91,7 +98,9 @@ func (ate *apiTransactionEvaluator) SimulateTransactionExecution(tx *transaction ate.mutExecution.Unlock() }() - return ate.txSimulator.ProcessTx(tx) + currentHeader := ate.blockChain.GetCurrentBlockHeader() + + return ate.txSimulator.ProcessTx(tx, currentHeader) } // ComputeTransactionGasLimit will calculate how many gas units a transaction will consume @@ -140,8 +149,9 @@ func (ate *apiTransactionEvaluator) simulateTransactionCost(tx *transaction.Tran } costResponse := &transaction.CostResponse{} + currentHeader := ate.blockChain.GetCurrentBlockHeader() - res, err := ate.txSimulator.ProcessTx(tx) + res, err := ate.txSimulator.ProcessTx(tx, currentHeader) if err != nil { costResponse.ReturnMessage = err.Error() return costResponse, nil diff --git a/process/transactionEvaluator/transactionEvaluator_test.go b/process/transactionEvaluator/transactionEvaluator_test.go index 586072856ac..29cf754ea73 100644 --- a/process/transactionEvaluator/transactionEvaluator_test.go +++ b/process/transactionEvaluator/transactionEvaluator_test.go @@ -30,6 +30,7 @@ func createArgs() ArgsApiTransactionEvaluator { Accounts: &stateMock.AccountsStub{}, ShardCoordinator: &mock.ShardCoordinatorStub{}, EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + BlockChain: &testscommon.ChainHandlerMock{}, } } @@ -115,7 +116,7 @@ func TestComputeTransactionGasLimit_MoveBalance(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{}, nil }, } @@ -154,7 +155,7 @@ func TestComputeTransactionGasLimit_MoveBalanceInvalidNonceShouldStillComputeCos }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return nil, simulationErr }, } @@ -185,7 +186,7 @@ func TestComputeTransactionGasLimit_BuiltInFunction(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{ VMOutput: &vmcommon.VMOutput{ ReturnCode: vmcommon.Ok, @@ -221,7 +222,7 @@ func TestComputeTransactionGasLimit_BuiltInFunctionShouldErr(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return nil, localErr }, } @@ -251,7 +252,7 @@ func TestComputeTransactionGasLimit_NilVMOutput(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{}, nil }, } @@ -260,7 +261,8 @@ func TestComputeTransactionGasLimit_NilVMOutput(t *testing.T) { return &stateMock.UserAccountStub{Balance: big.NewInt(100000)}, nil }, } - tce, _ := NewAPITransactionEvaluator(args) + tce, err := NewAPITransactionEvaluator(args) + require.Nil(t, err) tx := &transaction.Transaction{} cost, err := tce.ComputeTransactionGasLimit(tx) @@ -281,7 +283,7 @@ func TestComputeTransactionGasLimit_RetCodeNotOk(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, _ data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{ VMOutput: &vmcommon.VMOutput{ ReturnCode: vmcommon.UserError, diff --git a/process/transactionEvaluator/transactionSimulator.go b/process/transactionEvaluator/transactionSimulator.go index 8d1a405643d..c87e79b0472 100644 --- a/process/transactionEvaluator/transactionSimulator.go +++ b/process/transactionEvaluator/transactionSimulator.go @@ -6,6 +6,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/receipt" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" @@ -33,6 +34,7 @@ type ArgsTxSimulator struct { Hasher hashing.Hasher Marshalizer marshal.Marshalizer DataFieldParser DataFieldParser + BlockChainHook process.BlockChainHookHandler } type refundHandler interface { @@ -50,6 +52,7 @@ type transactionSimulator struct { marshalizer marshal.Marshalizer refundDetector refundHandler dataFieldParser DataFieldParser + blockChainHook process.BlockChainHookHandler } // NewTransactionSimulator returns a new instance of a transactionSimulator @@ -78,6 +81,9 @@ func NewTransactionSimulator(args ArgsTxSimulator) (*transactionSimulator, error if check.IfNilReflect(args.DataFieldParser) { return nil, ErrNilDataFieldParser } + if check.IfNil(args.BlockChainHook) { + return nil, process.ErrNilBlockChainHook + } return &transactionSimulator{ txProcessor: args.TransactionProcessor, @@ -89,17 +95,20 @@ func NewTransactionSimulator(args ArgsTxSimulator) (*transactionSimulator, error hasher: args.Hasher, refundDetector: transactionAPI.NewRefundDetector(), dataFieldParser: args.DataFieldParser, + blockChainHook: args.BlockChainHook, }, nil } // ProcessTx will process the transaction in a special environment, where state-writing is not allowed -func (ts *transactionSimulator) ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { +func (ts *transactionSimulator) ProcessTx(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { ts.mutOperation.Lock() defer ts.mutOperation.Unlock() txStatus := transaction.TxStatusPending failReason := "" + ts.blockChainHook.SetCurrentHeader(currentHeader) + retCode, err := ts.txProcessor.ProcessTransaction(tx) if err != nil { failReason = err.Error() diff --git a/process/transactionEvaluator/transactionSimulator_test.go b/process/transactionEvaluator/transactionSimulator_test.go index 727f158c7eb..ad477c25640 100644 --- a/process/transactionEvaluator/transactionSimulator_test.go +++ b/process/transactionEvaluator/transactionSimulator_test.go @@ -125,7 +125,7 @@ func TestTransactionSimulator_ProcessTxProcessingErrShouldSignal(t *testing.T) { } ts, _ := NewTransactionSimulator(args) - results, err := ts.ProcessTx(&transaction.Transaction{Nonce: 37}) + results, err := ts.ProcessTx(&transaction.Transaction{Nonce: 37}, &block.Header{}) require.NoError(t, err) require.Equal(t, expErr.Error(), results.FailReason) } @@ -207,7 +207,7 @@ func TestTransactionSimulator_ProcessTxShouldIncludeScrsAndReceipts(t *testing.T txHash, _ := core.CalculateHash(args.Marshalizer, args.Hasher, tx) args.VMOutputCacher.Put(txHash, &vmcommon.VMOutput{}, 0) - results, err := ts.ProcessTx(tx) + results, err := ts.ProcessTx(tx, &block.Header{}) require.NoError(t, err) require.Equal( t, @@ -236,6 +236,7 @@ func getTxSimulatorArgs() ArgsTxSimulator { Marshalizer: &mock.MarshalizerMock{}, Hasher: &hashingMocks.HasherMock{}, DataFieldParser: dataFieldParser, + BlockChainHook: &testscommon.BlockChainHookStub{}, } } @@ -261,7 +262,7 @@ func TestTransactionSimulator_ProcessTxConcurrentCalls(t *testing.T) { for i := 0; i < numCalls; i++ { go func(idx int) { time.Sleep(time.Millisecond * 10) - _, _ = txSimulator.ProcessTx(tx) + _, _ = txSimulator.ProcessTx(tx, &block.Header{}) wg.Done() }(i) } From c90f3b954be72692df895a0d6acfd0f2fc6961f9 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 26 Jan 2024 13:12:32 +0200 Subject: [PATCH 640/958] fix tests --- integrationTests/testProcessorNodeWithTestWebServer.go | 2 ++ integrationTests/vm/testInitializer.go | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/integrationTests/testProcessorNodeWithTestWebServer.go b/integrationTests/testProcessorNodeWithTestWebServer.go index f1a11c9d72a..4f5a007d683 100644 --- a/integrationTests/testProcessorNodeWithTestWebServer.go +++ b/integrationTests/testProcessorNodeWithTestWebServer.go @@ -179,6 +179,7 @@ func createFacadeComponents(tpn *TestProcessorNode) nodeFacade.ApiResolver { Hasher: TestHasher, VMOutputCacher: &testscommon.CacherMock{}, DataFieldParser: dataFieldParser, + BlockChainHook: tpn.BlockchainHook, } txSimulator, err := transactionEvaluator.NewTransactionSimulator(argSimulator) @@ -194,6 +195,7 @@ func createFacadeComponents(tpn *TestProcessorNode) nodeFacade.ApiResolver { Accounts: wrappedAccounts, ShardCoordinator: tpn.ShardCoordinator, EnableEpochsHandler: tpn.EnableEpochsHandler, + BlockChain: tpn.BlockChain, } apiTransactionEvaluator, err := transactionEvaluator.NewAPITransactionEvaluator(argsTransactionEvaluator) log.LogIfError(err) diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 0c9fa15b273..5230a14c841 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -818,6 +818,7 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( epochNotifierInstance process.EpochNotifier, guardianChecker process.GuardianChecker, roundNotifierInstance process.RoundNotifier, + chainHandler data.ChainHandler, ) (*ResultsCreateTxProcessor, error) { if check.IfNil(poolsHolder) { poolsHolder = dataRetrieverMock.NewPoolsHolderMock() @@ -980,6 +981,7 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( Marshalizer: integrationtests.TestMarshalizer, Hasher: integrationtests.TestHasher, DataFieldParser: dataFieldParser, + BlockChainHook: blockChainHook, } argsNewSCProcessor.VMOutputCacher = txSimulatorProcessorArgs.VMOutputCacher @@ -1006,6 +1008,7 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( Accounts: simulationAccountsDB, ShardCoordinator: shardCoordinator, EnableEpochsHandler: argsNewSCProcessor.EnableEpochsHandler, + BlockChain: chainHandler, } apiTransactionEvaluator, err := transactionEvaluator.NewAPITransactionEvaluator(argsTransactionEvaluator) if err != nil { @@ -1128,6 +1131,7 @@ func CreatePreparedTxProcessorAndAccountsWithVMsWithRoundsConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1279,6 +1283,7 @@ func CreatePreparedTxProcessorWithVMConfigWithShardCoordinatorDBAndGasAndRoundCo epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1374,6 +1379,7 @@ func CreateTxProcessorArwenVMWithGasScheduleAndRoundConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1455,6 +1461,7 @@ func CreateTxProcessorArwenWithVMConfigAndRoundConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1885,6 +1892,7 @@ func CreatePreparedTxProcessorWithVMsMultiShardRoundVMConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err From 438febe2c59aef84bcf1774d5ff94243c80877d0 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 26 Jan 2024 14:43:14 +0200 Subject: [PATCH 641/958] unit tests --- .../transactionEvaluator_test.go | 70 +++++++++++++++++++ .../transactionSimulator_test.go | 9 +++ 2 files changed, 79 insertions(+) diff --git a/process/transactionEvaluator/transactionEvaluator_test.go b/process/transactionEvaluator/transactionEvaluator_test.go index 29cf754ea73..ea8f01049b7 100644 --- a/process/transactionEvaluator/transactionEvaluator_test.go +++ b/process/transactionEvaluator/transactionEvaluator_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/mock" @@ -44,6 +45,16 @@ func TestTransactionEvaluator_NilTxTypeHandler(t *testing.T) { require.Equal(t, process.ErrNilTxTypeHandler, err) } +func TestTransactionEvaluator_NilBlockChain(t *testing.T) { + t.Parallel() + args := createArgs() + args.BlockChain = nil + tce, err := NewAPITransactionEvaluator(args) + + require.Nil(t, tce) + require.Equal(t, process.ErrNilBlockChain, err) +} + func TestTransactionEvaluator_NilFeeHandlerShouldErr(t *testing.T) { t.Parallel() @@ -337,3 +348,62 @@ func TestExtractGasUsedFromMessage(t *testing.T) { require.Equal(t, uint64(0), extractGasRemainedFromMessage("", gasRemainedSplitString)) require.Equal(t, uint64(0), extractGasRemainedFromMessage("too much gas provided, gas needed = 10000, gas used = wrong", gasUsedSlitString)) } + +func TestApiTransactionEvaluator_SimulateTransactionExecution(t *testing.T) { + t.Parallel() + + called := false + expectedNonce := uint64(1000) + args := createArgs() + args.BlockChain = &testscommon.ChainHandlerMock{} + _ = args.BlockChain.SetCurrentBlockHeaderAndRootHash(&block.Header{Nonce: expectedNonce}, []byte("test")) + + args.TxSimulator = &mock.TransactionSimulatorStub{ + ProcessTxCalled: func(_ *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { + called = true + require.Equal(t, expectedNonce, currentHeader.GetNonce()) + return nil, nil + }, + } + + tce, err := NewAPITransactionEvaluator(args) + require.Nil(t, err) + + tx := &transaction.Transaction{} + + _, err = tce.SimulateTransactionExecution(tx) + require.Nil(t, err) + require.True(t, called) +} + +func TestApiTransactionEvaluator_ComputeTransactionGasLimit(t *testing.T) { + t.Parallel() + + called := false + expectedNonce := uint64(1000) + args := createArgs() + args.BlockChain = &testscommon.ChainHandlerMock{} + _ = args.BlockChain.SetCurrentBlockHeaderAndRootHash(&block.Header{Nonce: expectedNonce}, []byte("test")) + + args.TxTypeHandler = &testscommon.TxTypeHandlerMock{ + ComputeTransactionTypeCalled: func(tx data.TransactionHandler) (process.TransactionType, process.TransactionType) { + return process.SCInvoking, process.SCInvoking + }, + } + args.TxSimulator = &mock.TransactionSimulatorStub{ + ProcessTxCalled: func(_ *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { + called = true + require.Equal(t, expectedNonce, currentHeader.GetNonce()) + return &txSimData.SimulationResultsWithVMOutput{}, nil + }, + } + + tce, err := NewAPITransactionEvaluator(args) + require.Nil(t, err) + + tx := &transaction.Transaction{} + + _, err = tce.ComputeTransactionGasLimit(tx) + require.Nil(t, err) + require.True(t, called) +} diff --git a/process/transactionEvaluator/transactionSimulator_test.go b/process/transactionEvaluator/transactionSimulator_test.go index ad477c25640..94da76f4254 100644 --- a/process/transactionEvaluator/transactionSimulator_test.go +++ b/process/transactionEvaluator/transactionSimulator_test.go @@ -76,6 +76,15 @@ func TestNewTransactionSimulator(t *testing.T) { }, exError: ErrNilHasher, }, + { + name: "NilBlockChainHook", + argsFunc: func() ArgsTxSimulator { + args := getTxSimulatorArgs() + args.BlockChainHook = nil + return args + }, + exError: process.ErrNilBlockChainHook, + }, { name: "NilMarshalizer", argsFunc: func() ArgsTxSimulator { From 335d51ed4ef89b18529efbaf257c996e3fad00d1 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Fri, 26 Jan 2024 16:10:03 +0200 Subject: [PATCH 642/958] add tests --- process/block/export_test.go | 4 ++ process/block/metablock_request_test.go | 21 ++++--- process/block/shardblock_request_test.go | 72 ++++++++++++++++++------ 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/process/block/export_test.go b/process/block/export_test.go index 917b52ba80c..81bb023431b 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -578,6 +578,10 @@ func (mp *metaProcessor) ComputeExistingAndRequestMissingShardHeaders(metaBlock return mp.computeExistingAndRequestMissingShardHeaders(metaBlock) } +func (sp *shardProcessor) ComputeExistingAndRequestMissingMetaHeaders(header data.ShardHeaderHandler) (uint32, uint32) { + return sp.computeExistingAndRequestMissingMetaHeaders(header) +} + // InitMaps - func (hfb *hdrForBlock) InitMaps() { hfb.initMaps() diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go index 406c2b9d001..1764817d3c5 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablock_request_test.go @@ -280,13 +280,14 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { hdrsForBlock := mp.GetHdrForBlock() hdrsForBlock.SetNumMissingHdrs(2) hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) - hdrsForBlock.SetHighestHdrNonce(0, td[1].referencedHeaderData.header.GetNonce()-1) - hdrsForBlock.SetHdrHashAndInfo(string(td[1].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ + referencedHeaderData := td[1].referencedHeaderData + hdrsForBlock.SetHighestHdrNonce(0, referencedHeaderData.header.GetNonce()-1) + hdrsForBlock.SetHdrHashAndInfo(string(referencedHeaderData.headerHash), &blockProcess.HdrInfo{ UsedInBlock: true, Hdr: nil, }) - mp.ReceivedShardHeader(td[1].referencedHeaderData.header, td[1].referencedHeaderData.headerHash) + mp.ReceivedShardHeader(referencedHeaderData.header, referencedHeaderData.headerHash) time.Sleep(100 * time.Millisecond) require.Nil(t, err) @@ -326,16 +327,17 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { hdrsForBlock := mp.GetHdrForBlock() hdrsForBlock.SetNumMissingHdrs(1) hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) - hdrsForBlock.SetHighestHdrNonce(0, td[0].referencedHeaderData.header.GetNonce()-1) - hdrsForBlock.SetHdrHashAndInfo(string(td[0].referencedHeaderData.headerHash), &blockProcess.HdrInfo{ + referencedHeaderData := td[0].attestationHeaderData + hdrsForBlock.SetHighestHdrNonce(0, referencedHeaderData.header.GetNonce()-1) + hdrsForBlock.SetHdrHashAndInfo(string(referencedHeaderData.headerHash), &blockProcess.HdrInfo{ UsedInBlock: true, Hdr: nil, }) // receive the missing header headersPool := mp.GetDataPool().Headers() - headersPool.AddHeader(td[0].referencedHeaderData.headerHash, td[0].referencedHeaderData.header) - mp.ReceivedShardHeader(td[0].referencedHeaderData.header, td[0].referencedHeaderData.headerHash) + headersPool.AddHeader(referencedHeaderData.headerHash, referencedHeaderData.header) + mp.ReceivedShardHeader(td[0].referencedHeaderData.header, referencedHeaderData.headerHash) time.Sleep(100 * time.Millisecond) require.Nil(t, err) @@ -354,8 +356,9 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { }(wg) // receive also the attestation header - headersPool.AddHeader(td[0].attestationHeaderData.headerHash, td[0].attestationHeaderData.header) - mp.ReceivedShardHeader(td[0].attestationHeaderData.header, td[0].attestationHeaderData.headerHash) + attestationHeaderData := td[0].attestationHeaderData + headersPool.AddHeader(attestationHeaderData.headerHash, attestationHeaderData.header) + mp.ReceivedShardHeader(attestationHeaderData.header, attestationHeaderData.headerHash) wg.Wait() require.Equal(t, uint32(1), numCalls.Load()) diff --git a/process/block/shardblock_request_test.go b/process/block/shardblock_request_test.go index 43c05428c8d..f00ef79b23a 100644 --- a/process/block/shardblock_request_test.go +++ b/process/block/shardblock_request_test.go @@ -30,6 +30,8 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { t.Parallel() t.Run("missing attesting meta header", func(t *testing.T) { + t.Parallel() + arguments, requestHandler := shardBlockRequestTestInit(t) testData := createShardProcessorTestData() numCalls := atomic.Uint32{} @@ -55,6 +57,8 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { require.Equal(t, uint32(1), numCalls.Load()) }) t.Run("no missing attesting meta header", func(t *testing.T) { + t.Parallel() + arguments, requestHandler := shardBlockRequestTestInit(t) testData := createShardProcessorTestData() requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { @@ -73,15 +77,59 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) res := sp.RequestMissingFinalityAttestingHeaders() time.Sleep(100 * time.Millisecond) + require.Equal(t, uint32(0), res) }) } func TestShardProcessor_computeExistingAndRequestMissingMetaHeaders(t *testing.T) { + t.Parallel() + + t.Run("one referenced metaBlock missing will be requested", func(t *testing.T) { + t.Parallel() + + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + numCalls := atomic.Uint32{} + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + attestationNonce := testData[core.MetachainShardId].confirmationHeaderData.header.GetNonce() + if nonce == attestationNonce { + require.Fail(t, fmt.Sprintf("should not request attestation block with nonce %d", attestationNonce)) + } + referencedMetaBlockNonce := testData[core.MetachainShardId].headerData.header.GetNonce() + if nonce != referencedMetaBlockNonce { + require.Fail(t, fmt.Sprintf("requested nonce should have been %d", referencedMetaBlockNonce)) + } + numCalls.Add(1) + } + sp, _ := blproc.NewShardProcessor(arguments) + metaBlockData := testData[core.MetachainShardId].headerData + // not adding the referenced metaBlock to the headers pool means it will be missing and requested + sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) + + // sp.ComputeExistingAndRequestMissingMetaHeaders() + + }) + t.Run("multiple referenced metaBlocks missing will be requested", func(t *testing.T) { + t.Parallel() + + }) + t.Run("all referenced metaBlocks existing with missing attestation, will request the attestation metaBlock", func(t *testing.T) { + t.Parallel() + + }) + t.Run("all referenced metaBlocks existing and existing attestation metaBlock will not request", func(t *testing.T) { + t.Parallel() + + }) } func TestShardProcessor_receivedMetaBlock(t *testing.T) { + t.Parallel() } @@ -113,6 +161,7 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { mbHash5 := []byte("mb hash 5") mbHash6 := []byte("mb hash 6") + prevMetaBlockHash := []byte("prev meta block hash") metaBlockHash := []byte("meta block hash") metaConfirmationHash := []byte("confirmation meta block hash") @@ -125,8 +174,9 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { shard1Block2Hash := []byte("shard 1 block 2 hash") metaBlock := &block.MetaBlock{ - Nonce: 100, - Round: 100, + Nonce: 100, + Round: 100, + PrevHash: prevMetaBlockHash, ShardInfo: []block.ShardData{ { ShardID: 0, @@ -138,16 +188,6 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { {Hash: mbHash3, SenderShardID: 0, ReceiverShardID: 1}, }, }, - { - ShardID: 1, - HeaderHash: shard1Block1Hash, - PrevHash: shard1Block0Hash, - ShardMiniBlockHeaders: []block.MiniBlockHeader{ - {Hash: mbHash4, SenderShardID: 1, ReceiverShardID: 0}, - {Hash: mbHash5, SenderShardID: 1, ReceiverShardID: 0}, - {Hash: mbHash6, SenderShardID: 1, ReceiverShardID: 0}, - }, - }, }, } metaConfirmationBlock := &block.MetaBlock{ @@ -180,8 +220,8 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { shar1Block1 := &block.Header{ ShardID: 1, PrevHash: shard1Block0Hash, - Nonce: 98, - Round: 98, + Nonce: 102, + Round: 102, MiniBlockHeaders: []block.MiniBlockHeader{ {Hash: mbHash4, SenderShardID: 0, ReceiverShardID: 1}, {Hash: mbHash5, SenderShardID: 0, ReceiverShardID: 1}, @@ -192,8 +232,8 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { shard1Block2 := &block.Header{ ShardID: 1, PrevHash: shard1Block1Hash, - Nonce: 99, - Round: 99, + Nonce: 103, + Round: 103, MiniBlockHeaders: []block.MiniBlockHeader{}, } From 591433d2d23c13ca559d51ed9168105ec18211d8 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Sat, 27 Jan 2024 00:22:32 +0200 Subject: [PATCH 643/958] - fixed the multikey backup step-in --- consensus/spos/bls/subroundEndRound.go | 27 +------- process/block/baseProcess.go | 9 ++- process/block/baseProcess_test.go | 8 ++- process/block/metablock_test.go | 1 + process/block/shardblock_test.go | 2 +- process/headerCheck/common.go | 24 +++++++ process/headerCheck/common_test.go | 92 ++++++++++++++++++++++++++ 7 files changed, 133 insertions(+), 30 deletions(-) diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index 3171f806077..21675715f39 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -15,6 +15,7 @@ import ( "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/consensus/spos" "github.com/multiversx/mx-chain-go/p2p" + "github.com/multiversx/mx-chain-go/process/headerCheck" ) type subroundEndRound struct { @@ -861,33 +862,9 @@ func (sr *subroundEndRound) doEndRoundConsensusCheck() bool { return false } -// computeSignersPublicKeys will extract from the provided consensus group slice only the strings that matched with the bitmap -func computeSignersPublicKeys(consensusGroup []string, bitmap []byte) []string { - nbBitsBitmap := len(bitmap) * 8 - consensusGroupSize := len(consensusGroup) - size := consensusGroupSize - if consensusGroupSize > nbBitsBitmap { - size = nbBitsBitmap - } - - result := make([]string, 0, len(consensusGroup)) - - for i := 0; i < size; i++ { - indexRequired := (bitmap[i/8] & (1 << uint16(i%8))) > 0 - if !indexRequired { - continue - } - - pubKey := consensusGroup[i] - result = append(result, pubKey) - } - - return result -} - func (sr *subroundEndRound) checkSignaturesValidity(bitmap []byte) error { consensusGroup := sr.ConsensusGroup() - signers := computeSignersPublicKeys(consensusGroup, bitmap) + signers := headerCheck.ComputeSignersPublicKeys(consensusGroup, bitmap) for _, pubKey := range signers { isSigJobDone, err := sr.JobDone(pubKey, SrSignature) if err != nil { diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index c51d7510110..fbe3da11832 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -2122,8 +2122,15 @@ func (bp *baseProcessor) checkSentSignaturesAtCommitTime(header data.HeaderHandl return err } + consensusGroup := make([]string, 0, len(validatorsGroup)) for _, validator := range validatorsGroup { - bp.sentSignaturesTracker.ResetCountersForManagedBlockSigner(validator.PubKey()) + consensusGroup = append(consensusGroup, string(validator.PubKey())) + } + + signers := headerCheck.ComputeSignersPublicKeys(consensusGroup, header.GetPubKeysBitmap()) + + for _, signer := range signers { + bp.sentSignaturesTracker.ResetCountersForManagedBlockSigner([]byte(signer)) } return nil diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 71737a1b2e4..2921d29caaa 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -3153,7 +3153,7 @@ func TestBaseProcessor_CheckSentSignaturesAtCommitTime(t *testing.T) { err := bp.CheckSentSignaturesAtCommitTime(&block.Header{}) assert.Equal(t, expectedErr, err) }) - t.Run("should work", func(t *testing.T) { + t.Run("should work with bitmap", func(t *testing.T) { validator0, _ := nodesCoordinator.NewValidator([]byte("pk0"), 0, 0) validator1, _ := nodesCoordinator.NewValidator([]byte("pk1"), 1, 1) validator2, _ := nodesCoordinator.NewValidator([]byte("pk2"), 2, 2) @@ -3173,9 +3173,11 @@ func TestBaseProcessor_CheckSentSignaturesAtCommitTime(t *testing.T) { arguments.NodesCoordinator = nodesCoordinatorInstance bp, _ := blproc.NewShardProcessor(arguments) - err := bp.CheckSentSignaturesAtCommitTime(&block.Header{}) + err := bp.CheckSentSignaturesAtCommitTime(&block.Header{ + PubKeysBitmap: []byte{0b00000101}, + }) assert.Nil(t, err) - assert.Equal(t, [][]byte{validator0.PubKey(), validator1.PubKey(), validator2.PubKey()}, resetCountersCalled) + assert.Equal(t, [][]byte{validator0.PubKey(), validator2.PubKey()}, resetCountersCalled) }) } diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index e06611c10f8..30051e3d582 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -991,6 +991,7 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { mdp := initDataPool([]byte("tx_hash")) rootHash := []byte("rootHash") hdr := createMetaBlockHeader() + hdr.PubKeysBitmap = []byte{0b11111111} body := &block.Body{} accounts := &stateMock.AccountsStub{ CommitCalled: func() (i []byte, e error) { diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index 1c967862542..1a2e2865266 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -2048,7 +2048,7 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { hdr := &block.Header{ Nonce: 1, Round: 1, - PubKeysBitmap: rootHash, + PubKeysBitmap: []byte{0b11111111}, PrevHash: hdrHash, Signature: rootHash, RootHash: rootHash, diff --git a/process/headerCheck/common.go b/process/headerCheck/common.go index b25e12c0833..01946580d87 100644 --- a/process/headerCheck/common.go +++ b/process/headerCheck/common.go @@ -26,3 +26,27 @@ func ComputeConsensusGroup(header data.HeaderHandler, nodesCoordinator nodesCoor return nodesCoordinator.ComputeConsensusGroup(prevRandSeed, header.GetRound(), header.GetShardID(), epoch) } + +// ComputeSignersPublicKeys will extract from the provided consensus group slice only the strings that matched with the bitmap +func ComputeSignersPublicKeys(consensusGroup []string, bitmap []byte) []string { + nbBitsBitmap := len(bitmap) * 8 + consensusGroupSize := len(consensusGroup) + size := consensusGroupSize + if consensusGroupSize > nbBitsBitmap { + size = nbBitsBitmap + } + + result := make([]string, 0, len(consensusGroup)) + + for i := 0; i < size; i++ { + indexRequired := (bitmap[i/8] & (1 << uint16(i%8))) > 0 + if !indexRequired { + continue + } + + pubKey := consensusGroup[i] + result = append(result, pubKey) + } + + return result +} diff --git a/process/headerCheck/common_test.go b/process/headerCheck/common_test.go index 3833a7b2d60..0961b7f2a20 100644 --- a/process/headerCheck/common_test.go +++ b/process/headerCheck/common_test.go @@ -1,6 +1,7 @@ package headerCheck import ( + "fmt" "testing" "github.com/multiversx/mx-chain-core-go/data/block" @@ -93,3 +94,94 @@ func TestComputeConsensusGroup(t *testing.T) { assert.Equal(t, validatorGroup, vGroup) }) } + +func generatePubKeys(num int) []string { + consensusGroup := make([]string, 0, num) + for i := 0; i < num; i++ { + consensusGroup = append(consensusGroup, fmt.Sprintf("pub key %d", i)) + } + + return consensusGroup +} + +func TestComputeSignersPublicKeys(t *testing.T) { + t.Parallel() + + t.Run("should compute with 16 validators", func(t *testing.T) { + t.Parallel() + + consensusGroup := generatePubKeys(16) + mask0 := byte(0b00110101) + mask1 := byte(0b01001101) + + result := ComputeSignersPublicKeys(consensusGroup, []byte{mask0, mask1}) + expected := []string{ + "pub key 0", + "pub key 2", + "pub key 4", + "pub key 5", + + "pub key 8", + "pub key 10", + "pub key 11", + "pub key 14", + } + + assert.Equal(t, expected, result) + }) + t.Run("should compute with 14 validators", func(t *testing.T) { + t.Parallel() + + consensusGroup := generatePubKeys(14) + mask0 := byte(0b00110101) + mask1 := byte(0b00001101) + + result := ComputeSignersPublicKeys(consensusGroup, []byte{mask0, mask1}) + expected := []string{ + "pub key 0", + "pub key 2", + "pub key 4", + "pub key 5", + + "pub key 8", + "pub key 10", + "pub key 11", + } + + assert.Equal(t, expected, result) + }) + t.Run("should compute with 14 validators, mask is 0", func(t *testing.T) { + t.Parallel() + + consensusGroup := generatePubKeys(14) + mask0 := byte(0b00000000) + mask1 := byte(0b00000000) + + result := ComputeSignersPublicKeys(consensusGroup, []byte{mask0, mask1}) + expected := make([]string, 0) + + assert.Equal(t, expected, result) + }) + t.Run("should compute with 14 validators, mask contains all bits set", func(t *testing.T) { + t.Parallel() + + consensusGroup := generatePubKeys(14) + mask0 := byte(0b11111111) + mask1 := byte(0b00111111) + + result := ComputeSignersPublicKeys(consensusGroup, []byte{mask0, mask1}) + + assert.Equal(t, consensusGroup, result) + }) + t.Run("should compute with 17 validators, mask contains 2 bytes", func(t *testing.T) { + t.Parallel() + + consensusGroup := generatePubKeys(17) + mask0 := byte(0b11111111) + mask1 := byte(0b11111111) + + result := ComputeSignersPublicKeys(consensusGroup, []byte{mask0, mask1}) + expected := generatePubKeys(16) + assert.Equal(t, expected, result) + }) +} From ddfca63763d9594583c4e69c502d13ea92b1ef6e Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 29 Jan 2024 16:02:45 +0200 Subject: [PATCH 644/958] - fixes after new libs integration --- common/constants.go | 2 + common/enablers/enableEpochsHandler.go | 6 ++ common/enablers/enableEpochsHandler_test.go | 2 + config/tomlConfig_test.go | 2 +- consensus/spos/bls/subroundStartRound_test.go | 2 +- go.mod | 24 +++--- go.sum | 48 +++++------ .../state/stateTrie/stateTrie_test.go | 84 +++++++++---------- .../vm/wasm/wasmvm/mockContracts.go | 4 +- state/accountsDB_test.go | 9 +- 10 files changed, 96 insertions(+), 87 deletions(-) diff --git a/common/constants.go b/common/constants.go index 1c3d9d9621b..332c2822aba 100644 --- a/common/constants.go +++ b/common/constants.go @@ -893,6 +893,7 @@ const MetricTrieSyncNumProcessedNodes = "erd_trie_sync_num_nodes_processed" // FullArchiveMetricSuffix is the suffix added to metrics specific for full archive network const FullArchiveMetricSuffix = "_full_archive" +// Enable epoch flags definitions const ( SCDeployFlag core.EnableEpochFlag = "SCDeployFlag" BuiltInFunctionsFlag core.EnableEpochFlag = "BuiltInFunctionsFlag" @@ -991,6 +992,7 @@ const ( MultiClaimOnDelegationFlag core.EnableEpochFlag = "MultiClaimOnDelegationFlag" ChangeUsernameFlag core.EnableEpochFlag = "ChangeUsernameFlag" AutoBalanceDataTriesFlag core.EnableEpochFlag = "AutoBalanceDataTriesFlag" + MigrateDataTrieFlag core.EnableEpochFlag = "MigrateDataTrieFlag" FixDelegationChangeOwnerOnAccountFlag core.EnableEpochFlag = "FixDelegationChangeOwnerOnAccountFlag" FixOOGReturnCodeFlag core.EnableEpochFlag = "FixOOGReturnCodeFlag" DeterministicSortOnValidatorsInfoFixFlag core.EnableEpochFlag = "DeterministicSortOnValidatorsInfoFixFlag" diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 197cab8fff8..9537e7465a2 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -629,6 +629,12 @@ func (handler *enableEpochsHandler) createAllFlagsMap() { }, activationEpoch: handler.enableEpochsConfig.AutoBalanceDataTriesEnableEpoch, }, + common.MigrateDataTrieFlag: { + isActiveInEpoch: func(epoch uint32) bool { + return epoch >= handler.enableEpochsConfig.MigrateDataTrieEnableEpoch + }, + activationEpoch: handler.enableEpochsConfig.MigrateDataTrieEnableEpoch, + }, common.FixDelegationChangeOwnerOnAccountFlag: { isActiveInEpoch: func(epoch uint32) bool { return epoch >= handler.enableEpochsConfig.FixDelegationChangeOwnerOnAccountEnableEpoch diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 30949150e49..973f586986d 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -287,6 +287,7 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { require.True(t, handler.IsFlagEnabled(common.MultiClaimOnDelegationFlag)) require.True(t, handler.IsFlagEnabled(common.ChangeUsernameFlag)) require.True(t, handler.IsFlagEnabled(common.AutoBalanceDataTriesFlag)) + require.True(t, handler.IsFlagEnabled(common.MigrateDataTrieFlag)) require.True(t, handler.IsFlagEnabled(common.FixDelegationChangeOwnerOnAccountFlag)) require.True(t, handler.IsFlagEnabled(common.FixOOGReturnCodeFlag)) require.True(t, handler.IsFlagEnabled(common.DeterministicSortOnValidatorsInfoFixFlag)) @@ -398,6 +399,7 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { require.Equal(t, cfg.MultiClaimOnDelegationEnableEpoch, handler.GetActivationEpoch(common.MultiClaimOnDelegationFlag)) require.Equal(t, cfg.ChangeUsernameEnableEpoch, handler.GetActivationEpoch(common.ChangeUsernameFlag)) require.Equal(t, cfg.AutoBalanceDataTriesEnableEpoch, handler.GetActivationEpoch(common.AutoBalanceDataTriesFlag)) + require.Equal(t, cfg.MigrateDataTrieEnableEpoch, handler.GetActivationEpoch(common.MigrateDataTrieFlag)) require.Equal(t, cfg.FixDelegationChangeOwnerOnAccountEnableEpoch, handler.GetActivationEpoch(common.FixDelegationChangeOwnerOnAccountFlag)) require.Equal(t, cfg.FixOOGReturnCodeEnableEpoch, handler.GetActivationEpoch(common.FixOOGReturnCodeFlag)) require.Equal(t, cfg.DeterministicSortOnValidatorsInfoEnableEpoch, handler.GetActivationEpoch(common.DeterministicSortOnValidatorsInfoFixFlag)) diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 12960025189..4b75c03300d 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -843,7 +843,7 @@ func TestEnableEpochConfig(t *testing.T) { MigrateDataTrieEnableEpoch = 92 # CurrentRandomnessOnSortingEnableEpoch represents the epoch when the current randomness on sorting is enabled - CurrentRandomnessOnSortingEnableEpoch = 92 + CurrentRandomnessOnSortingEnableEpoch = 93 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ diff --git a/consensus/spos/bls/subroundStartRound_test.go b/consensus/spos/bls/subroundStartRound_test.go index 963762b0feb..2f5c21d2659 100644 --- a/consensus/spos/bls/subroundStartRound_test.go +++ b/consensus/spos/bls/subroundStartRound_test.go @@ -668,7 +668,7 @@ func TestSubroundStartRound_InitCurrentRoundShouldMetrics(t *testing.T) { bls.ProcessingThresholdPercent, displayStatistics, executeStoredMessages, - &mock.SentSignatureTrackerStub{}, + &testscommon.SentSignatureTrackerStub{}, ) srStartRound.Check() assert.True(t, wasCalled) diff --git a/go.mod b/go.mod index fc80c4a65a9..a97fb145008 100644 --- a/go.mod +++ b/go.mod @@ -14,18 +14,18 @@ require ( github.com/gorilla/websocket v1.5.0 github.com/klauspost/cpuid/v2 v2.2.5 github.com/mitchellh/mapstructure v1.5.0 - github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240123161141-8b8b0259c602 - github.com/multiversx/mx-chain-core-go v1.2.19-0.20231214115026-a1e7279b14f1 - github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231129101537-ef355850e34b - github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20231228064619-e3b0caf29058 - github.com/multiversx/mx-chain-logger-go v1.0.14-0.20231215125130-a3bed6e76040 - github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 - github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 - github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa - github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92-0.20231228071246-c1b45eae5955 + github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad + github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 + github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 + github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129125735-5b36941ff52c + github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240104072921-bf87e7d0a729 + github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129124143-c8923624b305 + github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129082915-06639d9addfe + github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129123904-a81755ea8717 + github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129125540-591810692d64 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129124541-7a86f52ce97c + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129124838-73c71cddb7c0 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129125342-ab1077eeca97 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index d2984f6775f..8ef715ae2de 100644 --- a/go.sum +++ b/go.sum @@ -385,30 +385,30 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUYwbO0993uPI= github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o= -github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240123161141-8b8b0259c602 h1:R010kiv1Gp0ULko3TJxAGJmQQz24frgN05y9crLTp/Q= -github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240123161141-8b8b0259c602/go.mod h1:n4E8BWIV0g3AcNGe1gf+vcjUC8A2QCJ4ARQSbiUDGrI= -github.com/multiversx/mx-chain-core-go v1.2.19-0.20231214115026-a1e7279b14f1 h1:8rz1ZpRAsWVxSEBy7PJIUStQMKiHs3I4mvpRmHUpsbI= -github.com/multiversx/mx-chain-core-go v1.2.19-0.20231214115026-a1e7279b14f1/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= -github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231129101537-ef355850e34b h1:TIE6it719ZIW0E1bFgPAgE+U3zPSkPfAloFYEIeOL3U= -github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231129101537-ef355850e34b/go.mod h1:Ap6p7QZFtwPlb++OvCG+85BfuZ+bLP/JtQp6EwjWJsI= -github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20231228064619-e3b0caf29058 h1:6XH7ua4vUqhbE4NMzs8K63b7A/9KMO4H8XZfYjyy778= -github.com/multiversx/mx-chain-es-indexer-go v1.4.18-0.20231228064619-e3b0caf29058/go.mod h1:9BzrDTbIjruFXN6YcDOBsnOP0cUHhQobRUlmNOwkDME= -github.com/multiversx/mx-chain-logger-go v1.0.14-0.20231215125130-a3bed6e76040 h1:rsEflKFn5StRh0ADxElUkI/9wZV0Lbig+b0671LmjTk= -github.com/multiversx/mx-chain-logger-go v1.0.14-0.20231215125130-a3bed6e76040/go.mod h1:fH/fR/GEBsDjPkBoZDVJMoYo2HhlA7++DP6QfITJ1N8= -github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296 h1:jDGGEubkiTJfEFcbErUYCYM2Z6wKapgZyGaICScpynk= -github.com/multiversx/mx-chain-scenario-go v1.2.2-0.20231129113427-ad3056f45296/go.mod h1:WocyahfHCC3oGILEVdRe7I4/+q/TLCORoTo1X4wGmF4= -github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4 h1:2RJ6T31pLN75l4xfhTicGZ+gVOPMxSGPip+O1XYVYac= -github.com/multiversx/mx-chain-storage-go v1.0.15-0.20231213110622-e222ba96a9f4/go.mod h1:ioCT2oHQ+TyHQYpgjxzlUdy7dCdv56+w5HnBg9z96eY= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa h1:xdDeUC4yOfiUwctkYioYMjjigBZoZo5RZq1e5WoCVRs= -github.com/multiversx/mx-chain-vm-common-go v1.5.10-0.20231228070003-ae14e1e0adfa/go.mod h1:7jjGRykSfLeMs6iQdszlE0lGK2xp9/cctiVdeKbQLLM= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3 h1:qfzeTPI2oSgxnw52KiVWc2fHMem6FZIkX1Azwy64098= -github.com/multiversx/mx-chain-vm-go v1.5.23-0.20231228064104-964359cb8dd3/go.mod h1:4kcpwq70UB3Clnc6Q0krGA8hgQ26JTQpmCP+4y5aiV0= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216 h1:CDSn4hgiGwoOSSLmajgOvjdoRxfJSXjEu/CfXiqihwo= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65-0.20231228071026-eed2cb19c216/go.mod h1:h87SKR/p66XP0Er2Mx2KfjzS6mLmW6l3tDWyO1oNr94= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14 h1:7r2zQiAfqGjN7U8j5obXIoRSh+vnoupBhxBgQGUA2ck= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66-0.20231228071108-6b89bcebab14/go.mod h1:MnpQOi/P4K744ZJl8pQksulsHazmN6YRzJ4amgtZ0OQ= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92-0.20231228071246-c1b45eae5955 h1:5b0+UeSbcyh+9z9x/6Nql3cYwaNWzTwj+KIfH4YaASs= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.92-0.20231228071246-c1b45eae5955/go.mod h1:+DLltGV0h3/H9bJaz01JyeapKNki3Rh4o5VGpjd2ZNc= +github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad h1:izxTyKCxvT7z2mhXCWAZibSxwRVgLmq/kDovs4Nx/6Y= +github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad/go.mod h1:n4E8BWIV0g3AcNGe1gf+vcjUC8A2QCJ4ARQSbiUDGrI= +github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 h1:pFh9bwOTRgW173aHqA8Bmax+jYzLnRyXqRvi5alF7V4= +github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= +github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 h1:beVIhs5ysylwNplQ/bZ0h5DoDlqKNWgpWE/NMHHNmAw= +github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479/go.mod h1:Ap6p7QZFtwPlb++OvCG+85BfuZ+bLP/JtQp6EwjWJsI= +github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129125735-5b36941ff52c h1:5QITaKd7f45m1vWz9TuA91A29c33DYNCQbjd6y5otCg= +github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129125735-5b36941ff52c/go.mod h1:eTrx5MUTdT1eqbdfFJ/iT+yPme6nM66L3PqLLnQ2T8A= +github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240104072921-bf87e7d0a729 h1:dFxKHtGiZ51coWMtJFbxemVDxUs+kcVhrCMCrTt/Wnk= +github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240104072921-bf87e7d0a729/go.mod h1:fH/fR/GEBsDjPkBoZDVJMoYo2HhlA7++DP6QfITJ1N8= +github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129124143-c8923624b305 h1:tbC1HpgItcheiIPAT5szH/UHJbxq4PPKxHd6Zwwr71g= +github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129124143-c8923624b305/go.mod h1:5diKNqvtEMvRyGszOuglh0h7sT5cLN43VdWynOho+w8= +github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129082915-06639d9addfe h1:I2KM+wg0P/S4OWTrA8w3NbBDvUlnp/xWO71/YHTJlGo= +github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129082915-06639d9addfe/go.mod h1:dIpa2MbrCCmvVOqiNrOBNBivau7IbrYgm+PMrTNV880= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129123904-a81755ea8717 h1:6x8xV6/rYa0cJldA/ceQNnYLUkEIO/yITa4AWfSOt60= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129123904-a81755ea8717/go.mod h1:Dv5MF7SzU6fYx+GwpJW1QSaekSHbXnGrQnbq5bbp+MI= +github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129125540-591810692d64 h1:dSjiLokFM2G80bbfSaNNekZcNp2V0FfFJf+6H6/swDg= +github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129125540-591810692d64/go.mod h1:etMsc74nzcCy7KElEyh4yUS98bFTC/H7j7gAW+zEyhI= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129124541-7a86f52ce97c h1:ddmmTVggK/urIdk1BJpPUTH8UEZ2tKaEAXIojorf8N0= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129124541-7a86f52ce97c/go.mod h1:0ClcJiQ6/95JlwBqG5GTEE3wkkC1w0275AfMSnXlWkE= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129124838-73c71cddb7c0 h1:xuD6aTZQFhoTwxYSyut3kV6rV2vwBO/190ZM0SnHbUc= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129124838-73c71cddb7c0/go.mod h1:TYSVLkRZxF2zRI6eXql+26BvRFATB8aYyNeWD4eT66U= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129125342-ab1077eeca97 h1:n28mLnxY+m1qRxnFGYSeW56ZsvouEQoyxN0wwUVN+o0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129125342-ab1077eeca97/go.mod h1:VclZXtOC2mdFWnXF3cw2aNcnAWFmOx5FAnoHDZuFh1s= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= diff --git a/integrationTests/state/stateTrie/stateTrie_test.go b/integrationTests/state/stateTrie/stateTrie_test.go index 91c99db1857..ecb1b9b8ee0 100644 --- a/integrationTests/state/stateTrie/stateTrie_test.go +++ b/integrationTests/state/stateTrie/stateTrie_test.go @@ -222,15 +222,15 @@ func TestAccountsDB_CommitTwoOkAccountsShouldWork(t *testing.T) { acc, err := adb.LoadAccount(adr2) require.Nil(t, err) - stateMock := acc.(state.UserAccountHandler) - _ = stateMock.AddToBalance(balance2) + userAccount := acc.(state.UserAccountHandler) + _ = userAccount.AddToBalance(balance2) key := []byte("ABC") val := []byte("123") - _ = stateMock.SaveKeyValue(key, val) + _ = userAccount.SaveKeyValue(key, val) _ = adb.SaveAccount(state1) - _ = adb.SaveAccount(stateMock) + _ = adb.SaveAccount(userAccount) // states are now prepared, committing @@ -311,15 +311,15 @@ func TestAccountsDB_CommitTwoOkAccountsWithRecreationFromStorageShouldWork(t *te acc, err := adb.LoadAccount(adr2) require.Nil(t, err) - stateMock := acc.(state.UserAccountHandler) - _ = stateMock.AddToBalance(balance2) + userAccount := acc.(state.UserAccountHandler) + _ = userAccount.AddToBalance(balance2) key := []byte("ABC") val := []byte("123") - _ = stateMock.SaveKeyValue(key, val) + _ = userAccount.SaveKeyValue(key, val) _ = adb.SaveAccount(state1) - _ = adb.SaveAccount(stateMock) + _ = adb.SaveAccount(userAccount) // states are now prepared, committing @@ -452,9 +452,9 @@ func TestAccountsDB_RevertNonceStepByStepAccountDataShouldWork(t *testing.T) { fmt.Printf("State root - created 1-st account: %v\n", hrCreated1) - stateMock, err := adb.LoadAccount(adr2) + userAccount, err := adb.LoadAccount(adr2) require.Nil(t, err) - _ = adb.SaveAccount(stateMock) + _ = adb.SaveAccount(userAccount) snapshotCreated2 := adb.JournalLen() rootHash, err = adb.RootHash() require.Nil(t, err) @@ -478,8 +478,8 @@ func TestAccountsDB_RevertNonceStepByStepAccountDataShouldWork(t *testing.T) { hrWithNonce1 := base64.StdEncoding.EncodeToString(rootHash) fmt.Printf("State root - account with nonce 40: %v\n", hrWithNonce1) - stateMock.(state.UserAccountHandler).IncreaseNonce(50) - _ = adb.SaveAccount(stateMock) + userAccount.(state.UserAccountHandler).IncreaseNonce(50) + _ = adb.SaveAccount(userAccount) rootHash, err = adb.RootHash() require.Nil(t, err) @@ -529,9 +529,9 @@ func TestAccountsDB_RevertBalanceStepByStepAccountDataShouldWork(t *testing.T) { fmt.Printf("State root - created 1-st account: %v\n", hrCreated1) - stateMock, err := adb.LoadAccount(adr2) + userAccount, err := adb.LoadAccount(adr2) require.Nil(t, err) - _ = adb.SaveAccount(stateMock) + _ = adb.SaveAccount(userAccount) snapshotCreated2 := adb.JournalLen() rootHash, err = adb.RootHash() @@ -556,8 +556,8 @@ func TestAccountsDB_RevertBalanceStepByStepAccountDataShouldWork(t *testing.T) { hrWithBalance1 := base64.StdEncoding.EncodeToString(rootHash) fmt.Printf("State root - account with balance 40: %v\n", hrWithBalance1) - _ = stateMock.(state.UserAccountHandler).AddToBalance(big.NewInt(50)) - _ = adb.SaveAccount(stateMock) + _ = userAccount.(state.UserAccountHandler).AddToBalance(big.NewInt(50)) + _ = adb.SaveAccount(userAccount) rootHash, err = adb.RootHash() require.Nil(t, err) @@ -610,10 +610,10 @@ func TestAccountsDB_RevertCodeStepByStepAccountDataShouldWork(t *testing.T) { fmt.Printf("State root - created 1-st account: %v\n", hrCreated1) - stateMock, err := adb.LoadAccount(adr2) + userAccount, err := adb.LoadAccount(adr2) require.Nil(t, err) - stateMock.(state.UserAccountHandler).SetCode(code) - _ = adb.SaveAccount(stateMock) + userAccount.(state.UserAccountHandler).SetCode(code) + _ = adb.SaveAccount(userAccount) snapshotCreated2 := adb.JournalLen() rootHash, err = adb.RootHash() @@ -685,10 +685,10 @@ func TestAccountsDB_RevertDataStepByStepAccountDataShouldWork(t *testing.T) { fmt.Printf("State root - created 1-st account: %v\n", hrCreated1) fmt.Printf("data root - 1-st account: %v\n", hrRoot1) - stateMock, err := adb.LoadAccount(adr2) + userAccount, err := adb.LoadAccount(adr2) require.Nil(t, err) - _ = stateMock.(state.UserAccountHandler).SaveKeyValue(key, val) - err = adb.SaveAccount(stateMock) + _ = userAccount.(state.UserAccountHandler).SaveKeyValue(key, val) + err = adb.SaveAccount(userAccount) require.Nil(t, err) snapshotCreated2 := adb.JournalLen() rootHash, err = adb.RootHash() @@ -764,16 +764,16 @@ func TestAccountsDB_RevertDataStepByStepWithCommitsAccountDataShouldWork(t *test fmt.Printf("State root - created 1-st account: %v\n", hrCreated1) fmt.Printf("data root - 1-st account: %v\n", hrRoot1) - stateMock, err := adb.LoadAccount(adr2) + userAccount, err := adb.LoadAccount(adr2) require.Nil(t, err) - _ = stateMock.(state.UserAccountHandler).SaveKeyValue(key, val) - err = adb.SaveAccount(stateMock) + _ = userAccount.(state.UserAccountHandler).SaveKeyValue(key, val) + err = adb.SaveAccount(userAccount) require.Nil(t, err) snapshotCreated2 := adb.JournalLen() rootHash, err = adb.RootHash() require.Nil(t, err) hrCreated2 := base64.StdEncoding.EncodeToString(rootHash) - rootHash, err = stateMock.(state.UserAccountHandler).DataTrie().RootHash() + rootHash, err = userAccount.(state.UserAccountHandler).DataTrie().RootHash() require.Nil(t, err) hrRoot2 := base64.StdEncoding.EncodeToString(rootHash) @@ -795,15 +795,15 @@ func TestAccountsDB_RevertDataStepByStepWithCommitsAccountDataShouldWork(t *test // Step 4. 2-nd account changes its data snapshotMod := adb.JournalLen() - stateMock, err = adb.LoadAccount(adr2) + userAccount, err = adb.LoadAccount(adr2) require.Nil(t, err) - _ = stateMock.(state.UserAccountHandler).SaveKeyValue(key, newVal) - err = adb.SaveAccount(stateMock) + _ = userAccount.(state.UserAccountHandler).SaveKeyValue(key, newVal) + err = adb.SaveAccount(userAccount) require.Nil(t, err) rootHash, err = adb.RootHash() require.Nil(t, err) hrCreated2p1 := base64.StdEncoding.EncodeToString(rootHash) - rootHash, err = stateMock.(state.UserAccountHandler).DataTrie().RootHash() + rootHash, err = userAccount.(state.UserAccountHandler).DataTrie().RootHash() require.Nil(t, err) hrRoot2p1 := base64.StdEncoding.EncodeToString(rootHash) @@ -823,9 +823,9 @@ func TestAccountsDB_RevertDataStepByStepWithCommitsAccountDataShouldWork(t *test require.Nil(t, err) hrCreated2Rev := base64.StdEncoding.EncodeToString(rootHash) - stateMock, err = adb.LoadAccount(adr2) + userAccount, err = adb.LoadAccount(adr2) require.Nil(t, err) - rootHash, err = stateMock.(state.UserAccountHandler).DataTrie().RootHash() + rootHash, err = userAccount.(state.UserAccountHandler).DataTrie().RootHash() require.Nil(t, err) hrRoot2Rev := base64.StdEncoding.EncodeToString(rootHash) fmt.Printf("State root - reverted 2-nd account: %v\n", hrCreated2Rev) @@ -1248,17 +1248,17 @@ func TestTrieDbPruning_GetDataTrieTrackerAfterPruning(t *testing.T) { _ = adb.SaveAccount(state1) acc2, _ := adb.LoadAccount(address2) - stateMock := acc2.(state.UserAccountHandler) - _ = stateMock.SaveKeyValue(key1, value1) - _ = stateMock.SaveKeyValue(key2, value1) - _ = adb.SaveAccount(stateMock) + userAccount := acc2.(state.UserAccountHandler) + _ = userAccount.SaveKeyValue(key1, value1) + _ = userAccount.SaveKeyValue(key2, value1) + _ = adb.SaveAccount(userAccount) oldRootHash, _ := adb.Commit() acc2, _ = adb.LoadAccount(address2) - stateMock = acc2.(state.UserAccountHandler) - _ = stateMock.SaveKeyValue(key1, value2) - _ = adb.SaveAccount(stateMock) + userAccount = acc2.(state.UserAccountHandler) + _ = userAccount.SaveKeyValue(key1, value2) + _ = adb.SaveAccount(userAccount) newRootHash, _ := adb.Commit() adb.PruneTrie(oldRootHash, state.OldRoot, state.NewPruningHandler(state.EnableDataRemoval)) @@ -1270,13 +1270,13 @@ func TestTrieDbPruning_GetDataTrieTrackerAfterPruning(t *testing.T) { require.Nil(t, err) collapseTrie(state1, t) - collapseTrie(stateMock, t) + collapseTrie(userAccount, t) val, _, err := state1.RetrieveValue(key1) require.Nil(t, err) require.Equal(t, value1, val) - val, _, err = stateMock.RetrieveValue(key2) + val, _, err = userAccount.RetrieveValue(key2) require.Nil(t, err) require.Equal(t, value1, val) } @@ -2456,7 +2456,7 @@ func migrateDataTrieBuiltInFunc( round uint64, idxProposers []int, ) { - require.True(t, nodes[shardId].EnableEpochsHandler.IsAutoBalanceDataTriesEnabled()) + require.True(t, nodes[shardId].EnableEpochsHandler.IsFlagEnabled(common.AutoBalanceDataTriesFlag)) isMigrated := getAddressMigrationStatus(t, nodes[shardId].AccntState, migrationAddress) require.False(t, isMigrated) diff --git a/integrationTests/vm/wasm/wasmvm/mockContracts.go b/integrationTests/vm/wasm/wasmvm/mockContracts.go index e8478768cbc..4e1b2b2b2c2 100644 --- a/integrationTests/vm/wasm/wasmvm/mockContracts.go +++ b/integrationTests/vm/wasm/wasmvm/mockContracts.go @@ -17,7 +17,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/hashingMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" - "github.com/multiversx/mx-chain-scenario-go/worldmock" + worldmock "github.com/multiversx/mx-chain-scenario-go/worldmock" "github.com/multiversx/mx-chain-vm-go/executor" contextmock "github.com/multiversx/mx-chain-vm-go/mock/context" "github.com/multiversx/mx-chain-vm-go/testcommon" @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" ) +// MockInitialBalance represents a mock balance var MockInitialBalance = big.NewInt(10_000_000) // WalletAddressPrefix is the prefix of any smart contract address used for testing. @@ -191,6 +192,7 @@ func makeTestAddress(_ []byte, identifier string) []byte { return append(leftBytes, rightBytes...) } +// CreateHostAndInstanceBuilder creates a new host and instance builder func CreateHostAndInstanceBuilder(t *testing.T, net *integrationTests.TestNetwork, vmContainer process.VirtualMachinesContainer, diff --git a/state/accountsDB_test.go b/state/accountsDB_test.go index 8bd0e6b9c2e..b10ea8d5167 100644 --- a/state/accountsDB_test.go +++ b/state/accountsDB_test.go @@ -2986,11 +2986,8 @@ func testAccountMethodsConcurrency( func TestAccountsDB_MigrateDataTrieWithFunc(t *testing.T) { t.Parallel() - checkpointHashesHolder := hashesHolder.NewCheckpointHashesHolder(10000000, testscommon.HashSize) - enabeEpochsHandler := &enableEpochsHandlerMock.EnableEpochsHandlerStub{ - IsAutoBalanceDataTriesEnabledField: false, - } - adb, _, _ := getDefaultStateComponents(checkpointHashesHolder, testscommon.NewSnapshotPruningStorerMock(), enabeEpochsHandler) + enableEpochsHandler := enableEpochsHandlerMock.NewEnableEpochsHandlerStub() + adb, _, _ := getDefaultStateComponents(testscommon.NewSnapshotPruningStorerMock(), enableEpochsHandler) addr := []byte("addr") acc, _ := adb.LoadAccount(addr) @@ -2999,7 +2996,7 @@ func TestAccountsDB_MigrateDataTrieWithFunc(t *testing.T) { _ = acc.(state.UserAccountHandler).SaveKeyValue([]byte("key2"), value) _ = adb.SaveAccount(acc) - enabeEpochsHandler.IsAutoBalanceDataTriesEnabledField = true + enableEpochsHandler.AddActiveFlags(common.AutoBalanceDataTriesFlag) acc, _ = adb.LoadAccount(addr) isMigrated, err := acc.(state.AccountHandlerWithDataTrieMigrationStatus).IsDataTrieMigrated() From 6a6a993e8ecdfdbafaafd61cb620f88d70e21094 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 29 Jan 2024 17:13:37 +0200 Subject: [PATCH 645/958] - latest libs --- go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index a97fb145008..8c0a458138f 100644 --- a/go.mod +++ b/go.mod @@ -17,15 +17,15 @@ require ( github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 - github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129125735-5b36941ff52c - github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240104072921-bf87e7d0a729 - github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129124143-c8923624b305 - github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129082915-06639d9addfe - github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129123904-a81755ea8717 - github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129125540-591810692d64 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129124541-7a86f52ce97c - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129124838-73c71cddb7c0 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129125342-ab1077eeca97 + github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a + github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c + github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1 + github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 + github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 + github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129150215-43996b664ada github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index 8ef715ae2de..11cb5b9a820 100644 --- a/go.sum +++ b/go.sum @@ -391,24 +391,24 @@ github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 h1: github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 h1:beVIhs5ysylwNplQ/bZ0h5DoDlqKNWgpWE/NMHHNmAw= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479/go.mod h1:Ap6p7QZFtwPlb++OvCG+85BfuZ+bLP/JtQp6EwjWJsI= -github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129125735-5b36941ff52c h1:5QITaKd7f45m1vWz9TuA91A29c33DYNCQbjd6y5otCg= -github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129125735-5b36941ff52c/go.mod h1:eTrx5MUTdT1eqbdfFJ/iT+yPme6nM66L3PqLLnQ2T8A= -github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240104072921-bf87e7d0a729 h1:dFxKHtGiZ51coWMtJFbxemVDxUs+kcVhrCMCrTt/Wnk= -github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240104072921-bf87e7d0a729/go.mod h1:fH/fR/GEBsDjPkBoZDVJMoYo2HhlA7++DP6QfITJ1N8= -github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129124143-c8923624b305 h1:tbC1HpgItcheiIPAT5szH/UHJbxq4PPKxHd6Zwwr71g= -github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129124143-c8923624b305/go.mod h1:5diKNqvtEMvRyGszOuglh0h7sT5cLN43VdWynOho+w8= -github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129082915-06639d9addfe h1:I2KM+wg0P/S4OWTrA8w3NbBDvUlnp/xWO71/YHTJlGo= -github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129082915-06639d9addfe/go.mod h1:dIpa2MbrCCmvVOqiNrOBNBivau7IbrYgm+PMrTNV880= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129123904-a81755ea8717 h1:6x8xV6/rYa0cJldA/ceQNnYLUkEIO/yITa4AWfSOt60= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129123904-a81755ea8717/go.mod h1:Dv5MF7SzU6fYx+GwpJW1QSaekSHbXnGrQnbq5bbp+MI= -github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129125540-591810692d64 h1:dSjiLokFM2G80bbfSaNNekZcNp2V0FfFJf+6H6/swDg= -github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129125540-591810692d64/go.mod h1:etMsc74nzcCy7KElEyh4yUS98bFTC/H7j7gAW+zEyhI= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129124541-7a86f52ce97c h1:ddmmTVggK/urIdk1BJpPUTH8UEZ2tKaEAXIojorf8N0= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129124541-7a86f52ce97c/go.mod h1:0ClcJiQ6/95JlwBqG5GTEE3wkkC1w0275AfMSnXlWkE= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129124838-73c71cddb7c0 h1:xuD6aTZQFhoTwxYSyut3kV6rV2vwBO/190ZM0SnHbUc= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129124838-73c71cddb7c0/go.mod h1:TYSVLkRZxF2zRI6eXql+26BvRFATB8aYyNeWD4eT66U= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129125342-ab1077eeca97 h1:n28mLnxY+m1qRxnFGYSeW56ZsvouEQoyxN0wwUVN+o0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129125342-ab1077eeca97/go.mod h1:VclZXtOC2mdFWnXF3cw2aNcnAWFmOx5FAnoHDZuFh1s= +github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a h1:mOMUhbsjTq7n5oAv4KkVnL67ngS0+wkqmkiv1XJfBIY= +github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a/go.mod h1:3aSGRJNvfUuPQkZUGHWuF11rPPxphsKGuAuIB+eD3is= +github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c h1:QIUOn8FgNRa5cir4BCWHZi/Qcr6Gg0eGNhns4+jy6+k= +github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c/go.mod h1:fH/fR/GEBsDjPkBoZDVJMoYo2HhlA7++DP6QfITJ1N8= +github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1 h1:hkeHftnhRuJoT5FrfF97gEtb5aY351SWEjZPaTb6D+Y= +github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= +github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 h1:/EYv/HGX0OKbeNFt667J0yZRtuJiZH0lEK8YtobuH/c= +github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 h1:zImJa/r6B5L2OLWbKTn5io53U11PPGDla12H2OaJ9y0= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= +github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83 h1:G/d9aplnwP/9MrLE3gcANEpGfn5e8ZZufijPv2XVUfw= +github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83/go.mod h1:64dTd60QUGWx5W3eU28IOfpqAWApWqB/Z7mJHmuQfXo= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 h1:1uMlT5TjiHUlx81fEH/WQANWlY0PjF3opMlW+E3L3GI= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129150215-43996b664ada h1:NZLV2QmNPW+QTefuAhC24sOuGbOsAQEXzfv2CWoRJKc= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129150215-43996b664ada/go.mod h1:tCjtWeBEZCfjEjlBcgLIRDGJbVmdV8dsmG6ydtiUtSo= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From 52e51dbd3bc1080c9e156252f2fa5efda48cf977 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 30 Jan 2024 10:42:47 +0200 Subject: [PATCH 646/958] - adjusted p2p parameters --- cmd/node/config/fullArchiveP2P.toml | 4 ++-- cmd/node/config/p2p.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/node/config/fullArchiveP2P.toml b/cmd/node/config/fullArchiveP2P.toml index 0dd790a83f6..bfe1d27f1a6 100644 --- a/cmd/node/config/fullArchiveP2P.toml +++ b/cmd/node/config/fullArchiveP2P.toml @@ -73,8 +73,8 @@ # The targeted number of peer connections TargetPeerCount = 36 MaxIntraShardValidators = 7 - MaxCrossShardValidators = 15 - MaxIntraShardObservers = 2 + MaxCrossShardValidators = 13 + MaxIntraShardObservers = 4 MaxCrossShardObservers = 3 MaxSeeders = 2 diff --git a/cmd/node/config/p2p.toml b/cmd/node/config/p2p.toml index 62d30fd19f7..0ccc1c20398 100644 --- a/cmd/node/config/p2p.toml +++ b/cmd/node/config/p2p.toml @@ -73,8 +73,8 @@ # The targeted number of peer connections TargetPeerCount = 36 MaxIntraShardValidators = 7 - MaxCrossShardValidators = 15 - MaxIntraShardObservers = 2 + MaxCrossShardValidators = 13 + MaxIntraShardObservers = 4 MaxCrossShardObservers = 3 MaxSeeders = 2 From a22a39bf5da9a13de388a75f00b31346449825ac Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 11:37:56 +0200 Subject: [PATCH 647/958] FEAT: Ugly delegation test with addNodes and stakeNodes within and above node limits --- vm/systemSmartContracts/delegation.go | 2 +- vm/systemSmartContracts/delegation_test.go | 147 ++++++++++++++++++++- 2 files changed, 145 insertions(+), 4 deletions(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index e1304eca90d..cb882fccb1a 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1237,7 +1237,7 @@ func tooManyNodesLogs(logEntries []*vmcommon.LogEntry) bool { if len(logEntry.Topics) != 1 { continue } - if !bytes.Equal(logEntry.Topics[0], []byte(numberOfNodesTooHigh)) { + if bytes.Equal(logEntry.Topics[0], []byte(numberOfNodesTooHigh)) { return true } } diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index c26f1ff516b..a934548d941 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/process/smartContract/hooks" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" stateMock "github.com/multiversx/mx-chain-go/testscommon/state" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/mock" @@ -59,7 +60,7 @@ func createMockArgumentsForDelegation() ArgsNewDelegation { } } -func addValidatorAndStakingScToVmContext(eei *vmContext) { +func addValidatorAndStakingScToVmContext(eei *vmContext, blsKeys ...[]byte) { validatorArgs := createMockArgumentsForValidatorSC() validatorArgs.Eei = eei validatorArgs.StakingSCConfig.GenesisNodePrice = "100" @@ -78,13 +79,14 @@ func addValidatorAndStakingScToVmContext(eei *vmContext) { return stakingSc, nil } + blsPubKeys := getInputBlsKeysOrDefaultIfEmpty(blsKeys...) if bytes.Equal(key, vm.ValidatorSCAddress) { enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) _ = validatorSc.saveRegistrationData([]byte("addr"), &ValidatorDataV2{ RewardAddress: []byte("rewardAddr"), TotalStakeValue: big.NewInt(1000), LockedStake: big.NewInt(500), - BlsPubKeys: [][]byte{[]byte("blsKey1"), []byte("blsKey2")}, + BlsPubKeys: blsPubKeys, TotalUnstaked: big.NewInt(150), UnstakedInfo: []*UnstakedValue{ { @@ -96,7 +98,7 @@ func addValidatorAndStakingScToVmContext(eei *vmContext) { UnstakedValue: big.NewInt(80), }, }, - NumRegistered: 2, + NumRegistered: uint32(len(blsKeys)), }) validatorSc.unBondPeriod = 50 return validatorSc, nil @@ -106,6 +108,19 @@ func addValidatorAndStakingScToVmContext(eei *vmContext) { }}) } +func getInputBlsKeysOrDefaultIfEmpty(blsKeys ...[]byte) [][]byte { + ret := make([][]byte, 0) + for _, blsKey := range blsKeys { + ret = append(ret, blsKey) + } + + if len(ret) == 0 { + return [][]byte{[]byte("blsKey1"), []byte("blsKey2")} + } + + return ret +} + func getDefaultVmInputForFunc(funcName string, args [][]byte) *vmcommon.ContractCallInput { return &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ @@ -5043,3 +5058,129 @@ func TestDelegationSystemSC_SynchronizeOwner(t *testing.T) { eei.ResetReturnMessage() }) } + +func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { + t.Parallel() + + sig := []byte("sig1") + args := createMockArgumentsForDelegation() + args.EnableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub( + common.StakingV4Step1Flag, + common.StakingV4Step2Flag, + common.StakingV4Step3Flag, + + common.DelegationSmartContractFlag, + common.StakingV2FlagAfterEpoch, + common.AddTokensToDelegationFlag, + common.DeleteDelegatorAfterClaimRewardsFlag, + common.ComputeRewardCheckpointFlag, + common.ValidatorToDelegationFlag, + common.ReDelegateBelowMinCheckFlag, + common.MultiClaimOnDelegationFlag, + ) + eei := createDefaultEei() + delegationsMap := map[string][]byte{} + delegationsMap[ownerKey] = []byte("owner") + eei.storageUpdate[string(eei.scAddress)] = delegationsMap + args.Eei = eei + + d, _ := NewDelegationSystemSC(args) + key1 := &NodesData{ + BLSKey: []byte("blsKey1"), + } + key2 := &NodesData{ + BLSKey: []byte("blsKey2"), + } + dStatus := &DelegationContractStatus{ + StakedKeys: []*NodesData{key1, key2}, + } + _ = d.saveDelegationStatus(dStatus) + + globalFund := &GlobalFundData{ + TotalActive: big.NewInt(400), + } + _ = d.saveGlobalFundData(globalFund) + addValidatorAndStakingScToVmContext2(eei, [][]byte{[]byte("blsKey1"), []byte("blsKey2")}) + dStatus, _ = d.getDelegationStatus() + require.Equal(t, 2, len(dStatus.StakedKeys)) + require.Equal(t, 0, len(dStatus.UnStakedKeys)) + require.Equal(t, 0, len(dStatus.NotStakedKeys)) + + newBlsKey := []byte("newBlsKey") + vmInput := getDefaultVmInputForFunc("addNodes", [][]byte{newBlsKey, sig}) + output := d.Execute(vmInput) + require.Equal(t, vmcommon.Ok, output) + + vmInput = getDefaultVmInputForFunc("stakeNodes", [][]byte{newBlsKey}) + output = d.Execute(vmInput) + require.Equal(t, vmcommon.Ok, output) + + dStatus, _ = d.getDelegationStatus() + require.Equal(t, 3, len(dStatus.StakedKeys)) + require.Equal(t, 0, len(dStatus.UnStakedKeys)) + require.Equal(t, 0, len(dStatus.NotStakedKeys)) + + addValidatorAndStakingScToVmContext2(eei, [][]byte{[]byte("blsKey1"), []byte("blsKey2"), newBlsKey}) + + newBlsKey2 := []byte("newBlsKey2") + vmInput = getDefaultVmInputForFunc("addNodes", [][]byte{newBlsKey2, sig}) + output = d.Execute(vmInput) + require.Equal(t, vmcommon.Ok, output) + + vmInput = getDefaultVmInputForFunc("stakeNodes", [][]byte{newBlsKey2}) + output = d.Execute(vmInput) + require.Equal(t, vmcommon.UserError, output) + require.True(t, strings.Contains(eei.returnMessage, numberOfNodesTooHigh)) + + dStatus, _ = d.getDelegationStatus() + require.Equal(t, 3, len(dStatus.StakedKeys)) + require.Equal(t, 0, len(dStatus.UnStakedKeys)) + require.Equal(t, 1, len(dStatus.NotStakedKeys)) +} + +func addValidatorAndStakingScToVmContext2(eei *vmContext, blsKeys [][]byte) { + validatorArgs := createMockArgumentsForValidatorSC() + validatorArgs.StakingSCConfig.NodeLimitPercentage = 1 + validatorArgs.Eei = eei + validatorArgs.StakingSCConfig.GenesisNodePrice = "100" + validatorArgs.StakingSCAddress = vm.StakingSCAddress + validatorArgs.NodesCoordinator = &shardingMocks.NodesCoordinatorStub{GetNumTotalEligibleCalled: func() uint64 { + return 3 + }} + validatorSc, _ := NewValidatorSmartContract(validatorArgs) + + stakingArgs := createMockStakingScArguments() + stakingArgs.Eei = eei + stakingSc, _ := NewStakingSmartContract(stakingArgs) + + _ = eei.SetSystemSCContainer(&mock.SystemSCContainerStub{GetCalled: func(key []byte) (contract vm.SystemSmartContract, err error) { + if bytes.Equal(key, vm.StakingSCAddress) { + return stakingSc, nil + } + + if bytes.Equal(key, vm.ValidatorSCAddress) { + _ = validatorSc.saveRegistrationData([]byte("addr"), &ValidatorDataV2{ + RewardAddress: []byte("rewardAddr"), + TotalStakeValue: big.NewInt(1000), + LockedStake: big.NewInt(500), + BlsPubKeys: blsKeys, + TotalUnstaked: big.NewInt(150), + UnstakedInfo: []*UnstakedValue{ + { + UnstakedEpoch: 10, + UnstakedValue: big.NewInt(60), + }, + { + UnstakedEpoch: 50, + UnstakedValue: big.NewInt(80), + }, + }, + NumRegistered: uint32(len(blsKeys)), + }) + validatorSc.unBondPeriod = 50 + return validatorSc, nil + } + + return nil, nil + }}) +} From 8a13c0cc49cab8edec4e80d38e5551445ceb257c Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 12:32:46 +0200 Subject: [PATCH 648/958] CLN: Unit test with addNodes and stakeNodes within and above node limits --- vm/systemSmartContracts/delegation_test.go | 50 ++++++++++------------ 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index a934548d941..a3812174b93 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -60,7 +60,7 @@ func createMockArgumentsForDelegation() ArgsNewDelegation { } } -func addValidatorAndStakingScToVmContext(eei *vmContext, blsKeys ...[]byte) { +func addValidatorAndStakingScToVmContext(eei *vmContext) { validatorArgs := createMockArgumentsForValidatorSC() validatorArgs.Eei = eei validatorArgs.StakingSCConfig.GenesisNodePrice = "100" @@ -79,14 +79,13 @@ func addValidatorAndStakingScToVmContext(eei *vmContext, blsKeys ...[]byte) { return stakingSc, nil } - blsPubKeys := getInputBlsKeysOrDefaultIfEmpty(blsKeys...) if bytes.Equal(key, vm.ValidatorSCAddress) { enableEpochsHandler.AddActiveFlags(common.StakingV2Flag) _ = validatorSc.saveRegistrationData([]byte("addr"), &ValidatorDataV2{ RewardAddress: []byte("rewardAddr"), TotalStakeValue: big.NewInt(1000), LockedStake: big.NewInt(500), - BlsPubKeys: blsPubKeys, + BlsPubKeys: [][]byte{[]byte("blsKey1"), []byte("blsKey2")}, TotalUnstaked: big.NewInt(150), UnstakedInfo: []*UnstakedValue{ { @@ -98,7 +97,7 @@ func addValidatorAndStakingScToVmContext(eei *vmContext, blsKeys ...[]byte) { UnstakedValue: big.NewInt(80), }, }, - NumRegistered: uint32(len(blsKeys)), + NumRegistered: 2, }) validatorSc.unBondPeriod = 50 return validatorSc, nil @@ -108,19 +107,6 @@ func addValidatorAndStakingScToVmContext(eei *vmContext, blsKeys ...[]byte) { }}) } -func getInputBlsKeysOrDefaultIfEmpty(blsKeys ...[]byte) [][]byte { - ret := make([][]byte, 0) - for _, blsKey := range blsKeys { - ret = append(ret, blsKey) - } - - if len(ret) == 0 { - return [][]byte{[]byte("blsKey1"), []byte("blsKey2")} - } - - return ret -} - func getDefaultVmInputForFunc(funcName string, args [][]byte) *vmcommon.ContractCallInput { return &vmcommon.ContractCallInput{ VMInput: vmcommon.VMInput{ @@ -5068,6 +5054,7 @@ func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { common.StakingV4Step1Flag, common.StakingV4Step2Flag, common.StakingV4Step3Flag, + common.StakeLimitsFlag, common.DelegationSmartContractFlag, common.StakingV2FlagAfterEpoch, @@ -5085,11 +5072,14 @@ func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { args.Eei = eei d, _ := NewDelegationSystemSC(args) + + blsKey1 := []byte("blsKey1") + blsKey2 := []byte("blsKey2") key1 := &NodesData{ - BLSKey: []byte("blsKey1"), + BLSKey: blsKey1, } key2 := &NodesData{ - BLSKey: []byte("blsKey2"), + BLSKey: blsKey2, } dStatus := &DelegationContractStatus{ StakedKeys: []*NodesData{key1, key2}, @@ -5100,18 +5090,20 @@ func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { TotalActive: big.NewInt(400), } _ = d.saveGlobalFundData(globalFund) - addValidatorAndStakingScToVmContext2(eei, [][]byte{[]byte("blsKey1"), []byte("blsKey2")}) + + addValidatorAndStakingScToVmContextWithBlsKeys(eei, [][]byte{blsKey1, blsKey2}) + dStatus, _ = d.getDelegationStatus() require.Equal(t, 2, len(dStatus.StakedKeys)) require.Equal(t, 0, len(dStatus.UnStakedKeys)) require.Equal(t, 0, len(dStatus.NotStakedKeys)) - newBlsKey := []byte("newBlsKey") - vmInput := getDefaultVmInputForFunc("addNodes", [][]byte{newBlsKey, sig}) + newBlsKey1 := []byte("newBlsKey1") + vmInput := getDefaultVmInputForFunc("addNodes", [][]byte{newBlsKey1, sig}) output := d.Execute(vmInput) require.Equal(t, vmcommon.Ok, output) - vmInput = getDefaultVmInputForFunc("stakeNodes", [][]byte{newBlsKey}) + vmInput = getDefaultVmInputForFunc("stakeNodes", [][]byte{newBlsKey1}) output = d.Execute(vmInput) require.Equal(t, vmcommon.Ok, output) @@ -5120,7 +5112,7 @@ func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { require.Equal(t, 0, len(dStatus.UnStakedKeys)) require.Equal(t, 0, len(dStatus.NotStakedKeys)) - addValidatorAndStakingScToVmContext2(eei, [][]byte{[]byte("blsKey1"), []byte("blsKey2"), newBlsKey}) + addValidatorAndStakingScToVmContextWithBlsKeys(eei, [][]byte{blsKey1, blsKey2, newBlsKey1}) newBlsKey2 := []byte("newBlsKey2") vmInput = getDefaultVmInputForFunc("addNodes", [][]byte{newBlsKey2, sig}) @@ -5138,15 +5130,17 @@ func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { require.Equal(t, 1, len(dStatus.NotStakedKeys)) } -func addValidatorAndStakingScToVmContext2(eei *vmContext, blsKeys [][]byte) { +func addValidatorAndStakingScToVmContextWithBlsKeys(eei *vmContext, blsKeys [][]byte) { validatorArgs := createMockArgumentsForValidatorSC() validatorArgs.StakingSCConfig.NodeLimitPercentage = 1 validatorArgs.Eei = eei validatorArgs.StakingSCConfig.GenesisNodePrice = "100" validatorArgs.StakingSCAddress = vm.StakingSCAddress - validatorArgs.NodesCoordinator = &shardingMocks.NodesCoordinatorStub{GetNumTotalEligibleCalled: func() uint64 { - return 3 - }} + validatorArgs.NodesCoordinator = &shardingMocks.NodesCoordinatorStub{ + GetNumTotalEligibleCalled: func() uint64 { + return 3 + }, + } validatorSc, _ := NewValidatorSmartContract(validatorArgs) stakingArgs := createMockStakingScArguments() From 5159c7f230d26b62b138a079e3a38e753d057f50 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 13:06:07 +0200 Subject: [PATCH 649/958] CLN: Add extra explanatory vm error message for too many nodes --- vm/systemSmartContracts/delegation.go | 23 +++++++++++++++------- vm/systemSmartContracts/delegation_test.go | 2 ++ vm/systemSmartContracts/validator.go | 8 +++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/vm/systemSmartContracts/delegation.go b/vm/systemSmartContracts/delegation.go index cb882fccb1a..ac33ba81da2 100644 --- a/vm/systemSmartContracts/delegation.go +++ b/vm/systemSmartContracts/delegation.go @@ -1216,8 +1216,9 @@ func (d *delegation) stakeNodes(args *vmcommon.ContractCallInput) vmcommon.Retur } allLogs := d.eei.GetLogs() - if tooManyNodesLogs(allLogs) { - d.eei.AddReturnMessage(numberOfNodesTooHigh) + tooManyNodesErrMsg := getTooManyNodesErrMsg(allLogs) + if len(tooManyNodesErrMsg) != 0 { + d.eei.AddReturnMessage(tooManyNodesErrMsg) return vmcommon.UserError } @@ -1232,17 +1233,25 @@ func (d *delegation) stakeNodes(args *vmcommon.ContractCallInput) vmcommon.Retur return vmcommon.Ok } -func tooManyNodesLogs(logEntries []*vmcommon.LogEntry) bool { +func getTooManyNodesErrMsg(logEntries []*vmcommon.LogEntry) string { for _, logEntry := range logEntries { - if len(logEntry.Topics) != 1 { + topics := logEntry.Topics + if len(topics) != 3 { continue } - if bytes.Equal(logEntry.Topics[0], []byte(numberOfNodesTooHigh)) { - return true + if bytes.Equal(topics[0], []byte(numberOfNodesTooHigh)) { + return formatTooManyNodesMsg(topics) } } - return false + return "" +} + +func formatTooManyNodesMsg(topics [][]byte) string { + numRegisteredBlsKeys := big.NewInt(0).SetBytes(topics[1]).Int64() + nodeLimit := big.NewInt(0).SetBytes(topics[2]).Int64() + return fmt.Sprintf("%s, num registered bls keys: %d, node limit: %d", + numberOfNodesTooHigh, numRegisteredBlsKeys, nodeLimit) } func (d *delegation) updateDelegationStatusAfterStake( diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index a3812174b93..8936be6ae7d 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -5123,6 +5123,8 @@ func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { output = d.Execute(vmInput) require.Equal(t, vmcommon.UserError, output) require.True(t, strings.Contains(eei.returnMessage, numberOfNodesTooHigh)) + require.True(t, strings.Contains(eei.returnMessage, "num registered bls keys: 4")) + require.True(t, strings.Contains(eei.returnMessage, "node limit: 3")) dStatus, _ = d.getDelegationStatus() require.Equal(t, 3, len(dStatus.StakedKeys)) diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 081a1e848f7..dbcd79ae883 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -1074,10 +1074,16 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod args.CallerAddr, ) } else { + numRegisteredBlsKeys := int64(len(registrationData.BlsPubKeys)) + nodeLimit := int64(float64(v.nodesCoordinator.GetNumTotalEligible()) * v.nodeLimitPercentage) entry := &vmcommon.LogEntry{ Identifier: []byte(args.Function), Address: args.RecipientAddr, - Topics: [][]byte{[]byte(numberOfNodesTooHigh)}, + Topics: [][]byte{ + []byte(numberOfNodesTooHigh), + big.NewInt(numRegisteredBlsKeys).Bytes(), + big.NewInt(nodeLimit).Bytes(), + }, } v.eei.AddLogEntry(entry) } From 7f58cea0e46888c5780a7aaa9319ccfad845ab3f Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 13:09:51 +0200 Subject: [PATCH 650/958] CLN: Add calcNodeLimit func --- vm/systemSmartContracts/validator.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index dbcd79ae883..d2f6148c002 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -936,8 +936,12 @@ func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) return false } + return len(registrationData.BlsPubKeys) > v.calcNodeLimit() +} + +func (v *validatorSC) calcNodeLimit() int { nodeLimit := float64(v.nodesCoordinator.GetNumTotalEligible()) * v.nodeLimitPercentage - return len(registrationData.BlsPubKeys) > int(nodeLimit) + return int(nodeLimit) } func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCode { @@ -1075,7 +1079,7 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod ) } else { numRegisteredBlsKeys := int64(len(registrationData.BlsPubKeys)) - nodeLimit := int64(float64(v.nodesCoordinator.GetNumTotalEligible()) * v.nodeLimitPercentage) + nodeLimit := int64(v.calcNodeLimit()) entry := &vmcommon.LogEntry{ Identifier: []byte(args.Function), Address: args.RecipientAddr, From 72b0415f2e5c043ba68a83b1254aac7f5c123b8a Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 30 Jan 2024 13:32:05 +0200 Subject: [PATCH 651/958] stake and unstake --- node/chainSimulator/chainSimulator.go | 40 +++++ node/chainSimulator/chainSimulator_test.go | 163 +++++++++++++++++++++ node/chainSimulator/dtos/validators.go | 5 + 3 files changed, 208 insertions(+) create mode 100644 node/chainSimulator/dtos/validators.go diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index a9fda865a59..2040db9b41e 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -2,6 +2,8 @@ package chainSimulator import ( "bytes" + "encoding/base64" + "encoding/hex" "fmt" "sync" "time" @@ -9,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" + crypto "github.com/multiversx/mx-chain-crypto-go" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" @@ -39,6 +42,7 @@ type simulator struct { syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler handlers []ChainHandler initialWalletKeys *dtos.InitialWalletKeys + validatorsPrivateKeys []crypto.PrivateKey nodes map[uint32]process.NodeHandler numOfShards uint32 mutex sync.RWMutex @@ -105,6 +109,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { } s.initialWalletKeys = outputConfigs.InitialWallets + s.validatorsPrivateKeys = outputConfigs.ValidatorsPrivateKeys log.Info("running the chain simulator with the following parameters", "number of shards (including meta)", args.NumOfShards+1, @@ -202,6 +207,41 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { return s.initialWalletKeys } +// AddValidatorKeys will add the provided validators private keys in the keys handler on all nodes +func (s *simulator) AddValidatorKeys(validatorsPrivateKeys *dtos.ValidatorsKeys) error { + s.mutex.Lock() + defer s.mutex.Unlock() + + for shard, node := range s.nodes { + for idx, privateKeyHex := range validatorsPrivateKeys.PrivateKeysBase64 { + decodedPrivateKey, err := base64.StdEncoding.DecodeString(privateKeyHex) + if err != nil { + return fmt.Errorf("cannot base64 decode provided key index=%d, error=%s", idx, err.Error()) + } + + hexDecoded, err := hex.DecodeString(string(decodedPrivateKey)) + if err != nil { + return fmt.Errorf("cannot hex decode provided key index=%d, error=%s", idx, err.Error()) + } + + err = node.GetCryptoComponents().ManagedPeersHolder().AddManagedPeer(hexDecoded) + if err != nil { + return fmt.Errorf("cannot add private key for shard=%d, index=%d, error=%s", shard, idx, err.Error()) + } + } + } + + return nil +} + +// GetValidatorPrivateKeys will return the initial validators private keys +func (s *simulator) GetValidatorPrivateKeys() []crypto.PrivateKey { + s.mutex.Lock() + defer s.mutex.Unlock() + + return s.validatorsPrivateKeys +} + // SetKeyValueForAddress will set the provided state for a given address func (s *simulator) SetKeyValueForAddress(address string, keyValueMap map[string]string) error { s.mutex.Lock() diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 770c55976a2..16d55098d89 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -2,6 +2,7 @@ package chainSimulator import ( "encoding/base64" + "encoding/hex" "fmt" "math/big" "testing" @@ -9,7 +10,9 @@ import ( "github.com/multiversx/mx-chain-core-go/core" coreAPI "github.com/multiversx/mx-chain-core-go/data/api" + "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/process" "github.com/stretchr/testify/assert" @@ -158,6 +161,156 @@ func TestChainSimulator_SetState(t *testing.T) { require.Equal(t, keyValueMap, keyValuePairs) } +// Test scenario +// 1. Add a new validator private key in the multi key handler +// 2. Do a stake transaction for the validator key +// 3. Do an unstake transaction (to make a place for the new validator) +// 4. Check if the new validator has generated rewards +func TestChainSimulator_AddValidatorKey(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + }) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + + err = chainSimulator.GenerateBlocks(30) + require.Nil(t, err) + + // add validator key + validatorKeys := &dtos.ValidatorsKeys{ + PrivateKeysBase64: []string{"NjRhYjk3NmJjYWVjZTBjNWQ4YmJhNGU1NjZkY2VmYWFiYjcxNDI1Y2JiZDcwYzc1ODA2MGUxNTE5MGM2ZjE1Zg=="}, + } + err = chainSimulator.AddValidatorKeys(validatorKeys) + require.Nil(t, err) + + newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" + newValidatorOwnerBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) + rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" + rcvAddrBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(rcv) + + // set balance for sender + err = chainSimulator.SetStateMultiple([]*dtos.AddressState{ + { + Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", + Balance: "10000000000000000000000", + }, + }) + require.Nil(t, err) + + blsKey := "9b7de1b2d2c90b7bea8f6855075c77d6c63b5dada29abb9b87c52cfae9d4112fcac13279e1a07d94672a5e62a83e3716555513014324d5c6bb4261b465f1b8549a7a338bc3ae8edc1e940958f9c2e296bd3c118a4466dec99dda0ceee3eb6a8c" + blsKeyBytes, _ := hex.DecodeString(blsKey) + privateKey := chainSimulator.nodes[0].GetCryptoComponents().KeysHandler().GetHandledPrivateKey(blsKeyBytes) + signedMessage, _ := chainSimulator.nodes[0].GetCryptoComponents().BlockSigner().Sign(privateKey, newValidatorOwnerBytes) + + // stake validator + stakeValue, _ := big.NewInt(0).SetString("2500000000000000000000", 10) + tx := &transaction.Transaction{ + Nonce: 0, + Value: stakeValue, + SndAddr: newValidatorOwnerBytes, + RcvAddr: rcvAddrBytes, + Data: []byte(fmt.Sprintf("stake@01@%s@%s", blsKey, hex.EncodeToString(signedMessage))), + GasLimit: 50_000_000, + GasPrice: 1000000000, + Signature: []byte("dummy"), + ChainID: []byte(configs.ChainID), + Version: 1, + } + + err = chainSimulator.nodes[1].GetFacadeHandler().ValidateTransaction(tx) + require.Nil(t, err) + + _, err = chainSimulator.nodes[1].GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) + require.Nil(t, err) + + time.Sleep(100 * time.Millisecond) + + err = chainSimulator.GenerateBlocks(5) + require.Nil(t, err) + + txHash, err := computeTxHash(chainSimulator, tx) + require.Nil(t, err) + txFromMeta, err := chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) + require.Nil(t, err) + require.NotNil(t, txFromMeta) + + shardIDValidatorOwner := chainSimulator.nodes[0].GetShardCoordinator().ComputeId(newValidatorOwnerBytes) + accountValidatorOwner, _, err := chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceBeforeActiveValidator := accountValidatorOwner.Balance + + // unstake validator + firstValitorKey, err := chainSimulator.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() + require.Nil(t, err) + + initialAddressWithValidators := chainSimulator.GetInitialWalletKeys().InitialWalletWithStake.Address + senderBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(initialAddressWithValidators) + shardID := chainSimulator.nodes[0].GetShardCoordinator().ComputeId(senderBytes) + initialAccount, _, err := chainSimulator.nodes[shardID].GetFacadeHandler().GetAccount(initialAddressWithValidators, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + tx = &transaction.Transaction{ + Nonce: initialAccount.Nonce, + Value: big.NewInt(0), + SndAddr: senderBytes, + RcvAddr: rcvAddrBytes, + Data: []byte(fmt.Sprintf("unStake@%s", hex.EncodeToString(firstValitorKey))), + GasLimit: 50_000_000, + GasPrice: 1000000000, + Signature: []byte("dummy"), + ChainID: []byte(configs.ChainID), + Version: 1, + } + err = chainSimulator.nodes[shardID].GetFacadeHandler().ValidateTransaction(tx) + require.Nil(t, err) + + _, err = chainSimulator.nodes[shardID].GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) + require.Nil(t, err) + + time.Sleep(100 * time.Millisecond) + + err = chainSimulator.GenerateBlocks(5) + require.Nil(t, err) + + txHash, err = computeTxHash(chainSimulator, tx) + require.Nil(t, err) + txFromMeta, err = chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) + require.Nil(t, err) + + // check rewards + err = chainSimulator.GenerateBlocks(50) + require.Nil(t, err) + + accountValidatorOwner, _, err = chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterActiveValidator := accountValidatorOwner.Balance + + fmt.Println("balance before validator", balanceBeforeActiveValidator) + fmt.Println("balance after validator", balanceAfterActiveValidator) + + balanceBeforeBig, _ := big.NewInt(0).SetString(balanceBeforeActiveValidator, 10) + balanceAfterBig, _ := big.NewInt(0).SetString(balanceAfterActiveValidator, 10) + diff := balanceAfterBig.Sub(balanceAfterBig, balanceBeforeBig) + fmt.Println("difference", diff.String()) + + // cumulated rewards should be greater than zero + require.True(t, diff.Cmp(big.NewInt(0)) > 0) +} + func TestChainSimulator_SetEntireState(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -232,3 +385,13 @@ func TestChainSimulator_SetEntireState(t *testing.T) { require.Equal(t, accountState.Owner, account.OwnerAddress) require.Equal(t, accountState.RootHash, base64.StdEncoding.EncodeToString(account.RootHash)) } + +func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) (string, error) { + txBytes, err := chainSimulator.GetNodeHandler(1).GetCoreComponents().InternalMarshalizer().Marshal(tx) + if err != nil { + return "", err + } + + txHasBytes := chainSimulator.GetNodeHandler(1).GetCoreComponents().Hasher().Compute(string(txBytes)) + return hex.EncodeToString(txHasBytes), nil +} diff --git a/node/chainSimulator/dtos/validators.go b/node/chainSimulator/dtos/validators.go new file mode 100644 index 00000000000..434964bd82e --- /dev/null +++ b/node/chainSimulator/dtos/validators.go @@ -0,0 +1,5 @@ +package dtos + +type ValidatorsKeys struct { + PrivateKeysBase64 []string `json:"privateKeysBase64"` +} From 3f41fe7b49185012a46cf0276df03974ad691669 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 30 Jan 2024 13:37:49 +0200 Subject: [PATCH 652/958] fix linter --- node/chainSimulator/chainSimulator_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 16d55098d89..3eda963f638 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -290,6 +290,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.Nil(t, err) txFromMeta, err = chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) require.Nil(t, err) + require.NotNil(t, txFromMeta) // check rewards err = chainSimulator.GenerateBlocks(50) From 85817dc0f7e8400ecfc7602a2e252b7dbcd794bd Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 14:30:52 +0200 Subject: [PATCH 653/958] FIX: stakingV4 after merge --- go.mod | 2 +- go.sum | 4 ++-- integrationTests/vm/staking/metaBlockProcessorCreator.go | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8c0a458138f..368bdaa9287 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 - github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 + github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130121943-195dd9705834 github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 diff --git a/go.sum b/go.sum index 11cb5b9a820..aa31cda2b96 100644 --- a/go.sum +++ b/go.sum @@ -399,8 +399,8 @@ github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1 github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 h1:/EYv/HGX0OKbeNFt667J0yZRtuJiZH0lEK8YtobuH/c= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 h1:zImJa/r6B5L2OLWbKTn5io53U11PPGDla12H2OaJ9y0= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130121943-195dd9705834 h1:XKrwmrwVyYOoHZnyIPyLQyCi0fTIFqbRZOtiv9dcpWY= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130121943-195dd9705834/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83 h1:G/d9aplnwP/9MrLE3gcANEpGfn5e8ZZufijPv2XVUfw= github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83/go.mod h1:64dTd60QUGWx5W3eU28IOfpqAWApWqB/Z7mJHmuQfXo= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 66ada9ee344..759458cf30e 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -103,6 +103,7 @@ func createMetaBlockProcessor( ReceiptsRepository: &testscommon.ReceiptsRepositoryStub{}, ManagedPeersHolder: &testscommon.ManagedPeersHolderStub{}, BlockProcessingCutoffHandler: &testscommon.BlockProcessingCutoffStub{}, + SentSignaturesTracker: &testscommon.SentSignatureTrackerStub{}, }, SCToProtocol: stakingToPeer, PendingMiniBlocksHandler: &mock.PendingMiniBlocksHandlerStub{}, From 6a7d93b2671f962a0917533b9af97499b678c820 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 14:57:48 +0200 Subject: [PATCH 654/958] FIX: Test --- integrationTests/state/stateTrie/stateTrie_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/integrationTests/state/stateTrie/stateTrie_test.go b/integrationTests/state/stateTrie/stateTrie_test.go index ecb1b9b8ee0..510fea77957 100644 --- a/integrationTests/state/stateTrie/stateTrie_test.go +++ b/integrationTests/state/stateTrie/stateTrie_test.go @@ -2480,7 +2480,6 @@ func startNodesAndIssueToken( enableEpochs := config.EnableEpochs{ GlobalMintBurnDisableEpoch: integrationTests.UnreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: integrationTests.UnreachableEpoch, OptimizeGasUsedInCrossMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, From 355ff7760e1a5c5df2551de833ce5bb72c5b6157 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 15:09:08 +0200 Subject: [PATCH 655/958] FIX: Test --- integrationTests/state/stateTrie/stateTrie_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integrationTests/state/stateTrie/stateTrie_test.go b/integrationTests/state/stateTrie/stateTrie_test.go index 510fea77957..688adc61353 100644 --- a/integrationTests/state/stateTrie/stateTrie_test.go +++ b/integrationTests/state/stateTrie/stateTrie_test.go @@ -2484,6 +2484,10 @@ func startNodesAndIssueToken( ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, StakingV2EnableEpoch: integrationTests.UnreachableEpoch, + StakeLimitsEnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step1EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step2EnableEpoch: integrationTests.UnreachableEpoch, + StakingV4Step3EnableEpoch: integrationTests.UnreachableEpoch, AutoBalanceDataTriesEnableEpoch: 1, } nodes := integrationTests.CreateNodesWithEnableEpochs( From 2923c4dc4d64aa10fdc902666ec47c543352a763 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 15:35:19 +0200 Subject: [PATCH 656/958] FIX: Config values --- cmd/node/config/systemSmartContractsConfig.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index dcc01dc7f51..efcf86ce248 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -11,8 +11,8 @@ MaxNumberOfNodesForStake = 36 UnJailValue = "2500000000000000000" #0.1% of genesis node price ActivateBLSPubKeyMessageVerification = false - StakeLimitPercentage = 0.01 #fraction of value 0.01 - 1% - NodeLimitPercentage = 0.005 #fraction of value 0.005 - 0.5% + StakeLimitPercentage = 1.0 #fraction of value 1 - 100%, for the time being no stake limit + NodeLimitPercentage = 0.1 #fraction of value 0.1 - 10% [ESDTSystemSCConfig] BaseIssuingCost = "5000000000000000000" #5 eGLD From d836893b051a7f39fb9932519d38cd201aa9eb0f Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 15:39:13 +0200 Subject: [PATCH 657/958] FIX: Unit test name --- vm/systemSmartContracts/delegation_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 8936be6ae7d..4dcab8d7e44 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -5045,7 +5045,7 @@ func TestDelegationSystemSC_SynchronizeOwner(t *testing.T) { }) } -func TestDelegationSystemSC_ExecuteAddNodesStakedInStakingV4(t *testing.T) { +func TestDelegationSystemSC_ExecuteAddNodesStakeNodesWithNodesLimit(t *testing.T) { t.Parallel() sig := []byte("sig1") From 7cc9bc975c9070a871409318a7279b903131cefd Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 30 Jan 2024 16:49:17 +0200 Subject: [PATCH 658/958] FIX: Func name --- vm/systemSmartContracts/validator.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index d2f6148c002..e7e02c5e55e 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -936,10 +936,10 @@ func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) return false } - return len(registrationData.BlsPubKeys) > v.calcNodeLimit() + return len(registrationData.BlsPubKeys) > v.computeNodeLimit() } -func (v *validatorSC) calcNodeLimit() int { +func (v *validatorSC) computeNodeLimit() int { nodeLimit := float64(v.nodesCoordinator.GetNumTotalEligible()) * v.nodeLimitPercentage return int(nodeLimit) } @@ -1079,7 +1079,7 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod ) } else { numRegisteredBlsKeys := int64(len(registrationData.BlsPubKeys)) - nodeLimit := int64(v.calcNodeLimit()) + nodeLimit := int64(v.computeNodeLimit()) entry := &vmcommon.LogEntry{ Identifier: []byte(args.Function), Address: args.RecipientAddr, From 32a7c63351a029f4d22fa8f8af6c0d56a65c77b2 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 30 Jan 2024 17:38:23 +0200 Subject: [PATCH 659/958] fixes --- node/chainSimulator/chainSimulator.go | 8 ++++++- node/chainSimulator/chainSimulator_test.go | 7 +++---- .../components/coreComponents.go | 21 +++++++++++++++---- .../components/cryptoComponents.go | 2 +- .../components/testOnlyProcessingNode.go | 4 ++++ node/chainSimulator/configs/configs.go | 2 +- 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 2040db9b41e..743905f2339 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -93,7 +93,9 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { shardIDStr = "metachain" } - node, errCreate := s.createTestNode(outputConfigs.Configs, shardIDStr, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck, args.InitialRound) + node, errCreate := s.createTestNode( + outputConfigs.Configs, shardIDStr, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck, args.InitialRound, args.MinNodesPerShard, args.MetaChainMinNodes, + ) if errCreate != nil { return errCreate } @@ -133,6 +135,8 @@ func (s *simulator) createTestNode( apiInterface components.APIConfigurator, bypassTxSignatureCheck bool, initialRound int64, + minNodesPerShard uint32, + minNodesMeta uint32, ) (process.NodeHandler, error) { args := components.ArgsTestOnlyProcessingNode{ Configs: *configs, @@ -144,6 +148,8 @@ func (s *simulator) createTestNode( APIInterface: apiInterface, BypassTxSignatureCheck: bypassTxSignatureCheck, InitialRound: initialRound, + MinNodesPerShard: minNodesPerShard, + MinNodesMeta: minNodesMeta, } return components.NewTestOnlyProcessingNode(args) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 3eda963f638..5ee1ba039ea 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -213,9 +213,6 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.Nil(t, err) blsKey := "9b7de1b2d2c90b7bea8f6855075c77d6c63b5dada29abb9b87c52cfae9d4112fcac13279e1a07d94672a5e62a83e3716555513014324d5c6bb4261b465f1b8549a7a338bc3ae8edc1e940958f9c2e296bd3c118a4466dec99dda0ceee3eb6a8c" - blsKeyBytes, _ := hex.DecodeString(blsKey) - privateKey := chainSimulator.nodes[0].GetCryptoComponents().KeysHandler().GetHandledPrivateKey(blsKeyBytes) - signedMessage, _ := chainSimulator.nodes[0].GetCryptoComponents().BlockSigner().Sign(privateKey, newValidatorOwnerBytes) // stake validator stakeValue, _ := big.NewInt(0).SetString("2500000000000000000000", 10) @@ -224,7 +221,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { Value: stakeValue, SndAddr: newValidatorOwnerBytes, RcvAddr: rcvAddrBytes, - Data: []byte(fmt.Sprintf("stake@01@%s@%s", blsKey, hex.EncodeToString(signedMessage))), + Data: []byte(fmt.Sprintf("stake@01@%s@010101", blsKey)), GasLimit: 50_000_000, GasPrice: 1000000000, Signature: []byte("dummy"), @@ -248,6 +245,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { txFromMeta, err := chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) require.Nil(t, err) require.NotNil(t, txFromMeta) + require.Equal(t, 2, len(txFromMeta.SmartContractResults)) shardIDValidatorOwner := chainSimulator.nodes[0].GetShardCoordinator().ComputeId(newValidatorOwnerBytes) accountValidatorOwner, _, err := chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) @@ -291,6 +289,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { txFromMeta, err = chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) require.Nil(t, err) require.NotNil(t, txFromMeta) + require.Equal(t, 2, len(txFromMeta.SmartContractResults)) // check rewards err = chainSimulator.GenerateBlocks(50) diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 0d311e3d103..1ea1f7d61dc 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -35,7 +35,6 @@ import ( "github.com/multiversx/mx-chain-go/storage" storageFactory "github.com/multiversx/mx-chain-go/storage/factory" "github.com/multiversx/mx-chain-go/testscommon" - "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" ) type coreComponentsHolder struct { @@ -88,6 +87,9 @@ type ArgsCoreComponentsHolder struct { GasScheduleFilename string NumShards uint32 WorkingDir string + + MinNodesPerShard uint32 + MinNodesMeta uint32 } // CreateCoreComponents will create a new instance of factory.CoreComponentsHolder @@ -200,9 +202,20 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents // TODO check if we need this instance.ratingsData = &testscommon.RatingsInfoMock{} instance.rater = &testscommon.RaterMock{} - - // TODO check if we need nodes shuffler - instance.nodesShuffler = &shardingMocks.NodeShufflerMock{} + ////////////////////////////// + + instance.nodesShuffler, err = nodesCoordinator.NewHashValidatorsShuffler(&nodesCoordinator.NodesShufflerArgs{ + NodesShard: args.MinNodesPerShard, + NodesMeta: args.MinNodesMeta, + Hysteresis: 0, + Adaptivity: false, + ShuffleBetweenShards: true, + MaxNodesEnableConfig: args.EnableEpochsConfig.MaxNodesChangeEnableEpoch, + EnableEpochsHandler: instance.enableEpochsHandler, + }) + if err != nil { + return nil, err + } instance.roundNotifier = forking.NewGenericRoundNotifier() instance.enableRoundsHandler, err = enablers.NewEnableRoundsHandler(args.RoundsConfig, instance.roundNotifier) diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 9a8649a0f47..42432636724 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -56,7 +56,7 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp PrefsConfig: args.Preferences, CoreComponentsHolder: args.CoreComponentsHolder, KeyLoader: core.NewKeyLoader(), - ActivateBLSPubKeyMessageVerification: true, + ActivateBLSPubKeyMessageVerification: false, IsInImportMode: false, ImportModeNoSigCheck: false, // set validator key pem file with a file that doesn't exist to all validators key pem file diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index c33d1999c47..14ec26cba86 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -43,6 +43,8 @@ type ArgsTestOnlyProcessingNode struct { NumShards uint32 ShardIDStr string BypassTxSignatureCheck bool + MinNodesPerShard uint32 + MinNodesMeta uint32 } type testOnlyProcessingNode struct { @@ -95,6 +97,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces GasScheduleFilename: args.GasScheduleFilename, NodesSetupPath: args.Configs.ConfigurationPathsHolder.Nodes, InitialRound: args.InitialRound, + MinNodesPerShard: args.MinNodesPerShard, + MinNodesMeta: args.MinNodesMeta, }) if err != nil { return nil, err diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index a87d8e83a5e..7795e4d25ae 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -103,7 +103,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) - maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards + args.MetaChainMinNodes) + maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + uint64(args.NumOfShards+1) configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes for idx := 0; idx < len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch); idx++ { configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[idx].MaxNumNodes = uint32(maxNumNodes) From 54d48f215ca2d8d0419403996076a52c535181f7 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Wed, 31 Jan 2024 17:00:54 +0200 Subject: [PATCH 660/958] compute existing and request missing meta headers tests --- process/block/metablock_request_test.go | 2 +- process/block/shardblock_request_test.go | 210 ++++++++++++++++++----- 2 files changed, 169 insertions(+), 43 deletions(-) diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go index 1764817d3c5..bdc90162231 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablock_request_test.go @@ -327,7 +327,7 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { hdrsForBlock := mp.GetHdrForBlock() hdrsForBlock.SetNumMissingHdrs(1) hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) - referencedHeaderData := td[0].attestationHeaderData + referencedHeaderData := td[0].referencedHeaderData hdrsForBlock.SetHighestHdrNonce(0, referencedHeaderData.header.GetNonce()-1) hdrsForBlock.SetHdrHashAndInfo(string(referencedHeaderData.headerHash), &blockProcess.HdrInfo{ UsedInBlock: true, diff --git a/process/block/shardblock_request_test.go b/process/block/shardblock_request_test.go index f00ef79b23a..10cb7b73f1b 100644 --- a/process/block/shardblock_request_test.go +++ b/process/block/shardblock_request_test.go @@ -1,6 +1,7 @@ package block_test import ( + "bytes" "fmt" "sync/atomic" "testing" @@ -22,8 +23,7 @@ type headerData struct { } type shardBlockTestData struct { - headerData *headerData - confirmationHeaderData *headerData + headerData []*headerData } func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { @@ -34,12 +34,13 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { arguments, requestHandler := shardBlockRequestTestInit(t) testData := createShardProcessorTestData() + metaChainData := testData[core.MetachainShardId] numCalls := atomic.Uint32{} requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) } requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { - attestationNonce := testData[core.MetachainShardId].confirmationHeaderData.header.GetNonce() + attestationNonce := metaChainData.headerData[1].header.GetNonce() if nonce != attestationNonce { require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) } @@ -47,7 +48,7 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { } sp, _ := blproc.NewShardProcessor(arguments) - metaBlockData := testData[core.MetachainShardId].headerData + metaBlockData := metaChainData.headerData[0] // not adding the confirmation metaBlock to the headers pool means it will be missing and requested sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) res := sp.RequestMissingFinalityAttestingHeaders() @@ -61,6 +62,7 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { arguments, requestHandler := shardBlockRequestTestInit(t) testData := createShardProcessorTestData() + metaChainData := testData[core.MetachainShardId] requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) } @@ -71,8 +73,8 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { headersDataPool := arguments.DataComponents.Datapool().Headers() require.NotNil(t, headersDataPool) - metaBlockData := testData[core.MetachainShardId].headerData - confirmationMetaBlockData := testData[core.MetachainShardId].confirmationHeaderData + metaBlockData := metaChainData.headerData[0] + confirmationMetaBlockData := metaChainData.headerData[1] headersDataPool.AddHeader(confirmationMetaBlockData.hash, confirmationMetaBlockData.header) sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) res := sp.RequestMissingFinalityAttestingHeaders() @@ -85,46 +87,162 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { func TestShardProcessor_computeExistingAndRequestMissingMetaHeaders(t *testing.T) { t.Parallel() + shard1ID := uint32(1) t.Run("one referenced metaBlock missing will be requested", func(t *testing.T) { t.Parallel() arguments, requestHandler := shardBlockRequestTestInit(t) testData := createShardProcessorTestData() + metaChainData := testData[core.MetachainShardId] + shard1Data := testData[shard1ID] numCalls := atomic.Uint32{} requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) } requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { - attestationNonce := testData[core.MetachainShardId].confirmationHeaderData.header.GetNonce() - if nonce == attestationNonce { - require.Fail(t, fmt.Sprintf("should not request attestation block with nonce %d", attestationNonce)) - } - referencedMetaBlockNonce := testData[core.MetachainShardId].headerData.header.GetNonce() - if nonce != referencedMetaBlockNonce { - require.Fail(t, fmt.Sprintf("requested nonce should have been %d", referencedMetaBlockNonce)) - } + // should only be called when requesting attestation meta header block + require.Fail(t, "should not request meta header by nonce") + } + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + require.Equal(t, metaChainData.headerData[1].hash, hash) numCalls.Add(1) } sp, _ := blproc.NewShardProcessor(arguments) - metaBlockData := testData[core.MetachainShardId].headerData - // not adding the referenced metaBlock to the headers pool means it will be missing and requested + metaBlockData := metaChainData.headerData[0] sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) + // not adding the referenced metaBlock to the headers pool means it will be missing and requested + // first of the 2 referenced headers is added, the other will be missing + headersDataPool := arguments.DataComponents.Datapool().Headers() + headersDataPool.AddHeader(metaBlockData.hash, metaBlockData.header) - // sp.ComputeExistingAndRequestMissingMetaHeaders() + blockBeingProcessed := shard1Data.headerData[1].header + shardBlockBeingProcessed := blockBeingProcessed.(*block.Header) + missingHeaders, missingFinalityAttestingHeaders := sp.ComputeExistingAndRequestMissingMetaHeaders(shardBlockBeingProcessed) + time.Sleep(100 * time.Millisecond) + require.Equal(t, uint32(1), missingHeaders) + require.Equal(t, uint32(0), missingFinalityAttestingHeaders) + require.Equal(t, uint32(1), numCalls.Load()) }) t.Run("multiple referenced metaBlocks missing will be requested", func(t *testing.T) { t.Parallel() + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + numCalls := atomic.Uint32{} + metaChainData := testData[core.MetachainShardId] + shard1Data := testData[shard1ID] + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + // not yet requesting the attestation metaBlock + require.Fail(t, "should not request meta header by nonce") + } + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + if !(bytes.Equal(hash, metaChainData.headerData[0].hash) || bytes.Equal(hash, metaChainData.headerData[1].hash)) { + require.Fail(t, "other requests than the expected 2 metaBlocks are not expected") + } + + numCalls.Add(1) + } + sp, _ := blproc.NewShardProcessor(arguments) + metaBlockData := testData[core.MetachainShardId].headerData[0] + // not adding the referenced metaBlock to the headers pool means it will be missing and requested + sp.SetHighestHdrNonceForCurrentBlock(core.MetachainShardId, metaBlockData.header.GetNonce()) + + blockBeingProcessed := shard1Data.headerData[1].header + shardBlockBeingProcessed := blockBeingProcessed.(*block.Header) + missingHeaders, missingFinalityAttestingHeaders := sp.ComputeExistingAndRequestMissingMetaHeaders(shardBlockBeingProcessed) + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(2), missingHeaders) + require.Equal(t, uint32(0), missingFinalityAttestingHeaders) + require.Equal(t, uint32(2), numCalls.Load()) }) t.Run("all referenced metaBlocks existing with missing attestation, will request the attestation metaBlock", func(t *testing.T) { t.Parallel() + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + numCallsMissing := atomic.Uint32{} + numCallsAttestation := atomic.Uint32{} + metaChainData := testData[core.MetachainShardId] + shard1Data := testData[shard1ID] + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + // not yet requesting the attestation metaBlock + require.Equal(t, metaChainData.headerData[1].header.GetNonce()+1, nonce) + numCallsAttestation.Add(1) + } + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + if !(bytes.Equal(hash, metaChainData.headerData[0].hash) || bytes.Equal(hash, metaChainData.headerData[1].hash)) { + require.Fail(t, "other requests than the expected 2 metaBlocks are not expected") + } + + numCallsMissing.Add(1) + } + sp, _ := blproc.NewShardProcessor(arguments) + // not adding the referenced metaBlock to the headers pool means it will be missing and requested + headersDataPool := arguments.DataComponents.Datapool().Headers() + headersDataPool.AddHeader(metaChainData.headerData[0].hash, metaChainData.headerData[0].header) + headersDataPool.AddHeader(metaChainData.headerData[1].hash, metaChainData.headerData[1].header) + + blockBeingProcessed := shard1Data.headerData[1].header + shardBlockBeingProcessed := blockBeingProcessed.(*block.Header) + missingHeaders, missingFinalityAttestingHeaders := sp.ComputeExistingAndRequestMissingMetaHeaders(shardBlockBeingProcessed) + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(0), missingHeaders) + require.Equal(t, uint32(1), missingFinalityAttestingHeaders) + require.Equal(t, uint32(0), numCallsMissing.Load()) + require.Equal(t, uint32(1), numCallsAttestation.Load()) }) t.Run("all referenced metaBlocks existing and existing attestation metaBlock will not request", func(t *testing.T) { t.Parallel() + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + numCallsMissing := atomic.Uint32{} + numCallsAttestation := atomic.Uint32{} + shard1Data := testData[shard1ID] + metaChainData := testData[core.MetachainShardId] + requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { + require.Fail(t, fmt.Sprintf("should not request shard header by nonce, shardID: %d, nonce: %d", shardID, nonce)) + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + numCallsAttestation.Add(1) + } + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + numCallsMissing.Add(1) + } + sp, _ := blproc.NewShardProcessor(arguments) + // not adding the referenced metaBlock to the headers pool means it will be missing and requested + headersDataPool := arguments.DataComponents.Datapool().Headers() + headersDataPool.AddHeader(metaChainData.headerData[0].hash, metaChainData.headerData[0].header) + headersDataPool.AddHeader(metaChainData.headerData[1].hash, metaChainData.headerData[1].header) + attestationMetaBlock := &block.MetaBlock{ + Nonce: 102, + Round: 102, + PrevHash: metaChainData.headerData[1].hash, + ShardInfo: []block.ShardData{}, + } + attestationMetaBlockHash := []byte("attestationHash") + + headersDataPool.AddHeader(attestationMetaBlockHash, attestationMetaBlock) + + blockBeingProcessed := shard1Data.headerData[1].header + shardBlockBeingProcessed := blockBeingProcessed.(*block.Header) + missingHeaders, missingFinalityAttestingHeaders := sp.ComputeExistingAndRequestMissingMetaHeaders(shardBlockBeingProcessed) + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(0), missingHeaders) + require.Equal(t, uint32(0), missingFinalityAttestingHeaders) + require.Equal(t, uint32(0), numCallsMissing.Load()) + require.Equal(t, uint32(0), numCallsAttestation.Load()) }) } @@ -218,10 +336,11 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { } shar1Block1 := &block.Header{ - ShardID: 1, - PrevHash: shard1Block0Hash, - Nonce: 102, - Round: 102, + ShardID: 1, + PrevHash: shard1Block0Hash, + MetaBlockHashes: [][]byte{prevMetaBlockHash}, + Nonce: 102, + Round: 102, MiniBlockHeaders: []block.MiniBlockHeader{ {Hash: mbHash4, SenderShardID: 0, ReceiverShardID: 1}, {Hash: mbHash5, SenderShardID: 0, ReceiverShardID: 1}, @@ -232,6 +351,7 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { shard1Block2 := &block.Header{ ShardID: 1, PrevHash: shard1Block1Hash, + MetaBlockHashes: [][]byte{metaBlockHash, metaConfirmationHash}, Nonce: 103, Round: 103, MiniBlockHeaders: []block.MiniBlockHeader{}, @@ -239,33 +359,39 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { sbd := map[uint32]*shardBlockTestData{ 0: { - headerData: &headerData{ - hash: shard0Block1Hash, - header: shard0Block1, - }, - confirmationHeaderData: &headerData{ - hash: shard0Block2Hash, - header: shard0Block2, + headerData: []*headerData{ + { + hash: shard0Block1Hash, + header: shard0Block1, + }, + { + hash: shard0Block2Hash, + header: shard0Block2, + }, }, }, 1: { - headerData: &headerData{ - hash: shard1Block1Hash, - header: shar1Block1, - }, - confirmationHeaderData: &headerData{ - hash: shard1Block2Hash, - header: shard1Block2, + headerData: []*headerData{ + { + hash: shard1Block1Hash, + header: shar1Block1, + }, + { + hash: shard1Block2Hash, + header: shard1Block2, + }, }, }, core.MetachainShardId: { - headerData: &headerData{ - hash: metaBlockHash, - header: metaBlock, - }, - confirmationHeaderData: &headerData{ - hash: metaConfirmationHash, - header: metaConfirmationBlock, + headerData: []*headerData{ + { + hash: metaBlockHash, + header: metaBlock, + }, + { + hash: metaConfirmationHash, + header: metaConfirmationBlock, + }, }, }, } From 8975f7999af59d78d2cad911cbbd0e2db470a782 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 31 Jan 2024 18:36:51 +0200 Subject: [PATCH 661/958] - added a critical section in the trie nodes resolvers and a different throttler --- cmd/node/config/config.toml | 1 + config/config.go | 19 ++--- .../factory/resolverscontainer/args.go | 35 +++++----- .../baseResolversContainerFactory.go | 8 ++- .../metaResolversContainerFactory.go | 10 ++- .../metaResolversContainerFactory_test.go | 40 ++++++----- .../shardResolversContainerFactory.go | 10 ++- .../shardResolversContainerFactory_test.go | 40 ++++++----- dataRetriever/resolvers/trieNodeResolver.go | 12 ++++ epochStart/bootstrap/process.go | 33 ++++----- factory/processing/processComponents.go | 70 ++++++++++--------- integrationTests/testHeartbeatNode.go | 15 ++-- integrationTests/testProcessorNode.go | 33 ++++----- testscommon/generalConfig.go | 3 +- 14 files changed, 191 insertions(+), 138 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 184bf0db1ac..0e4bdf0c9fb 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -519,6 +519,7 @@ [Antiflood] Enabled = true NumConcurrentResolverJobs = 50 + NumConcurrentResolvingTrieNodesJobs = 3 [Antiflood.FastReacting] IntervalInSeconds = 1 ReservedPercent = 20.0 diff --git a/config/config.go b/config/config.go index b53e46a2201..366e288ee8e 100644 --- a/config/config.go +++ b/config/config.go @@ -362,15 +362,16 @@ type TxAccumulatorConfig struct { // AntifloodConfig will hold all p2p antiflood parameters type AntifloodConfig struct { - Enabled bool - NumConcurrentResolverJobs int32 - OutOfSpecs FloodPreventerConfig - FastReacting FloodPreventerConfig - SlowReacting FloodPreventerConfig - PeerMaxOutput AntifloodLimitsConfig - Cache CacheConfig - Topic TopicAntifloodConfig - TxAccumulator TxAccumulatorConfig + Enabled bool + NumConcurrentResolverJobs int32 + NumConcurrentResolvingTrieNodesJobs int32 + OutOfSpecs FloodPreventerConfig + FastReacting FloodPreventerConfig + SlowReacting FloodPreventerConfig + PeerMaxOutput AntifloodLimitsConfig + Cache CacheConfig + Topic TopicAntifloodConfig + TxAccumulator TxAccumulatorConfig } // FloodPreventerConfig will hold all flood preventer parameters diff --git a/dataRetriever/factory/resolverscontainer/args.go b/dataRetriever/factory/resolverscontainer/args.go index 1446af01b97..d0001014a4d 100644 --- a/dataRetriever/factory/resolverscontainer/args.go +++ b/dataRetriever/factory/resolverscontainer/args.go @@ -11,21 +11,22 @@ import ( // FactoryArgs will hold the arguments for ResolversContainerFactory for both shard and meta type FactoryArgs struct { - NumConcurrentResolvingJobs int32 - ShardCoordinator sharding.Coordinator - MainMessenger p2p.Messenger - FullArchiveMessenger p2p.Messenger - Store dataRetriever.StorageService - Marshalizer marshal.Marshalizer - DataPools dataRetriever.PoolsHolder - Uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter - DataPacker dataRetriever.DataPacker - TriesContainer common.TriesHolder - InputAntifloodHandler dataRetriever.P2PAntifloodHandler - OutputAntifloodHandler dataRetriever.P2PAntifloodHandler - MainPreferredPeersHolder p2p.PreferredPeersHolderHandler - FullArchivePreferredPeersHolder p2p.PreferredPeersHolderHandler - SizeCheckDelta uint32 - IsFullHistoryNode bool - PayloadValidator dataRetriever.PeerAuthenticationPayloadValidator + NumConcurrentResolvingJobs int32 + NumConcurrentResolvingTrieNodesJobs int32 + ShardCoordinator sharding.Coordinator + MainMessenger p2p.Messenger + FullArchiveMessenger p2p.Messenger + Store dataRetriever.StorageService + Marshalizer marshal.Marshalizer + DataPools dataRetriever.PoolsHolder + Uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter + DataPacker dataRetriever.DataPacker + TriesContainer common.TriesHolder + InputAntifloodHandler dataRetriever.P2PAntifloodHandler + OutputAntifloodHandler dataRetriever.P2PAntifloodHandler + MainPreferredPeersHolder p2p.PreferredPeersHolderHandler + FullArchivePreferredPeersHolder p2p.PreferredPeersHolderHandler + SizeCheckDelta uint32 + IsFullHistoryNode bool + PayloadValidator dataRetriever.PeerAuthenticationPayloadValidator } diff --git a/dataRetriever/factory/resolverscontainer/baseResolversContainerFactory.go b/dataRetriever/factory/resolverscontainer/baseResolversContainerFactory.go index c1fc1e3a16b..3d0eff8eaa9 100644 --- a/dataRetriever/factory/resolverscontainer/baseResolversContainerFactory.go +++ b/dataRetriever/factory/resolverscontainer/baseResolversContainerFactory.go @@ -36,6 +36,7 @@ type baseResolversContainerFactory struct { inputAntifloodHandler dataRetriever.P2PAntifloodHandler outputAntifloodHandler dataRetriever.P2PAntifloodHandler throttler dataRetriever.ResolverThrottler + trieNodesThrottler dataRetriever.ResolverThrottler intraShardTopic string isFullHistoryNode bool mainPreferredPeersHolder dataRetriever.PreferredPeersHolderHandler @@ -78,7 +79,10 @@ func (brcf *baseResolversContainerFactory) checkParams() error { return fmt.Errorf("%w for output", dataRetriever.ErrNilAntifloodHandler) } if check.IfNil(brcf.throttler) { - return dataRetriever.ErrNilThrottler + return fmt.Errorf("%w for the main throttler", dataRetriever.ErrNilThrottler) + } + if check.IfNil(brcf.trieNodesThrottler) { + return fmt.Errorf("%w for the trie nodes throttler", dataRetriever.ErrNilThrottler) } if check.IfNil(brcf.mainPreferredPeersHolder) { return fmt.Errorf("%w for main network", dataRetriever.ErrNilPreferredPeersHolder) @@ -351,7 +355,7 @@ func (brcf *baseResolversContainerFactory) createTrieNodesResolver( SenderResolver: resolverSender, Marshaller: brcf.marshalizer, AntifloodHandler: brcf.inputAntifloodHandler, - Throttler: brcf.throttler, + Throttler: brcf.trieNodesThrottler, }, TrieDataGetter: trie, } diff --git a/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory.go b/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory.go index 426a978ae20..b72f8c3154a 100644 --- a/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory.go +++ b/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory.go @@ -27,7 +27,12 @@ func NewMetaResolversContainerFactory( args.Marshalizer = marshal.NewSizeCheckUnmarshalizer(args.Marshalizer, args.SizeCheckDelta) } - thr, err := throttler.NewNumGoRoutinesThrottler(args.NumConcurrentResolvingJobs) + mainThrottler, err := throttler.NewNumGoRoutinesThrottler(args.NumConcurrentResolvingJobs) + if err != nil { + return nil, err + } + + trieNodesThrottler, err := throttler.NewNumGoRoutinesThrottler(args.NumConcurrentResolvingTrieNodesJobs) if err != nil { return nil, err } @@ -46,7 +51,8 @@ func NewMetaResolversContainerFactory( triesContainer: args.TriesContainer, inputAntifloodHandler: args.InputAntifloodHandler, outputAntifloodHandler: args.OutputAntifloodHandler, - throttler: thr, + throttler: mainThrottler, + trieNodesThrottler: trieNodesThrottler, isFullHistoryNode: args.IsFullHistoryNode, mainPreferredPeersHolder: args.MainPreferredPeersHolder, fullArchivePreferredPeersHolder: args.FullArchivePreferredPeersHolder, diff --git a/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory_test.go b/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory_test.go index c6659693d79..755672384cd 100644 --- a/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory_test.go +++ b/dataRetriever/factory/resolverscontainer/metaResolversContainerFactory_test.go @@ -94,8 +94,15 @@ func TestNewMetaResolversContainerFactory_NewNumGoRoutinesThrottlerFailsShouldEr args := getArgumentsMeta() args.NumConcurrentResolvingJobs = 0 + rcf, err := resolverscontainer.NewMetaResolversContainerFactory(args) + assert.Nil(t, rcf) + assert.Equal(t, core.ErrNotPositiveValue, err) + + args.NumConcurrentResolvingJobs = 10 + args.NumConcurrentResolvingTrieNodesJobs = 0 + rcf, err = resolverscontainer.NewMetaResolversContainerFactory(args) assert.Nil(t, rcf) assert.Equal(t, core.ErrNotPositiveValue, err) } @@ -357,21 +364,22 @@ func TestMetaResolversContainerFactory_IsInterfaceNil(t *testing.T) { func getArgumentsMeta() resolverscontainer.FactoryArgs { return resolverscontainer.FactoryArgs{ - ShardCoordinator: mock.NewOneShardCoordinatorMock(), - MainMessenger: createStubMessengerForMeta("", ""), - FullArchiveMessenger: createStubMessengerForMeta("", ""), - Store: createStoreForMeta(), - Marshalizer: &mock.MarshalizerMock{}, - DataPools: createDataPoolsForMeta(), - Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, - DataPacker: &mock.DataPackerStub{}, - TriesContainer: createTriesHolderForMeta(), - SizeCheckDelta: 0, - InputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, - OutputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, - NumConcurrentResolvingJobs: 10, - MainPreferredPeersHolder: &p2pmocks.PeersHolderStub{}, - FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, - PayloadValidator: &testscommon.PeerAuthenticationPayloadValidatorStub{}, + ShardCoordinator: mock.NewOneShardCoordinatorMock(), + MainMessenger: createStubMessengerForMeta("", ""), + FullArchiveMessenger: createStubMessengerForMeta("", ""), + Store: createStoreForMeta(), + Marshalizer: &mock.MarshalizerMock{}, + DataPools: createDataPoolsForMeta(), + Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, + DataPacker: &mock.DataPackerStub{}, + TriesContainer: createTriesHolderForMeta(), + SizeCheckDelta: 0, + InputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, + OutputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, + NumConcurrentResolvingJobs: 10, + NumConcurrentResolvingTrieNodesJobs: 3, + MainPreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + PayloadValidator: &testscommon.PeerAuthenticationPayloadValidatorStub{}, } } diff --git a/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory.go b/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory.go index 28582f03bc5..f24beaa4331 100644 --- a/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory.go +++ b/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory.go @@ -25,7 +25,12 @@ func NewShardResolversContainerFactory( args.Marshalizer = marshal.NewSizeCheckUnmarshalizer(args.Marshalizer, args.SizeCheckDelta) } - thr, err := throttler.NewNumGoRoutinesThrottler(args.NumConcurrentResolvingJobs) + mainThrottler, err := throttler.NewNumGoRoutinesThrottler(args.NumConcurrentResolvingJobs) + if err != nil { + return nil, err + } + + trieNodesThrottler, err := throttler.NewNumGoRoutinesThrottler(args.NumConcurrentResolvingTrieNodesJobs) if err != nil { return nil, err } @@ -44,7 +49,8 @@ func NewShardResolversContainerFactory( triesContainer: args.TriesContainer, inputAntifloodHandler: args.InputAntifloodHandler, outputAntifloodHandler: args.OutputAntifloodHandler, - throttler: thr, + throttler: mainThrottler, + trieNodesThrottler: trieNodesThrottler, isFullHistoryNode: args.IsFullHistoryNode, mainPreferredPeersHolder: args.MainPreferredPeersHolder, fullArchivePreferredPeersHolder: args.FullArchivePreferredPeersHolder, diff --git a/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory_test.go b/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory_test.go index 4d6ca351195..ca97015f3ae 100644 --- a/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory_test.go +++ b/dataRetriever/factory/resolverscontainer/shardResolversContainerFactory_test.go @@ -100,8 +100,15 @@ func TestNewShardResolversContainerFactory_NewNumGoRoutinesThrottlerFailsShouldE args := getArgumentsShard() args.NumConcurrentResolvingJobs = 0 + rcf, err := resolverscontainer.NewShardResolversContainerFactory(args) + assert.Nil(t, rcf) + assert.Equal(t, core.ErrNotPositiveValue, err) + + args.NumConcurrentResolvingJobs = 10 + args.NumConcurrentResolvingTrieNodesJobs = 0 + rcf, err = resolverscontainer.NewShardResolversContainerFactory(args) assert.Nil(t, rcf) assert.Equal(t, core.ErrNotPositiveValue, err) } @@ -465,21 +472,22 @@ func TestShardResolversContainerFactory_IsInterfaceNil(t *testing.T) { func getArgumentsShard() resolverscontainer.FactoryArgs { return resolverscontainer.FactoryArgs{ - ShardCoordinator: mock.NewOneShardCoordinatorMock(), - MainMessenger: createMessengerStubForShard("", ""), - FullArchiveMessenger: createMessengerStubForShard("", ""), - Store: createStoreForShard(), - Marshalizer: &mock.MarshalizerMock{}, - DataPools: createDataPoolsForShard(), - Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, - DataPacker: &mock.DataPackerStub{}, - TriesContainer: createTriesHolderForShard(), - SizeCheckDelta: 0, - InputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, - OutputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, - NumConcurrentResolvingJobs: 10, - MainPreferredPeersHolder: &p2pmocks.PeersHolderStub{}, - FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, - PayloadValidator: &testscommon.PeerAuthenticationPayloadValidatorStub{}, + ShardCoordinator: mock.NewOneShardCoordinatorMock(), + MainMessenger: createMessengerStubForShard("", ""), + FullArchiveMessenger: createMessengerStubForShard("", ""), + Store: createStoreForShard(), + Marshalizer: &mock.MarshalizerMock{}, + DataPools: createDataPoolsForShard(), + Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, + DataPacker: &mock.DataPackerStub{}, + TriesContainer: createTriesHolderForShard(), + SizeCheckDelta: 0, + InputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, + OutputAntifloodHandler: &mock.P2PAntifloodHandlerStub{}, + NumConcurrentResolvingJobs: 10, + NumConcurrentResolvingTrieNodesJobs: 3, + MainPreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + PayloadValidator: &testscommon.PeerAuthenticationPayloadValidatorStub{}, } } diff --git a/dataRetriever/resolvers/trieNodeResolver.go b/dataRetriever/resolvers/trieNodeResolver.go index 871ed85fee5..275327d44c6 100644 --- a/dataRetriever/resolvers/trieNodeResolver.go +++ b/dataRetriever/resolvers/trieNodeResolver.go @@ -1,6 +1,8 @@ package resolvers import ( + "sync" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data/batch" @@ -20,6 +22,7 @@ type ArgTrieNodeResolver struct { // TrieNodeResolver is a wrapper over Resolver that is specialized in resolving trie node requests type TrieNodeResolver struct { + mutCriticalSection sync.Mutex *baseResolver messageProcessor trieDataGetter dataRetriever.TrieDataGetter @@ -104,6 +107,9 @@ func (tnRes *TrieNodeResolver) resolveMultipleHashes(hashesBuff []byte, message } func (tnRes *TrieNodeResolver) resolveOnlyRequestedHashes(hashes [][]byte, nodes map[string]struct{}) (int, bool) { + tnRes.mutCriticalSection.Lock() + defer tnRes.mutCriticalSection.Unlock() + spaceUsed := 0 usedAllSpace := false remainingSpace := core.MaxBufferSizeToSendTrieNodes @@ -129,6 +135,9 @@ func (tnRes *TrieNodeResolver) resolveOnlyRequestedHashes(hashes [][]byte, nodes } func (tnRes *TrieNodeResolver) resolveSubTries(hashes [][]byte, nodes map[string]struct{}, spaceUsedAlready int) { + tnRes.mutCriticalSection.Lock() + defer tnRes.mutCriticalSection.Unlock() + var serializedNodes [][]byte var err error var serializedNode []byte @@ -168,7 +177,10 @@ func convertMapToSlice(m map[string]struct{}) [][]byte { } func (tnRes *TrieNodeResolver) resolveOneHash(hash []byte, chunkIndex uint32, message p2p.MessageP2P, source p2p.MessageHandler) error { + tnRes.mutCriticalSection.Lock() serializedNode, err := tnRes.trieDataGetter.GetSerializedNode(hash) + tnRes.mutCriticalSection.Unlock() + if err != nil { return err } diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index d4f3f2a58d6..5dd718ea802 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -1210,22 +1210,23 @@ func (e *epochStartBootstrap) createResolversContainer() error { // this one should only be used before determining the correct shard where the node should reside log.Debug("epochStartBootstrap.createRequestHandler", "shard", e.shardCoordinator.SelfId()) resolversContainerArgs := resolverscontainer.FactoryArgs{ - ShardCoordinator: e.shardCoordinator, - MainMessenger: e.mainMessenger, - FullArchiveMessenger: e.fullArchiveMessenger, - Store: storageService, - Marshalizer: e.coreComponentsHolder.InternalMarshalizer(), - DataPools: e.dataPool, - Uint64ByteSliceConverter: uint64ByteSlice.NewBigEndianConverter(), - NumConcurrentResolvingJobs: 10, - DataPacker: dataPacker, - TriesContainer: e.trieContainer, - SizeCheckDelta: 0, - InputAntifloodHandler: disabled.NewAntiFloodHandler(), - OutputAntifloodHandler: disabled.NewAntiFloodHandler(), - MainPreferredPeersHolder: disabled.NewPreferredPeersHolder(), - FullArchivePreferredPeersHolder: disabled.NewPreferredPeersHolder(), - PayloadValidator: payloadValidator, + ShardCoordinator: e.shardCoordinator, + MainMessenger: e.mainMessenger, + FullArchiveMessenger: e.fullArchiveMessenger, + Store: storageService, + Marshalizer: e.coreComponentsHolder.InternalMarshalizer(), + DataPools: e.dataPool, + Uint64ByteSliceConverter: uint64ByteSlice.NewBigEndianConverter(), + NumConcurrentResolvingJobs: 10, + NumConcurrentResolvingTrieNodesJobs: 3, + DataPacker: dataPacker, + TriesContainer: e.trieContainer, + SizeCheckDelta: 0, + InputAntifloodHandler: disabled.NewAntiFloodHandler(), + OutputAntifloodHandler: disabled.NewAntiFloodHandler(), + MainPreferredPeersHolder: disabled.NewPreferredPeersHolder(), + FullArchivePreferredPeersHolder: disabled.NewPreferredPeersHolder(), + PayloadValidator: payloadValidator, } resolverFactory, err := resolverscontainer.NewMetaResolversContainerFactory(resolversContainerArgs) if err != nil { diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index f36eee4e29e..d58c8d14e8e 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -1365,23 +1365,24 @@ func (pcf *processComponentsFactory) newShardResolverContainerFactory( } resolversContainerFactoryArgs := resolverscontainer.FactoryArgs{ - ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), - MainMessenger: pcf.network.NetworkMessenger(), - FullArchiveMessenger: pcf.network.FullArchiveNetworkMessenger(), - Store: pcf.data.StorageService(), - Marshalizer: pcf.coreData.InternalMarshalizer(), - DataPools: pcf.data.Datapool(), - Uint64ByteSliceConverter: pcf.coreData.Uint64ByteSliceConverter(), - DataPacker: dataPacker, - TriesContainer: pcf.state.TriesContainer(), - SizeCheckDelta: pcf.config.Marshalizer.SizeCheckDelta, - InputAntifloodHandler: pcf.network.InputAntiFloodHandler(), - OutputAntifloodHandler: pcf.network.OutputAntiFloodHandler(), - NumConcurrentResolvingJobs: pcf.config.Antiflood.NumConcurrentResolverJobs, - IsFullHistoryNode: pcf.prefConfigs.Preferences.FullArchive, - MainPreferredPeersHolder: pcf.network.PreferredPeersHolderHandler(), - FullArchivePreferredPeersHolder: pcf.network.FullArchivePreferredPeersHolderHandler(), - PayloadValidator: payloadValidator, + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + MainMessenger: pcf.network.NetworkMessenger(), + FullArchiveMessenger: pcf.network.FullArchiveNetworkMessenger(), + Store: pcf.data.StorageService(), + Marshalizer: pcf.coreData.InternalMarshalizer(), + DataPools: pcf.data.Datapool(), + Uint64ByteSliceConverter: pcf.coreData.Uint64ByteSliceConverter(), + DataPacker: dataPacker, + TriesContainer: pcf.state.TriesContainer(), + SizeCheckDelta: pcf.config.Marshalizer.SizeCheckDelta, + InputAntifloodHandler: pcf.network.InputAntiFloodHandler(), + OutputAntifloodHandler: pcf.network.OutputAntiFloodHandler(), + NumConcurrentResolvingJobs: pcf.config.Antiflood.NumConcurrentResolverJobs, + NumConcurrentResolvingTrieNodesJobs: pcf.config.Antiflood.NumConcurrentResolvingTrieNodesJobs, + IsFullHistoryNode: pcf.prefConfigs.Preferences.FullArchive, + MainPreferredPeersHolder: pcf.network.PreferredPeersHolderHandler(), + FullArchivePreferredPeersHolder: pcf.network.FullArchivePreferredPeersHolderHandler(), + PayloadValidator: payloadValidator, } resolversContainerFactory, err := resolverscontainer.NewShardResolversContainerFactory(resolversContainerFactoryArgs) if err != nil { @@ -1401,23 +1402,24 @@ func (pcf *processComponentsFactory) newMetaResolverContainerFactory( } resolversContainerFactoryArgs := resolverscontainer.FactoryArgs{ - ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), - MainMessenger: pcf.network.NetworkMessenger(), - FullArchiveMessenger: pcf.network.FullArchiveNetworkMessenger(), - Store: pcf.data.StorageService(), - Marshalizer: pcf.coreData.InternalMarshalizer(), - DataPools: pcf.data.Datapool(), - Uint64ByteSliceConverter: pcf.coreData.Uint64ByteSliceConverter(), - DataPacker: dataPacker, - TriesContainer: pcf.state.TriesContainer(), - SizeCheckDelta: pcf.config.Marshalizer.SizeCheckDelta, - InputAntifloodHandler: pcf.network.InputAntiFloodHandler(), - OutputAntifloodHandler: pcf.network.OutputAntiFloodHandler(), - NumConcurrentResolvingJobs: pcf.config.Antiflood.NumConcurrentResolverJobs, - IsFullHistoryNode: pcf.prefConfigs.Preferences.FullArchive, - MainPreferredPeersHolder: pcf.network.PreferredPeersHolderHandler(), - FullArchivePreferredPeersHolder: pcf.network.FullArchivePreferredPeersHolderHandler(), - PayloadValidator: payloadValidator, + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + MainMessenger: pcf.network.NetworkMessenger(), + FullArchiveMessenger: pcf.network.FullArchiveNetworkMessenger(), + Store: pcf.data.StorageService(), + Marshalizer: pcf.coreData.InternalMarshalizer(), + DataPools: pcf.data.Datapool(), + Uint64ByteSliceConverter: pcf.coreData.Uint64ByteSliceConverter(), + DataPacker: dataPacker, + TriesContainer: pcf.state.TriesContainer(), + SizeCheckDelta: pcf.config.Marshalizer.SizeCheckDelta, + InputAntifloodHandler: pcf.network.InputAntiFloodHandler(), + OutputAntifloodHandler: pcf.network.OutputAntiFloodHandler(), + NumConcurrentResolvingJobs: pcf.config.Antiflood.NumConcurrentResolverJobs, + NumConcurrentResolvingTrieNodesJobs: pcf.config.Antiflood.NumConcurrentResolvingTrieNodesJobs, + IsFullHistoryNode: pcf.prefConfigs.Preferences.FullArchive, + MainPreferredPeersHolder: pcf.network.PreferredPeersHolderHandler(), + FullArchivePreferredPeersHolder: pcf.network.FullArchivePreferredPeersHolderHandler(), + PayloadValidator: payloadValidator, } return resolverscontainer.NewMetaResolversContainerFactory(resolversContainerFactoryArgs) diff --git a/integrationTests/testHeartbeatNode.go b/integrationTests/testHeartbeatNode.go index 51c3091292c..c0772fb0868 100644 --- a/integrationTests/testHeartbeatNode.go +++ b/integrationTests/testHeartbeatNode.go @@ -525,13 +525,14 @@ func (thn *TestHeartbeatNode) initResolversAndRequesters() { return &trieMock.TrieStub{} }, }, - SizeCheckDelta: 100, - InputAntifloodHandler: &mock.NilAntifloodHandler{}, - OutputAntifloodHandler: &mock.NilAntifloodHandler{}, - NumConcurrentResolvingJobs: 10, - MainPreferredPeersHolder: &p2pmocks.PeersHolderStub{}, - FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, - PayloadValidator: payloadValidator, + SizeCheckDelta: 100, + InputAntifloodHandler: &mock.NilAntifloodHandler{}, + OutputAntifloodHandler: &mock.NilAntifloodHandler{}, + NumConcurrentResolvingJobs: 10, + NumConcurrentResolvingTrieNodesJobs: 3, + MainPreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + PayloadValidator: payloadValidator, } requestersContainerFactoryArgs := requesterscontainer.FactoryArgs{ diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index cb23b90ca8c..29aba701c35 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1441,22 +1441,23 @@ func (tpn *TestProcessorNode) initResolvers() { fullArchivePreferredPeersHolder, _ := p2pFactory.NewPeersHolder([]string{}) resolverContainerFactory := resolverscontainer.FactoryArgs{ - ShardCoordinator: tpn.ShardCoordinator, - MainMessenger: tpn.MainMessenger, - FullArchiveMessenger: tpn.FullArchiveMessenger, - Store: tpn.Storage, - Marshalizer: TestMarshalizer, - DataPools: tpn.DataPool, - Uint64ByteSliceConverter: TestUint64Converter, - DataPacker: dataPacker, - TriesContainer: tpn.TrieContainer, - SizeCheckDelta: 100, - InputAntifloodHandler: &mock.NilAntifloodHandler{}, - OutputAntifloodHandler: &mock.NilAntifloodHandler{}, - NumConcurrentResolvingJobs: 10, - MainPreferredPeersHolder: preferredPeersHolder, - FullArchivePreferredPeersHolder: fullArchivePreferredPeersHolder, - PayloadValidator: payloadValidator, + ShardCoordinator: tpn.ShardCoordinator, + MainMessenger: tpn.MainMessenger, + FullArchiveMessenger: tpn.FullArchiveMessenger, + Store: tpn.Storage, + Marshalizer: TestMarshalizer, + DataPools: tpn.DataPool, + Uint64ByteSliceConverter: TestUint64Converter, + DataPacker: dataPacker, + TriesContainer: tpn.TrieContainer, + SizeCheckDelta: 100, + InputAntifloodHandler: &mock.NilAntifloodHandler{}, + OutputAntifloodHandler: &mock.NilAntifloodHandler{}, + NumConcurrentResolvingJobs: 10, + NumConcurrentResolvingTrieNodesJobs: 3, + MainPreferredPeersHolder: preferredPeersHolder, + FullArchivePreferredPeersHolder: fullArchivePreferredPeersHolder, + PayloadValidator: payloadValidator, } var err error diff --git a/testscommon/generalConfig.go b/testscommon/generalConfig.go index 1a653313e0e..ac89501ee31 100644 --- a/testscommon/generalConfig.go +++ b/testscommon/generalConfig.go @@ -384,7 +384,8 @@ func GetGeneralConfig() config.Config { CheckNodesOnDisk: false, }, Antiflood: config.AntifloodConfig{ - NumConcurrentResolverJobs: 2, + NumConcurrentResolverJobs: 2, + NumConcurrentResolvingTrieNodesJobs: 1, TxAccumulator: config.TxAccumulatorConfig{ MaxAllowedTimeInMilliseconds: 10, MaxDeviationTimeInMilliseconds: 1, From 8050945b83a566e092f0b141c661988194aa3252 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 1 Feb 2024 11:27:34 +0200 Subject: [PATCH 662/958] add state statistics field to config file --- cmd/node/config/config.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 85fde2e08cf..6523fd6a9bf 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -658,6 +658,7 @@ PeerStatePruningEnabled = true MaxStateTrieLevelInMemory = 5 MaxPeerTrieLevelInMemory = 5 + StateStatisticsEnabled = false [BlockSizeThrottleConfig] MinSizeInBytes = 104857 # 104857 is 10% from 1MB From 0f837ed7a83c4f6f116afe166d488ef158c13730 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 12:31:13 +0200 Subject: [PATCH 663/958] fixes after review --- node/chainSimulator/chainSimulator.go | 68 ++++++++----------- node/chainSimulator/chainSimulator_test.go | 35 ++++++---- .../components/coreComponents.go | 1 - 3 files changed, 48 insertions(+), 56 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 743905f2339..5419b775648 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -2,8 +2,6 @@ package chainSimulator import ( "bytes" - "encoding/base64" - "encoding/hex" "fmt" "sync" "time" @@ -12,7 +10,6 @@ import ( "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" crypto "github.com/multiversx/mx-chain-crypto-go" - "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" @@ -93,9 +90,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { shardIDStr = "metachain" } - node, errCreate := s.createTestNode( - outputConfigs.Configs, shardIDStr, outputConfigs.GasScheduleFilename, args.ApiInterface, args.BypassTxSignatureCheck, args.InitialRound, args.MinNodesPerShard, args.MetaChainMinNodes, - ) + node, errCreate := s.createTestNode(outputConfigs, args, shardIDStr) if errCreate != nil { return errCreate } @@ -129,30 +124,23 @@ func computeStartTimeBaseOnInitialRound(args ArgsChainSimulator) int64 { } func (s *simulator) createTestNode( - configs *config.Configs, - shardIDStr string, - gasScheduleFilename string, - apiInterface components.APIConfigurator, - bypassTxSignatureCheck bool, - initialRound int64, - minNodesPerShard uint32, - minNodesMeta uint32, + outputConfigs *configs.ArgsConfigsSimulator, args ArgsChainSimulator, shardIDStr string, ) (process.NodeHandler, error) { - args := components.ArgsTestOnlyProcessingNode{ - Configs: *configs, + argsTestOnlyProcessorNode := components.ArgsTestOnlyProcessingNode{ + Configs: *outputConfigs.Configs, ChanStopNodeProcess: s.chanStopNodeProcess, SyncedBroadcastNetwork: s.syncedBroadcastNetwork, NumShards: s.numOfShards, - GasScheduleFilename: gasScheduleFilename, + GasScheduleFilename: outputConfigs.GasScheduleFilename, ShardIDStr: shardIDStr, - APIInterface: apiInterface, - BypassTxSignatureCheck: bypassTxSignatureCheck, - InitialRound: initialRound, - MinNodesPerShard: minNodesPerShard, - MinNodesMeta: minNodesMeta, + APIInterface: args.ApiInterface, + BypassTxSignatureCheck: args.BypassTxSignatureCheck, + InitialRound: args.InitialRound, + MinNodesPerShard: args.MinNodesPerShard, + MinNodesMeta: args.MetaChainMinNodes, } - return components.NewTestOnlyProcessingNode(args) + return components.NewTestOnlyProcessingNode(argsTestOnlyProcessorNode) } // GenerateBlocks will generate the provided number of blocks @@ -214,26 +202,26 @@ func (s *simulator) GetInitialWalletKeys() *dtos.InitialWalletKeys { } // AddValidatorKeys will add the provided validators private keys in the keys handler on all nodes -func (s *simulator) AddValidatorKeys(validatorsPrivateKeys *dtos.ValidatorsKeys) error { +func (s *simulator) AddValidatorKeys(validatorsPrivateKeys [][]byte) error { s.mutex.Lock() defer s.mutex.Unlock() - for shard, node := range s.nodes { - for idx, privateKeyHex := range validatorsPrivateKeys.PrivateKeysBase64 { - decodedPrivateKey, err := base64.StdEncoding.DecodeString(privateKeyHex) - if err != nil { - return fmt.Errorf("cannot base64 decode provided key index=%d, error=%s", idx, err.Error()) - } - - hexDecoded, err := hex.DecodeString(string(decodedPrivateKey)) - if err != nil { - return fmt.Errorf("cannot hex decode provided key index=%d, error=%s", idx, err.Error()) - } - - err = node.GetCryptoComponents().ManagedPeersHolder().AddManagedPeer(hexDecoded) - if err != nil { - return fmt.Errorf("cannot add private key for shard=%d, index=%d, error=%s", shard, idx, err.Error()) - } + for _, node := range s.nodes { + err := s.setValidatorKeysForNode(node, validatorsPrivateKeys) + if err != nil { + return err + } + } + + return nil +} + +func (s *simulator) setValidatorKeysForNode(node process.NodeHandler, validatorsPrivateKeys [][]byte) error { + for idx, privateKey := range validatorsPrivateKeys { + + err := node.GetCryptoComponents().ManagedPeersHolder().AddManagedPeer(privateKey) + if err != nil { + return fmt.Errorf("cannot add private key for shard=%d, index=%d, error=%s", node.GetShardCoordinator().SelfId(), idx, err.Error()) } } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 5ee1ba039ea..4f3fbe3b51f 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -191,11 +191,14 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { err = chainSimulator.GenerateBlocks(30) require.Nil(t, err) - // add validator key - validatorKeys := &dtos.ValidatorsKeys{ - PrivateKeysBase64: []string{"NjRhYjk3NmJjYWVjZTBjNWQ4YmJhNGU1NjZkY2VmYWFiYjcxNDI1Y2JiZDcwYzc1ODA2MGUxNTE5MGM2ZjE1Zg=="}, - } - err = chainSimulator.AddValidatorKeys(validatorKeys) + // Step 1 --- add a new validator key in the chain simulator + privateKeyBase64 := "NjRhYjk3NmJjYWVjZTBjNWQ4YmJhNGU1NjZkY2VmYWFiYjcxNDI1Y2JiZDcwYzc1ODA2MGUxNTE5MGM2ZjE1Zg==" + privateKeyHex, err := base64.StdEncoding.DecodeString(privateKeyBase64) + require.Nil(t, err) + privateKeyBytes, err := hex.DecodeString(string(privateKeyHex)) + require.Nil(t, err) + + err = chainSimulator.AddValidatorKeys([][]byte{privateKeyBytes}) require.Nil(t, err) newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" @@ -203,7 +206,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" rcvAddrBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(rcv) - // set balance for sender + // Step 2 --- set an initial balance for the address that will initialize all the transactions err = chainSimulator.SetStateMultiple([]*dtos.AddressState{ { Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", @@ -214,7 +217,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { blsKey := "9b7de1b2d2c90b7bea8f6855075c77d6c63b5dada29abb9b87c52cfae9d4112fcac13279e1a07d94672a5e62a83e3716555513014324d5c6bb4261b465f1b8549a7a338bc3ae8edc1e940958f9c2e296bd3c118a4466dec99dda0ceee3eb6a8c" - // stake validator + // Step 3 --- generate and send a stake transaction with the BLS key of the validator key that was added at step 1 stakeValue, _ := big.NewInt(0).SetString("2500000000000000000000", 10) tx := &transaction.Transaction{ Nonce: 0, @@ -237,6 +240,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { time.Sleep(100 * time.Millisecond) + // Step 4 --- generate 5 blocks so that the transaction from step 2 can be executed err = chainSimulator.GenerateBlocks(5) require.Nil(t, err) @@ -252,8 +256,8 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.Nil(t, err) balanceBeforeActiveValidator := accountValidatorOwner.Balance - // unstake validator - firstValitorKey, err := chainSimulator.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() + // Step 5 --- create an unStake transaction with the bls key of an initial validator and execute the transaction to make place for the validator that was added at step 3 + firstValidatorKey, err := chainSimulator.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() require.Nil(t, err) initialAddressWithValidators := chainSimulator.GetInitialWalletKeys().InitialWalletWithStake.Address @@ -266,7 +270,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { Value: big.NewInt(0), SndAddr: senderBytes, RcvAddr: rcvAddrBytes, - Data: []byte(fmt.Sprintf("unStake@%s", hex.EncodeToString(firstValitorKey))), + Data: []byte(fmt.Sprintf("unStake@%s", hex.EncodeToString(firstValidatorKey))), GasLimit: 50_000_000, GasPrice: 1000000000, Signature: []byte("dummy"), @@ -281,6 +285,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { time.Sleep(100 * time.Millisecond) + // Step 6 --- generate 5 blocks so that the transaction from step 5 can be executed err = chainSimulator.GenerateBlocks(5) require.Nil(t, err) @@ -291,7 +296,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.NotNil(t, txFromMeta) require.Equal(t, 2, len(txFromMeta.SmartContractResults)) - // check rewards + // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards err = chainSimulator.GenerateBlocks(50) require.Nil(t, err) @@ -299,15 +304,15 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.Nil(t, err) balanceAfterActiveValidator := accountValidatorOwner.Balance - fmt.Println("balance before validator", balanceBeforeActiveValidator) - fmt.Println("balance after validator", balanceAfterActiveValidator) + log.Info("balance before validator", "value", balanceBeforeActiveValidator) + log.Info("balance after validator", "value", balanceAfterActiveValidator) balanceBeforeBig, _ := big.NewInt(0).SetString(balanceBeforeActiveValidator, 10) balanceAfterBig, _ := big.NewInt(0).SetString(balanceAfterActiveValidator, 10) diff := balanceAfterBig.Sub(balanceAfterBig, balanceBeforeBig) - fmt.Println("difference", diff.String()) + log.Info("difference", "value", diff.String()) - // cumulated rewards should be greater than zero + // Step 7 --- check the balance of the validator owner has been increased require.True(t, diff.Cmp(big.NewInt(0)) > 0) } diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 1ea1f7d61dc..373e34de033 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -202,7 +202,6 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents // TODO check if we need this instance.ratingsData = &testscommon.RatingsInfoMock{} instance.rater = &testscommon.RaterMock{} - ////////////////////////////// instance.nodesShuffler, err = nodesCoordinator.NewHashValidatorsShuffler(&nodesCoordinator.NodesShufflerArgs{ NodesShard: args.MinNodesPerShard, From 643d84a88772ba7a62783b1beb6466a2b94513a9 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 13:05:14 +0200 Subject: [PATCH 664/958] FIX: Delete delegation ticker --- cmd/node/config/config.toml | 2 +- .../config/systemSmartContractsConfig.toml | 1 - config/systemSmartContractsConfig.go | 5 ++-- epochStart/metachain/systemSCs_test.go | 5 ++-- factory/processing/processComponents_test.go | 5 ++-- genesis/process/genesisBlockCreator_test.go | 5 ++-- .../multiShard/hardFork/hardFork_test.go | 5 ++-- integrationTests/testInitializer.go | 10 +++---- integrationTests/testProcessorNode.go | 10 +++---- .../vm/staking/systemSCCreator.go | 5 ++-- integrationTests/vm/testInitializer.go | 5 ++-- .../metachain/vmContainerFactory_test.go | 10 +++---- testscommon/components/components.go | 5 ++-- vm/errors.go | 9 ------ vm/factory/systemSCFactory_test.go | 5 ++-- vm/systemSmartContracts/esdt.go | 28 ------------------- vm/systemSmartContracts/esdt_test.go | 3 +- 17 files changed, 32 insertions(+), 86 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 047a9dd7890..0a58c816e33 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -940,5 +940,5 @@ # Changing this config is not backwards compatible [SoftAuctionConfig] TopUpStep = "10000000000000000000" # 10 EGLD - MinTopUp = "1" # 0.00...01 EGLD , should be very low, but != zero + MinTopUp = "1000000000000000000" # 1 EGLD should be minimum MaxTopUp = "32000000000000000000000000" # 32 mil EGLD diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index efcf86ce248..1b7724ee9e4 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -17,7 +17,6 @@ [ESDTSystemSCConfig] BaseIssuingCost = "5000000000000000000" #5 eGLD OwnerAddress = "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c" - DelegationTicker = "DEL" [GovernanceSystemSCConfig] OwnerAddress = "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80" #should use a multisign contract instead of a wallet address diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index eb32d9451b4..a593fe40268 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -29,9 +29,8 @@ type StakingSystemSCConfig struct { // ESDTSystemSCConfig defines a set of constant to initialize the esdt system smart contract type ESDTSystemSCConfig struct { - BaseIssuingCost string - OwnerAddress string - DelegationTicker string + BaseIssuingCost string + OwnerAddress string } // GovernanceSystemSCConfigV1 holds the initial set of values that were used to initialise the diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index d5f4254856f..a8a58dadfa0 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -832,9 +832,8 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp Marshalizer: marshalizer, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index bc98d90407c..b0266dc158b 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -108,9 +108,8 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto MaxRating: 100, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/genesis/process/genesisBlockCreator_test.go b/genesis/process/genesisBlockCreator_test.go index 9b33b2e2cae..79588c87135 100644 --- a/genesis/process/genesisBlockCreator_test.go +++ b/genesis/process/genesisBlockCreator_test.go @@ -123,9 +123,8 @@ func createMockArgument( }, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "5000000000000000000000", - OwnerAddress: "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp", - DelegationTicker: "DEL", + BaseIssuingCost: "5000000000000000000000", + OwnerAddress: "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index b238660009f..bbac759a1be 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -437,9 +437,8 @@ func hardForkImport( TrieStorageManagers: node.TrieStorageManagers, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 4bce97881fe..69e3297d821 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -687,9 +687,8 @@ func CreateFullGenesisBlocks( TrieStorageManagers: trieStorageManagers, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ OwnerAddress: DelegationManagerConfigChangeAddress, @@ -797,9 +796,8 @@ func CreateGenesisMetaBlock( HardForkConfig: config.HardforkConfig{}, SystemSCConfig: config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 30f068efb27..744a6b753b2 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -922,9 +922,8 @@ func (tpn *TestProcessorNode) createFullSCQueryService(gasMap map[string]map[str Marshalizer: TestMarshalizer, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ @@ -1885,9 +1884,8 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors(gasMap map[string]map[stri Marshalizer: TestMarshalizer, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 906832b8e8f..9c7567a1ec0 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -195,9 +195,8 @@ func createVMContainerFactory( Marshalizer: coreComponents.InternalMarshalizer(), SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 99e742c9257..b6d189b93ae 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -734,9 +734,8 @@ func CreateVMAndBlockchainHookMeta( func createSystemSCConfig() *config.SystemSmartContractsConfig { return &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "5000000000000000000", - OwnerAddress: "3132333435363738393031323334353637383930313233343536373839303233", - DelegationTicker: "DEL", + BaseIssuingCost: "5000000000000000000", + OwnerAddress: "3132333435363738393031323334353637383930313233343536373839303233", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index c5d6cd3a8d3..9b3c2f6de59 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -37,9 +37,8 @@ func createVmContainerMockArgument(gasSchedule core.GasScheduleNotifier) ArgsNew Marshalizer: &mock.MarshalizerMock{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "100000000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "100000000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ @@ -333,9 +332,8 @@ func TestVmContainerFactory_Create(t *testing.T) { Marshalizer: &mock.MarshalizerMock{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "100000000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "100000000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/testscommon/components/components.go b/testscommon/components/components.go index 65a3130713e..1687a0c1817 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -516,9 +516,8 @@ func GetProcessArgs( ImportStartHandler: &testscommon.ImportStartHandlerStub{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - DelegationTicker: "DEL", - BaseIssuingCost: "1000", - OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + BaseIssuingCost: "1000", + OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/vm/errors.go b/vm/errors.go index 85e21579126..0e3ea608ed2 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -268,15 +268,6 @@ var ErrWrongNewOwnerAddress = errors.New("wrong new owner address") // ErrInternalErrorWhileSettingNewOwner signals that an error occurred when setting the new contract owner var ErrInternalErrorWhileSettingNewOwner = errors.New("internal error when setting new contract owner") -// ErrInvalidDelegationTicker signals that invalid delegation ticker name was provided -var ErrInvalidDelegationTicker = errors.New("invalid delegation ticker name") - -// ErrInvalidReturnData signals that invalid return data was provided -var ErrInvalidReturnData = errors.New("invalid return data") - -// ErrNotEnoughRemainingFunds signals that operation is invalid as remaining funds are below minimum -var ErrNotEnoughRemainingFunds = errors.New("not enough remaining funds - do not leave dust behind") - // ErrInvalidStakeLimitPercentage signals the invalid stake limit percentage was provided var ErrInvalidStakeLimitPercentage = errors.New("invalid stake limit percentage") diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index 9145e568570..280c196b25c 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -33,9 +33,8 @@ func createMockNewSystemScFactoryArgs() ArgsNewSystemSCFactory { Hasher: &hashingMocks.HasherMock{}, SystemSCConfig: &config.SystemSmartContractsConfig{ ESDTSystemSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "100000000", - OwnerAddress: "aaaaaa", - DelegationTicker: "DEL", + BaseIssuingCost: "100000000", + OwnerAddress: "aaaaaa", }, GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ V1: config.GovernanceSystemSCConfigV1{ diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 299b6f717f4..74d2a681310 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -23,8 +23,6 @@ import ( const numOfRetriesForIdentifier = 50 const tickerSeparator = "-" const tickerRandomSequenceLength = 3 -const minLengthForTickerName = 3 -const maxLengthForTickerName = 10 const minLengthForInitTokenName = 10 const minLengthForTokenName = 3 const maxLengthForTokenName = 20 @@ -58,7 +56,6 @@ type esdt struct { mutExecution sync.RWMutex addressPubKeyConverter core.PubkeyConverter enableEpochsHandler common.EnableEpochsHandler - delegationTicker string } // ArgsNewESDTSmartContract defines the arguments needed for the esdt contract @@ -112,9 +109,6 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { if len(args.EndOfEpochSCAddress) == 0 { return nil, vm.ErrNilEndOfEpochSmartContractAddress } - if !isTickerValid([]byte(args.ESDTSCConfig.DelegationTicker)) { - return nil, vm.ErrInvalidDelegationTicker - } baseIssuingCost, okConvert := big.NewInt(0).SetString(args.ESDTSCConfig.BaseIssuingCost, conversionBase) if !okConvert || baseIssuingCost.Cmp(big.NewInt(0)) < 0 { return nil, vm.ErrInvalidBaseIssuingCost @@ -133,7 +127,6 @@ func NewESDTSmartContract(args ArgsNewESDTSmartContract) (*esdt, error) { endOfEpochSCAddress: args.EndOfEpochSCAddress, addressPubKeyConverter: args.AddressPubKeyConverter, enableEpochsHandler: args.EnableEpochsHandler, - delegationTicker: args.ESDTSCConfig.DelegationTicker, }, nil } @@ -623,10 +616,6 @@ func (e *esdt) createNewToken( if !isTokenNameHumanReadable(tokenName) { return nil, nil, vm.ErrTokenNameNotHumanReadable } - if !isTickerValid(tickerName) { - return nil, nil, vm.ErrTickerNameNotValid - } - tokenIdentifier, err := e.createNewTokenIdentifier(owner, tickerName) if err != nil { return nil, nil, err @@ -657,23 +646,6 @@ func (e *esdt) createNewToken( return tokenIdentifier, newESDTToken, nil } -func isTickerValid(tickerName []byte) bool { - if len(tickerName) < minLengthForTickerName || len(tickerName) > maxLengthForTickerName { - return false - } - - for _, ch := range tickerName { - isBigCharacter := ch >= 'A' && ch <= 'Z' - isNumber := ch >= '0' && ch <= '9' - isReadable := isBigCharacter || isNumber - if !isReadable { - return false - } - } - - return true -} - func isTokenNameHumanReadable(tokenName []byte) bool { for _, ch := range tokenName { isSmallCharacter := ch >= 'a' && ch <= 'z' diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index 24e964f0bfe..0504527efb6 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -29,8 +29,7 @@ func createMockArgumentsForESDT() ArgsNewESDTSmartContract { Eei: &mock.SystemEIStub{}, GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{ESDTIssue: 10}}, ESDTSCConfig: config.ESDTSystemSCConfig{ - BaseIssuingCost: "1000", - DelegationTicker: "DEL", + BaseIssuingCost: "1000", }, ESDTSCAddress: []byte("address"), Marshalizer: &mock.MarshalizerMock{}, From 3e3fd89622f80cd6490a8ec929f0f0ba1d284d10 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 14:16:49 +0200 Subject: [PATCH 665/958] fixes aster second review --- node/chainSimulator/dtos/validators.go | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 node/chainSimulator/dtos/validators.go diff --git a/node/chainSimulator/dtos/validators.go b/node/chainSimulator/dtos/validators.go deleted file mode 100644 index 434964bd82e..00000000000 --- a/node/chainSimulator/dtos/validators.go +++ /dev/null @@ -1,5 +0,0 @@ -package dtos - -type ValidatorsKeys struct { - PrivateKeysBase64 []string `json:"privateKeysBase64"` -} From abe1cb9758b9e6406e9f9ece3879a6b88e1aa502 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 14:43:55 +0200 Subject: [PATCH 666/958] FEAT: Treat overflow qualified nodes + set max num of iterations cap --- cmd/node/config/config.toml | 1 + config/config.go | 7 +- epochStart/metachain/auctionListSelector.go | 33 ++++++--- .../metachain/auctionListSelector_test.go | 73 ++++++++++++++++++- epochStart/metachain/systemSCs_test.go | 14 ++-- integrationTests/testProcessorNode.go | 7 +- .../vm/staking/systemSCCreator.go | 7 +- testscommon/generalConfig.go | 7 +- vm/errors.go | 3 - vm/systemSmartContracts/esdt_test.go | 12 --- 10 files changed, 117 insertions(+), 47 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 0a58c816e33..66e79dfbad9 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -942,3 +942,4 @@ TopUpStep = "10000000000000000000" # 10 EGLD MinTopUp = "1000000000000000000" # 1 EGLD should be minimum MaxTopUp = "32000000000000000000000000" # 32 mil EGLD + MaxNumberOfIterations = 100000 # 100k max number of iterations for soft auction config diff --git a/config/config.go b/config/config.go index 99b927c1408..44d7d524544 100644 --- a/config/config.go +++ b/config/config.go @@ -641,7 +641,8 @@ type RedundancyConfig struct { // SoftAuctionConfig represents the config options for soft auction selecting used in staking v4 type SoftAuctionConfig struct { - TopUpStep string - MinTopUp string - MaxTopUp string + TopUpStep string + MinTopUp string + MaxTopUp string + MaxNumberOfIterations uint64 } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index b01ce492d3e..5bc3d915647 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -27,10 +27,11 @@ type ownerAuctionData struct { } type auctionConfig struct { - step *big.Int - minTopUp *big.Int - maxTopUp *big.Int - denominator *big.Int + step *big.Int + minTopUp *big.Int + maxTopUp *big.Int + denominator *big.Int + maxNumOfIterations uint64 } type auctionListSelector struct { @@ -110,10 +111,11 @@ func getAuctionConfig(softAuctionConfig config.SoftAuctionConfig, denomination i } return &auctionConfig{ - step: step, - minTopUp: minTopUp, - maxTopUp: maxTopUp, - denominator: big.NewInt(int64(math.Pow10(denomination))), + step: step, + minTopUp: minTopUp, + maxTopUp: maxTopUp, + denominator: big.NewInt(int64(math.Pow10(denomination))), + maxNumOfIterations: softAuctionConfig.MaxNumberOfIterations, }, nil } @@ -256,13 +258,19 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( topUp := big.NewInt(0).SetBytes(minTopUp.Bytes()) previousConfig := copyOwnersData(ownersData) - for ; topUp.Cmp(maxTopUp) < 0; topUp.Add(topUp, als.softAuctionConfig.step) { + iterationNumber := uint64(0) + maxNumberOfIterationsReached := false + + for ; topUp.Cmp(maxTopUp) < 0 && !maxNumberOfIterationsReached; topUp.Add(topUp, als.softAuctionConfig.step) { previousConfig = copyOwnersData(ownersData) numNodesQualifyingForTopUp := calcNodesConfig(ownersData, topUp) if numNodesQualifyingForTopUp < int64(numAvailableSlots) { break } + + iterationNumber++ + maxNumberOfIterationsReached = iterationNumber >= als.softAuctionConfig.maxNumOfIterations } als.displayMinRequiredTopUp(topUp, minTopUp) @@ -323,8 +331,11 @@ func calcNodesConfig(ownersData map[string]*ownerAuctionData, topUp *big.Int) in continue } - qualifiedNodes := big.NewInt(0).Div(validatorTopUpForAuction, topUp).Int64() - if qualifiedNodes > owner.numAuctionNodes { + qualifiedNodesBigInt := big.NewInt(0).Div(validatorTopUpForAuction, topUp) + qualifiedNodes := qualifiedNodesBigInt.Int64() + isNumQualifiedNodesOverflow := !qualifiedNodesBigInt.IsUint64() + + if qualifiedNodes > owner.numAuctionNodes || isNumQualifiedNodesOverflow { numNodesQualifyingForTopUp += owner.numAuctionNodes } else { numNodesQualifyingForTopUp += qualifiedNodes diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 7a96e00bd94..b9108d9b847 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -21,9 +21,10 @@ import ( func createSoftAuctionConfig() config.SoftAuctionConfig { return config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, } } @@ -595,6 +596,72 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { selectedNodes = als.selectNodes(softAuctionConfig, 1, randomness) require.Equal(t, []state.ValidatorInfoHandler{v2}, selectedNodes) }) + + t.Run("large top up difference, would qualify more nodes than an owner has, expect correct computation", func(t *testing.T) { + argsLargeTopUp := createAuctionListSelectorArgs(nil) + argsLargeTopUp.SoftAuctionConfig = config.SoftAuctionConfig{ + TopUpStep: "10000000000000000000", // 10 eGLD + MinTopUp: "1000000000000000000", // 1 eGLD + MaxTopUp: "32000000000000000000000000", // 32 mil eGLD + MaxNumberOfIterations: 10, + } + argsLargeTopUp.Denomination = 18 + selector, _ := NewAuctionListSelector(argsLargeTopUp) + + v0 := &state.ValidatorInfo{PublicKey: []byte("pk0")} + v1 := &state.ValidatorInfo{PublicKey: []byte("pk1")} + v2 := &state.ValidatorInfo{PublicKey: []byte("pk2")} + + oneEGLD, _ := big.NewInt(0).SetString("1000000000000000000", 10) + owner1TopUp, _ := big.NewInt(0).SetString("32000000000000000000000000", 10) // 31 mil eGLD + owner1 := "owner1" + owner2 := "owner2" + ownersData := map[string]*ownerAuctionData{ + owner1: { + numActiveNodes: 0, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + numStakedNodes: 1, + totalTopUp: owner1TopUp, + topUpPerNode: owner1TopUp, + qualifiedTopUpPerNode: owner1TopUp, + auctionList: []state.ValidatorInfoHandler{v0}, + }, + owner2: { + numActiveNodes: 0, + numAuctionNodes: 2, + numQualifiedAuctionNodes: 2, + numStakedNodes: 2, + totalTopUp: big.NewInt(0), + topUpPerNode: big.NewInt(0), + qualifiedTopUpPerNode: big.NewInt(0), + auctionList: []state.ValidatorInfoHandler{v1, v2}, + }, + } + + minTopUp, maxTopUp := selector.getMinMaxPossibleTopUp(ownersData) + require.Equal(t, oneEGLD, minTopUp) + require.Equal(t, owner1TopUp, maxTopUp) + + softAuctionConfig := selector.calcSoftAuctionNodesConfig(ownersData, 3) + require.Equal(t, ownersData, softAuctionConfig) + selectedNodes := selector.selectNodes(softAuctionConfig, 3, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v0, v2, v1}, selectedNodes) + + softAuctionConfig = selector.calcSoftAuctionNodesConfig(ownersData, 2) + expectedSoftAuction := copyOwnersData(ownersData) + expectedSoftAuction[owner1].numQualifiedAuctionNodes = 1 + expectedSoftAuction[owner1].qualifiedTopUpPerNode = owner1TopUp + require.Equal(t, expectedSoftAuction, softAuctionConfig) + selectedNodes = selector.selectNodes(softAuctionConfig, 2, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v0, v2}, selectedNodes) + + softAuctionConfig = selector.calcSoftAuctionNodesConfig(ownersData, 1) + delete(expectedSoftAuction, owner2) + require.Equal(t, expectedSoftAuction, softAuctionConfig) + selectedNodes = selector.selectNodes(softAuctionConfig, 1, randomness) + require.Equal(t, []state.ValidatorInfoHandler{v0}, selectedNodes) + }) } func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index a8a58dadfa0..46e19c64db1 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -900,9 +900,10 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp StakingDataProvider: stakingSCProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, }, } als, _ := NewAuctionListSelector(argsAuctionListSelector) @@ -1908,9 +1909,10 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing StakingDataProvider: args.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, }, } als, _ := NewAuctionListSelector(argsAuctionListSelector) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 744a6b753b2..97d729337d6 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2328,9 +2328,10 @@ func (tpn *TestProcessorNode) initBlockProcessor() { StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, }, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 9c7567a1ec0..1beee160be2 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -50,9 +50,10 @@ func createSystemSCProcessor( StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, }, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) diff --git a/testscommon/generalConfig.go b/testscommon/generalConfig.go index 0e26d266197..1e2c8d758bd 100644 --- a/testscommon/generalConfig.go +++ b/testscommon/generalConfig.go @@ -9,9 +9,10 @@ import ( func GetGeneralConfig() config.Config { return config.Config{ SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, }, Hardfork: config.HardforkConfig{ PublicKeyToListenFrom: "153dae6cb3963260f309959bf285537b77ae16d82e9933147be7827f7394de8dc97d9d9af41e970bc72aecb44b77e819621081658c37f7000d21e2d0e8963df83233407bde9f46369ba4fcd03b57f40b80b06c191a428cfb5c447ec510e79307", diff --git a/vm/errors.go b/vm/errors.go index 0e3ea608ed2..ba8958321dd 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -178,9 +178,6 @@ var ErrInvalidMaxNumberOfNodes = errors.New("invalid number of max number of nod // ErrTokenNameNotHumanReadable signals that token name is not human-readable var ErrTokenNameNotHumanReadable = errors.New("token name is not human readable") -// ErrTickerNameNotValid signals that ticker name is not valid -var ErrTickerNameNotValid = errors.New("ticker name is not valid") - // ErrCouldNotCreateNewTokenIdentifier signals that token identifier could not be created var ErrCouldNotCreateNewTokenIdentifier = errors.New("token identifier could not be created") diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index 0504527efb6..47171b4af24 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -4032,12 +4032,6 @@ func TestEsdt_ExecuteIssueMetaESDT(t *testing.T) { assert.Equal(t, vmcommon.UserError, output) assert.True(t, strings.Contains(eei.returnMessage, "invalid number of decimals")) - vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("ticker"), big.NewInt(10).Bytes()} - eei.returnMessage = "" - output = e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) - assert.True(t, strings.Contains(eei.returnMessage, "ticker name is not valid")) - vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("TICKER"), big.NewInt(10).Bytes()} eei.returnMessage = "" output = e.Execute(vmInput) @@ -4168,12 +4162,6 @@ func TestEsdt_ExecuteRegisterAndSetErrors(t *testing.T) { assert.Equal(t, vmcommon.UserError, output) assert.True(t, strings.Contains(eei.returnMessage, vm.ErrInvalidArgument.Error())) - vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("ticker"), []byte("FNG"), big.NewInt(10).Bytes()} - eei.returnMessage = "" - output = e.Execute(vmInput) - assert.Equal(t, vmcommon.UserError, output) - assert.True(t, strings.Contains(eei.returnMessage, "ticker name is not valid")) - vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("ticker"), []byte("FNG"), big.NewInt(20).Bytes()} eei.returnMessage = "" output = e.Execute(vmInput) From d4333fe0a0a4febd943a883602799847f3306911 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 15:03:07 +0200 Subject: [PATCH 667/958] fix synced messenger --- node/chainSimulator/components/syncedMessenger.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node/chainSimulator/components/syncedMessenger.go b/node/chainSimulator/components/syncedMessenger.go index d5cc0da5d6c..711cdd7a415 100644 --- a/node/chainSimulator/components/syncedMessenger.go +++ b/node/chainSimulator/components/syncedMessenger.go @@ -60,6 +60,11 @@ func NewSyncedMessenger(network SyncedBroadcastNetworkHandler) (*syncedMessenger return messenger, nil } +// HasCompatibleProtocolID returns false as it is disabled +func (messenger *syncedMessenger) HasCompatibleProtocolID(_ string) bool { + return false +} + func (messenger *syncedMessenger) receive(fromConnectedPeer core.PeerID, message p2p.MessageP2P) { if check.IfNil(message) { return From abe6c7e999098d0aabbbd6783516502e522bc0f1 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 15:10:25 +0200 Subject: [PATCH 668/958] fixes --- node/chainSimulator/components/processComponents.go | 7 +++++++ node/chainSimulator/components/statusCoreComponents.go | 8 ++++++++ node/chainSimulator/components/storageService.go | 2 -- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index e5ca52ad96f..27b1e358614 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -93,6 +93,7 @@ type processComponentsHolder struct { processedMiniBlocksTracker process.ProcessedMiniBlocksTracker esdtDataStorageHandlerForAPI vmcommon.ESDTNFTStorageHandler accountsParser genesis.AccountsParser + sendSignatureTracker process.SentSignaturesTracker } // CreateProcessComponents will create the process components holder @@ -260,6 +261,7 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC processedMiniBlocksTracker: managedProcessComponents.ProcessedMiniBlocksTracker(), esdtDataStorageHandlerForAPI: managedProcessComponents.ESDTDataStorageHandlerForAPI(), accountsParser: managedProcessComponents.AccountsParser(), + sendSignatureTracker: managedProcessComponents.SentSignaturesTracker(), } instance.collectClosableComponents() @@ -267,6 +269,11 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC return instance, nil } +// SentSignaturesTracker will return the send signature tracker +func (p *processComponentsHolder) SentSignaturesTracker() process.SentSignaturesTracker { + return p.sendSignatureTracker +} + // NodesCoordinator will return the nodes coordinator func (p *processComponentsHolder) NodesCoordinator() nodesCoordinator.NodesCoordinator { return p.nodesCoordinator diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 27fa6a81a0c..47428f14a95 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -2,6 +2,7 @@ package components import ( "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/factory/statusCore" @@ -16,6 +17,7 @@ type statusCoreComponentsHolder struct { statusHandler core.AppStatusHandler statusMetrics external.StatusMetricsHandler persistentStatusHandler factory.PersistentStatusHandler + stateStatisticsHandler common.StateStatisticsHandler } // CreateStatusCoreComponents will create a new instance of factory.StatusCoreComponentsHandler @@ -55,6 +57,7 @@ func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.C statusHandler: managedStatusCoreComponents.AppStatusHandler(), statusMetrics: managedStatusCoreComponents.StatusMetrics(), persistentStatusHandler: managedStatusCoreComponents.PersistentStatusHandler(), + stateStatisticsHandler: managedStatusCoreComponents.StateStatsHandler(), } instance.collectClosableComponents() @@ -62,6 +65,11 @@ func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.C return instance, nil } +// StateStatsHandler will return the state statistics handler +func (s *statusCoreComponentsHolder) StateStatsHandler() common.StateStatisticsHandler { + return s.stateStatisticsHandler +} + // ResourceMonitor will return the resource monitor func (s *statusCoreComponentsHolder) ResourceMonitor() factory.ResourceMonitor { return s.resourceMonitor diff --git a/node/chainSimulator/components/storageService.go b/node/chainSimulator/components/storageService.go index e33287427a2..9a2a7c4860f 100644 --- a/node/chainSimulator/components/storageService.go +++ b/node/chainSimulator/components/storageService.go @@ -21,9 +21,7 @@ func CreateStore(numOfShards uint32) dataRetriever.StorageService { store.AddStorer(dataRetriever.ScheduledSCRsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.TxLogsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.UserAccountsUnit, CreateMemUnitForTries()) - store.AddStorer(dataRetriever.UserAccountsCheckpointsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.PeerAccountsUnit, CreateMemUnitForTries()) - store.AddStorer(dataRetriever.PeerAccountsCheckpointsUnit, CreateMemUnit()) store.AddStorer(dataRetriever.ESDTSuppliesUnit, CreateMemUnit()) store.AddStorer(dataRetriever.RoundHdrHashDataUnit, CreateMemUnit()) store.AddStorer(dataRetriever.MiniblocksMetadataUnit, CreateMemUnit()) From 564b5cca158fe112820d79c7ac296433a2d74d3f Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Thu, 1 Feb 2024 15:30:50 +0200 Subject: [PATCH 669/958] receivedMetaBlock tests --- process/block/export_test.go | 13 ++ process/block/metablock_request_test.go | 31 ++-- process/block/shardblock_request_test.go | 186 +++++++++++++++++++++++ 3 files changed, 216 insertions(+), 14 deletions(-) diff --git a/process/block/export_test.go b/process/block/export_test.go index 81bb023431b..4f371041bd9 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -570,18 +570,31 @@ func (mp *metaProcessor) GetHdrForBlock() *hdrForBlock { return mp.hdrsForCurrBlock } +// ChannelReceiveAllHeaders - func (mp *metaProcessor) ChannelReceiveAllHeaders() chan bool { return mp.chRcvAllHdrs } +// ComputeExistingAndRequestMissingShardHeaders - func (mp *metaProcessor) ComputeExistingAndRequestMissingShardHeaders(metaBlock *block.MetaBlock) (uint32, uint32) { return mp.computeExistingAndRequestMissingShardHeaders(metaBlock) } +// ComputeExistingAndRequestMissingMetaHeaders - func (sp *shardProcessor) ComputeExistingAndRequestMissingMetaHeaders(header data.ShardHeaderHandler) (uint32, uint32) { return sp.computeExistingAndRequestMissingMetaHeaders(header) } +// GetHdrForBlock - +func (sp *shardProcessor) GetHdrForBlock() *hdrForBlock { + return sp.hdrsForCurrBlock +} + +// ChannelReceiveAllHeaders - +func (sp *shardProcessor) ChannelReceiveAllHeaders() chan bool { + return sp.chRcvAllMetaHdrs +} + // InitMaps - func (hfb *hdrForBlock) InitMaps() { hfb.initMaps() diff --git a/process/block/metablock_request_test.go b/process/block/metablock_request_test.go index bdc90162231..0343a2cc57e 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablock_request_test.go @@ -347,13 +347,7 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { // needs to be done before receiving the last header otherwise it will // be blocked waiting on writing to the channel - wg := &sync.WaitGroup{} - wg.Add(1) - go func(w *sync.WaitGroup) { - receivedAllHeaders := checkReceivedAllHeaders(mp.ChannelReceiveAllHeaders()) - require.True(t, receivedAllHeaders) - wg.Done() - }(wg) + wg := startWaitingForAllHeadersReceivedSignal(t, mp) // receive also the attestation header attestationHeaderData := td[0].attestationHeaderData @@ -430,13 +424,7 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { // needs to be done before receiving the last header otherwise it will // be blocked writing to a channel no one is reading from - wg := &sync.WaitGroup{} - wg.Add(1) - go func(w *sync.WaitGroup) { - receivedAllHeaders := checkReceivedAllHeaders(mp.ChannelReceiveAllHeaders()) - require.True(t, receivedAllHeaders) - wg.Done() - }(wg) + wg := startWaitingForAllHeadersReceivedSignal(t, mp) // receive also the attestation header headersPool.AddHeader(td[0].attestationHeaderData.headerHash, td[0].attestationHeaderData.header) @@ -454,6 +442,21 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { }) } +type ReceivedAllHeadersSignaler interface { + ChannelReceiveAllHeaders() chan bool +} + +func startWaitingForAllHeadersReceivedSignal(t *testing.T, mp ReceivedAllHeadersSignaler) *sync.WaitGroup { + wg := &sync.WaitGroup{} + wg.Add(1) + go func(w *sync.WaitGroup) { + receivedAllHeaders := checkReceivedAllHeaders(mp.ChannelReceiveAllHeaders()) + require.True(t, receivedAllHeaders) + wg.Done() + }(wg) + return wg +} + func checkReceivedAllHeaders(channelReceiveAllHeaders chan bool) bool { select { case <-time.After(100 * time.Millisecond): diff --git a/process/block/shardblock_request_test.go b/process/block/shardblock_request_test.go index 10cb7b73f1b..b4d8bd27a07 100644 --- a/process/block/shardblock_request_test.go +++ b/process/block/shardblock_request_test.go @@ -249,6 +249,192 @@ func TestShardProcessor_computeExistingAndRequestMissingMetaHeaders(t *testing.T func TestShardProcessor_receivedMetaBlock(t *testing.T) { t.Parallel() + t.Run("received non referenced metaBlock, while still having missing referenced metaBlocks", func(t *testing.T) { + t.Parallel() + + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + sp, _ := blproc.NewShardProcessor(arguments) + hdrsForBlock := sp.GetHdrForBlock() + + firstMissingMetaBlockData := testData[core.MetachainShardId].headerData[0] + secondMissingMetaBlockData := testData[core.MetachainShardId].headerData[1] + + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + require.Fail(t, "no requests expected") + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + require.Fail(t, "no requests expected") + } + + highestHeaderNonce := firstMissingMetaBlockData.header.GetNonce() - 1 + hdrsForBlock.SetNumMissingHdrs(2) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(core.MetachainShardId, highestHeaderNonce) + hdrsForBlock.SetHdrHashAndInfo(string(firstMissingMetaBlockData.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + hdrsForBlock.SetHdrHashAndInfo(string(secondMissingMetaBlockData.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + otherMetaBlock := &block.MetaBlock{ + Nonce: 102, + Round: 102, + PrevHash: []byte("other meta block prev hash"), + } + + otherMetaBlockHash := []byte("other meta block hash") + sp.ReceivedMetaBlock(otherMetaBlock, otherMetaBlockHash) + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(2), hdrsForBlock.GetMissingHdrs()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + highestHeaderNonces := hdrsForBlock.GetHighestHdrNonce() + require.Equal(t, highestHeaderNonce, highestHeaderNonces[core.MetachainShardId]) + }) + t.Run("received missing referenced metaBlock, other referenced metaBlock still missing", func(t *testing.T) { + t.Parallel() + + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + sp, _ := blproc.NewShardProcessor(arguments) + hdrsForBlock := sp.GetHdrForBlock() + + firstMissingMetaBlockData := testData[core.MetachainShardId].headerData[0] + secondMissingMetaBlockData := testData[core.MetachainShardId].headerData[1] + + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + require.Fail(t, "no requests expected") + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + require.Fail(t, "no requests expected") + } + + highestHeaderNonce := firstMissingMetaBlockData.header.GetNonce() - 1 + hdrsForBlock.SetNumMissingHdrs(2) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(core.MetachainShardId, highestHeaderNonce) + hdrsForBlock.SetHdrHashAndInfo(string(firstMissingMetaBlockData.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + hdrsForBlock.SetHdrHashAndInfo(string(secondMissingMetaBlockData.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + + sp.ReceivedMetaBlock(firstMissingMetaBlockData.header, firstMissingMetaBlockData.hash) + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(1), hdrsForBlock.GetMissingHdrs()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + highestHeaderNonces := hdrsForBlock.GetHighestHdrNonce() + require.Equal(t, firstMissingMetaBlockData.header.GetNonce(), highestHeaderNonces[core.MetachainShardId]) + }) + t.Run("received non missing referenced metaBlock", func(t *testing.T) { + t.Parallel() + + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + sp, _ := blproc.NewShardProcessor(arguments) + hdrsForBlock := sp.GetHdrForBlock() + + notMissingReferencedMetaBlockData := testData[core.MetachainShardId].headerData[0] + missingMetaBlockData := testData[core.MetachainShardId].headerData[1] + + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + require.Fail(t, "no requests expected") + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + require.Fail(t, "no requests expected") + } + + highestHeaderNonce := notMissingReferencedMetaBlockData.header.GetNonce() - 1 + hdrsForBlock.SetNumMissingHdrs(1) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(0) + hdrsForBlock.SetHighestHdrNonce(core.MetachainShardId, highestHeaderNonce) + hdrsForBlock.SetHdrHashAndInfo(string(notMissingReferencedMetaBlockData.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: notMissingReferencedMetaBlockData.header, + }) + hdrsForBlock.SetHdrHashAndInfo(string(missingMetaBlockData.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: nil, + }) + + headersDataPool := arguments.DataComponents.Datapool().Headers() + require.NotNil(t, headersDataPool) + headersDataPool.AddHeader(notMissingReferencedMetaBlockData.hash, notMissingReferencedMetaBlockData.header) + + sp.ReceivedMetaBlock(notMissingReferencedMetaBlockData.header, notMissingReferencedMetaBlockData.hash) + time.Sleep(100 * time.Millisecond) + + require.Equal(t, uint32(1), hdrsForBlock.GetMissingHdrs()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + hdrsForBlockHighestNonces := hdrsForBlock.GetHighestHdrNonce() + require.Equal(t, highestHeaderNonce, hdrsForBlockHighestNonces[core.MetachainShardId]) + }) + t.Run("received missing attestation metaBlock", func(t *testing.T) { + t.Parallel() + + arguments, requestHandler := shardBlockRequestTestInit(t) + testData := createShardProcessorTestData() + sp, _ := blproc.NewShardProcessor(arguments) + hdrsForBlock := sp.GetHdrForBlock() + + referencedMetaBlock := testData[core.MetachainShardId].headerData[0] + lastReferencedMetaBlock := testData[core.MetachainShardId].headerData[1] + attestationMetaBlockHash := []byte("attestation meta block hash") + attestationMetaBlock := &block.MetaBlock{ + Nonce: lastReferencedMetaBlock.header.GetNonce() + 1, + Round: lastReferencedMetaBlock.header.GetRound() + 1, + PrevHash: lastReferencedMetaBlock.hash, + } + + requestHandler.RequestMetaHeaderCalled = func(hash []byte) { + require.Fail(t, "no requests expected") + } + requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { + require.Fail(t, "no requests expected") + } + + hdrsForBlock.SetNumMissingHdrs(0) + hdrsForBlock.SetNumMissingFinalityAttestingHdrs(1) + hdrsForBlock.SetHighestHdrNonce(core.MetachainShardId, lastReferencedMetaBlock.header.GetNonce()) + hdrsForBlock.SetHdrHashAndInfo(string(referencedMetaBlock.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: referencedMetaBlock.header, + }) + hdrsForBlock.SetHdrHashAndInfo(string(lastReferencedMetaBlock.hash), + &blproc.HdrInfo{ + UsedInBlock: true, + Hdr: lastReferencedMetaBlock.header, + }) + + headersDataPool := arguments.DataComponents.Datapool().Headers() + require.NotNil(t, headersDataPool) + headersDataPool.AddHeader(referencedMetaBlock.hash, referencedMetaBlock.header) + headersDataPool.AddHeader(lastReferencedMetaBlock.hash, lastReferencedMetaBlock.header) + headersDataPool.AddHeader(attestationMetaBlockHash, attestationMetaBlock) + wg := startWaitingForAllHeadersReceivedSignal(t, sp) + + sp.ReceivedMetaBlock(attestationMetaBlock, attestationMetaBlockHash) + wg.Wait() + + require.Equal(t, uint32(0), hdrsForBlock.GetMissingHdrs()) + require.Equal(t, uint32(0), hdrsForBlock.GetMissingFinalityAttestingHdrs()) + hdrsForBlockHighestNonces := hdrsForBlock.GetHighestHdrNonce() + require.Equal(t, lastReferencedMetaBlock.header.GetNonce(), hdrsForBlockHighestNonces[core.MetachainShardId]) + }) } func shardBlockRequestTestInit(t *testing.T) (blproc.ArgShardProcessor, *testscommon.RequestHandlerStub) { From c99893f66f9c43416c1dee13cd9b97d735923f15 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 15:34:34 +0200 Subject: [PATCH 670/958] fix --- node/chainSimulator/components/syncedMessenger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/components/syncedMessenger.go b/node/chainSimulator/components/syncedMessenger.go index 711cdd7a415..f69f572191c 100644 --- a/node/chainSimulator/components/syncedMessenger.go +++ b/node/chainSimulator/components/syncedMessenger.go @@ -60,9 +60,9 @@ func NewSyncedMessenger(network SyncedBroadcastNetworkHandler) (*syncedMessenger return messenger, nil } -// HasCompatibleProtocolID returns false as it is disabled +// HasCompatibleProtocolID returns true func (messenger *syncedMessenger) HasCompatibleProtocolID(_ string) bool { - return false + return true } func (messenger *syncedMessenger) receive(fromConnectedPeer core.PeerID, message p2p.MessageP2P) { From 000e18f23100b3a616795efb0c88d4d30ab7524f Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 15:41:09 +0200 Subject: [PATCH 671/958] FEAT: Extra checks for soft auction config --- epochStart/metachain/auctionListSelector.go | 55 ++++++++--- .../metachain/auctionListSelector_test.go | 94 +++++++++++++++++-- 2 files changed, 129 insertions(+), 20 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 5bc3d915647..6a212030f9d 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -27,11 +27,11 @@ type ownerAuctionData struct { } type auctionConfig struct { - step *big.Int - minTopUp *big.Int - maxTopUp *big.Int - denominator *big.Int - maxNumOfIterations uint64 + step *big.Int + minTopUp *big.Int + maxTopUp *big.Int + denominator *big.Int + maxNumberOfIterations uint64 } type auctionListSelector struct { @@ -103,19 +103,50 @@ func getAuctionConfig(softAuctionConfig config.SoftAuctionConfig, denomination i ) } + if minTopUp.Cmp(maxTopUp) > 0 { + return nil, fmt.Errorf("%w for min/max top up in soft auction config; min value: %s > max value: %s", + process.ErrInvalidValue, + softAuctionConfig.MinTopUp, + softAuctionConfig.MaxTopUp, + ) + } + if denomination < 0 { - return nil, fmt.Errorf("%w for denomination soft auction config;expected number >= 0, got %d", + return nil, fmt.Errorf("%w for denomination in soft auction config;expected number >= 0, got %d", process.ErrInvalidValue, denomination, ) } + if softAuctionConfig.MaxNumberOfIterations == 0 { + return nil, fmt.Errorf("%w for max number of iterations in soft auction config;expected value > 0", + process.ErrInvalidValue, + ) + } + + denominator := big.NewInt(int64(math.Pow10(denomination))) + if minTopUp.Cmp(denominator) < 0 { + return nil, fmt.Errorf("%w for min top up in auction config; expected value to be >= %s, got %s", + process.ErrInvalidValue, + denominator.String(), + minTopUp.String(), + ) + } + + if step.Cmp(denominator) < 0 { + return nil, fmt.Errorf("%w for step in auction config; expected value to be >= %s, got %s", + process.ErrInvalidValue, + denominator.String(), + step.String(), + ) + } + return &auctionConfig{ - step: step, - minTopUp: minTopUp, - maxTopUp: maxTopUp, - denominator: big.NewInt(int64(math.Pow10(denomination))), - maxNumOfIterations: softAuctionConfig.MaxNumberOfIterations, + step: step, + minTopUp: minTopUp, + maxTopUp: maxTopUp, + denominator: denominator, + maxNumberOfIterations: softAuctionConfig.MaxNumberOfIterations, }, nil } @@ -270,7 +301,7 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( } iterationNumber++ - maxNumberOfIterationsReached = iterationNumber >= als.softAuctionConfig.maxNumOfIterations + maxNumberOfIterationsReached = iterationNumber >= als.softAuctionConfig.maxNumberOfIterations } als.displayMinRequiredTopUp(topUp, minTopUp) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index b9108d9b847..8aa4a2937a8 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -198,22 +198,100 @@ func TestGetAuctionConfig(t *testing.T) { requireInvalidValueError(t, err, "denomination") }) + t.Run("zero max number of iterations", func(t *testing.T) { + t.Parallel() + + cfg := createSoftAuctionConfig() + cfg.MaxNumberOfIterations = 0 + + res, err := getAuctionConfig(cfg, 10) + require.Nil(t, res) + requireInvalidValueError(t, err, "for max number of iterations in soft auction config") + }) + + t.Run("min top up > max top up", func(t *testing.T) { + t.Parallel() + + cfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "32", + MaxTopUp: "16", + MaxNumberOfIterations: 1, + } + + res, err := getAuctionConfig(cfg, 1) + require.Nil(t, res) + requireInvalidValueError(t, err, "min value: 32 > max value: 16") + }) + + t.Run("min top up < denominator", func(t *testing.T) { + t.Parallel() + + cfg := config.SoftAuctionConfig{ + TopUpStep: "100", + MinTopUp: "10", + MaxTopUp: "5000", + MaxNumberOfIterations: 1, + } + + res, err := getAuctionConfig(cfg, 2) + require.Nil(t, res) + requireInvalidValueError(t, err, "for min top up in auction config; expected value to be >= 100, got 10") + }) + + t.Run("step < denominator", func(t *testing.T) { + t.Parallel() + + cfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "100", + MaxTopUp: "5000", + MaxNumberOfIterations: 1, + } + + res, err := getAuctionConfig(cfg, 2) + require.Nil(t, res) + requireInvalidValueError(t, err, "for step in auction config; expected value to be >= 100, got 10") + }) + t.Run("should work", func(t *testing.T) { t.Parallel() cfg := config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "444", + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "444", + MaxNumberOfIterations: 100000, + } + + res, err := getAuctionConfig(cfg, 0) + require.Nil(t, err) + require.Equal(t, &auctionConfig{ + step: big.NewInt(10), + minTopUp: big.NewInt(1), + maxTopUp: big.NewInt(444), + denominator: big.NewInt(1), + maxNumberOfIterations: 100000, + }, res) + + minTopUp, _ := big.NewInt(0).SetString("1000000000000000000", 10) + maxTopUp, _ := big.NewInt(0).SetString("32000000000000000000000000", 10) + step, _ := big.NewInt(0).SetString("10000000000000000000", 10) + cfg = config.SoftAuctionConfig{ + TopUpStep: step.String(), + MinTopUp: minTopUp.String(), + MaxTopUp: maxTopUp.String(), + MaxNumberOfIterations: 100000, } - res, err := getAuctionConfig(cfg, 4) + res, err = getAuctionConfig(cfg, 18) require.Nil(t, err) require.Equal(t, &auctionConfig{ - step: big.NewInt(10), - minTopUp: big.NewInt(1), - maxTopUp: big.NewInt(444), - denominator: big.NewInt(10000), + step: step, + minTopUp: minTopUp, + maxTopUp: maxTopUp, + denominator: minTopUp, + maxNumberOfIterations: 100000, }, res) }) } From 2c4670a15e1c64f2651a082fd21eaab300a1a2f1 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 15:55:04 +0200 Subject: [PATCH 672/958] CLN: Move SoftAuctionConfig to systemSmartContractsConfig.toml --- cmd/node/config/config.toml | 7 ------- cmd/node/config/systemSmartContractsConfig.toml | 7 +++++++ config/config.go | 10 ---------- config/systemSmartContractsConfig.go | 9 +++++++++ epochStart/metachain/systemSCs_test.go | 6 ++++++ factory/processing/blockProcessorCreator.go | 4 ++-- factory/processing/processComponents_test.go | 6 ++++++ genesis/process/genesisBlockCreator_test.go | 6 ++++++ .../multiShard/hardFork/hardFork_test.go | 6 ++++++ integrationTests/testInitializer.go | 12 ++++++++++++ integrationTests/testProcessorNode.go | 12 ++++++++++++ integrationTests/vm/staking/systemSCCreator.go | 6 ++++++ integrationTests/vm/testInitializer.go | 6 ++++++ process/factory/metachain/vmContainerFactory_test.go | 12 ++++++++++++ testscommon/components/components.go | 6 ++++++ testscommon/generalConfig.go | 6 ------ vm/factory/systemSCFactory_test.go | 6 ++++++ 17 files changed, 102 insertions(+), 25 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 66e79dfbad9..85fde2e08cf 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -936,10 +936,3 @@ # MaxRoundsOfInactivityAccepted defines the number of rounds missed by a main or higher level backup machine before # the current machine will take over and propose/sign blocks. Used in both single-key and multi-key modes. MaxRoundsOfInactivityAccepted = 3 - -# Changing this config is not backwards compatible -[SoftAuctionConfig] - TopUpStep = "10000000000000000000" # 10 EGLD - MinTopUp = "1000000000000000000" # 1 EGLD should be minimum - MaxTopUp = "32000000000000000000000000" # 32 mil EGLD - MaxNumberOfIterations = 100000 # 100k max number of iterations for soft auction config diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index 1b7724ee9e4..247be7171e5 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -41,3 +41,10 @@ [DelegationSystemSCConfig] MinServiceFee = 0 MaxServiceFee = 10000 + +# Changing this config is not backwards compatible +[SoftAuctionConfig] + TopUpStep = "10000000000000000000" # 10 EGLD + MinTopUp = "1000000000000000000" # 1 EGLD should be minimum + MaxTopUp = "32000000000000000000000000" # 32 mil EGLD + MaxNumberOfIterations = 100000 # 100k max number of iterations for soft auction config diff --git a/config/config.go b/config/config.go index 44d7d524544..6b76bbfe2ad 100644 --- a/config/config.go +++ b/config/config.go @@ -226,8 +226,6 @@ type Config struct { PeersRatingConfig PeersRatingConfig PoolsCleanersConfig PoolsCleanersConfig Redundancy RedundancyConfig - - SoftAuctionConfig SoftAuctionConfig } // PeersRatingConfig will hold settings related to peers rating @@ -638,11 +636,3 @@ type PoolsCleanersConfig struct { type RedundancyConfig struct { MaxRoundsOfInactivityAccepted int } - -// SoftAuctionConfig represents the config options for soft auction selecting used in staking v4 -type SoftAuctionConfig struct { - TopUpStep string - MinTopUp string - MaxTopUp string - MaxNumberOfIterations uint64 -} diff --git a/config/systemSmartContractsConfig.go b/config/systemSmartContractsConfig.go index a593fe40268..0ed6cce28b1 100644 --- a/config/systemSmartContractsConfig.go +++ b/config/systemSmartContractsConfig.go @@ -7,6 +7,7 @@ type SystemSmartContractsConfig struct { StakingSystemSCConfig StakingSystemSCConfig DelegationManagerSystemSCConfig DelegationManagerSystemSCConfig DelegationSystemSCConfig DelegationSystemSCConfig + SoftAuctionConfig SoftAuctionConfig } // StakingSystemSCConfig will hold the staking system smart contract settings @@ -73,3 +74,11 @@ type DelegationSystemSCConfig struct { MaxServiceFee uint64 AddTokensWhitelistedAddress string } + +// SoftAuctionConfig represents the config options for soft auction selecting used in staking v4 +type SoftAuctionConfig struct { + TopUpStep string + MinTopUp string + MaxTopUp string + MaxNumberOfIterations uint64 +} diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 46e19c64db1..6979a357baa 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -872,6 +872,12 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ValidatorAccountsDB: peerAccountsDB, UserAccountsDB: userAccountsDB, diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index aeda108e73f..38f5308bcdf 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -891,7 +891,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, - SoftAuctionConfig: pcf.config.SoftAuctionConfig, + SoftAuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, Denomination: pcf.economicsConfig.GlobalSettings.Denomination, } auctionListSelector, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelector) @@ -903,7 +903,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), StakingDataProvider: stakingDataProviderAPI, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, - SoftAuctionConfig: pcf.config.SoftAuctionConfig, + SoftAuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, Denomination: pcf.economicsConfig.GlobalSettings.Denomination, } auctionListSelectorAPI, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelectorAPI) diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index b0266dc158b..9e4b8dc8e95 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -151,6 +151,12 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ImportStartHandler: &testscommon.ImportStartHandlerStub{}, HistoryRepo: &dblookupext.HistoryRepositoryStub{}, diff --git a/genesis/process/genesisBlockCreator_test.go b/genesis/process/genesisBlockCreator_test.go index 79588c87135..366fb9620de 100644 --- a/genesis/process/genesisBlockCreator_test.go +++ b/genesis/process/genesisBlockCreator_test.go @@ -163,6 +163,12 @@ func createMockArgument( MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, TrieStorageManagers: trieStorageManagers, BlockSignKeyGen: &mock.KeyGenMock{}, diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index bbac759a1be..f7ed4d3603c 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -477,6 +477,12 @@ func hardForkImport( MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, AccountsParser: &genesisMocks.AccountsParserStub{}, SmartContractParser: &mock.SmartContractParserStub{}, diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 69e3297d821..dac914ba837 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -727,6 +727,12 @@ func CreateFullGenesisBlocks( MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, AccountsParser: accountsParser, SmartContractParser: smartContractParser, @@ -836,6 +842,12 @@ func CreateGenesisMetaBlock( MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, BlockSignKeyGen: &mock.KeyGenMock{}, GenesisNodePrice: big.NewInt(1000), diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 97d729337d6..33233498fdc 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -967,6 +967,12 @@ func (tpn *TestProcessorNode) createFullSCQueryService(gasMap map[string]map[str MinServiceFee: 0, MaxServiceFee: 100000, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ValidatorAccountsDB: tpn.PeerState, UserAccountsDB: tpn.AccntState, @@ -1925,6 +1931,12 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors(gasMap map[string]map[stri MinServiceFee: 0, MaxServiceFee: 100000, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ValidatorAccountsDB: tpn.PeerState, UserAccountsDB: tpn.AccntState, diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 1beee160be2..0fda20f4722 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -233,6 +233,12 @@ func createVMContainerFactory( MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ValidatorAccountsDB: stateComponents.PeerAccounts(), ChanceComputer: coreComponents.Rater(), diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index b6d189b93ae..7a4f4d7d7dd 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -779,6 +779,12 @@ func createSystemSCConfig() *config.SystemSmartContractsConfig { MinServiceFee: 1, MaxServiceFee: 20, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, } } diff --git a/process/factory/metachain/vmContainerFactory_test.go b/process/factory/metachain/vmContainerFactory_test.go index 9b3c2f6de59..98bb8396d45 100644 --- a/process/factory/metachain/vmContainerFactory_test.go +++ b/process/factory/metachain/vmContainerFactory_test.go @@ -66,6 +66,12 @@ func createVmContainerMockArgument(gasSchedule core.GasScheduleNotifier) ArgsNew StakeLimitPercentage: 100.0, NodeLimitPercentage: 100.0, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ValidatorAccountsDB: &stateMock.AccountsStub{}, UserAccountsDB: &stateMock.AccountsStub{}, @@ -372,6 +378,12 @@ func TestVmContainerFactory_Create(t *testing.T) { MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, ValidatorAccountsDB: &stateMock.AccountsStub{}, UserAccountsDB: &stateMock.AccountsStub{}, diff --git a/testscommon/components/components.go b/testscommon/components/components.go index 1687a0c1817..055c4ba37e2 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -560,6 +560,12 @@ func GetProcessArgs( MinServiceFee: 0, MaxServiceFee: 100, }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, HistoryRepo: &dblookupext.HistoryRepositoryStub{}, FlagsConfig: config.ContextFlagsConfig{ diff --git a/testscommon/generalConfig.go b/testscommon/generalConfig.go index 1e2c8d758bd..0cf69ff24ed 100644 --- a/testscommon/generalConfig.go +++ b/testscommon/generalConfig.go @@ -8,12 +8,6 @@ import ( // GetGeneralConfig returns the common configuration used for testing func GetGeneralConfig() config.Config { return config.Config{ - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - MaxNumberOfIterations: 100000, - }, Hardfork: config.HardforkConfig{ PublicKeyToListenFrom: "153dae6cb3963260f309959bf285537b77ae16d82e9933147be7827f7394de8dc97d9d9af41e970bc72aecb44b77e819621081658c37f7000d21e2d0e8963df83233407bde9f46369ba4fcd03b57f40b80b06c191a428cfb5c447ec510e79307", CloseAfterExportInMinutes: 2, diff --git a/vm/factory/systemSCFactory_test.go b/vm/factory/systemSCFactory_test.go index 280c196b25c..76c46685cb1 100644 --- a/vm/factory/systemSCFactory_test.go +++ b/vm/factory/systemSCFactory_test.go @@ -77,6 +77,12 @@ func createMockNewSystemScFactoryArgs() ArgsNewSystemSCFactory { MinStakeAmount: "10", ConfigChangeAddress: "3132333435363738393031323334353637383930313233343536373839303234", }, + SoftAuctionConfig: config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + }, }, AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, ShardCoordinator: &mock.ShardCoordinatorStub{}, From c984bcb26850f33d9504bdc377b9c59bdc8d61f8 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 16:32:52 +0200 Subject: [PATCH 673/958] fix --- cmd/node/config/testKeys/validatorKey.pem | 4 ---- node/external/timemachine/fee/memoryFootprint/memory_test.go | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 cmd/node/config/testKeys/validatorKey.pem diff --git a/cmd/node/config/testKeys/validatorKey.pem b/cmd/node/config/testKeys/validatorKey.pem deleted file mode 100644 index e4e7ec71328..00000000000 --- a/cmd/node/config/testKeys/validatorKey.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PRIVATE KEY for 75907bf66c64949f8d1dd003ed8fd815e8dec189a9e50e4bfd7e2592cfdc92641baf500e3533820e0f58c4ed3f39c01750f0017726731fe5bc66a0ab6fc9a7b5661d163e72f099fe29df16fd59ded198dc1423575be1b6e2160e0d84a5ece08a----- -MmVkOGZmZDRmNWQ5NjIyMjU5YjRiYjE2OGQ5ZTk2YjYxMjIyMmMwOGU5NTM4MTcz -MGVkMzI3ODY4Y2I2NDUwNA== ------END PRIVATE KEY for 75907bf66c64949f8d1dd003ed8fd815e8dec189a9e50e4bfd7e2592cfdc92641baf500e3533820e0f58c4ed3f39c01750f0017726731fe5bc66a0ab6fc9a7b5661d163e72f099fe29df16fd59ded198dc1423575be1b6e2160e0d84a5ece08a----- diff --git a/node/external/timemachine/fee/memoryFootprint/memory_test.go b/node/external/timemachine/fee/memoryFootprint/memory_test.go index 52c91c22ff8..2f32427e4de 100644 --- a/node/external/timemachine/fee/memoryFootprint/memory_test.go +++ b/node/external/timemachine/fee/memoryFootprint/memory_test.go @@ -23,7 +23,7 @@ func TestFeeComputer_MemoryFootprint(t *testing.T) { } numEpochs := 10000 - maxFootprintNumBytes := 60_000_000 + maxFootprintNumBytes := 50_000_000 journal := &memoryFootprintJournal{} journal.before = getMemStats() From 60c9cb1d9a849e05451881c74da8f8dcb89989c3 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 1 Feb 2024 17:07:55 +0200 Subject: [PATCH 674/958] fixes --- node/chainSimulator/chainSimulator.go | 5 +---- node/chainSimulator/configs/configs.go | 5 +++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 5419b775648..a22c563ed9f 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -75,15 +75,12 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { TempDir: args.TempDir, MinNodesPerShard: args.MinNodesPerShard, MetaChainMinNodes: args.MetaChainMinNodes, + RoundsPerEpoch: args.RoundsPerEpoch, }) if err != nil { return err } - if args.RoundsPerEpoch.HasValue { - outputConfigs.Configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) - } - for idx := 0; idx < int(args.NumOfShards)+1; idx++ { shardIDStr := fmt.Sprintf("%d", idx-1) if idx == 0 { diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 7795e4d25ae..1e09dc53ee4 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -47,6 +47,7 @@ type ArgsChainSimulatorConfigs struct { TempDir string MinNodesPerShard uint32 MetaChainMinNodes uint32 + RoundsPerEpoch core.OptionalUint64 } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -115,6 +116,10 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi // enable db lookup extension configs.GeneralConfig.DbLookupExtensions.Enabled = true + if args.RoundsPerEpoch.HasValue { + configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) + } + return &ArgsConfigsSimulator{ Configs: configs, ValidatorsPrivateKeys: privateKeys, From e99e4e425ec41a5572a8fcdfdad0ec70512aff47 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 17:14:21 +0200 Subject: [PATCH 675/958] FIX: Revert deleted check for token ticker --- vm/errors.go | 3 +++ vm/systemSmartContracts/esdt.go | 23 +++++++++++++++++++++++ vm/systemSmartContracts/esdt_test.go | 12 ++++++++++++ 3 files changed, 38 insertions(+) diff --git a/vm/errors.go b/vm/errors.go index ba8958321dd..0e3ea608ed2 100644 --- a/vm/errors.go +++ b/vm/errors.go @@ -178,6 +178,9 @@ var ErrInvalidMaxNumberOfNodes = errors.New("invalid number of max number of nod // ErrTokenNameNotHumanReadable signals that token name is not human-readable var ErrTokenNameNotHumanReadable = errors.New("token name is not human readable") +// ErrTickerNameNotValid signals that ticker name is not valid +var ErrTickerNameNotValid = errors.New("ticker name is not valid") + // ErrCouldNotCreateNewTokenIdentifier signals that token identifier could not be created var ErrCouldNotCreateNewTokenIdentifier = errors.New("token identifier could not be created") diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 74d2a681310..7e8abf040cf 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -23,6 +23,8 @@ import ( const numOfRetriesForIdentifier = 50 const tickerSeparator = "-" const tickerRandomSequenceLength = 3 +const minLengthForTickerName = 3 +const maxLengthForTickerName = 10 const minLengthForInitTokenName = 10 const minLengthForTokenName = 3 const maxLengthForTokenName = 20 @@ -616,6 +618,10 @@ func (e *esdt) createNewToken( if !isTokenNameHumanReadable(tokenName) { return nil, nil, vm.ErrTokenNameNotHumanReadable } + if !isTickerValid(tickerName) { + return nil, nil, vm.ErrTickerNameNotValid + } + tokenIdentifier, err := e.createNewTokenIdentifier(owner, tickerName) if err != nil { return nil, nil, err @@ -659,6 +665,23 @@ func isTokenNameHumanReadable(tokenName []byte) bool { return true } +func isTickerValid(tickerName []byte) bool { + if len(tickerName) < minLengthForTickerName || len(tickerName) > maxLengthForTickerName { + return false + } + + for _, ch := range tickerName { + isBigCharacter := ch >= 'A' && ch <= 'Z' + isNumber := ch >= '0' && ch <= '9' + isReadable := isBigCharacter || isNumber + if !isReadable { + return false + } + } + + return true +} + func (e *esdt) createNewTokenIdentifier(caller []byte, ticker []byte) ([]byte, error) { newRandomBase := append(caller, e.eei.BlockChainHook().CurrentRandomSeed()...) newRandom := e.hasher.Compute(string(newRandomBase)) diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index 47171b4af24..0504527efb6 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -4032,6 +4032,12 @@ func TestEsdt_ExecuteIssueMetaESDT(t *testing.T) { assert.Equal(t, vmcommon.UserError, output) assert.True(t, strings.Contains(eei.returnMessage, "invalid number of decimals")) + vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("ticker"), big.NewInt(10).Bytes()} + eei.returnMessage = "" + output = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, output) + assert.True(t, strings.Contains(eei.returnMessage, "ticker name is not valid")) + vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("TICKER"), big.NewInt(10).Bytes()} eei.returnMessage = "" output = e.Execute(vmInput) @@ -4162,6 +4168,12 @@ func TestEsdt_ExecuteRegisterAndSetErrors(t *testing.T) { assert.Equal(t, vmcommon.UserError, output) assert.True(t, strings.Contains(eei.returnMessage, vm.ErrInvalidArgument.Error())) + vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("ticker"), []byte("FNG"), big.NewInt(10).Bytes()} + eei.returnMessage = "" + output = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, output) + assert.True(t, strings.Contains(eei.returnMessage, "ticker name is not valid")) + vmInput.Arguments = [][]byte{[]byte("tokenName"), []byte("ticker"), []byte("FNG"), big.NewInt(20).Bytes()} eei.returnMessage = "" output = e.Execute(vmInput) From 0426272d1599345335eddff45c348d7fec088de9 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 17:15:42 +0200 Subject: [PATCH 676/958] FIX: Revert deleted check for token ticker --- vm/systemSmartContracts/esdt.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 7e8abf040cf..1a6d0cabbbe 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -652,33 +652,33 @@ func (e *esdt) createNewToken( return tokenIdentifier, newESDTToken, nil } -func isTokenNameHumanReadable(tokenName []byte) bool { - for _, ch := range tokenName { - isSmallCharacter := ch >= 'a' && ch <= 'z' +func isTickerValid(tickerName []byte) bool { + if len(tickerName) < minLengthForTickerName || len(tickerName) > maxLengthForTickerName { + return false + } + + for _, ch := range tickerName { isBigCharacter := ch >= 'A' && ch <= 'Z' isNumber := ch >= '0' && ch <= '9' - isReadable := isSmallCharacter || isBigCharacter || isNumber + isReadable := isBigCharacter || isNumber if !isReadable { return false } } + return true } -func isTickerValid(tickerName []byte) bool { - if len(tickerName) < minLengthForTickerName || len(tickerName) > maxLengthForTickerName { - return false - } - - for _, ch := range tickerName { +func isTokenNameHumanReadable(tokenName []byte) bool { + for _, ch := range tokenName { + isSmallCharacter := ch >= 'a' && ch <= 'z' isBigCharacter := ch >= 'A' && ch <= 'Z' isNumber := ch >= '0' && ch <= '9' - isReadable := isBigCharacter || isNumber + isReadable := isSmallCharacter || isBigCharacter || isNumber if !isReadable { return false } } - return true } From f0553a993fb11f058f72b2ffc594914297b22779 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 1 Feb 2024 17:22:05 +0200 Subject: [PATCH 677/958] - changed the chain simulator to use less config pointers --- node/chainSimulator/chainSimulator.go | 6 +++--- .../components/testOnlyProcessingNode_test.go | 2 +- node/chainSimulator/configs/configs.go | 4 ++-- node/chainSimulator/configs/configs_test.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index a22c563ed9f..b3edda81eed 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -87,7 +87,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { shardIDStr = "metachain" } - node, errCreate := s.createTestNode(outputConfigs, args, shardIDStr) + node, errCreate := s.createTestNode(*outputConfigs, args, shardIDStr) if errCreate != nil { return errCreate } @@ -121,10 +121,10 @@ func computeStartTimeBaseOnInitialRound(args ArgsChainSimulator) int64 { } func (s *simulator) createTestNode( - outputConfigs *configs.ArgsConfigsSimulator, args ArgsChainSimulator, shardIDStr string, + outputConfigs configs.ArgsConfigsSimulator, args ArgsChainSimulator, shardIDStr string, ) (process.NodeHandler, error) { argsTestOnlyProcessorNode := components.ArgsTestOnlyProcessingNode{ - Configs: *outputConfigs.Configs, + Configs: outputConfigs.Configs, ChanStopNodeProcess: s.chanStopNodeProcess, SyncedBroadcastNetwork: s.syncedBroadcastNetwork, NumShards: s.numOfShards, diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index fade9b12e6f..64dbf32b8e3 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -25,7 +25,7 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo require.Nil(t, err) return ArgsTestOnlyProcessingNode{ - Configs: *outputConfigs.Configs, + Configs: outputConfigs.Configs, GasScheduleFilename: outputConfigs.GasScheduleFilename, NumShards: 3, diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 1e09dc53ee4..329436a000d 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -53,7 +53,7 @@ type ArgsChainSimulatorConfigs struct { // ArgsConfigsSimulator holds the configs for the chain simulator type ArgsConfigsSimulator struct { GasScheduleFilename string - Configs *config.Configs + Configs config.Configs ValidatorsPrivateKeys []crypto.PrivateKey InitialWallets *dtos.InitialWalletKeys } @@ -121,7 +121,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi } return &ArgsConfigsSimulator{ - Configs: configs, + Configs: *configs, ValidatorsPrivateKeys: privateKeys, GasScheduleFilename: gasScheduleName, InitialWallets: initialWallets, diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index 15c633ce8cd..52da48ecda0 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -23,6 +23,6 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { }) require.Nil(t, err) - pr := realcomponents.NewProcessorRunner(t, *outputConfig.Configs) + pr := realcomponents.NewProcessorRunner(t, outputConfig.Configs) pr.Close(t) } From 19efa59b3edb35546a9ab388ade7793db9ecc625 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 17:25:33 +0200 Subject: [PATCH 678/958] FIX: Denominator calculation using string instead of int64 --- epochStart/metachain/auctionListSelector.go | 12 ++++++++++-- epochStart/metachain/auctionListSelector_test.go | 1 + epochStart/metachain/errors.go | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 6a212030f9d..b2e39ab14dc 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -2,8 +2,8 @@ package metachain import ( "fmt" - "math" "math/big" + "strings" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" @@ -124,7 +124,15 @@ func getAuctionConfig(softAuctionConfig config.SoftAuctionConfig, denomination i ) } - denominator := big.NewInt(int64(math.Pow10(denomination))) + denominationStr := "1" + strings.Repeat("0", denomination) + denominator, ok := big.NewInt(0).SetString(denominationStr, 10) + if !ok { + return nil, fmt.Errorf("%w for denomination: %d", + errCannotComputeDenominator, + denomination, + ) + } + if minTopUp.Cmp(denominator) < 0 { return nil, fmt.Errorf("%w for min top up in auction config; expected value to be >= %s, got %s", process.ErrInvalidValue, diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 8aa4a2937a8..46073ffd37a 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -113,6 +113,7 @@ func TestNewAuctionListSelector(t *testing.T) { als, err := NewAuctionListSelector(args) require.NotNil(t, als) require.Nil(t, err) + require.False(t, als.IsInterfaceNil()) }) } diff --git a/epochStart/metachain/errors.go b/epochStart/metachain/errors.go index e55f55ba9a3..9a6d1375024 100644 --- a/epochStart/metachain/errors.go +++ b/epochStart/metachain/errors.go @@ -3,3 +3,5 @@ package metachain import "errors" var errNilValidatorsInfoMap = errors.New("received nil shard validators info map") + +var errCannotComputeDenominator = errors.New("cannot compute denominator value") From 85bcc52e7a2f9df83358161f3c3d91faff3be600 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 1 Feb 2024 18:03:58 +0200 Subject: [PATCH 679/958] FIX: Unit test --- node/nodeRunner_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/nodeRunner_test.go b/node/nodeRunner_test.go index 6e3c61a12cd..050ddcaf69b 100644 --- a/node/nodeRunner_test.go +++ b/node/nodeRunner_test.go @@ -46,6 +46,7 @@ func TestNodeRunner_StartAndCloseNodeUsingSIGINT(t *testing.T) { t.Parallel() configs := testscommon.CreateTestConfigs(t, originalConfigsPath) + configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].MaxNumNodes = 50 runner, _ := NewNodeRunner(configs) trigger := mock.NewApplicationRunningTrigger() From aca9162d5cf50e53e346ffc643ec759ef869fe64 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 09:10:49 +0200 Subject: [PATCH 680/958] skip test --- node/chainSimulator/chainSimulator_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 4f3fbe3b51f..17eebfc81d7 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -76,6 +76,10 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { } func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ From 95954e4e72f98665b7b59b6c6e899d8035ecbc63 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 10:36:45 +0200 Subject: [PATCH 681/958] fixes --- .../components/bootstrapComponents.go | 26 ++++++++++++------- .../components/testOnlyProcessingNode.go | 6 ++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index b40eeb0810d..9bc5a406c89 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -10,6 +10,7 @@ import ( bootstrapComp "github.com/multiversx/mx-chain-go/factory/bootstrap" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" ) // ArgsBootstrapComponentsHolder will hold the components needed for the bootstrap components holders @@ -27,15 +28,16 @@ type ArgsBootstrapComponentsHolder struct { } type bootstrapComponentsHolder struct { - closeHandler *closeHandler - epochStartBootstrapper factory.EpochStartBootstrapper - epochBootstrapParams factory.BootstrapParamsHolder - nodeType core.NodeType - shardCoordinator sharding.Coordinator - versionedHeaderFactory nodeFactory.VersionedHeaderFactory - headerVersionHandler nodeFactory.HeaderVersionHandler - headerIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler - guardedAccountHandler process.GuardedAccountHandler + closeHandler *closeHandler + epochStartBootstrapper factory.EpochStartBootstrapper + epochBootstrapParams factory.BootstrapParamsHolder + nodeType core.NodeType + shardCoordinator sharding.Coordinator + versionedHeaderFactory nodeFactory.VersionedHeaderFactory + headerVersionHandler nodeFactory.HeaderVersionHandler + headerIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler + guardedAccountHandler process.GuardedAccountHandler + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory } // CreateBootstrapComponents will create a new instance of bootstrap components holder @@ -81,12 +83,18 @@ func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (factory.Boot instance.headerVersionHandler = managedBootstrapComponents.HeaderVersionHandler() instance.headerIntegrityVerifier = managedBootstrapComponents.HeaderIntegrityVerifier() instance.guardedAccountHandler = managedBootstrapComponents.GuardedAccountHandler() + instance.nodesCoordinatorRegistryFactory = managedBootstrapComponents.NodesCoordinatorRegistryFactory() instance.collectClosableComponents() return instance, nil } +// NodesCoordinatorRegistryFactory will return the nodes coordinator registry factory +func (b *bootstrapComponentsHolder) NodesCoordinatorRegistryFactory() nodesCoordinator.NodesCoordinatorRegistryFactory { + return b.nodesCoordinatorRegistryFactory +} + // EpochStartBootstrapper will return the epoch start bootstrapper func (b *bootstrapComponentsHolder) EpochStartBootstrapper() factory.EpochStartBootstrapper { return b.epochStartBootstrapper diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 14ec26cba86..c0f7e3523de 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -81,10 +81,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } var err error - instance.TransactionFeeHandler, err = postprocess.NewFeeAccumulator() - if err != nil { - return nil, err - } + instance.TransactionFeeHandler = postprocess.NewFeeAccumulator() instance.CoreComponentsHolder, err = CreateCoreComponents(ArgsCoreComponentsHolder{ Config: *args.Configs.GeneralConfig, @@ -300,6 +297,7 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc node.CoreComponentsHolder.NodeTypeProvider(), node.CoreComponentsHolder.EnableEpochsHandler(), node.DataPool.CurrentEpochValidatorInfo(), + node.BootstrapComponentsHolder.NodesCoordinatorRegistryFactory(), ) if err != nil { return err From f041f645196dca078c91bdcbb1dd4238a9579d23 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 2 Feb 2024 12:43:32 +0200 Subject: [PATCH 682/958] updated parameters --- cmd/node/config/fullArchiveP2P.toml | 4 ++-- cmd/node/config/p2p.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/node/config/fullArchiveP2P.toml b/cmd/node/config/fullArchiveP2P.toml index bfe1d27f1a6..0a7ee26a73f 100644 --- a/cmd/node/config/fullArchiveP2P.toml +++ b/cmd/node/config/fullArchiveP2P.toml @@ -72,9 +72,9 @@ [Sharding] # The targeted number of peer connections TargetPeerCount = 36 - MaxIntraShardValidators = 7 + MaxIntraShardValidators = 6 MaxCrossShardValidators = 13 - MaxIntraShardObservers = 4 + MaxIntraShardObservers = 5 MaxCrossShardObservers = 3 MaxSeeders = 2 diff --git a/cmd/node/config/p2p.toml b/cmd/node/config/p2p.toml index 0ccc1c20398..6e9931f9bc1 100644 --- a/cmd/node/config/p2p.toml +++ b/cmd/node/config/p2p.toml @@ -72,9 +72,9 @@ [Sharding] # The targeted number of peer connections TargetPeerCount = 36 - MaxIntraShardValidators = 7 + MaxIntraShardValidators = 6 MaxCrossShardValidators = 13 - MaxIntraShardObservers = 4 + MaxIntraShardObservers = 5 MaxCrossShardObservers = 3 MaxSeeders = 2 From 4d289ecbca9bea4215d8aea7a709facd2d56750d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 12:48:50 +0200 Subject: [PATCH 683/958] fix staking v4 --- node/chainSimulator/components/coreComponents.go | 1 + node/chainSimulator/configs/configs.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 373e34de033..2c436453d59 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -211,6 +211,7 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents ShuffleBetweenShards: true, MaxNodesEnableConfig: args.EnableEpochsConfig.MaxNodesChangeEnableEpoch, EnableEpochsHandler: instance.enableEpochsHandler, + EnableEpochs: args.EnableEpochsConfig, }) if err != nil { return nil, err diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 329436a000d..d904ce0b6a0 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -106,10 +106,16 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + uint64(args.NumOfShards+1) configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes - for idx := 0; idx < len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch); idx++ { + numMaxNumNodesEnableEpochs := len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) + for idx := 0; idx < numMaxNumNodesEnableEpochs-1; idx++ { configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[idx].MaxNumNodes = uint32(maxNumNodes) } + configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].EpochEnable = configs.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch + prevEntry := configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-2] + configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].NodesToShufflePerShard = prevEntry.NodesToShufflePerShard + configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].MaxNumNodes = prevEntry.MaxNumNodes - (args.NumOfShards+1)*prevEntry.NodesToShufflePerShard + // set compatible trie configs configs.GeneralConfig.StateTriesConfig.SnapshotsEnabled = false From 3156c0ac939fa134376279e5c30d28ca922596c0 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 2 Feb 2024 14:13:00 +0200 Subject: [PATCH 684/958] FIX: Leaving node in previous config --- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 1b0b87ef342..0bfca899282 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -824,12 +824,14 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( validatorInfo *state.ShardValidatorInfo, ) { shardId := validatorInfo.ShardId - if !ihnc.flagStakingV4Started.IsSet() { + previousList := validatorInfo.PreviousList + if !ihnc.flagStakingV4Started.IsSet() || len(previousList) == 0 { + log.Debug("leaving node before staking v4 or with not previous list set node found in", + "list", "eligible", "shardId", shardId, "previous list", previousList) eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) return } - previousList := validatorInfo.PreviousList if previousList == string(common.EligibleList) { log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) currentValidator.index = validatorInfo.PreviousIndex From 1c1dd6d2a3e3f5df03444fb19819a37a2c9db8f9 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 17:21:42 +0200 Subject: [PATCH 685/958] fix unit test --- node/chainSimulator/chainSimulator_test.go | 74 +++++++++++----------- node/chainSimulator/interface.go | 1 + 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 17eebfc81d7..27364160268 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -235,25 +235,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ChainID: []byte(configs.ChainID), Version: 1, } - - err = chainSimulator.nodes[1].GetFacadeHandler().ValidateTransaction(tx) - require.Nil(t, err) - - _, err = chainSimulator.nodes[1].GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) - require.Nil(t, err) - - time.Sleep(100 * time.Millisecond) - - // Step 4 --- generate 5 blocks so that the transaction from step 2 can be executed - err = chainSimulator.GenerateBlocks(5) - require.Nil(t, err) - - txHash, err := computeTxHash(chainSimulator, tx) - require.Nil(t, err) - txFromMeta, err := chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) - require.Nil(t, err) - require.NotNil(t, txFromMeta) - require.Equal(t, 2, len(txFromMeta.SmartContractResults)) + sendTxAndGenerateBlockTilTxIsExecuted(t, chainSimulator, tx) shardIDValidatorOwner := chainSimulator.nodes[0].GetShardCoordinator().ComputeId(newValidatorOwnerBytes) accountValidatorOwner, _, err := chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) @@ -281,24 +263,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ChainID: []byte(configs.ChainID), Version: 1, } - err = chainSimulator.nodes[shardID].GetFacadeHandler().ValidateTransaction(tx) - require.Nil(t, err) - - _, err = chainSimulator.nodes[shardID].GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) - require.Nil(t, err) - - time.Sleep(100 * time.Millisecond) - - // Step 6 --- generate 5 blocks so that the transaction from step 5 can be executed - err = chainSimulator.GenerateBlocks(5) - require.Nil(t, err) - - txHash, err = computeTxHash(chainSimulator, tx) - require.Nil(t, err) - txFromMeta, err = chainSimulator.nodes[core.MetachainShardId].GetFacadeHandler().GetTransaction(txHash, true) - require.Nil(t, err) - require.NotNil(t, txFromMeta) - require.Equal(t, 2, len(txFromMeta.SmartContractResults)) + sendTxAndGenerateBlockTilTxIsExecuted(t, chainSimulator, tx) // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards err = chainSimulator.GenerateBlocks(50) @@ -404,3 +369,38 @@ func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) ( txHasBytes := chainSimulator.GetNodeHandler(1).GetCoreComponents().Hasher().Compute(string(txBytes)) return hex.EncodeToString(txHasBytes), nil } + +func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSimulator, tx *transaction.Transaction) { + + shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) + err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) + require.Nil(t, err) + + txHash, err := computeTxHash(chainSimulator, tx) + require.Nil(t, err) + log.Warn("send transaction", "txHash", txHash) + + _, err = chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) + require.Nil(t, err) + + time.Sleep(100 * time.Millisecond) + + destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.RcvAddr) + for { + err = chainSimulator.GenerateBlocks(2) + require.Nil(t, err) + + txFromMeta, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) + if errGet != nil { + continue + } + + if txFromMeta.Status != transaction.TxStatusPending { + break + } + } + + log.Warn("transaction was executed", "txHash", txHash) + + return +} diff --git a/node/chainSimulator/interface.go b/node/chainSimulator/interface.go index b1540611302..0b2f51ca457 100644 --- a/node/chainSimulator/interface.go +++ b/node/chainSimulator/interface.go @@ -11,6 +11,7 @@ type ChainHandler interface { // ChainSimulator defines what a chain simulator should be able to do type ChainSimulator interface { + GenerateBlocks(numOfBlocks int) error GetNodeHandler(shardID uint32) process.NodeHandler IsInterfaceNil() bool } From 4c326af24670689ff1080f2cf2e910b2d9c6c69a Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 17:27:53 +0200 Subject: [PATCH 686/958] fix linter --- node/chainSimulator/chainSimulator_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 27364160268..5cbd84a01ce 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -401,6 +401,4 @@ func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSim } log.Warn("transaction was executed", "txHash", txHash) - - return } From f00ffb24ca63f878e38d259c383493cda2aa3810 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 17:41:22 +0200 Subject: [PATCH 687/958] fix function --- node/chainSimulator/chainSimulator_test.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 5cbd84a01ce..48a0c4ad07c 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -20,7 +20,8 @@ import ( ) const ( - defaultPathToInitialConfig = "../../cmd/node/config/" + defaultPathToInitialConfig = "../../cmd/node/config/" + maxNumOfBlockToGenerateWhenExecutingTx = 10 ) func TestNewChainSimulator(t *testing.T) { @@ -371,7 +372,6 @@ func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) ( } func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSimulator, tx *transaction.Transaction) { - shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) require.Nil(t, err) @@ -386,18 +386,25 @@ func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSim time.Sleep(100 * time.Millisecond) destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.RcvAddr) + count := 0 for { - err = chainSimulator.GenerateBlocks(2) + err = chainSimulator.GenerateBlocks(1) require.Nil(t, err) txFromMeta, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) - if errGet != nil { + if errGet != nil && count < maxNumOfBlockToGenerateWhenExecutingTx { + count++ continue } - if txFromMeta.Status != transaction.TxStatusPending { + if txFromMeta != nil && txFromMeta.Status != transaction.TxStatusPending { break } + + count++ + if count >= maxNumOfBlockToGenerateWhenExecutingTx { + t.Error("something went wrong transaction is still in pending") + } } log.Warn("transaction was executed", "txHash", txHash) From 411ee31858f863a8873f7776c1b82b0d52de7195 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 2 Feb 2024 17:49:13 +0200 Subject: [PATCH 688/958] stop test execution --- node/chainSimulator/chainSimulator_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 48a0c4ad07c..5f1c26b6d20 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -404,6 +404,7 @@ func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSim count++ if count >= maxNumOfBlockToGenerateWhenExecutingTx { t.Error("something went wrong transaction is still in pending") + t.FailNow() } } From 19abaf2e5b2a476ad088cf0dba56d99227df2309 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 5 Feb 2024 10:47:00 +0200 Subject: [PATCH 689/958] fixes after review --- node/chainSimulator/chainSimulator_test.go | 27 +++++++++------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 5f1c26b6d20..4a4aadaa48b 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -21,7 +21,7 @@ import ( const ( defaultPathToInitialConfig = "../../cmd/node/config/" - maxNumOfBlockToGenerateWhenExecutingTx = 10 + maxNumOfBlockToGenerateWhenExecutingTx = 7 ) func TestNewChainSimulator(t *testing.T) { @@ -371,33 +371,28 @@ func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) ( return hex.EncodeToString(txHasBytes), nil } -func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSimulator, tx *transaction.Transaction) { - shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) - err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) +func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSimulator, txToSend *transaction.Transaction) { + shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.SndAddr) + err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(txToSend) require.Nil(t, err) - txHash, err := computeTxHash(chainSimulator, tx) + txHash, err := computeTxHash(chainSimulator, txToSend) require.Nil(t, err) - log.Warn("send transaction", "txHash", txHash) + log.Info("############## send transaction ##############", "txHash", txHash) - _, err = chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) + _, err = chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{txToSend}) require.Nil(t, err) time.Sleep(100 * time.Millisecond) - destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.RcvAddr) + destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) count := 0 for { err = chainSimulator.GenerateBlocks(1) require.Nil(t, err) - txFromMeta, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) - if errGet != nil && count < maxNumOfBlockToGenerateWhenExecutingTx { - count++ - continue - } - - if txFromMeta != nil && txFromMeta.Status != transaction.TxStatusPending { + tx, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) + if errGet == nil && tx.Status != transaction.TxStatusPending { break } @@ -408,5 +403,5 @@ func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSim } } - log.Warn("transaction was executed", "txHash", txHash) + log.Warn("############## transaction was executed ##############", "txHash", txHash) } From 1a0751e167e61582ff354f5116c7f88611f160e5 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 5 Feb 2024 11:20:55 +0200 Subject: [PATCH 690/958] small fix --- node/chainSimulator/chainSimulator_test.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 4a4aadaa48b..8eb7a48c21e 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -386,22 +386,17 @@ func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSim time.Sleep(100 * time.Millisecond) destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) - count := 0 - for { + for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { err = chainSimulator.GenerateBlocks(1) require.Nil(t, err) tx, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) if errGet == nil && tx.Status != transaction.TxStatusPending { - break - } - - count++ - if count >= maxNumOfBlockToGenerateWhenExecutingTx { - t.Error("something went wrong transaction is still in pending") - t.FailNow() + log.Info("############## transaction was executed ##############", "txHash", txHash) + return } } - log.Warn("############## transaction was executed ##############", "txHash", txHash) + t.Error("something went wrong transaction is still in pending") + t.FailNow() } From d91b11c44b50c13a413c902625944e145ca3f742 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 5 Feb 2024 12:08:05 +0200 Subject: [PATCH 691/958] - minor config adjustment --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 44fa754146d..02befa60608 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -309,7 +309,7 @@ # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ - { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, + { EpochEnable = 0, MaxNumNodes = 48, NodesToShufflePerShard = 4 }, { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 }, # Staking v4 configuration, where: # - Enable epoch = StakingV4Step3EnableEpoch From ad55f84f8abac5a1bee7e17228d976312a543f88 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 12:16:16 +0200 Subject: [PATCH 692/958] FEAT: System test config like scenario for sanity checks --- config/configChecker_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/config/configChecker_test.go b/config/configChecker_test.go index caa5461b144..0d9a8a9fb8c 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -276,6 +276,32 @@ func TestSanityCheckNodesConfig(t *testing.T) { } err = SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) + + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 48, + NodesToShufflePerShard: 4, + }, + { + EpochEnable: 1, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 6, + MaxNumNodes: 48, + NodesToShufflePerShard: 2, + }, + } + nodesSetup = &nodesSetupMock.NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 10, + MinNumberOfShardNodesField: 10, + } + err = SanityCheckNodesConfig(nodesSetup, cfg) + require.Nil(t, err) }) t.Run("zero nodes to shuffle per shard, should not return error", func(t *testing.T) { From b219639c3cdd2f60f9cd08d1aa31525137e57b29 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 12:34:50 +0200 Subject: [PATCH 693/958] FEAT: Extra unit test --- config/configChecker_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/config/configChecker_test.go b/config/configChecker_test.go index 0d9a8a9fb8c..ec993631fbb 100644 --- a/config/configChecker_test.go +++ b/config/configChecker_test.go @@ -302,6 +302,32 @@ func TestSanityCheckNodesConfig(t *testing.T) { } err = SanityCheckNodesConfig(nodesSetup, cfg) require.Nil(t, err) + + cfg.MaxNodesChangeEnableEpoch = []MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 2169, + NodesToShufflePerShard: 143, + }, + { + EpochEnable: 1, + MaxNumNodes: 3200, + NodesToShufflePerShard: 80, + }, + { + EpochEnable: 6, + MaxNumNodes: 2880, + NodesToShufflePerShard: 80, + }, + } + nodesSetup = &nodesSetupMock.NodesSetupMock{ + NumberOfShardsField: numShards, + HysteresisField: 0.2, + MinNumberOfMetaNodesField: 400, + MinNumberOfShardNodesField: 400, + } + err = SanityCheckNodesConfig(nodesSetup, cfg) + require.Nil(t, err) }) t.Run("zero nodes to shuffle per shard, should not return error", func(t *testing.T) { From b2450f5b3345aa9ceab78d2c44bbf936d92aa7d0 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 5 Feb 2024 15:49:23 +0200 Subject: [PATCH 694/958] - refactored configs --- cmd/node/config/enableEpochs.toml | 6 +- cmd/node/config/genesis.json | 477 ++++++++++++++++-- cmd/node/config/nodesSetup.json | 397 ++++++++++++++- .../config/systemSmartContractsConfig.toml | 2 +- cmd/node/config/testKeys/delegators.pem | 50 ++ .../testKeys/group1/allValidatorsKeys.pem | 60 +++ .../testKeys/group2/allValidatorsKeys.pem | 60 +++ .../testKeys/group3/allValidatorsKeys.pem | 64 +++ cmd/node/config/testKeys/unStakedKeys.pem | 24 + cmd/node/config/testKeys/validatorKey.pem | 96 ++++ cmd/node/config/testKeys/walletKeys.pem | 175 +++++++ 11 files changed, 1346 insertions(+), 65 deletions(-) create mode 100644 cmd/node/config/testKeys/delegators.pem create mode 100644 cmd/node/config/testKeys/group1/allValidatorsKeys.pem create mode 100644 cmd/node/config/testKeys/group2/allValidatorsKeys.pem create mode 100644 cmd/node/config/testKeys/group3/allValidatorsKeys.pem create mode 100644 cmd/node/config/testKeys/unStakedKeys.pem create mode 100644 cmd/node/config/testKeys/validatorKey.pem create mode 100644 cmd/node/config/testKeys/walletKeys.pem diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 6a9384c8490..a1ca0008fad 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -258,7 +258,7 @@ AutoBalanceDataTriesEnableEpoch = 1 # MigrateDataTrieEnableEpoch represents the epoch when the data tries migration is enabled - MigrateDataTrieEnableEpoch = 2 + MigrateDataTrieEnableEpoch = 1 # KeepExecOrderOnCreatedSCRsEnableEpoch represents the epoch when the execution order of created SCRs is ensured KeepExecOrderOnCreatedSCRsEnableEpoch = 1 @@ -298,8 +298,8 @@ # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ - { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, - { EpochEnable = 1, MaxNumNodes = 56, NodesToShufflePerShard = 2 } + { EpochEnable = 0, MaxNumNodes = 48, NodesToShufflePerShard = 4 }, # 4 shuffled out keys / shard will not get reached normally + { EpochEnable = 1, MaxNumNodes = 64, NodesToShufflePerShard = 2 } ] [GasSchedule] diff --git a/cmd/node/config/genesis.json b/cmd/node/config/genesis.json index 10cc1e97d95..15b2d785964 100644 --- a/cmd/node/config/genesis.json +++ b/cmd/node/config/genesis.json @@ -1,92 +1,497 @@ [ { - "address": "erd1ulhw20j7jvgfgak5p05kv667k5k9f320sgef5ayxkt9784ql0zssrzyhjp", - "supply": "2222222222222222222222224", - "balance": "2219722222222222222222224", + "info": "delegator1 for legacy delegation", + "address": "erd1z48u9l275l2uy4augfytpp2355wvdnc4gwc9ms9gdhdqru3fz9eq5wqe3e", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd17c4fs6mz2aa2hcvva2jfxdsrdknu4220496jmswer9njznt22eds0rxlr4", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator2 for legacy delegation", + "address": "erd1qm5erxm0va3hcw9jfxtp2gl3u9q9p4k242pk9xx3vezefkgj2vhs0wk8cx", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd10d2gufxesrp8g409tzxljlaefhs0rsgjle3l7nq38de59txxt8csj54cd3", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator3 for legacy delegation", + "address": "erd1rqwt9vpfn072tahtcvup2dxz4nvqfs3n5p9eh0jnypkppxmdheaqpcqfzz", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd1e0vueugj66l5cgrz83se0a74c3hst7u4w55t3usfa3at8yhfq94qtajf2c", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator4 for legacy delegation", + "address": "erd17uygg7qq05mjhectgymj6fwq59ysr4p92cy0yz3jrxxj6253p40sj77wr6", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd1fn9faxsh6felld6c2vd82par6nzshkj609550qu3dngh8faxjz5syukjcq", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator5 for legacy delegation", + "address": "erd1qslr87nj5gkv2396js3fa2za5kqgwugqnz4j4qqh22mxpnse2lws8srsq6", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd12ymx62jlp0dez40slu22dxmese5fl0rwrtqzlnff844rtltnlpdse9ecsm", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator6 for legacy delegation", + "address": "erd17pjlqg55c6v3fjvpqec8peefk74g8neygr84ymw7cqzudmzaw7lqnln7sz", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd1qsrfugd567kv68sysp455cshqr30257c8jnuq2q7zct943w82feszr8n32", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator7 for legacy delegation", + "address": "erd19ztfuew6ejrwq5mpax4xztjwh5j63u9vge4dum9vlyy7hg3pc86qgmt6nm", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd153a3wkfng4cupvkd86k07nl0acq548s72xr3yvpjut6u6fnpzads9zyq37", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator8 for legacy delegation", + "address": "erd1age5t5qfrke4vm47vaq9a4yewllh6227qm4fcy3rc7g5ktmzyatsgf4wcw", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" } }, { - "address": "erd1yajssshtsc75x87cxvylnwu4r9dv3c2tegufrd07fjmw72krlq9spmw32d", - "supply": "2222222222222222222222222", - "balance": "2219722222222222222222222", + "info": "delegator9 for legacy delegation", + "address": "erd1jt0vv29trqs3nddzkxsf950xx0t5uvyncmuamwryneh9wsee5wpsgue96d", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", "stakingvalue": "0", "delegation": { "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", - "value": "2500000000000000000000" + "value": "1000000000000000000000" + } + }, + { + "info": "delegator10 for legacy delegation", + "address": "erd1c83rmk3n8ys4g9dkg3q70thx3v787qtpfmk23epu4xsadpyd3dnsejf2r7", + "supply": "1001000000000000000000", + "balance": "1000000000000000000", + "stakingvalue": "0", + "delegation": { + "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", + "value": "1000000000000000000000" + } + }, + { + "info": "wallet1 2500*8 staked + 10000 initial balance", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "supply": "30000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "20000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet2 2500*6 staked + 10000 initial balance", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "supply": "25000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "15000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet3 2500*4 staked + 10000 initial balance", + "address": "erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35", + "supply": "20000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "10000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet4 2500*4 staked + 10000 initial balance", + "address": "erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84", + "supply": "20000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "10000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet5 2500*3 staked + 10000 initial balance", + "address": "erd1dzjes5c6a8ru45clgla3q0k3ezm06svefjz7vzs8pjfnrqa8tcasl4j8hs", + "supply": "17500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "7500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet6 2500*3 staked + 10000 initial balance", + "address": "erd14gg3v6j4505ucx7t2wtl98tgupmyp748aq92jefmp5ha6e3pccgq9clwe9", + "supply": "17500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "7500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet7 2500*2 staked + 10000 initial balance", + "address": "erd1xdfc44mk4ut5cv6l3mq0py6h88cty9ykacskm8xv3tvrp893kmxqppcefg", + "supply": "15000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "5000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet8 2500*2 staked + 10000 initial balance", + "address": "erd1997jfwzrum4rrk59ar5supcyge9rpa73xgv2p45h3unt880v399svt8c9g", + "supply": "15000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "5000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet9 2500 staked + 10000 initial balance", + "address": "erd1e9cg9ys8fh77n9eaxpg47sxaes4fe9g2nvy6a65qpxykcx8grg9sv45lss", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet10 2500 staked + 10000 initial balance", + "address": "erd1xdrltsygywhmtxzsmrgjlsxsxrf4y2ayv0z50y666dgsp66trxwqzajk96", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet11 2500 staked + 10000 initial balance", + "address": "erd1lytewufjflpwl6gtf0faazjr59nd2fhfwlk7ew72hkpgdkmunl8qfrpywg", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet12 2500 staked + 10000 initial balance", + "address": "erd1s8tqztm4u4gw23489lps97qxe8vck8eln3a424y9c6yujsc96nas0l968d", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet13 2500 staked + 10000 initial balance", + "address": "erd1p7p0f3n8dxtj08hsp9hccqg932pd4f94rq3adg6g55etx8g4z8tsmg5e0g", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet14 2500 staked + 10000 initial balance", + "address": "erd1uyeel03ea837dphrx2ak77hdvlhjdcqdwgyg6k99gqn602ymsn7qptmedj", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet15 2500 staked + 10000 initial balance", + "address": "erd1ftyzkdhl7rl782mrzrdc2jck3egydp0ydzhcjm9gc8s2jym5egrqadl4h6", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet16 2500*3 staked + 10000 initial balance", + "address": "erd1rsl2sj5g87ltfq0hvrmgm35mlg4lzfs29p4gzxh0lh4vj2e8ykuqh69lha", + "supply": "17500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "7500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet17 2500*2 staked + 10000 initial balance", + "address": "erd19yrjty2l4ytl6d3jynp5mqfekq4uf2x93akz60w7l3cp6qzny3psnfyerw", + "supply": "15000000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "5000000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet18 2500 staked + 10000 initial balance", + "address": "erd148lq42zdzz34y0yr8avldsy7gw0rmuvj4lmstzug77v08z3q0ncszfk8w9", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet19 2500 staked + 10000 initial balance", + "address": "erd1k2v4h3805gnxf78c22g7lfe4pgq2lmr4ezmkk2rqkej6yjd7g5ssu88fme", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet20 2500 staked + 10000 initial balance", + "address": "erd1nzjyj2ykpway04pczl42fgrlza2f0eaf97fxgnuuw39vyee36xlqccc3qz", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet21 2500 staked + 10000 initial balance", + "address": "erd1yp0nvml5c45us3qzreqxkjxaakxn744t3gdva9s8xndcakzawutstepmm5", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet22 2500 staked + 10000 initial balance", + "address": "erd1qyg80tr4rd65ur3hedm9h4yv3fcwmm6vnyrypnm972nd80889hxqdfgwrc", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet23 2500 staked + 10000 initial balance", + "address": "erd14x6d48q59zjh5p909fyw7e46czftgdawyf734cnmgk5e63ghrvvsqp254t", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet24 2500 staked + 10000 initial balance", + "address": "erd1wyxylus33e476h5kta7e0caeqvgvcgrxh0az33e7szya6g7mh2ws0n27sa", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet25 2500 staked + 10000 initial balance", + "address": "erd1v3ylw7t6vzjzs06xjf6ccmf576ud38g2ws45tjkjg48s38jefpzqlwms9w", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet26 2500 staked + 10000 initial balance", + "address": "erd1twel4azu6uptw878y063p93mjr84y5m4kpsww2aeqj4pg5jeplgst04rhg", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet27 2500 staked + 10000 initial balance", + "address": "erd1q2se75ucl9as9j7e48v00jrnj6hvtk5vqxa4a3ag5729vctsdkasm20cyc", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet28 2500 staked + 10000 initial balance", + "address": "erd18cc6cm35xhv7kzwsm79l4ma6jpz3ee5l0yjxuc66kh6rcgtawtuq6lzp9f", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet29 2500 staked + 10000 initial balance", + "address": "erd1psux99h4jljyt3nkw8pruv3spw5r0unqe4wk8837mm9my88gl28qj6mml5", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet30 2500 staked + 10000 initial balance", + "address": "erd1vgm89ngmv2ghzsyq8xjtt45crekkxnhsq30yxzlq86uc3ra3r57qa3mw2p", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet31 2500 staked + 10000 initial balance", + "address": "erd1k767vmmn8vg8xvuny32ppwr4dxrlgmpykn0u7nm92evlag3wkukqdgsf5u", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet32 2500 staked + 10000 initial balance", + "address": "erd1hwe8lskmzsdpuy3f6hldamvn0zrhzldec8m4tt8hupq58d7gyrequy8wsp", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet33 2500 staked + 10000 initial balance", + "address": "erd125eyrjk99zadr04gm9z2p4nckmnegexs5nyk7ek85rut2665t75sql3w88", + "supply": "12500000000000000000000", + "balance": "10000000000000000000000", + "stakingvalue": "2500000000000000000000", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet34 no staking, initial funds - 10 million EGLD", + "address": "erd17ndrqg38lqf2zjgeqvle90rsn9ejrd9upx8evkyvh8e0m5xlph5scv9l6n", + "supply": "10000000000000000000000000", + "balance": "10000000000000000000000000", + "stakingvalue": "0", + "delegation": { + "address": "", + "value": "0" + } + }, + { + "info": "wallet35 no staking, initial funds - 9509990 EGLD", + "address": "erd1zed89c8226rs7f59zh2xea39qk9ym9tsmt4s0sg2uw7u9nvtzt3q8fdj2e", + "supply": "9509990000000000000000000", + "balance": "9509990000000000000000000", + "stakingvalue": "0", + "delegation": { + "address": "", + "value": "0" } } ] \ No newline at end of file diff --git a/cmd/node/config/nodesSetup.json b/cmd/node/config/nodesSetup.json index 239fd9a52f6..beabb167872 100644 --- a/cmd/node/config/nodesSetup.json +++ b/cmd/node/config/nodesSetup.json @@ -1,48 +1,395 @@ { "startTime": 0, - "roundDuration": 4000, - "consensusGroupSize": 3, - "minNodesPerShard": 3, - "metaChainConsensusGroupSize": 3, - "metaChainMinNodes": 3, - "hysteresis": 0, + "roundDuration": 6000, + "consensusGroupSize": 7, + "minNodesPerShard": 10, + "metaChainConsensusGroupSize": 10, + "metaChainMinNodes": 10, + "hysteresis": 0.2, "adaptivity": false, "initialNodes": [ { - "pubkey": "cbc8c9a6a8d9c874e89eb9366139368ae728bd3eda43f173756537877ba6bca87e01a97b815c9f691df73faa16f66b15603056540aa7252d73fecf05d24cd36b44332a88386788fbdb59d04502e8ecb0132d8ebd3d875be4c83e8b87c55eb901", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - legacy delegation", + "pubkey": "309198fd7b6bccb1b6279ea2e5c5f2a33b9f6fe5f23180778d8721710344989b07d10dd1bd19307b3cd06eab9d1358062511610ccdad681ae1165016256cc1fdc0fed5041a5c29d7773b2994022bf2dc9efb937b3bb7cc9d72670448fad7d091", + "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", + "initialRating": 5000001 }, { - "pubkey": "ef9522d654bc08ebf2725468f41a693aa7f3cf1cb93922cff1c8c81fba78274016010916f4a7e5b0855c430a724a2d0b3acd1fe8e61e37273a17d58faa8c0d3ef6b883a33ec648950469a1e9757b978d9ae662a019068a401cff56eea059fd08", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - legacy delegation", + "pubkey": "cd8cc9d70a8f78df0922470f1ebee727f57a70fb0571c0b512475c8c7d3ce1d9b70dd28e6582c038b18d05f8fbd6ac0a167a38614c40353b32ef47896d13c45bde57e86d87dd6e6f73420db93aeb79a1fd8f4e297f70478685a38ed73e49598f", + "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", + "initialRating": 5000001 }, { - "pubkey": "e91ab494cedd4da346f47aaa1a3e792bea24fb9f6cc40d3546bc4ca36749b8bfb0164e40dbad2195a76ee0fd7fb7da075ecbf1b35a2ac20638d53ea5520644f8c16952225c48304bb202867e2d71d396bff5a5971f345bcfe32c7b6b0ca34c84", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - legacy delegation", + "pubkey": "e441b8a7d35545f7a02f0d57d144c89810d67ecb9abb5804d1bcfd8b270dc30978c56fbf9618e9a6621ca4e6c545c90807f7fe5edfd34ccab83db7bc0bd68536bb65403503d213c9763ec2137d80081579bb1b327f22c677bdb19891f4aae980", + "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", + "initialRating": 5000001 }, { - "pubkey": "8f8bf2e6ad1566cd06ba968b319d264b8ce4f8700032a88556c2ecc3992017654d69d9661ad67b12c8e49289a2925a0c3ab3c161a22c16e772a4fe8a84b273b7ac7c00d9da8fa90a9bb710961faa6e0e2e092f383f2fc365f1cda35d803f0901", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - legacy delegation", + "pubkey": "72d8341713a271d510c7dfd02455ef86e9af4c66e06ac28fbb4c4e8df1e944e685bae2bee2af4101c19922b64e44e40b5d4905755594a719c1d50dc210515495d0de9b3a1d4ed42fd45a973353fe2c2548c45bb2157d8bf68e0937cc20fe1011", + "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd", + "initialRating": 5000001 }, { - "pubkey": "aa930dc117738baead60088e9fd53ebc3157ad219f6a11ad4ee662eedb406baad013160ec1083fa68bf25b4ce7503e00e0e6dfbb4e405107a350d88feda2d01ae5b7b27a068d6accc980e498b36fc9ab1df4f3bcffec9f1611e20dea05b55a92", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "796d2f56ee9fa8f4ff9fc7735bbb4d644be8dd044f7f965362aed3d562e00b11f730b2fe21eb9c9fd100b68a5d3dbf07bae63d25739f1304ab638330f0e8c207a76de648e2523ad1693f4ffe9def8a1d5aca2c6c1c14e1fcc20089db069d1a0e", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 }, { - "pubkey": "70cf21360c0d276bb49af3a76e1bc193f05f688c0f8029a895742dbc4713fe2c36b8a90dd9455b308c3fbf5e3a3ea115ec1a6c353af028d104402a0f1813d6178740b62911470d75eab62ae630d7f1181c68fc1e966967749dc98eab35c03f0c", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "4cc0bfcdf4515927e3ae7890197bfd7c2e3c6f80ff7570fc6313d095e0d4e518ecc81db7087fefb8af166723a32ded1324f4ee00a6a97d206a024fd95ab60f7fe18c896c829ac43782c56d922415fb4ddbc0384936e3f860feb0666da43bcd19", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 }, { - "pubkey": "ea4a05326f44746beff6302f4a0452ad789113186ede483a577294d3bdf638a0742a57d453edbc61db32e04e101b7c021a1480a8d4989856a83b375d66fe61df64effc0cb68a18bebbc99b7e12ebc3084c17599b83bba33c435b8953974d2484", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "3449c9d672472ea52e83be4a8d6ce55785044233d848ac0a9a4b7fc22bf5b1bf5776f95f4b459f4e4cd3ba1d20b46a197c5a55ec00fa8d795d35f2232a6fae360129d186e3a0c219d42d8357de2823c8566da7841c2739b30d1581c4a38ec80e", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 }, { - "pubkey": "86b5dcfb9372b0865f0531782827bed66cb7313ab0924c052d3701c59d3c686748e757bb9e20ad1924d3531dc1eb1206f89d00791e79ea994e0a8b5d4ef92335f0d83f09cc358b718b103dd44d772e2286123ceffb6bd8236b8be7e4eb3e1308", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "1bdef34453a83d19748b02d964c43409a66535678b6234c42d289ed2b7571bf60d35ba7a43cd951d4fc9fc2e8ff618038a2edc9cb0181dcac0b62a0859aafd8d9993aa3069c14fec11cb66a653311a37861d225847bf535bcb920b4f0ea98b8b", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 }, { - "pubkey": "227a5a5ec0c58171b7f4ee9ecc304ea7b176fb626741a25c967add76d6cd361d6995929f9b60a96237381091cefb1b061225e5bb930b40494a5ac9d7524fd67dfe478e5ccd80f17b093cff5722025761fb0217c39dbd5ae45e01eb5a3113be93", - "address": "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "3bd60bd8c5ace7d1999cd4bfd93dcb7bdc397d8d84efa5fd89439b7b727b0331bd00e3feae85df79e7d2b5eba1ea07003972fde3a7eb8d4ba25583a848be812e89b75fe8f3531d810ba2aaef629748ace6ac5ae73d8a2e6a65bb379f5be3b906", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 + }, + { + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "2b9a1e5e291471f9eb0cf1a52db991f2dbb85446d132f47381b7912b041be00cccab748c25bdd6165cd6a517b6e99b0133bda4dc091dcdf6d17bc460ac0e8c6fe4b2460a980dd8dea8c857647bc5826a2b77fc8ba92c02deb2ba3daafb4d5407", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 + }, + { + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "e464c43c4f3442ec520d4a6464d7fa96397ab711adf38b5a96f208303337f6a97ffdbd22e34a10deef6aa21ff078360d2bf7fae627a1ec55a9f120b35224b8e461b0f4de7d3ce800e6b910f37c4d03cce7039ce3a4a3a79ac0511c36435ccf85", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 + }, + { + "info": "multikey - group1 - wallet1 with 8 BLS keys", + "pubkey": "dab5c34e66e096d1f328fd9b045136724c8ccbf7b5a4bcf1e8c9edc9510712c0a7feff7818563aa799b37f1cdcfb330cc49d8482c7154988d33f63fe2526b27945326112c832fdf72a1b35f10da34c6e08b4079d9c56195c1ab64c84eab93b95", + "address": "erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7", + "initialRating": 5000001 + }, + { + "info": "multikey - group1 - wallet2 with 6 BLS keys", + "pubkey": "a5624bec34e06d5026a334654be9e0118c8a02720a6bd868a51d5eb687819442cded09d1fef2e9d9db8bb2d5be01f1148b4819aee9e6a48b9c530285dbc4d800f4dd10d7f9a75d4b36de8fb52aec672cec91e0256f7e9848b10219748d9e708b", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet2 with 6 BLS keys", + "pubkey": "eedbc5a3141b92148205d178d150905e68ca745ba54617025f84b33c91233afda2c2109084821e14f9a50d3f220fbc000ce6ad432f2a1865da9c6547016ecc7e07242ef490c0bdda29ec677f3e833f54eb2cf27e95b10b8edbdfa7de4e1bc000", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet2 with 6 BLS keys", + "pubkey": "48c77bbf5d619fb13d76883736c664493b323c00f89131c9d70b3e4ac875103bd8248e790e47a82c9fdcd46fe33b52093a4b3b248ce20e6f958acd22dfb17335fcaf752bab5e29934f0a7e0af54fb2f51a9e6b1be30abdd701f7c9fbd0ad5d8e", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet2 with 6 BLS keys", + "pubkey": "dd59e326a160d3b49ca25f2ab93b4f7ba766b124de66b68507b9e7a9cf69df7c4fca695592eb31e7e63061daef52d30cc1d362fc612d22631398cad4af46969e35407b293808133fc130b8f930ba41c6b88bc9ed9b884892113593d3ffc55297", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet2 with 6 BLS keys", + "pubkey": "6b1a8bf3e5e7bacaaf99e3c89891a8a4ec7e9022986043f8206db9171ede3bd8cdcbbd7e8e1234180de5d651110ef706a8d964cb35048bc961611b55c8d9bd1b942b93c7e1b88157e7f79f2c08dbabe1af4612afe6044ab1be316976111b7019", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet2 with 6 BLS keys", + "pubkey": "d8f8ef204ac892dd1a04648fc449ffdd11418dbd5c8fe623e5efda0bcae47cb41eb99c981585d80be1d668d8b7466619b6ead4d83976cc4f6879627a455603a74ab2adbfb5fed0f1a2b954363d97cbd3ac7feb284c83ac64422fad518e589c8e", + "address": "erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet3 with 4 BLS keys", + "pubkey": "f547e115b1ada7cf9b8aeef45ee0d9ec4b206315ef44be706d994a0571688cd96291d1ab6c3761df29d00a2ba290a3185e4796bc49891906f86e16da01af3fd52320944b96b60e679ac8e686d4819e97e15e5fe46503c556b4acdd8079624005", + "address": "erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet3 with 4 BLS keys", + "pubkey": "0e5cc5f218a8fa9bae1f6b452430c0de205e6b251d0f1d606d1ce28203fb556768e6c4545ce8e90d640ef2cc1062f40ccf2ede124b926cbf3b2b0050b0e19f67e7e36ac1a7049178a77cbd65ee30cd0a40d9f98846ce439cc120717501f03180", + "address": "erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet3 with 4 BLS keys", + "pubkey": "760dc22525dce5be65a3a55ee07f7f012e0a89f435daec56eb475b0b5ca2d84b157894b8df64dfb570ecc633d5e1611639d43976e29f11c232236a9548b0145ee4e43fe495252c8c1f006b8df51d3835dee64a826f43167096b347b6919aa292", + "address": "erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet3 with 4 BLS keys", + "pubkey": "39316473217f7c435a543efa078254198dd079e3c6505e7cc1564b033de8a161dc2e9c392b1e584440510113b5942816102d7be5f4af9461af21a454fc1938a962b256c1c1d1f939198029ed0bf22c62893038d5687787cb46436c0ef4f12417", + "address": "erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet4 with 4 BLS keys", + "pubkey": "6a3b9f6b5fd38e79433daa9bf03543314f8a2a3d9f1fec8ebe2bc1ee97f135d83845dcecd201207c1b31d7624ddb330ae67fbfab4137cd734d96bc0975ae8bcfeecc4441b384d39d6900cdb7436450c23b4cc7674ec50055ea4a90861c503a91", + "address": "erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet4 with 4 BLS keys", + "pubkey": "ee8c987b9af9bba2912763fb7fcd6d6575db60806c5041fa91816ecc339ccfd60bf3cf49fb7017158f0b8e6050276907620bc040816207f14a952bb86752816231ae7f31ff701862cfe0abca367fc4cd63bafd4ad6e4df67612e4ec71462650c", + "address": "erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet4 with 4 BLS keys", + "pubkey": "cfe96f6b010d08f211c83f4ae3eb451d1d5205a50bdcd451706044dc21f523d25f214ab89dd5aab7ae03111197d6e6156e70ab348c9b0fab0a7839ea57fef6cd2324882b4387014dba201e6f87d5ca395e14d900e4563494f4f11a69ef6cdf14", + "address": "erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84", + "initialRating": 5000001 + }, + { + "info": "multikey - group2 - wallet4 with 4 BLS keys", + "pubkey": "05e9e43732ecff55e553b35b5ee1416065818db162a6fbf096186a1230d88bd057cebb72c5afaec16a803c4c4f69770752fe29be73a4069d0d01666ede963271192d4f324f2b3dcaec8b2c871c23cf185579a039dd5ab093c7cd9bca53e09c85", + "address": "erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet5 with 3 BLS keys", + "pubkey": "82cfc47999d1499cb880d46e8280b8c4fe576dff20a8ca6f6ac551887c637f935153f9ce2f21921a532477535d42ac05f730760c78415756add2eab6d57d94916f3ad51590b23404739d152f89b6d052df48cace1793897cd4eba722247a6195", + "address": "erd1dzjes5c6a8ru45clgla3q0k3ezm06svefjz7vzs8pjfnrqa8tcasl4j8hs", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet5 with 3 BLS keys", + "pubkey": "7675098e73574db9c59bdce61e4b80251c6536201715dca40b2b69c09ce097690f3a9095d22b006531e3b13b30894803bd7ede3e6d80c9064c431f8671db085ab1052354cb26a7a2436340b273b6c95c84ab94bb9531b99c5f883602b5284017", + "address": "erd1dzjes5c6a8ru45clgla3q0k3ezm06svefjz7vzs8pjfnrqa8tcasl4j8hs", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet5 with 3 BLS keys", + "pubkey": "c50f398a853c670ed625a12eddae175df5a90e034a54484a832566fc91f9b83d5daf1bc821cc347ba7e45f3acd4e1d00d0d7f52235824fd1326a7f370b58fc7dd98edfff4a41739a2015c6ed3a3c0bf3c986efeee187be70f1133fc4379dad95", + "address": "erd1dzjes5c6a8ru45clgla3q0k3ezm06svefjz7vzs8pjfnrqa8tcasl4j8hs", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet6 with 3 BLS keys", + "pubkey": "4bd3f30f608b22b32100c6360def228ec95aa24e3048010bb64606392f602e180a0b2a12f7f92ef1d7f73ce1271ae30693bec692b15802c7ba079939640570fdc7f4d411c084ed0fe612ee223227ca3d02dc9732cf686ba8885007de53f8ec89", + "address": "erd14gg3v6j4505ucx7t2wtl98tgupmyp748aq92jefmp5ha6e3pccgq9clwe9", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet6 with 3 BLS keys", + "pubkey": "71e8458f92997a00c1cd0e638b9ec42ab136828fc13f0ec643b60af451270cc81d50f4c4578a7c93a700ee21e065281593e7995d2454356cbfdeadb9ffe7bf33ba8f7a31a1d2e76bba5a5f88a613ef37e35595838d0b7f4bd12da7d6fe743499", + "address": "erd14gg3v6j4505ucx7t2wtl98tgupmyp748aq92jefmp5ha6e3pccgq9clwe9", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet6 with 3 BLS keys", + "pubkey": "d9c30948bffad18776b786f6367142b76605ac6e33a8d38c68c31c7afb099f1a83efb752a87afaf9d04a4a8fb656e40bfe2a4aa6e0c16b82d22bd6c232c2ce5e6672ac6232d2da6945bc033b04cbaaeb4b9af4b29585094e034ab8dcfb8b9c19", + "address": "erd14gg3v6j4505ucx7t2wtl98tgupmyp748aq92jefmp5ha6e3pccgq9clwe9", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet7 with 2 BLS keys", + "pubkey": "55fc7ab2e8c0a07bef2e1a9b35764cee1d604cb5634b7226a7310ce56a1f02e99d248fc5b416c4253ac7b88353b1a60f31e1104534e36cb00f46bdcb20a0d24f453e2c8d3cc48dc3c6086edbe16149aae14eb3a4d24ee2b217a4759bc0c0ea88", + "address": "erd1xdfc44mk4ut5cv6l3mq0py6h88cty9ykacskm8xv3tvrp893kmxqppcefg", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet7 with 2 BLS keys", + "pubkey": "a8e662e63ad0e87f2dc66cbed41d398b73a2da2aaced6cc466ed378b62daee28b3db8e8327a06278a094b05840965c17448ffc8a1c96e532a7960d1a15d2cabd16edadc476bfb4af3a825aff801f615d127b70b4745b88e01627a99ba52d5317", + "address": "erd1xdfc44mk4ut5cv6l3mq0py6h88cty9ykacskm8xv3tvrp893kmxqppcefg", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet8 with 2 BLS keys", + "pubkey": "f5e5eb9dd18aeb5d4829ab08795a9e4c8632a4fd248feed68382add1f2474d3cec042d51b897871bfee1f1c1fbeabf13d1c39d4f9b412948d27737f2b82e85474b7049a700ee8735373564791f0d20692dd1f8b494de7bab0a8415f01532ed90", + "address": "erd1997jfwzrum4rrk59ar5supcyge9rpa73xgv2p45h3unt880v399svt8c9g", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet8 with 2 BLS keys", + "pubkey": "e66d7ac5e51a382164aeaae9924dda3272296a145d3c6178b962e3b7eb83e75515e665c327e86f3ef597ca840f8c5c0ace19ac9a8fbcdc573f9237d112fb1c467d646737863ccd1fe61f4c4341f9805f8e1fe98348b50c3c3f93f62de3975980", + "address": "erd1997jfwzrum4rrk59ar5supcyge9rpa73xgv2p45h3unt880v399svt8c9g", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet9", + "pubkey": "2a1c49643e564cdf28bba96dfd6cd8ad38a5958b2b3c9a8293ffb54e9df0a0188a67de2fb947b8ae3dd06b7411aaae0e8bedef795ad3b35ac9f1402dcd0631d9d530b01b3880362fbd3ed9a8488ecabfb1b46cac225c5d48c39be3e28503f90f", + "address": "erd1e9cg9ys8fh77n9eaxpg47sxaes4fe9g2nvy6a65qpxykcx8grg9sv45lss", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet10", + "pubkey": "5c9784523f360a802d4687c9c76bcef41a738d034aa8503a055c33898504b09670c1f637ca632e5290b3acf79a2191072f68c4192a9cbeb34f50c4a941e34247a64f642a6a074bec683bdfb83587cfdc0390ebd74505cb836cf04f3268e32f99", + "address": "erd1xdrltsygywhmtxzsmrgjlsxsxrf4y2ayv0z50y666dgsp66trxwqzajk96", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet11", + "pubkey": "db7f7726c3e68abb28d070f529f2c222755d863aa9d7c0200fde10c93ccb8edcee8d45c9eb925bd5a0fa33c54d19270b7058f6e72256dad84214375f189310a73153cd84feef4b493ab61437b0cbcc2c592e6c093653a533631c8e0ab036c207", + "address": "erd1lytewufjflpwl6gtf0faazjr59nd2fhfwlk7ew72hkpgdkmunl8qfrpywg", + "initialRating": 5000001 + }, + { + "info": "multikey - group3 - wallet12", + "pubkey": "a27b6f47c53263e5c8d69779a169d50605cdd7ddb4b5384f2d46e08ace6f787a60f6cf26256b62fafba9c91a87ff070bc99254fcb5a73239fc14f2108de62189005b51b21e2922b37c6cc657017832e3a59dfcc7a54ac5dcb997136da4e2748b", + "address": "erd1s8tqztm4u4gw23489lps97qxe8vck8eln3a424y9c6yujsc96nas0l968d", + "initialRating": 5000001 + }, + { + "info": "single key 1 - wallet13", + "pubkey": "d3e0427c22ff9cc80ef4156f976644cfa25c54e5a69ed199132053f8cbbfddd4eb15a2f732a3c9b392169c8b1d060e0b5ab0d88b4dd7b4010fa051a17ef81bdbace5e68025965b00bf48e14a9ec8d8e2a8bcc9e62f97ddac3268f6b805f7b80e", + "address": "erd1p7p0f3n8dxtj08hsp9hccqg932pd4f94rq3adg6g55etx8g4z8tsmg5e0g", + "initialRating": 5000001 + }, + { + "info": "single key 2 - wallet14", + "pubkey": "b0b6349b3f693e08c433970d10efb2fe943eac4057a945146bee5fd163687f4e1800d541aa0f11bf9e4cb6552f512e126068e68eb471d18fcc477ddfe0b9b3334f34e30d8b7b2c08f914f4ae54454f75fb28922ba9fd28785bcadc627031fa8a", + "address": "erd1uyeel03ea837dphrx2ak77hdvlhjdcqdwgyg6k99gqn602ymsn7qptmedj", + "initialRating": 5000001 + }, + { + "info": "single key 3 - wallet15", + "pubkey": "67c301358a41bef74df2ae6aa9914e3a5e7a4b528bbd19596cca4b2fd97a62ab2c0a88b02adf1c5973a82c7544cdc40539ae62a9ac05351cfc59c300bbf4492f4266c550987355c39cff8e84ff74e012c7fd372c240eeb916ef87eead82ffd98", + "address": "erd1ftyzkdhl7rl782mrzrdc2jck3egydp0ydzhcjm9gc8s2jym5egrqadl4h6", + "initialRating": 5000001 + }, + { + "info": "single key 4 - wallet16 with 3 BLS keys", + "pubkey": "ab0a22ba2be6560af8520208393381760f9d4f69fca4f152b0a3fe7b124dd7f932fd8c1fbb372792c235baafac36030ceaf6ebf215de4e8d8d239f347f2fed10a75a07cbf9dc56efbbfca2e319152a363df122c300cdeb2faa02a61ebefd8a0e", + "address": "erd1rsl2sj5g87ltfq0hvrmgm35mlg4lzfs29p4gzxh0lh4vj2e8ykuqh69lha", + "initialRating": 5000001 + }, + { + "info": "single key 5 - wallet16 with 3 BLS keys", + "pubkey": "caa87d67e195b52355d2c8f7f74c829395b134bd4a911f158e04b2d7e66a5ba195265743f10cf190105512fb3df9d708a8056c07a6165874d8749742502c0eada7d15b6c55f22c2cce2cf5001288f6b2d89319e6ff888344c01adcd362be8998", + "address": "erd1rsl2sj5g87ltfq0hvrmgm35mlg4lzfs29p4gzxh0lh4vj2e8ykuqh69lha", + "initialRating": 5000001 + }, + { + "info": "single key 6 - wallet16 with 3 BLS keys", + "pubkey": "598be7548d6bb605bd19d83037bf58a7797a4e48b33011a60a5633cf6fe8d59906130777c46f50a50d3d0f958effb5147befd5d67cbec7c5daddeaade4dca5d8a54fe0394fde7b6455e4fc4db91f33f907d450b45fc2d4a9990f96d893093d91", + "address": "erd1rsl2sj5g87ltfq0hvrmgm35mlg4lzfs29p4gzxh0lh4vj2e8ykuqh69lha", + "initialRating": 5000001 + }, + { + "info": "single key 7 - wallet17 with 2 BLS keys", + "pubkey": "69b277b127d025638dbb54d36baa8321540f6210fc5edaac77f94798c039a383aead3ae7c93cdfb8b4caab93a952d101ee2322c129b6ce2726359a65aa326bd35e54c974118503944fcaf80be80b5c3fc9cf86d574d0096140f16fbc55fc4984", + "address": "erd19yrjty2l4ytl6d3jynp5mqfekq4uf2x93akz60w7l3cp6qzny3psnfyerw", + "initialRating": 5000001 + }, + { + "info": "single key 8 - wallet17 with 2 BLS keys", + "pubkey": "a006ad94b28c414c6ec0a5effb84594f39ede4f82b60aa077e2065b89407c78dd6479ebceed7bd42ed2779c34b718f11651427e550948cb8be2e6cea03a128ac3c52e599ada6f34912b119f94de472af0397a68769f1b3f647e87090918e030b", + "address": "erd19yrjty2l4ytl6d3jynp5mqfekq4uf2x93akz60w7l3cp6qzny3psnfyerw", + "initialRating": 5000001 + }, + { + "info": "single key 9 - wallet18", + "pubkey": "91874fdfa8dfb85faf4f404b21c95fbb5d154db5a6abe46bd7860de9e5ddb78b61b5c6ddcf86e5ec8a237e130ed0fc0e418fb97d6fce5f6642ba33f99eff694ec7fb2921b423899a9a5888914bd625636a9b1ea186566561cd35b79aaca20e88", + "address": "erd148lq42zdzz34y0yr8avldsy7gw0rmuvj4lmstzug77v08z3q0ncszfk8w9", + "initialRating": 5000001 + }, + { + "info": "single key 10 - wallet19", + "pubkey": "cc3e0c1021f8c4c092499547b064cffef19d07f0bf250e5265cea1e49b282a7f6efb4b415ad37db2ef6efa253475f511e74efc2f76c087c9798f72187986bb752f61d0ac220045f8e2d945343f3bbb8ef34a6025fb855dd7d953a81477ad2309", + "address": "erd1k2v4h3805gnxf78c22g7lfe4pgq2lmr4ezmkk2rqkej6yjd7g5ssu88fme", + "initialRating": 5000001 + }, + { + "info": "single key 11 - wallet20", + "pubkey": "c2885340a6ba4341d68f80ce419deadf374bc52e2749c278b5bce5f795e9a90a04ef4f07a0b47777feb1982749b57a174b4927338df9da99a417a2df3152a9ebaf3465bfc092058324edf6892313f24be4612eb5663bb59d67a831dda135aa8b", + "address": "erd1nzjyj2ykpway04pczl42fgrlza2f0eaf97fxgnuuw39vyee36xlqccc3qz", + "initialRating": 5000001 + }, + { + "info": "single key 12 - wallet21", + "pubkey": "cf8a2f97b7822acb16016a6debaaedea39959c9ac60b80e50f24734a0e0f6128ed1d216f5aed71866ca34bb30b6e8300e7995237744e766f6016ca28d4ebb2274326cb7af1a3c12d795cc127a4bf9aa9497d89ef0450c40f675afd1afa761012", + "address": "erd1yp0nvml5c45us3qzreqxkjxaakxn744t3gdva9s8xndcakzawutstepmm5", + "initialRating": 5000001 + }, + { + "info": "single key 13 - wallet22", + "pubkey": "95a81b70474d59c1292bc5742db1a7b9bf03cb516ede6fb5cb3489ee812de8cccfc648f3ff3cda26106396a38c1c1f183b722392397a752d949c5123888b7a8ec012fe518f6efc25015a620b1559e4609286b52921e06b79fd563a9b3b4c4e16", + "address": "erd1qyg80tr4rd65ur3hedm9h4yv3fcwmm6vnyrypnm972nd80889hxqdfgwrc", + "initialRating": 5000001 + }, + { + "info": "single key 14 - wallet23", + "pubkey": "5909def579148f456e8490659b859f80f8ccd62b5adda411e1acdc615c2ec795a88632cf2ec210a56ba91973fd3f07160f559f82f7afaafee008679fefb1b0cd2f26f4324197e6239c000accd1c427138568a8a9e276690c154d3df71a1f970c", + "address": "erd14x6d48q59zjh5p909fyw7e46czftgdawyf734cnmgk5e63ghrvvsqp254t", + "initialRating": 5000001 + }, + { + "info": "single key 15 - wallet24", + "pubkey": "58d6cfe7e8c3ec675da17e492c4ba97759fa15fc0f41bbe29d1d49d5f5ca7db142450ada15e1e4bf4657614e26cceb04ed5c0ca17207b0e24c4baf5f91afc092d43a02aaeae76218420817c85292f8de7d3a2b4f3c8615c2bb6a6d1c74267788", + "address": "erd1wyxylus33e476h5kta7e0caeqvgvcgrxh0az33e7szya6g7mh2ws0n27sa", + "initialRating": 5000001 + }, + { + "info": "single key 16 - wallet25", + "pubkey": "eb79770be0ae70e1d6932832eab94117b0c1a2442b3fdb380b1ad5a809b6221a4905e02a628886c925d152c4e5006413fe69d1f11cf543f4802d4ce4e5eac2b18b78a79215c737e2e098b40802044bc6e946b712299286c34f6d33d8b681790d", + "address": "erd1v3ylw7t6vzjzs06xjf6ccmf576ud38g2ws45tjkjg48s38jefpzqlwms9w", + "initialRating": 5000001 + }, + { + "info": "single key 17 - wallet26", + "pubkey": "bc03265a52610464f2f0431a69647be3106924f5bf67cf87cd889bf86d81739b3f0f37bad11ab93c5209dc4496f4130d69a9649596b97884b7e91e0b4d7c59169dd0729ac3e3bcd308efac56bc29d3cc249d8759580ab117943aa40df3baac05", + "address": "erd1twel4azu6uptw878y063p93mjr84y5m4kpsww2aeqj4pg5jeplgst04rhg", + "initialRating": 5000001 + }, + { + "info": "single key 18 - wallet27", + "pubkey": "aa4be8f36c2880ee4d2ca79dbd7a53537e3965f255dfb5c75324fe29fcb6ce56148fbaea334268e413f0df95f580c40fb3484165b2852236e3a1aa68151ac3327d981cfae52d99f9a564bd3139cdd768661854dae78880d9320191cdb2989815", + "address": "erd1q2se75ucl9as9j7e48v00jrnj6hvtk5vqxa4a3ag5729vctsdkasm20cyc", + "initialRating": 5000001 + }, + { + "info": "single key 19 - wallet28", + "pubkey": "3e86fea8365791b3becfc9aa2bc239f6be58725e61e46e7935c56479ad285e0781da1f277980d2e1d0ecff3982f2d90f321aa03f3d934adf260628d0ed0dc81a98dfaf1e6278e042d6c78dc65f2fa79d3b457754a321b8a0d7bf9998feeea817", + "address": "erd18cc6cm35xhv7kzwsm79l4ma6jpz3ee5l0yjxuc66kh6rcgtawtuq6lzp9f", + "initialRating": 5000001 + }, + { + "info": "single key 20 - wallet29", + "pubkey": "aa92cf6e0ac62df09e7adca139c41a162ad668e7a797770b6d195cd9b175d0fca9eac3f4bf859967139f2ba109741a144e3dc5e6ccaeb6cd21f1d202b10f08832274cd9cdf6b10dbc2c60acdd1c70ae9beae2139e2b69eccbcde32a7f3991393", + "address": "erd1psux99h4jljyt3nkw8pruv3spw5r0unqe4wk8837mm9my88gl28qj6mml5", + "initialRating": 5000001 + }, + { + "info": "single key 21 - wallet30", + "pubkey": "f2b7819d1c2e2e1d007edcf896034085645f3c81e7c7fe21aa7ad4f35f8b863ee1db13448d15a3d0d15018f741a991010a9374710b628e41ef078be8a10249f2a3000598432c28186af1c04a219ac914434dca9c27e61485d701505112093f8a", + "address": "erd1vgm89ngmv2ghzsyq8xjtt45crekkxnhsq30yxzlq86uc3ra3r57qa3mw2p", + "initialRating": 5000001 + }, + { + "info": "single key 22 - wallet31", + "pubkey": "292742eee9d12dade21b4cd8bcd44c210c26d927ef6dbd9cad59008643a971a86ea6dfce247515d4266789b3fe8e35167278e781e52b4cd7b9781554ba67ecc08680eb19628e7741c94d8456090a08aceab1c8d2ed39bf59e8e282381aa32a0a", + "address": "erd1k767vmmn8vg8xvuny32ppwr4dxrlgmpykn0u7nm92evlag3wkukqdgsf5u", + "initialRating": 5000001 + }, + { "info": "single key 23 - wallet32", + "pubkey": "11f784d2970d65769ce267710b3d08b28b78c3f79283758918c8ef15717ccbe90c23348cafe0e98a5d101b8dafbe7d081c6821dee8bf40ba150664ccc2dbbdd6358c92404e677d82910ce61f1d7584fbbbc9ebf71b7f35a118556e2a5c220501", + "address": "erd1hwe8lskmzsdpuy3f6hldamvn0zrhzldec8m4tt8hupq58d7gyrequy8wsp", + "initialRating": 5000001 + }, + { + "info": "single key 24", + "pubkey": "0382c11222db8a15e42e3ff64893df46c7720b439fb2a546462815ac0a8fa3bed99fceae5da9b68524e36f61cc074d09ceafec274c54f182c56a77583f9421f19c777265c43da1d5747304b36f0367cf3e8e5f63f41dad1a4362d9e1997a9e16", + "address": "erd125eyrjk99zadr04gm9z2p4nckmnegexs5nyk7ek85rut2665t75sql3w88", + "initialRating": 5000001 } ] -} +} \ No newline at end of file diff --git a/cmd/node/config/systemSmartContractsConfig.toml b/cmd/node/config/systemSmartContractsConfig.toml index 1f4c9456292..fc898335f79 100644 --- a/cmd/node/config/systemSmartContractsConfig.toml +++ b/cmd/node/config/systemSmartContractsConfig.toml @@ -8,7 +8,7 @@ NumRoundsWithoutBleed = 100 MaximumPercentageToBleed = 0.5 BleedPercentagePerRound = 0.00001 - MaxNumberOfNodesForStake = 36 + MaxNumberOfNodesForStake = 64 UnJailValue = "2500000000000000000" #0.1% of genesis node price ActivateBLSPubKeyMessageVerification = false diff --git a/cmd/node/config/testKeys/delegators.pem b/cmd/node/config/testKeys/delegators.pem new file mode 100644 index 00000000000..78f89d05110 --- /dev/null +++ b/cmd/node/config/testKeys/delegators.pem @@ -0,0 +1,50 @@ +-----BEGIN PRIVATE KEY for erd1z48u9l275l2uy4augfytpp2355wvdnc4gwc9ms9gdhdqru3fz9eq5wqe3e----- +MzJlYzk2ZTgxMDMyYzBiZjhmN2UxNjhhODliNTc2MGMxMzM5NmMyNmEyNDhiYzU0 +NjhlMTVmZTlmZDc3NDM4YTE1NGZjMmZkNWVhN2Q1YzI1N2JjNDI0OGIwODU1MWE1 +MWNjNmNmMTU0M2IwNWRjMGE4NmRkYTAxZjIyOTExNzI= +-----END PRIVATE KEY for erd1z48u9l275l2uy4augfytpp2355wvdnc4gwc9ms9gdhdqru3fz9eq5wqe3e----- +-----BEGIN PRIVATE KEY for erd1qm5erxm0va3hcw9jfxtp2gl3u9q9p4k242pk9xx3vezefkgj2vhs0wk8cx----- +NWI5ODczMjc4YjExNmFkMmE2NjY2NTI2MmVmNDhlN2FlYWM4OWRlMTAyMDhkZGEw +ODdmMWVjMThkMDBkMzc5NTA2ZTk5MTliNmY2NzYzN2MzOGIyNDk5NjE1MjNmMWUx +NDA1MGQ2Y2FhYTgzNjI5OGQxNjY0NTk0ZDkxMjUzMmY= +-----END PRIVATE KEY for erd1qm5erxm0va3hcw9jfxtp2gl3u9q9p4k242pk9xx3vezefkgj2vhs0wk8cx----- +-----BEGIN PRIVATE KEY for erd1rqwt9vpfn072tahtcvup2dxz4nvqfs3n5p9eh0jnypkppxmdheaqpcqfzz----- +MmFjNGZlYTlkNmI3OWQ5ZGU5MjkyZmZlZGE4ZjkwYWNmODQzNzVmZDIwOGEyMjkz +YjcxN2JhNWI1ZWI1MjQ3ZjE4MWNiMmIwMjk5YmZjYTVmNmViYzMzODE1MzRjMmFj +ZDgwNGMyMzNhMDRiOWJiZTUzMjA2YzEwOWI2ZGJlN2E= +-----END PRIVATE KEY for erd1rqwt9vpfn072tahtcvup2dxz4nvqfs3n5p9eh0jnypkppxmdheaqpcqfzz----- +-----BEGIN PRIVATE KEY for erd17uygg7qq05mjhectgymj6fwq59ysr4p92cy0yz3jrxxj6253p40sj77wr6----- +MzU0N2M5MWRhNzRhMTY5MDZjMzhkMTY5ODQ4MWRiOGI1Zjk0YWJjM2VlNDgyMjY5 +ZDhjMDEzMTdlOWVlYWUxYWY3MDg4NDc4MDA3ZDM3MmJlNzBiNDEzNzJkMjVjMGEx +NDkwMWQ0MjU1NjA4ZjIwYTMyMTk4ZDJkMmE5MTBkNWY= +-----END PRIVATE KEY for erd17uygg7qq05mjhectgymj6fwq59ysr4p92cy0yz3jrxxj6253p40sj77wr6----- +-----BEGIN PRIVATE KEY for erd1qslr87nj5gkv2396js3fa2za5kqgwugqnz4j4qqh22mxpnse2lws8srsq6----- +MDc5N2IzZDFmMmY1YzYzOTYxYjdhMThmNmI2OWZlNDk0NmJkNjUyOGFhNjU3ZTQw +Zjg3NjY2MmM3MmNhMWQ3ODA0M2UzM2ZhNzJhMjJjYzU0NGJhOTQyMjllYTg1ZGE1 +ODA4NzcxMDA5OGFiMmE4MDE3NTJiNjYwY2UxOTU3ZGQ= +-----END PRIVATE KEY for erd1qslr87nj5gkv2396js3fa2za5kqgwugqnz4j4qqh22mxpnse2lws8srsq6----- +-----BEGIN PRIVATE KEY for erd17pjlqg55c6v3fjvpqec8peefk74g8neygr84ymw7cqzudmzaw7lqnln7sz----- +NTBkMzFiMzdmOWMyM2NmMWMyYjgzZThkNGRmYzgzNjU5OTkyOGIxMzVhZDI3OGQ0 +Yzk5Y2UyZjFhMDUzMjI4YWYwNjVmMDIyOTRjNjk5MTRjOTgxMDY3MDcwZTcyOWI3 +YWE4M2NmMjQ0MGNmNTI2ZGRlYzAwNWM2ZWM1ZDc3YmU= +-----END PRIVATE KEY for erd17pjlqg55c6v3fjvpqec8peefk74g8neygr84ymw7cqzudmzaw7lqnln7sz----- +-----BEGIN PRIVATE KEY for erd19ztfuew6ejrwq5mpax4xztjwh5j63u9vge4dum9vlyy7hg3pc86qgmt6nm----- +Mjg2ZjFlOGJmNDY5OGU3ODMwNzc2YTRjZjdiMDcwZDNhZGUzYzQyMzgwN2U1ODdk +MTYxN2Y3NDBlNWZiYzU3MjI4OTY5ZTY1ZGFjYzg2ZTA1MzYxZTlhYTYxMmU0ZWJk +MjVhOGYwYWM0NjZhZGU2Y2FjZjkwOWViYTIyMWMxZjQ= +-----END PRIVATE KEY for erd19ztfuew6ejrwq5mpax4xztjwh5j63u9vge4dum9vlyy7hg3pc86qgmt6nm----- +-----BEGIN PRIVATE KEY for erd1age5t5qfrke4vm47vaq9a4yewllh6227qm4fcy3rc7g5ktmzyatsgf4wcw----- +MzkzMDA1MjU2OWY2MDhkYjYxOGI1NDYzMmI1ZWFkZGNhYmJhODQ2NGJmMjY4NWU4 +YmU0YWY5MDNkNzAwYTQ0NGVhMzM0NWQwMDkxZGIzNTY2ZWJlNjc0MDVlZDQ5OTc3 +ZmY3ZDI5NWUwNmVhOWMxMjIzYzc5MTRiMmY2MjI3NTc= +-----END PRIVATE KEY for erd1age5t5qfrke4vm47vaq9a4yewllh6227qm4fcy3rc7g5ktmzyatsgf4wcw----- +-----BEGIN PRIVATE KEY for erd1jt0vv29trqs3nddzkxsf950xx0t5uvyncmuamwryneh9wsee5wpsgue96d----- +NTBlZDI0NzM3ZWNlOGEzYWZlYjJlZTY3N2NiNzUxYWI0ZTA4OWNhMGY3ODhlNjNj +MmVhNWQzMGE2MmMzNmE4ZTkyZGVjNjI4YWIxODIxMTliNWEyYjFhMDkyZDFlNjMz +ZDc0ZTMwOTNjNmY5ZGRiODY0OWU2ZTU3NDMzOWEzODM= +-----END PRIVATE KEY for erd1jt0vv29trqs3nddzkxsf950xx0t5uvyncmuamwryneh9wsee5wpsgue96d----- +-----BEGIN PRIVATE KEY for erd1c83rmk3n8ys4g9dkg3q70thx3v787qtpfmk23epu4xsadpyd3dnsejf2r7----- +OGQ1MDBkNjg3NTA4MWU0Y2JjODk5ZTMxNmYwOGVmMDVkZDMyODRkMWFhZDUzYmJk +NGRmYmY4MTAyMzEyYmY4YmMxZTIzZGRhMzMzOTIxNTQxNWI2NDQ0MWU3YWVlNjhi +M2M3ZjAxNjE0ZWVjYThlNDNjYTlhMWQ2ODQ4ZDhiNjc= +-----END PRIVATE KEY for erd1c83rmk3n8ys4g9dkg3q70thx3v787qtpfmk23epu4xsadpyd3dnsejf2r7----- diff --git a/cmd/node/config/testKeys/group1/allValidatorsKeys.pem b/cmd/node/config/testKeys/group1/allValidatorsKeys.pem new file mode 100644 index 00000000000..0a34418f748 --- /dev/null +++ b/cmd/node/config/testKeys/group1/allValidatorsKeys.pem @@ -0,0 +1,60 @@ +-----BEGIN PRIVATE KEY for 309198fd7b6bccb1b6279ea2e5c5f2a33b9f6fe5f23180778d8721710344989b07d10dd1bd19307b3cd06eab9d1358062511610ccdad681ae1165016256cc1fdc0fed5041a5c29d7773b2994022bf2dc9efb937b3bb7cc9d72670448fad7d091----- +NmRjMzcwNGQ0YzhkOTcyM2I2MjBmZmUwOTkyNDk5ODhiNzc3NmRiMDliYTI3NjAx +MWY1MTc1ZWM1ZTZlNWIzNg== +-----END PRIVATE KEY for 309198fd7b6bccb1b6279ea2e5c5f2a33b9f6fe5f23180778d8721710344989b07d10dd1bd19307b3cd06eab9d1358062511610ccdad681ae1165016256cc1fdc0fed5041a5c29d7773b2994022bf2dc9efb937b3bb7cc9d72670448fad7d091----- +-----BEGIN PRIVATE KEY for cd8cc9d70a8f78df0922470f1ebee727f57a70fb0571c0b512475c8c7d3ce1d9b70dd28e6582c038b18d05f8fbd6ac0a167a38614c40353b32ef47896d13c45bde57e86d87dd6e6f73420db93aeb79a1fd8f4e297f70478685a38ed73e49598f----- +ZGMyYmYxYzVjNzY1OTI2MjVmZGVmNzFkNGJiNjlkZTFiYmNkMGIyZmUwYWU4NzY2 +YzQyMmFmMjM1NmQ2MWY2OA== +-----END PRIVATE KEY for cd8cc9d70a8f78df0922470f1ebee727f57a70fb0571c0b512475c8c7d3ce1d9b70dd28e6582c038b18d05f8fbd6ac0a167a38614c40353b32ef47896d13c45bde57e86d87dd6e6f73420db93aeb79a1fd8f4e297f70478685a38ed73e49598f----- +-----BEGIN PRIVATE KEY for e441b8a7d35545f7a02f0d57d144c89810d67ecb9abb5804d1bcfd8b270dc30978c56fbf9618e9a6621ca4e6c545c90807f7fe5edfd34ccab83db7bc0bd68536bb65403503d213c9763ec2137d80081579bb1b327f22c677bdb19891f4aae980----- +MTA0NWEwNjFlYzVmY2E5NWZiZmQwYmY2YWJjYjRiNDM4ODI0M2U0MzdjZTAwZTZl +ZTMzYTcxY2MyZThlNTQxMw== +-----END PRIVATE KEY for e441b8a7d35545f7a02f0d57d144c89810d67ecb9abb5804d1bcfd8b270dc30978c56fbf9618e9a6621ca4e6c545c90807f7fe5edfd34ccab83db7bc0bd68536bb65403503d213c9763ec2137d80081579bb1b327f22c677bdb19891f4aae980----- +-----BEGIN PRIVATE KEY for 72d8341713a271d510c7dfd02455ef86e9af4c66e06ac28fbb4c4e8df1e944e685bae2bee2af4101c19922b64e44e40b5d4905755594a719c1d50dc210515495d0de9b3a1d4ed42fd45a973353fe2c2548c45bb2157d8bf68e0937cc20fe1011----- +YzFkZWY5YTY3YTBhYmI1MzVjNjYyYjE1MTIwMjA2NjgwZTc0MjBhODYyNTkyZjRi +NTQ2NjE5NDM0YTBlOTI2Nw== +-----END PRIVATE KEY for 72d8341713a271d510c7dfd02455ef86e9af4c66e06ac28fbb4c4e8df1e944e685bae2bee2af4101c19922b64e44e40b5d4905755594a719c1d50dc210515495d0de9b3a1d4ed42fd45a973353fe2c2548c45bb2157d8bf68e0937cc20fe1011----- +-----BEGIN PRIVATE KEY for 796d2f56ee9fa8f4ff9fc7735bbb4d644be8dd044f7f965362aed3d562e00b11f730b2fe21eb9c9fd100b68a5d3dbf07bae63d25739f1304ab638330f0e8c207a76de648e2523ad1693f4ffe9def8a1d5aca2c6c1c14e1fcc20089db069d1a0e----- +YzUyY2M3YzVkY2Y5MWZkMDgyZDcwZDZlZDg0NWY1YWZkZDNiODRiZWFjOWE4MTU3 +YWFiYTAxNTQ1ODIxMmUxOQ== +-----END PRIVATE KEY for 796d2f56ee9fa8f4ff9fc7735bbb4d644be8dd044f7f965362aed3d562e00b11f730b2fe21eb9c9fd100b68a5d3dbf07bae63d25739f1304ab638330f0e8c207a76de648e2523ad1693f4ffe9def8a1d5aca2c6c1c14e1fcc20089db069d1a0e----- +-----BEGIN PRIVATE KEY for 4cc0bfcdf4515927e3ae7890197bfd7c2e3c6f80ff7570fc6313d095e0d4e518ecc81db7087fefb8af166723a32ded1324f4ee00a6a97d206a024fd95ab60f7fe18c896c829ac43782c56d922415fb4ddbc0384936e3f860feb0666da43bcd19----- +NWM4OTQzMjExNWU1ZjVkMGI2YzEzOGI4MjI2MjVlZmM2MDk2NzIyNWRmMThlNzVj +MTFhMTYzMGM5MmRlOTI1YQ== +-----END PRIVATE KEY for 4cc0bfcdf4515927e3ae7890197bfd7c2e3c6f80ff7570fc6313d095e0d4e518ecc81db7087fefb8af166723a32ded1324f4ee00a6a97d206a024fd95ab60f7fe18c896c829ac43782c56d922415fb4ddbc0384936e3f860feb0666da43bcd19----- +-----BEGIN PRIVATE KEY for 3449c9d672472ea52e83be4a8d6ce55785044233d848ac0a9a4b7fc22bf5b1bf5776f95f4b459f4e4cd3ba1d20b46a197c5a55ec00fa8d795d35f2232a6fae360129d186e3a0c219d42d8357de2823c8566da7841c2739b30d1581c4a38ec80e----- +NjIwZjkzZGZhMmQ1ZWY2NzliY2EzYTQ1MzE2NTg1ODU2OTVjNDM5NzM2NTgzNTJk +ZGM2OWU0MjQ4ZGQxNjQ0NQ== +-----END PRIVATE KEY for 3449c9d672472ea52e83be4a8d6ce55785044233d848ac0a9a4b7fc22bf5b1bf5776f95f4b459f4e4cd3ba1d20b46a197c5a55ec00fa8d795d35f2232a6fae360129d186e3a0c219d42d8357de2823c8566da7841c2739b30d1581c4a38ec80e----- +-----BEGIN PRIVATE KEY for 1bdef34453a83d19748b02d964c43409a66535678b6234c42d289ed2b7571bf60d35ba7a43cd951d4fc9fc2e8ff618038a2edc9cb0181dcac0b62a0859aafd8d9993aa3069c14fec11cb66a653311a37861d225847bf535bcb920b4f0ea98b8b----- +YWNkNzhjNzk2OTc5YjIxMTk5ZDc0YzgwNmExNzE1Y2EyNjNiMGMyNDI2MzFhZmNi +YzdlODNmYTRmMzFkNjMzMw== +-----END PRIVATE KEY for 1bdef34453a83d19748b02d964c43409a66535678b6234c42d289ed2b7571bf60d35ba7a43cd951d4fc9fc2e8ff618038a2edc9cb0181dcac0b62a0859aafd8d9993aa3069c14fec11cb66a653311a37861d225847bf535bcb920b4f0ea98b8b----- +-----BEGIN PRIVATE KEY for 3bd60bd8c5ace7d1999cd4bfd93dcb7bdc397d8d84efa5fd89439b7b727b0331bd00e3feae85df79e7d2b5eba1ea07003972fde3a7eb8d4ba25583a848be812e89b75fe8f3531d810ba2aaef629748ace6ac5ae73d8a2e6a65bb379f5be3b906----- +YWQ0ODk0ZmIzYjhkOTBiN2QzNTNhN2NhZjc4NTE1MjlhOTRkNjkyMjIyMGU4OTI5 +YzdjODMzOGJiNDRlZWExMw== +-----END PRIVATE KEY for 3bd60bd8c5ace7d1999cd4bfd93dcb7bdc397d8d84efa5fd89439b7b727b0331bd00e3feae85df79e7d2b5eba1ea07003972fde3a7eb8d4ba25583a848be812e89b75fe8f3531d810ba2aaef629748ace6ac5ae73d8a2e6a65bb379f5be3b906----- +-----BEGIN PRIVATE KEY for 2b9a1e5e291471f9eb0cf1a52db991f2dbb85446d132f47381b7912b041be00cccab748c25bdd6165cd6a517b6e99b0133bda4dc091dcdf6d17bc460ac0e8c6fe4b2460a980dd8dea8c857647bc5826a2b77fc8ba92c02deb2ba3daafb4d5407----- +NTk1NTg4YWMyMWI4ZGU4MThjYzdkMDI4NThmZDU4ZDk5NTg3Mjk0NDRiMzk0OWM5 +MzBjYjIwZGEyYWNlZTMzYg== +-----END PRIVATE KEY for 2b9a1e5e291471f9eb0cf1a52db991f2dbb85446d132f47381b7912b041be00cccab748c25bdd6165cd6a517b6e99b0133bda4dc091dcdf6d17bc460ac0e8c6fe4b2460a980dd8dea8c857647bc5826a2b77fc8ba92c02deb2ba3daafb4d5407----- +-----BEGIN PRIVATE KEY for e464c43c4f3442ec520d4a6464d7fa96397ab711adf38b5a96f208303337f6a97ffdbd22e34a10deef6aa21ff078360d2bf7fae627a1ec55a9f120b35224b8e461b0f4de7d3ce800e6b910f37c4d03cce7039ce3a4a3a79ac0511c36435ccf85----- +NDk1MzMwNThiY2VmZjNmOTFmMTRlMTI4MWE0OWRiZDkyYzAwOTVjOTcxMTViMmY3 +Yzk3OWFkNjdjOWVlNjM0YQ== +-----END PRIVATE KEY for e464c43c4f3442ec520d4a6464d7fa96397ab711adf38b5a96f208303337f6a97ffdbd22e34a10deef6aa21ff078360d2bf7fae627a1ec55a9f120b35224b8e461b0f4de7d3ce800e6b910f37c4d03cce7039ce3a4a3a79ac0511c36435ccf85----- +-----BEGIN PRIVATE KEY for dab5c34e66e096d1f328fd9b045136724c8ccbf7b5a4bcf1e8c9edc9510712c0a7feff7818563aa799b37f1cdcfb330cc49d8482c7154988d33f63fe2526b27945326112c832fdf72a1b35f10da34c6e08b4079d9c56195c1ab64c84eab93b95----- +NDZlZDkwNzcwNTQwNjcyZTlmYTQzODUyNzc3YjM0OGM1MmIzNmM3YjAzZGYwMmJk +ZjE0NmM0MTkxMjQwNjE0NQ== +-----END PRIVATE KEY for dab5c34e66e096d1f328fd9b045136724c8ccbf7b5a4bcf1e8c9edc9510712c0a7feff7818563aa799b37f1cdcfb330cc49d8482c7154988d33f63fe2526b27945326112c832fdf72a1b35f10da34c6e08b4079d9c56195c1ab64c84eab93b95----- +-----BEGIN PRIVATE KEY for a5624bec34e06d5026a334654be9e0118c8a02720a6bd868a51d5eb687819442cded09d1fef2e9d9db8bb2d5be01f1148b4819aee9e6a48b9c530285dbc4d800f4dd10d7f9a75d4b36de8fb52aec672cec91e0256f7e9848b10219748d9e708b----- +YzY2MjU0NGU0OWM1YTRkMTdmZjQ4YjZkZjU0YzdkZmUzZWRlY2M1Yjk2ZWM1MjMx +OGRjZjAyZjkwMjdjNTg1ZQ== +-----END PRIVATE KEY for a5624bec34e06d5026a334654be9e0118c8a02720a6bd868a51d5eb687819442cded09d1fef2e9d9db8bb2d5be01f1148b4819aee9e6a48b9c530285dbc4d800f4dd10d7f9a75d4b36de8fb52aec672cec91e0256f7e9848b10219748d9e708b----- +-----BEGIN PRIVATE KEY for 283ccdc58e0df19717ecd0c4c3a553059bf6c8d91b9c7b624afa8cb0564c7fd86e5a199973d17b7b939e63186b25f20a7234ad7f162c8f2547ba2e326c30a6c0571ea04cba83b35fd9a2a60f13e95ee1767b5fe87cbf378458ac7e27b4833f96----- +NGJjZmIzODdkYmJkN2Q3NzIxOWVmOWFkZGI3OTMyZmRlYzcwNjZiOTk3MmVkNjg3 +ZjkyYmIyMzg5MGFhOTMzMQ== +-----END PRIVATE KEY for 283ccdc58e0df19717ecd0c4c3a553059bf6c8d91b9c7b624afa8cb0564c7fd86e5a199973d17b7b939e63186b25f20a7234ad7f162c8f2547ba2e326c30a6c0571ea04cba83b35fd9a2a60f13e95ee1767b5fe87cbf378458ac7e27b4833f96----- +-----BEGIN PRIVATE KEY for 7d1a1b4f36fcd8cea426005212022511bc25a414019e2b5c65947f00c28c8f1220ff1473c36efaa22a94d3e2b5258705ff6efb91902afb2c951c90502edf60072c3330ad9fd1b5c4b85226f10a474a0ddda9b61730946629b110b6eac70de70a----- +ZDE1ZDk1YzdhMGU1ZGY5MDRmNzQxODI2NDFiN2FlOGEwYmJkYzE5Y2RkOGNhMGZh +MzEyNDI3OTY2YjNkODE1YQ== +-----END PRIVATE KEY for 7d1a1b4f36fcd8cea426005212022511bc25a414019e2b5c65947f00c28c8f1220ff1473c36efaa22a94d3e2b5258705ff6efb91902afb2c951c90502edf60072c3330ad9fd1b5c4b85226f10a474a0ddda9b61730946629b110b6eac70de70a----- diff --git a/cmd/node/config/testKeys/group2/allValidatorsKeys.pem b/cmd/node/config/testKeys/group2/allValidatorsKeys.pem new file mode 100644 index 00000000000..cbd478d5b5b --- /dev/null +++ b/cmd/node/config/testKeys/group2/allValidatorsKeys.pem @@ -0,0 +1,60 @@ +-----BEGIN PRIVATE KEY for eedbc5a3141b92148205d178d150905e68ca745ba54617025f84b33c91233afda2c2109084821e14f9a50d3f220fbc000ce6ad432f2a1865da9c6547016ecc7e07242ef490c0bdda29ec677f3e833f54eb2cf27e95b10b8edbdfa7de4e1bc000----- +YzU4OWY2MTQ1MjUyZjg4MmExYmIwY2QyNzVjOTQ5MzZlMjMxYTk0ZTZhYmNjM2Q1 +ZGY3OTA2Mzc0M2NhZmMwYw== +-----END PRIVATE KEY for eedbc5a3141b92148205d178d150905e68ca745ba54617025f84b33c91233afda2c2109084821e14f9a50d3f220fbc000ce6ad432f2a1865da9c6547016ecc7e07242ef490c0bdda29ec677f3e833f54eb2cf27e95b10b8edbdfa7de4e1bc000----- +-----BEGIN PRIVATE KEY for 48c77bbf5d619fb13d76883736c664493b323c00f89131c9d70b3e4ac875103bd8248e790e47a82c9fdcd46fe33b52093a4b3b248ce20e6f958acd22dfb17335fcaf752bab5e29934f0a7e0af54fb2f51a9e6b1be30abdd701f7c9fbd0ad5d8e----- +ZjJmZjg3MTNmMzdjZmYxYTljZTM5MTA4ZjA3OGFkOTc2OGViYzg2MDY0NTEyYjg2 +OTFhYTk0MmE3ODQzODQ1Mw== +-----END PRIVATE KEY for 48c77bbf5d619fb13d76883736c664493b323c00f89131c9d70b3e4ac875103bd8248e790e47a82c9fdcd46fe33b52093a4b3b248ce20e6f958acd22dfb17335fcaf752bab5e29934f0a7e0af54fb2f51a9e6b1be30abdd701f7c9fbd0ad5d8e----- +-----BEGIN PRIVATE KEY for dd59e326a160d3b49ca25f2ab93b4f7ba766b124de66b68507b9e7a9cf69df7c4fca695592eb31e7e63061daef52d30cc1d362fc612d22631398cad4af46969e35407b293808133fc130b8f930ba41c6b88bc9ed9b884892113593d3ffc55297----- +NThiOGMyNWVmMThmNTJhM2NhYTRiMjEwMWRhMTdhN2YwMTg1MWU2Y2RjZTRiZjM5 +ZTNmOGRjNzY0OThmMmU1OQ== +-----END PRIVATE KEY for dd59e326a160d3b49ca25f2ab93b4f7ba766b124de66b68507b9e7a9cf69df7c4fca695592eb31e7e63061daef52d30cc1d362fc612d22631398cad4af46969e35407b293808133fc130b8f930ba41c6b88bc9ed9b884892113593d3ffc55297----- +-----BEGIN PRIVATE KEY for 6b1a8bf3e5e7bacaaf99e3c89891a8a4ec7e9022986043f8206db9171ede3bd8cdcbbd7e8e1234180de5d651110ef706a8d964cb35048bc961611b55c8d9bd1b942b93c7e1b88157e7f79f2c08dbabe1af4612afe6044ab1be316976111b7019----- +NzJhNGVhN2E4ZmExZjQ3ZGUxY2ZjNzQxZGFjOGU5Zjc4ZDdiMWQyNWNlMDBkNTY1 +YWMyOGZkYzkxNDQ1NTYzNA== +-----END PRIVATE KEY for 6b1a8bf3e5e7bacaaf99e3c89891a8a4ec7e9022986043f8206db9171ede3bd8cdcbbd7e8e1234180de5d651110ef706a8d964cb35048bc961611b55c8d9bd1b942b93c7e1b88157e7f79f2c08dbabe1af4612afe6044ab1be316976111b7019----- +-----BEGIN PRIVATE KEY for d8f8ef204ac892dd1a04648fc449ffdd11418dbd5c8fe623e5efda0bcae47cb41eb99c981585d80be1d668d8b7466619b6ead4d83976cc4f6879627a455603a74ab2adbfb5fed0f1a2b954363d97cbd3ac7feb284c83ac64422fad518e589c8e----- +NDFiNDAxYjBkZDdmMDFhNDEwNmZjYmNjMDAwZDkwMWY5NWYwZTg4YjQ4ZjFmNzlh +MmY1ZmE5NWZjOTNjNWQxZA== +-----END PRIVATE KEY for d8f8ef204ac892dd1a04648fc449ffdd11418dbd5c8fe623e5efda0bcae47cb41eb99c981585d80be1d668d8b7466619b6ead4d83976cc4f6879627a455603a74ab2adbfb5fed0f1a2b954363d97cbd3ac7feb284c83ac64422fad518e589c8e----- +-----BEGIN PRIVATE KEY for f547e115b1ada7cf9b8aeef45ee0d9ec4b206315ef44be706d994a0571688cd96291d1ab6c3761df29d00a2ba290a3185e4796bc49891906f86e16da01af3fd52320944b96b60e679ac8e686d4819e97e15e5fe46503c556b4acdd8079624005----- +ZmFmMDA2YjRhYjNiZDhiZTg4ZTYwMWZjNDIyNjVlZjliMTQwZTRiNDNjYTNhYjVh +YzVlNGQ4NmUxOTkzNzY2Mw== +-----END PRIVATE KEY for f547e115b1ada7cf9b8aeef45ee0d9ec4b206315ef44be706d994a0571688cd96291d1ab6c3761df29d00a2ba290a3185e4796bc49891906f86e16da01af3fd52320944b96b60e679ac8e686d4819e97e15e5fe46503c556b4acdd8079624005----- +-----BEGIN PRIVATE KEY for 0e5cc5f218a8fa9bae1f6b452430c0de205e6b251d0f1d606d1ce28203fb556768e6c4545ce8e90d640ef2cc1062f40ccf2ede124b926cbf3b2b0050b0e19f67e7e36ac1a7049178a77cbd65ee30cd0a40d9f98846ce439cc120717501f03180----- +YzFiYzc1YjNjM2U0NWM4MjM5OTRjNWM0MTQzZDNhNWMzOWQ3YWY2ZmM2OTE0ODZi +NzdmZGU3ZTY1YjljZGIzNw== +-----END PRIVATE KEY for 0e5cc5f218a8fa9bae1f6b452430c0de205e6b251d0f1d606d1ce28203fb556768e6c4545ce8e90d640ef2cc1062f40ccf2ede124b926cbf3b2b0050b0e19f67e7e36ac1a7049178a77cbd65ee30cd0a40d9f98846ce439cc120717501f03180----- +-----BEGIN PRIVATE KEY for 760dc22525dce5be65a3a55ee07f7f012e0a89f435daec56eb475b0b5ca2d84b157894b8df64dfb570ecc633d5e1611639d43976e29f11c232236a9548b0145ee4e43fe495252c8c1f006b8df51d3835dee64a826f43167096b347b6919aa292----- +OGM2NjdjNTM2NWViNDZhMGExMDZmZDA1ZmZhYmUxNWU5NjA4NzU3ZWE0MDA4MzE5 +YmM4NmQ5MjY3YzNiMDIxMQ== +-----END PRIVATE KEY for 760dc22525dce5be65a3a55ee07f7f012e0a89f435daec56eb475b0b5ca2d84b157894b8df64dfb570ecc633d5e1611639d43976e29f11c232236a9548b0145ee4e43fe495252c8c1f006b8df51d3835dee64a826f43167096b347b6919aa292----- +-----BEGIN PRIVATE KEY for 39316473217f7c435a543efa078254198dd079e3c6505e7cc1564b033de8a161dc2e9c392b1e584440510113b5942816102d7be5f4af9461af21a454fc1938a962b256c1c1d1f939198029ed0bf22c62893038d5687787cb46436c0ef4f12417----- +NzdkYjE3MzMyOWY0MjIyYTMxOTFlZDUwMzM2MWZjZDQ2NTkwZjRhZmIxZjYwNWQx +MTMxYjNjOTg5MzRhNDc2MQ== +-----END PRIVATE KEY for 39316473217f7c435a543efa078254198dd079e3c6505e7cc1564b033de8a161dc2e9c392b1e584440510113b5942816102d7be5f4af9461af21a454fc1938a962b256c1c1d1f939198029ed0bf22c62893038d5687787cb46436c0ef4f12417----- +-----BEGIN PRIVATE KEY for 6a3b9f6b5fd38e79433daa9bf03543314f8a2a3d9f1fec8ebe2bc1ee97f135d83845dcecd201207c1b31d7624ddb330ae67fbfab4137cd734d96bc0975ae8bcfeecc4441b384d39d6900cdb7436450c23b4cc7674ec50055ea4a90861c503a91----- +MjkwNThjZmJmYzAxM2I2YjJlYzgzMTA5MWY0MWIzNzVkNDUzMTRiZTNmOTRiNjA3 +MDY1MzJmZWEwNzUyMDUzZA== +-----END PRIVATE KEY for 6a3b9f6b5fd38e79433daa9bf03543314f8a2a3d9f1fec8ebe2bc1ee97f135d83845dcecd201207c1b31d7624ddb330ae67fbfab4137cd734d96bc0975ae8bcfeecc4441b384d39d6900cdb7436450c23b4cc7674ec50055ea4a90861c503a91----- +-----BEGIN PRIVATE KEY for ee8c987b9af9bba2912763fb7fcd6d6575db60806c5041fa91816ecc339ccfd60bf3cf49fb7017158f0b8e6050276907620bc040816207f14a952bb86752816231ae7f31ff701862cfe0abca367fc4cd63bafd4ad6e4df67612e4ec71462650c----- +NTk1NjY3ZjUzMjg2MjUxYjc2MWNlNDIyOWNjMmNlYTBlOWVmNDg4MjJmNTk3MmU3 +NDZiZDM2ZGY2ZTY0OTM0Ng== +-----END PRIVATE KEY for ee8c987b9af9bba2912763fb7fcd6d6575db60806c5041fa91816ecc339ccfd60bf3cf49fb7017158f0b8e6050276907620bc040816207f14a952bb86752816231ae7f31ff701862cfe0abca367fc4cd63bafd4ad6e4df67612e4ec71462650c----- +-----BEGIN PRIVATE KEY for cfe96f6b010d08f211c83f4ae3eb451d1d5205a50bdcd451706044dc21f523d25f214ab89dd5aab7ae03111197d6e6156e70ab348c9b0fab0a7839ea57fef6cd2324882b4387014dba201e6f87d5ca395e14d900e4563494f4f11a69ef6cdf14----- +MTJjMzU0MzQ1ZDMzNTc2YTk4ZDQ0NjljZmY4Y2FlYWQ1ZDRmODgxODIwOGI0M2Vi +MmM2YzZiY2E4NjU3MWUxMQ== +-----END PRIVATE KEY for cfe96f6b010d08f211c83f4ae3eb451d1d5205a50bdcd451706044dc21f523d25f214ab89dd5aab7ae03111197d6e6156e70ab348c9b0fab0a7839ea57fef6cd2324882b4387014dba201e6f87d5ca395e14d900e4563494f4f11a69ef6cdf14----- +-----BEGIN PRIVATE KEY for 05e9e43732ecff55e553b35b5ee1416065818db162a6fbf096186a1230d88bd057cebb72c5afaec16a803c4c4f69770752fe29be73a4069d0d01666ede963271192d4f324f2b3dcaec8b2c871c23cf185579a039dd5ab093c7cd9bca53e09c85----- +MGMwM2JmYjcyMDI1OGU1NWVkNTU1NDk5ZjNiYWNlMDIxMjU4OTc3NDAwYzA5NGQ2 +YTg4NzViZWQ4NDA4MzIzYg== +-----END PRIVATE KEY for 05e9e43732ecff55e553b35b5ee1416065818db162a6fbf096186a1230d88bd057cebb72c5afaec16a803c4c4f69770752fe29be73a4069d0d01666ede963271192d4f324f2b3dcaec8b2c871c23cf185579a039dd5ab093c7cd9bca53e09c85----- +-----BEGIN PRIVATE KEY for 03e79df244aef557cd6e3b9c7e8063575b6cce83bbff005a0abf96000d0a93652ef0071decdd3ce052aab0912e4d510566af6273d91f41b0d8505a8ca69cff449dc979ff0c3c9c319feab9f2d3a965a49c1bf0d899e85fb3851951a798b0ab03----- +NjIyMWJmYzY2ZmYwYzg1OWY5MTYxZDNkZjY3NGJmMWQ4ZjkwZjExZThmN2MyMWU3 +NzM5NDVmYTIzYTQ2YjUzYw== +-----END PRIVATE KEY for 03e79df244aef557cd6e3b9c7e8063575b6cce83bbff005a0abf96000d0a93652ef0071decdd3ce052aab0912e4d510566af6273d91f41b0d8505a8ca69cff449dc979ff0c3c9c319feab9f2d3a965a49c1bf0d899e85fb3851951a798b0ab03----- +-----BEGIN PRIVATE KEY for 06d0a320440091cc0f44979753c036744cd762d2bf7aa3b61b425397b74c27b581ec39d250818068eef095cb0a49be0c586526bcc9bd98ec3120b9633efd390d4d9a7b6ffcafae8bdbbcf2c98f0cb2cd75897c4d6701b9d77861bf7ab8be3f88----- +OTdkYTJmM2FkOWI1NzRmZTg2N2U1Y2YzMmEwMWYwNjEzOGE2OGM0NjUwNWQzNTI4 +NmJlM2Y4OTQzMDQ3YmIwMg== +-----END PRIVATE KEY for 06d0a320440091cc0f44979753c036744cd762d2bf7aa3b61b425397b74c27b581ec39d250818068eef095cb0a49be0c586526bcc9bd98ec3120b9633efd390d4d9a7b6ffcafae8bdbbcf2c98f0cb2cd75897c4d6701b9d77861bf7ab8be3f88----- diff --git a/cmd/node/config/testKeys/group3/allValidatorsKeys.pem b/cmd/node/config/testKeys/group3/allValidatorsKeys.pem new file mode 100644 index 00000000000..3503b12fbf2 --- /dev/null +++ b/cmd/node/config/testKeys/group3/allValidatorsKeys.pem @@ -0,0 +1,64 @@ +-----BEGIN PRIVATE KEY for 82cfc47999d1499cb880d46e8280b8c4fe576dff20a8ca6f6ac551887c637f935153f9ce2f21921a532477535d42ac05f730760c78415756add2eab6d57d94916f3ad51590b23404739d152f89b6d052df48cace1793897cd4eba722247a6195----- +OWQyYTcwMWQxOGNlNzE4NjQzNDNhNDI5YWY4OGM1YTc3YTEzMjg3MjY1ZDFhMDEz +ZjZhYWFhZGI1NDU4YTM0NA== +-----END PRIVATE KEY for 82cfc47999d1499cb880d46e8280b8c4fe576dff20a8ca6f6ac551887c637f935153f9ce2f21921a532477535d42ac05f730760c78415756add2eab6d57d94916f3ad51590b23404739d152f89b6d052df48cace1793897cd4eba722247a6195----- +-----BEGIN PRIVATE KEY for 7675098e73574db9c59bdce61e4b80251c6536201715dca40b2b69c09ce097690f3a9095d22b006531e3b13b30894803bd7ede3e6d80c9064c431f8671db085ab1052354cb26a7a2436340b273b6c95c84ab94bb9531b99c5f883602b5284017----- +MWFjOWZkZDFlNWZhMmI5NzAxZTVjZWY4ZGFjMTUzMDgyMjE5MjE2YWFhMTU1NzM0 +NzdhMmNjZjhhN2Q4OTkzNg== +-----END PRIVATE KEY for 7675098e73574db9c59bdce61e4b80251c6536201715dca40b2b69c09ce097690f3a9095d22b006531e3b13b30894803bd7ede3e6d80c9064c431f8671db085ab1052354cb26a7a2436340b273b6c95c84ab94bb9531b99c5f883602b5284017----- +-----BEGIN PRIVATE KEY for c50f398a853c670ed625a12eddae175df5a90e034a54484a832566fc91f9b83d5daf1bc821cc347ba7e45f3acd4e1d00d0d7f52235824fd1326a7f370b58fc7dd98edfff4a41739a2015c6ed3a3c0bf3c986efeee187be70f1133fc4379dad95----- +MTE5NWQzZjk0OTk1MDNhMDBjMzhmOWY2NzQwNDZmMzQ4MGZiODk4YzZiZWNmOGVi +ODU5ZDU2MWUxOWY5MGY0YQ== +-----END PRIVATE KEY for c50f398a853c670ed625a12eddae175df5a90e034a54484a832566fc91f9b83d5daf1bc821cc347ba7e45f3acd4e1d00d0d7f52235824fd1326a7f370b58fc7dd98edfff4a41739a2015c6ed3a3c0bf3c986efeee187be70f1133fc4379dad95----- +-----BEGIN PRIVATE KEY for 4bd3f30f608b22b32100c6360def228ec95aa24e3048010bb64606392f602e180a0b2a12f7f92ef1d7f73ce1271ae30693bec692b15802c7ba079939640570fdc7f4d411c084ed0fe612ee223227ca3d02dc9732cf686ba8885007de53f8ec89----- +ZGU3YmUzZGU1NzdiNjk3OTY4ODJkYzljYjY2MzE5NTc2YzJlM2M4Y2Q4MDRlMjJm +YzMyMmZmYmVlM2Y3MGY1Mg== +-----END PRIVATE KEY for 4bd3f30f608b22b32100c6360def228ec95aa24e3048010bb64606392f602e180a0b2a12f7f92ef1d7f73ce1271ae30693bec692b15802c7ba079939640570fdc7f4d411c084ed0fe612ee223227ca3d02dc9732cf686ba8885007de53f8ec89----- +-----BEGIN PRIVATE KEY for 71e8458f92997a00c1cd0e638b9ec42ab136828fc13f0ec643b60af451270cc81d50f4c4578a7c93a700ee21e065281593e7995d2454356cbfdeadb9ffe7bf33ba8f7a31a1d2e76bba5a5f88a613ef37e35595838d0b7f4bd12da7d6fe743499----- +ZjJkOTY0ODVlZDk3YmQ1YWQ3M2M0OTk0NDg1ODIyMGNiMTY0ZDg1YTAwZWEzZTlm +YzYwMjY1ZGM3YjliMTMzNQ== +-----END PRIVATE KEY for 71e8458f92997a00c1cd0e638b9ec42ab136828fc13f0ec643b60af451270cc81d50f4c4578a7c93a700ee21e065281593e7995d2454356cbfdeadb9ffe7bf33ba8f7a31a1d2e76bba5a5f88a613ef37e35595838d0b7f4bd12da7d6fe743499----- +-----BEGIN PRIVATE KEY for d9c30948bffad18776b786f6367142b76605ac6e33a8d38c68c31c7afb099f1a83efb752a87afaf9d04a4a8fb656e40bfe2a4aa6e0c16b82d22bd6c232c2ce5e6672ac6232d2da6945bc033b04cbaaeb4b9af4b29585094e034ab8dcfb8b9c19----- +MmJjYzZkZmYzMDc5MjlmNjg1M2M5OTViZjA5ZWRiYjMxYWFhNjYwZDVjMTc1NTM3 +NzFjMmYwNGEwOWFkOWMxZg== +-----END PRIVATE KEY for d9c30948bffad18776b786f6367142b76605ac6e33a8d38c68c31c7afb099f1a83efb752a87afaf9d04a4a8fb656e40bfe2a4aa6e0c16b82d22bd6c232c2ce5e6672ac6232d2da6945bc033b04cbaaeb4b9af4b29585094e034ab8dcfb8b9c19----- +-----BEGIN PRIVATE KEY for 55fc7ab2e8c0a07bef2e1a9b35764cee1d604cb5634b7226a7310ce56a1f02e99d248fc5b416c4253ac7b88353b1a60f31e1104534e36cb00f46bdcb20a0d24f453e2c8d3cc48dc3c6086edbe16149aae14eb3a4d24ee2b217a4759bc0c0ea88----- +YmY3YjhmZjgxZmMzMzhjZWYwNzQ3ZWM1NzdlMzI3NTVkYTdjYThjMWVlN2QxYWNi +YzNkZDJhZDNhM2RkYzgzYg== +-----END PRIVATE KEY for 55fc7ab2e8c0a07bef2e1a9b35764cee1d604cb5634b7226a7310ce56a1f02e99d248fc5b416c4253ac7b88353b1a60f31e1104534e36cb00f46bdcb20a0d24f453e2c8d3cc48dc3c6086edbe16149aae14eb3a4d24ee2b217a4759bc0c0ea88----- +-----BEGIN PRIVATE KEY for a8e662e63ad0e87f2dc66cbed41d398b73a2da2aaced6cc466ed378b62daee28b3db8e8327a06278a094b05840965c17448ffc8a1c96e532a7960d1a15d2cabd16edadc476bfb4af3a825aff801f615d127b70b4745b88e01627a99ba52d5317----- +NWUyYWQyMGU5MzliMDUzMDU3Y2FkYjNkYTU0NmRkOWIyYjI3ODE1MWJkZDc1ODBl +MGFmYWEyZDM3YTZmNGY2Nw== +-----END PRIVATE KEY for a8e662e63ad0e87f2dc66cbed41d398b73a2da2aaced6cc466ed378b62daee28b3db8e8327a06278a094b05840965c17448ffc8a1c96e532a7960d1a15d2cabd16edadc476bfb4af3a825aff801f615d127b70b4745b88e01627a99ba52d5317----- +-----BEGIN PRIVATE KEY for f5e5eb9dd18aeb5d4829ab08795a9e4c8632a4fd248feed68382add1f2474d3cec042d51b897871bfee1f1c1fbeabf13d1c39d4f9b412948d27737f2b82e85474b7049a700ee8735373564791f0d20692dd1f8b494de7bab0a8415f01532ed90----- +NGNmNTQxMDMyYmNkNjQ3MWU0ZGNkN2NjYzZkNGY5ZDg4MTgwMThiMGIyOWE5NGZi +YTBlMTA2YmJlMTExMzMzMQ== +-----END PRIVATE KEY for f5e5eb9dd18aeb5d4829ab08795a9e4c8632a4fd248feed68382add1f2474d3cec042d51b897871bfee1f1c1fbeabf13d1c39d4f9b412948d27737f2b82e85474b7049a700ee8735373564791f0d20692dd1f8b494de7bab0a8415f01532ed90----- +-----BEGIN PRIVATE KEY for e66d7ac5e51a382164aeaae9924dda3272296a145d3c6178b962e3b7eb83e75515e665c327e86f3ef597ca840f8c5c0ace19ac9a8fbcdc573f9237d112fb1c467d646737863ccd1fe61f4c4341f9805f8e1fe98348b50c3c3f93f62de3975980----- +Mjc5N2ZjYjViYWMyOTJmOTZhMGI3NmYwNzhjZjVjMWJkMTkzYThjNmY1YWQ4NTdl +ZGU5MmU1MjVhMDE3NGIwNA== +-----END PRIVATE KEY for e66d7ac5e51a382164aeaae9924dda3272296a145d3c6178b962e3b7eb83e75515e665c327e86f3ef597ca840f8c5c0ace19ac9a8fbcdc573f9237d112fb1c467d646737863ccd1fe61f4c4341f9805f8e1fe98348b50c3c3f93f62de3975980----- +-----BEGIN PRIVATE KEY for 2a1c49643e564cdf28bba96dfd6cd8ad38a5958b2b3c9a8293ffb54e9df0a0188a67de2fb947b8ae3dd06b7411aaae0e8bedef795ad3b35ac9f1402dcd0631d9d530b01b3880362fbd3ed9a8488ecabfb1b46cac225c5d48c39be3e28503f90f----- +OTFjZTI1YzZiMjU2ZDZjNzE1MzIwMDUwYjIzZGU2YmI1NmNlYjc5Mzc0M2YyYTcz +MDRiOWUyN2ZjMjhkNmUxYQ== +-----END PRIVATE KEY for 2a1c49643e564cdf28bba96dfd6cd8ad38a5958b2b3c9a8293ffb54e9df0a0188a67de2fb947b8ae3dd06b7411aaae0e8bedef795ad3b35ac9f1402dcd0631d9d530b01b3880362fbd3ed9a8488ecabfb1b46cac225c5d48c39be3e28503f90f----- +-----BEGIN PRIVATE KEY for 5c9784523f360a802d4687c9c76bcef41a738d034aa8503a055c33898504b09670c1f637ca632e5290b3acf79a2191072f68c4192a9cbeb34f50c4a941e34247a64f642a6a074bec683bdfb83587cfdc0390ebd74505cb836cf04f3268e32f99----- +ZWMzOTQ2YTBlYmY2MjY5YTQwNWRkOTI2ODcxNjEzODVkMTUxYmEzZjRiOThlYTBj +YzUyMzc1OThiYmVkOGIzZA== +-----END PRIVATE KEY for 5c9784523f360a802d4687c9c76bcef41a738d034aa8503a055c33898504b09670c1f637ca632e5290b3acf79a2191072f68c4192a9cbeb34f50c4a941e34247a64f642a6a074bec683bdfb83587cfdc0390ebd74505cb836cf04f3268e32f99----- +-----BEGIN PRIVATE KEY for db7f7726c3e68abb28d070f529f2c222755d863aa9d7c0200fde10c93ccb8edcee8d45c9eb925bd5a0fa33c54d19270b7058f6e72256dad84214375f189310a73153cd84feef4b493ab61437b0cbcc2c592e6c093653a533631c8e0ab036c207----- +ZjFiODNjZTc2Y2Q1NGQzOWViNWFhNDNlMzdiNTBjMWJiNjY3YzVlNWQwNzg5YTg5 +ZWJlMWQ2NWE1ZmExZmQ1Nw== +-----END PRIVATE KEY for db7f7726c3e68abb28d070f529f2c222755d863aa9d7c0200fde10c93ccb8edcee8d45c9eb925bd5a0fa33c54d19270b7058f6e72256dad84214375f189310a73153cd84feef4b493ab61437b0cbcc2c592e6c093653a533631c8e0ab036c207----- +-----BEGIN PRIVATE KEY for a27b6f47c53263e5c8d69779a169d50605cdd7ddb4b5384f2d46e08ace6f787a60f6cf26256b62fafba9c91a87ff070bc99254fcb5a73239fc14f2108de62189005b51b21e2922b37c6cc657017832e3a59dfcc7a54ac5dcb997136da4e2748b----- +Mjk1YWExMDkzOWMyZWI2OGUyM2EzZWFmYzE1YjE2NmRjZDllMDIyZTUwYjU4MWE2 +ODcxN2NmN2E1ZDEyMmIxOA== +-----END PRIVATE KEY for a27b6f47c53263e5c8d69779a169d50605cdd7ddb4b5384f2d46e08ace6f787a60f6cf26256b62fafba9c91a87ff070bc99254fcb5a73239fc14f2108de62189005b51b21e2922b37c6cc657017832e3a59dfcc7a54ac5dcb997136da4e2748b----- +-----BEGIN PRIVATE KEY for 125af943ccf7405f204a34fe82d8b35f487d3c69c536311f999328ccaa7d1570626ea17c3fc4a75bba336746942e52025ebad7caf46e56ebd916178d89828ef3eb427c8e6c0cafe4adf91620e3ba23bb25cf751fc18f34775295765371c22b11----- +ZjU0OGUwZTZjODc0NzVjMTk2MjY5M2QzNzg2ZWIyZDMyYmViZDkxZmYwOWYxZThj +NGNhZWM3M2E5N2IwODk0OQ== +-----END PRIVATE KEY for 125af943ccf7405f204a34fe82d8b35f487d3c69c536311f999328ccaa7d1570626ea17c3fc4a75bba336746942e52025ebad7caf46e56ebd916178d89828ef3eb427c8e6c0cafe4adf91620e3ba23bb25cf751fc18f34775295765371c22b11----- +-----BEGIN PRIVATE KEY for a07ff46694c1faa139166fccf535ca18f1dada26d7ee4879334e70d0f4cd948deba46617ebeabc2f5c5e021a3b16e5099ee3eed5e03a259b3609fcac5256bb064ac0718c277018c6b2ab73f079ac81baca252afd031954af2883c8b2a4063909----- +OWM0NGIwY2U0OTliMDgwZjE1ZTBkYzdhMjg2MTY1ZThlMDU5MWU0Yjc3OTM0YzFl +NmQwNWJhOGQyMjk2NjA1MA== +-----END PRIVATE KEY for a07ff46694c1faa139166fccf535ca18f1dada26d7ee4879334e70d0f4cd948deba46617ebeabc2f5c5e021a3b16e5099ee3eed5e03a259b3609fcac5256bb064ac0718c277018c6b2ab73f079ac81baca252afd031954af2883c8b2a4063909----- diff --git a/cmd/node/config/testKeys/unStakedKeys.pem b/cmd/node/config/testKeys/unStakedKeys.pem new file mode 100644 index 00000000000..96a3bf2d715 --- /dev/null +++ b/cmd/node/config/testKeys/unStakedKeys.pem @@ -0,0 +1,24 @@ +-----BEGIN PRIVATE KEY for 283ccdc58e0df19717ecd0c4c3a553059bf6c8d91b9c7b624afa8cb0564c7fd86e5a199973d17b7b939e63186b25f20a7234ad7f162c8f2547ba2e326c30a6c0571ea04cba83b35fd9a2a60f13e95ee1767b5fe87cbf378458ac7e27b4833f96----- +NGJjZmIzODdkYmJkN2Q3NzIxOWVmOWFkZGI3OTMyZmRlYzcwNjZiOTk3MmVkNjg3 +ZjkyYmIyMzg5MGFhOTMzMQ== +-----END PRIVATE KEY for 283ccdc58e0df19717ecd0c4c3a553059bf6c8d91b9c7b624afa8cb0564c7fd86e5a199973d17b7b939e63186b25f20a7234ad7f162c8f2547ba2e326c30a6c0571ea04cba83b35fd9a2a60f13e95ee1767b5fe87cbf378458ac7e27b4833f96----- +-----BEGIN PRIVATE KEY for 7d1a1b4f36fcd8cea426005212022511bc25a414019e2b5c65947f00c28c8f1220ff1473c36efaa22a94d3e2b5258705ff6efb91902afb2c951c90502edf60072c3330ad9fd1b5c4b85226f10a474a0ddda9b61730946629b110b6eac70de70a----- +ZDE1ZDk1YzdhMGU1ZGY5MDRmNzQxODI2NDFiN2FlOGEwYmJkYzE5Y2RkOGNhMGZh +MzEyNDI3OTY2YjNkODE1YQ== +-----END PRIVATE KEY for 7d1a1b4f36fcd8cea426005212022511bc25a414019e2b5c65947f00c28c8f1220ff1473c36efaa22a94d3e2b5258705ff6efb91902afb2c951c90502edf60072c3330ad9fd1b5c4b85226f10a474a0ddda9b61730946629b110b6eac70de70a----- +-----BEGIN PRIVATE KEY for 03e79df244aef557cd6e3b9c7e8063575b6cce83bbff005a0abf96000d0a93652ef0071decdd3ce052aab0912e4d510566af6273d91f41b0d8505a8ca69cff449dc979ff0c3c9c319feab9f2d3a965a49c1bf0d899e85fb3851951a798b0ab03----- +NjIyMWJmYzY2ZmYwYzg1OWY5MTYxZDNkZjY3NGJmMWQ4ZjkwZjExZThmN2MyMWU3 +NzM5NDVmYTIzYTQ2YjUzYw== +-----END PRIVATE KEY for 03e79df244aef557cd6e3b9c7e8063575b6cce83bbff005a0abf96000d0a93652ef0071decdd3ce052aab0912e4d510566af6273d91f41b0d8505a8ca69cff449dc979ff0c3c9c319feab9f2d3a965a49c1bf0d899e85fb3851951a798b0ab03----- +-----BEGIN PRIVATE KEY for 06d0a320440091cc0f44979753c036744cd762d2bf7aa3b61b425397b74c27b581ec39d250818068eef095cb0a49be0c586526bcc9bd98ec3120b9633efd390d4d9a7b6ffcafae8bdbbcf2c98f0cb2cd75897c4d6701b9d77861bf7ab8be3f88----- +OTdkYTJmM2FkOWI1NzRmZTg2N2U1Y2YzMmEwMWYwNjEzOGE2OGM0NjUwNWQzNTI4 +NmJlM2Y4OTQzMDQ3YmIwMg== +-----END PRIVATE KEY for 06d0a320440091cc0f44979753c036744cd762d2bf7aa3b61b425397b74c27b581ec39d250818068eef095cb0a49be0c586526bcc9bd98ec3120b9633efd390d4d9a7b6ffcafae8bdbbcf2c98f0cb2cd75897c4d6701b9d77861bf7ab8be3f88----- +-----BEGIN PRIVATE KEY for 125af943ccf7405f204a34fe82d8b35f487d3c69c536311f999328ccaa7d1570626ea17c3fc4a75bba336746942e52025ebad7caf46e56ebd916178d89828ef3eb427c8e6c0cafe4adf91620e3ba23bb25cf751fc18f34775295765371c22b11----- +ZjU0OGUwZTZjODc0NzVjMTk2MjY5M2QzNzg2ZWIyZDMyYmViZDkxZmYwOWYxZThj +NGNhZWM3M2E5N2IwODk0OQ== +-----END PRIVATE KEY for 125af943ccf7405f204a34fe82d8b35f487d3c69c536311f999328ccaa7d1570626ea17c3fc4a75bba336746942e52025ebad7caf46e56ebd916178d89828ef3eb427c8e6c0cafe4adf91620e3ba23bb25cf751fc18f34775295765371c22b11----- +-----BEGIN PRIVATE KEY for a07ff46694c1faa139166fccf535ca18f1dada26d7ee4879334e70d0f4cd948deba46617ebeabc2f5c5e021a3b16e5099ee3eed5e03a259b3609fcac5256bb064ac0718c277018c6b2ab73f079ac81baca252afd031954af2883c8b2a4063909----- +OWM0NGIwY2U0OTliMDgwZjE1ZTBkYzdhMjg2MTY1ZThlMDU5MWU0Yjc3OTM0YzFl +NmQwNWJhOGQyMjk2NjA1MA== +-----END PRIVATE KEY for a07ff46694c1faa139166fccf535ca18f1dada26d7ee4879334e70d0f4cd948deba46617ebeabc2f5c5e021a3b16e5099ee3eed5e03a259b3609fcac5256bb064ac0718c277018c6b2ab73f079ac81baca252afd031954af2883c8b2a4063909----- diff --git a/cmd/node/config/testKeys/validatorKey.pem b/cmd/node/config/testKeys/validatorKey.pem new file mode 100644 index 00000000000..b6039543aa4 --- /dev/null +++ b/cmd/node/config/testKeys/validatorKey.pem @@ -0,0 +1,96 @@ +-----BEGIN PRIVATE KEY for d3e0427c22ff9cc80ef4156f976644cfa25c54e5a69ed199132053f8cbbfddd4eb15a2f732a3c9b392169c8b1d060e0b5ab0d88b4dd7b4010fa051a17ef81bdbace5e68025965b00bf48e14a9ec8d8e2a8bcc9e62f97ddac3268f6b805f7b80e----- +MTMyZTliNDcyOTFmY2M2MmM2NGIzMzRmZDQzNGFiMmRiNzRiZjY0YjQyZDRjYzFi +NGNlZGQxMGRmNzdjMTkzNg== +-----END PRIVATE KEY for d3e0427c22ff9cc80ef4156f976644cfa25c54e5a69ed199132053f8cbbfddd4eb15a2f732a3c9b392169c8b1d060e0b5ab0d88b4dd7b4010fa051a17ef81bdbace5e68025965b00bf48e14a9ec8d8e2a8bcc9e62f97ddac3268f6b805f7b80e----- +-----BEGIN PRIVATE KEY for b0b6349b3f693e08c433970d10efb2fe943eac4057a945146bee5fd163687f4e1800d541aa0f11bf9e4cb6552f512e126068e68eb471d18fcc477ddfe0b9b3334f34e30d8b7b2c08f914f4ae54454f75fb28922ba9fd28785bcadc627031fa8a----- +NDkwYTU1YWI0MGNiZWE3Nzk4ZjdhNzQzYmNkM2RhNDQyNzZiZWM2YWQwODM3NTlh +NDUxNjY0NjE4NjI1NzQ2Ng== +-----END PRIVATE KEY for b0b6349b3f693e08c433970d10efb2fe943eac4057a945146bee5fd163687f4e1800d541aa0f11bf9e4cb6552f512e126068e68eb471d18fcc477ddfe0b9b3334f34e30d8b7b2c08f914f4ae54454f75fb28922ba9fd28785bcadc627031fa8a----- +-----BEGIN PRIVATE KEY for 67c301358a41bef74df2ae6aa9914e3a5e7a4b528bbd19596cca4b2fd97a62ab2c0a88b02adf1c5973a82c7544cdc40539ae62a9ac05351cfc59c300bbf4492f4266c550987355c39cff8e84ff74e012c7fd372c240eeb916ef87eead82ffd98----- +NTkwNzQzOTJmNGY5NzBjM2I1ZDRiYTE3ODM5NTVmY2Y5ZmNjNDRkOWE1YWZmMmI1 +Y2RkYjAwMjBjYTE1NWI1Yw== +-----END PRIVATE KEY for 67c301358a41bef74df2ae6aa9914e3a5e7a4b528bbd19596cca4b2fd97a62ab2c0a88b02adf1c5973a82c7544cdc40539ae62a9ac05351cfc59c300bbf4492f4266c550987355c39cff8e84ff74e012c7fd372c240eeb916ef87eead82ffd98----- +-----BEGIN PRIVATE KEY for ab0a22ba2be6560af8520208393381760f9d4f69fca4f152b0a3fe7b124dd7f932fd8c1fbb372792c235baafac36030ceaf6ebf215de4e8d8d239f347f2fed10a75a07cbf9dc56efbbfca2e319152a363df122c300cdeb2faa02a61ebefd8a0e----- +YTYwOTFmYjUxNzY0NTE5NjM5NmQwNGFhYjM2NzllNGYwNTlkYjlkODVjOTgxNjI1 +YzE5OTlkYWRhOTg1Y2Q1ZQ== +-----END PRIVATE KEY for ab0a22ba2be6560af8520208393381760f9d4f69fca4f152b0a3fe7b124dd7f932fd8c1fbb372792c235baafac36030ceaf6ebf215de4e8d8d239f347f2fed10a75a07cbf9dc56efbbfca2e319152a363df122c300cdeb2faa02a61ebefd8a0e----- +-----BEGIN PRIVATE KEY for caa87d67e195b52355d2c8f7f74c829395b134bd4a911f158e04b2d7e66a5ba195265743f10cf190105512fb3df9d708a8056c07a6165874d8749742502c0eada7d15b6c55f22c2cce2cf5001288f6b2d89319e6ff888344c01adcd362be8998----- +NDM2NDEwYTEwMmVmZDFjOWJjNjA2ZmRmM2FlNWI3ZDlkZTM3NjVkZDkxYTg0YjA1 +OTY4NjJjNTg3OTcwZjU3MQ== +-----END PRIVATE KEY for caa87d67e195b52355d2c8f7f74c829395b134bd4a911f158e04b2d7e66a5ba195265743f10cf190105512fb3df9d708a8056c07a6165874d8749742502c0eada7d15b6c55f22c2cce2cf5001288f6b2d89319e6ff888344c01adcd362be8998----- +-----BEGIN PRIVATE KEY for 598be7548d6bb605bd19d83037bf58a7797a4e48b33011a60a5633cf6fe8d59906130777c46f50a50d3d0f958effb5147befd5d67cbec7c5daddeaade4dca5d8a54fe0394fde7b6455e4fc4db91f33f907d450b45fc2d4a9990f96d893093d91----- +MTRiMjkxYzY1MzA0NzE1NzY1ZTYzYjUzMTUzYzNmZmIyNzNlZTRlMWNjYzY1ZTc4 +MjdhMDNmYmViMWRjZmE2NQ== +-----END PRIVATE KEY for 598be7548d6bb605bd19d83037bf58a7797a4e48b33011a60a5633cf6fe8d59906130777c46f50a50d3d0f958effb5147befd5d67cbec7c5daddeaade4dca5d8a54fe0394fde7b6455e4fc4db91f33f907d450b45fc2d4a9990f96d893093d91----- +-----BEGIN PRIVATE KEY for 69b277b127d025638dbb54d36baa8321540f6210fc5edaac77f94798c039a383aead3ae7c93cdfb8b4caab93a952d101ee2322c129b6ce2726359a65aa326bd35e54c974118503944fcaf80be80b5c3fc9cf86d574d0096140f16fbc55fc4984----- +Njc2ZDA3ZjBjNzQ5MWM4ZTYxOTg5NDdmN2Y1YThjMDcyMzAwZmM3NTlkYTkyOTQy +ODg5NjcyMDJhOTRiZWExNA== +-----END PRIVATE KEY for 69b277b127d025638dbb54d36baa8321540f6210fc5edaac77f94798c039a383aead3ae7c93cdfb8b4caab93a952d101ee2322c129b6ce2726359a65aa326bd35e54c974118503944fcaf80be80b5c3fc9cf86d574d0096140f16fbc55fc4984----- +-----BEGIN PRIVATE KEY for a006ad94b28c414c6ec0a5effb84594f39ede4f82b60aa077e2065b89407c78dd6479ebceed7bd42ed2779c34b718f11651427e550948cb8be2e6cea03a128ac3c52e599ada6f34912b119f94de472af0397a68769f1b3f647e87090918e030b----- +YzBkNjM4NjczODAxYWY4MWY5NWNkZjgxYzVkMWNiMTQwYWZjMmYwMjJkOTU3YTk0 +OGQ3ZTI4YTVjZjViMzE0Nw== +-----END PRIVATE KEY for a006ad94b28c414c6ec0a5effb84594f39ede4f82b60aa077e2065b89407c78dd6479ebceed7bd42ed2779c34b718f11651427e550948cb8be2e6cea03a128ac3c52e599ada6f34912b119f94de472af0397a68769f1b3f647e87090918e030b----- +-----BEGIN PRIVATE KEY for 91874fdfa8dfb85faf4f404b21c95fbb5d154db5a6abe46bd7860de9e5ddb78b61b5c6ddcf86e5ec8a237e130ed0fc0e418fb97d6fce5f6642ba33f99eff694ec7fb2921b423899a9a5888914bd625636a9b1ea186566561cd35b79aaca20e88----- +OTBhN2Y0YjlkNTVmMzliZmMzYmQ3Y2RiZWE2NWYyNmEzYThiNTk1ZjEyNzg5Yjlm +OGJmYzg5MDlhZTZjZmEzYQ== +-----END PRIVATE KEY for 91874fdfa8dfb85faf4f404b21c95fbb5d154db5a6abe46bd7860de9e5ddb78b61b5c6ddcf86e5ec8a237e130ed0fc0e418fb97d6fce5f6642ba33f99eff694ec7fb2921b423899a9a5888914bd625636a9b1ea186566561cd35b79aaca20e88----- +-----BEGIN PRIVATE KEY for cc3e0c1021f8c4c092499547b064cffef19d07f0bf250e5265cea1e49b282a7f6efb4b415ad37db2ef6efa253475f511e74efc2f76c087c9798f72187986bb752f61d0ac220045f8e2d945343f3bbb8ef34a6025fb855dd7d953a81477ad2309----- +OTc2NDdhMzYwODMyMTliZDhhYjI4NTYxYWQxZTRjOTZmNDdmNmUxOTM1NTVjNGY4 +MTc2ZDEwM2I4Y2Q0YjkzZA== +-----END PRIVATE KEY for cc3e0c1021f8c4c092499547b064cffef19d07f0bf250e5265cea1e49b282a7f6efb4b415ad37db2ef6efa253475f511e74efc2f76c087c9798f72187986bb752f61d0ac220045f8e2d945343f3bbb8ef34a6025fb855dd7d953a81477ad2309----- +-----BEGIN PRIVATE KEY for c2885340a6ba4341d68f80ce419deadf374bc52e2749c278b5bce5f795e9a90a04ef4f07a0b47777feb1982749b57a174b4927338df9da99a417a2df3152a9ebaf3465bfc092058324edf6892313f24be4612eb5663bb59d67a831dda135aa8b----- +MWQxOGIyMGFiZWUyNDFjOWU0ODEwZDQxMjI2ZGU4NDk3Y2FhYzk3OTczYmVhYzBk +YzUyYjI2ODg3M2FlMjM2NA== +-----END PRIVATE KEY for c2885340a6ba4341d68f80ce419deadf374bc52e2749c278b5bce5f795e9a90a04ef4f07a0b47777feb1982749b57a174b4927338df9da99a417a2df3152a9ebaf3465bfc092058324edf6892313f24be4612eb5663bb59d67a831dda135aa8b----- +-----BEGIN PRIVATE KEY for cf8a2f97b7822acb16016a6debaaedea39959c9ac60b80e50f24734a0e0f6128ed1d216f5aed71866ca34bb30b6e8300e7995237744e766f6016ca28d4ebb2274326cb7af1a3c12d795cc127a4bf9aa9497d89ef0450c40f675afd1afa761012----- +ZWRkY2RmNzg3NGQ3Y2M2N2Q2Yjc1OTRlOTlkY2JjMWY0OTNiNGEzNjA4ZWM0NTdk +MjY0NDU1OTJiMmYwM2YwNA== +-----END PRIVATE KEY for cf8a2f97b7822acb16016a6debaaedea39959c9ac60b80e50f24734a0e0f6128ed1d216f5aed71866ca34bb30b6e8300e7995237744e766f6016ca28d4ebb2274326cb7af1a3c12d795cc127a4bf9aa9497d89ef0450c40f675afd1afa761012----- +-----BEGIN PRIVATE KEY for 95a81b70474d59c1292bc5742db1a7b9bf03cb516ede6fb5cb3489ee812de8cccfc648f3ff3cda26106396a38c1c1f183b722392397a752d949c5123888b7a8ec012fe518f6efc25015a620b1559e4609286b52921e06b79fd563a9b3b4c4e16----- +MDUwNzJiZGQ3NGIyNzdkZTMzOTZhOGNlODk1ZGNmNzhhZWMzNGViYjJmNGI0ZmFi +MjI4MzVlNjhjNjUwNzMzZQ== +-----END PRIVATE KEY for 95a81b70474d59c1292bc5742db1a7b9bf03cb516ede6fb5cb3489ee812de8cccfc648f3ff3cda26106396a38c1c1f183b722392397a752d949c5123888b7a8ec012fe518f6efc25015a620b1559e4609286b52921e06b79fd563a9b3b4c4e16----- +-----BEGIN PRIVATE KEY for 5909def579148f456e8490659b859f80f8ccd62b5adda411e1acdc615c2ec795a88632cf2ec210a56ba91973fd3f07160f559f82f7afaafee008679fefb1b0cd2f26f4324197e6239c000accd1c427138568a8a9e276690c154d3df71a1f970c----- +OWMzYWU5MGNmOWJkOWIzZDUyOWE2YjBkZjMxOGU4MWU3MzRkNzA4MjdhMjZlYzc4 +YTcyZTBjYzhmYWQ4YzQ0Yg== +-----END PRIVATE KEY for 5909def579148f456e8490659b859f80f8ccd62b5adda411e1acdc615c2ec795a88632cf2ec210a56ba91973fd3f07160f559f82f7afaafee008679fefb1b0cd2f26f4324197e6239c000accd1c427138568a8a9e276690c154d3df71a1f970c----- +-----BEGIN PRIVATE KEY for 58d6cfe7e8c3ec675da17e492c4ba97759fa15fc0f41bbe29d1d49d5f5ca7db142450ada15e1e4bf4657614e26cceb04ed5c0ca17207b0e24c4baf5f91afc092d43a02aaeae76218420817c85292f8de7d3a2b4f3c8615c2bb6a6d1c74267788----- +N2YxOWM0MTU0NGIyMzAxYjA1NzBiM2E5MjhlODIyOTQyNTBlN2JmZjg4NTE3OTll +MTRhNTk3NDZkNmFhYzQ0ZA== +-----END PRIVATE KEY for 58d6cfe7e8c3ec675da17e492c4ba97759fa15fc0f41bbe29d1d49d5f5ca7db142450ada15e1e4bf4657614e26cceb04ed5c0ca17207b0e24c4baf5f91afc092d43a02aaeae76218420817c85292f8de7d3a2b4f3c8615c2bb6a6d1c74267788----- +-----BEGIN PRIVATE KEY for eb79770be0ae70e1d6932832eab94117b0c1a2442b3fdb380b1ad5a809b6221a4905e02a628886c925d152c4e5006413fe69d1f11cf543f4802d4ce4e5eac2b18b78a79215c737e2e098b40802044bc6e946b712299286c34f6d33d8b681790d----- +OWM1Njc4NjEyMWFiMmQ2MTdhYTIwM2QxMzU1N2QwNThmM2FhNDhhOTMyNWVhNzhh +N2NlODVhOTFjZGY4ODAwNA== +-----END PRIVATE KEY for eb79770be0ae70e1d6932832eab94117b0c1a2442b3fdb380b1ad5a809b6221a4905e02a628886c925d152c4e5006413fe69d1f11cf543f4802d4ce4e5eac2b18b78a79215c737e2e098b40802044bc6e946b712299286c34f6d33d8b681790d----- +-----BEGIN PRIVATE KEY for bc03265a52610464f2f0431a69647be3106924f5bf67cf87cd889bf86d81739b3f0f37bad11ab93c5209dc4496f4130d69a9649596b97884b7e91e0b4d7c59169dd0729ac3e3bcd308efac56bc29d3cc249d8759580ab117943aa40df3baac05----- +ZmEyMmRkODcyMzExMzgzZmRlNmE3ZWFmYTk1ZGZhNWRhMWNmNTJjYTE3NTc1NTdi +Yzk5MjAyNDE2YzFkY2IwNw== +-----END PRIVATE KEY for bc03265a52610464f2f0431a69647be3106924f5bf67cf87cd889bf86d81739b3f0f37bad11ab93c5209dc4496f4130d69a9649596b97884b7e91e0b4d7c59169dd0729ac3e3bcd308efac56bc29d3cc249d8759580ab117943aa40df3baac05----- +-----BEGIN PRIVATE KEY for aa4be8f36c2880ee4d2ca79dbd7a53537e3965f255dfb5c75324fe29fcb6ce56148fbaea334268e413f0df95f580c40fb3484165b2852236e3a1aa68151ac3327d981cfae52d99f9a564bd3139cdd768661854dae78880d9320191cdb2989815----- +MmRmYmFkMzMyNGMyZWEwNzZlZDQyYWY1NjFkZDRiZDdmMTU4ZGRiODQxZTUzMzYy +ODI5YmZlOWI5YzljYmUzMg== +-----END PRIVATE KEY for aa4be8f36c2880ee4d2ca79dbd7a53537e3965f255dfb5c75324fe29fcb6ce56148fbaea334268e413f0df95f580c40fb3484165b2852236e3a1aa68151ac3327d981cfae52d99f9a564bd3139cdd768661854dae78880d9320191cdb2989815----- +-----BEGIN PRIVATE KEY for 3e86fea8365791b3becfc9aa2bc239f6be58725e61e46e7935c56479ad285e0781da1f277980d2e1d0ecff3982f2d90f321aa03f3d934adf260628d0ed0dc81a98dfaf1e6278e042d6c78dc65f2fa79d3b457754a321b8a0d7bf9998feeea817----- +NTM4ZmFkYjlkZjRkMzJjZDcxMzU5MmZhN2Q1MWI2NmNjODg1MGQ0NmZjZDQ2YTIz +N2RmN2ExN2ZhODE5MjAxNQ== +-----END PRIVATE KEY for 3e86fea8365791b3becfc9aa2bc239f6be58725e61e46e7935c56479ad285e0781da1f277980d2e1d0ecff3982f2d90f321aa03f3d934adf260628d0ed0dc81a98dfaf1e6278e042d6c78dc65f2fa79d3b457754a321b8a0d7bf9998feeea817----- +-----BEGIN PRIVATE KEY for aa92cf6e0ac62df09e7adca139c41a162ad668e7a797770b6d195cd9b175d0fca9eac3f4bf859967139f2ba109741a144e3dc5e6ccaeb6cd21f1d202b10f08832274cd9cdf6b10dbc2c60acdd1c70ae9beae2139e2b69eccbcde32a7f3991393----- +ZjQ0ZDNmZDcyZTVmYjJmYmFiMTVkYjdlMmNjYTYzYzBjM2VjYWE0NjkwMjg0MTcz +OTQxZDIzM2FjMWEzZDQxMA== +-----END PRIVATE KEY for aa92cf6e0ac62df09e7adca139c41a162ad668e7a797770b6d195cd9b175d0fca9eac3f4bf859967139f2ba109741a144e3dc5e6ccaeb6cd21f1d202b10f08832274cd9cdf6b10dbc2c60acdd1c70ae9beae2139e2b69eccbcde32a7f3991393----- +-----BEGIN PRIVATE KEY for f2b7819d1c2e2e1d007edcf896034085645f3c81e7c7fe21aa7ad4f35f8b863ee1db13448d15a3d0d15018f741a991010a9374710b628e41ef078be8a10249f2a3000598432c28186af1c04a219ac914434dca9c27e61485d701505112093f8a----- +NTNiOGVmY2EwYmY0NmIzNjI1MzUzOGM1YjU2YjIzYTg4MDgxYWUwOThmZjk0Y2Yx +YjI2OGIwYmYzOTQ4ZmIwZA== +-----END PRIVATE KEY for f2b7819d1c2e2e1d007edcf896034085645f3c81e7c7fe21aa7ad4f35f8b863ee1db13448d15a3d0d15018f741a991010a9374710b628e41ef078be8a10249f2a3000598432c28186af1c04a219ac914434dca9c27e61485d701505112093f8a----- +-----BEGIN PRIVATE KEY for 292742eee9d12dade21b4cd8bcd44c210c26d927ef6dbd9cad59008643a971a86ea6dfce247515d4266789b3fe8e35167278e781e52b4cd7b9781554ba67ecc08680eb19628e7741c94d8456090a08aceab1c8d2ed39bf59e8e282381aa32a0a----- +NjFjZmE3YmYyNTZhNTIzY2FjM2ZiY2I4NzQ5ZDVmZWNhNzc1OWU1YmZlMGM2OWY5 +YmRkNTU0MGU4MmMwYTQwOA== +-----END PRIVATE KEY for 292742eee9d12dade21b4cd8bcd44c210c26d927ef6dbd9cad59008643a971a86ea6dfce247515d4266789b3fe8e35167278e781e52b4cd7b9781554ba67ecc08680eb19628e7741c94d8456090a08aceab1c8d2ed39bf59e8e282381aa32a0a----- +-----BEGIN PRIVATE KEY for 11f784d2970d65769ce267710b3d08b28b78c3f79283758918c8ef15717ccbe90c23348cafe0e98a5d101b8dafbe7d081c6821dee8bf40ba150664ccc2dbbdd6358c92404e677d82910ce61f1d7584fbbbc9ebf71b7f35a118556e2a5c220501----- +MjU2ZGI2MmU3ZTBmMzkzMjlhYmM1YzE1NWM2NmE0YTdhNmRhOTY2MTVmMDgxOTMz +NTYwMzU0YjllNWQ3YjYyYw== +-----END PRIVATE KEY for 11f784d2970d65769ce267710b3d08b28b78c3f79283758918c8ef15717ccbe90c23348cafe0e98a5d101b8dafbe7d081c6821dee8bf40ba150664ccc2dbbdd6358c92404e677d82910ce61f1d7584fbbbc9ebf71b7f35a118556e2a5c220501----- +-----BEGIN PRIVATE KEY for 0382c11222db8a15e42e3ff64893df46c7720b439fb2a546462815ac0a8fa3bed99fceae5da9b68524e36f61cc074d09ceafec274c54f182c56a77583f9421f19c777265c43da1d5747304b36f0367cf3e8e5f63f41dad1a4362d9e1997a9e16----- +ZTUxOWQwNzcwZWRlZDhhNTFiMzIwN2M4MWRmMDhjMWZlMWZhMTQ1ZjFmYWQwNDU3 +YzI4NzRiNWQzYmY3Y2MwMw== +-----END PRIVATE KEY for 0382c11222db8a15e42e3ff64893df46c7720b439fb2a546462815ac0a8fa3bed99fceae5da9b68524e36f61cc074d09ceafec274c54f182c56a77583f9421f19c777265c43da1d5747304b36f0367cf3e8e5f63f41dad1a4362d9e1997a9e16----- \ No newline at end of file diff --git a/cmd/node/config/testKeys/walletKeys.pem b/cmd/node/config/testKeys/walletKeys.pem new file mode 100644 index 00000000000..a0fe3cb02f0 --- /dev/null +++ b/cmd/node/config/testKeys/walletKeys.pem @@ -0,0 +1,175 @@ +-----BEGIN PRIVATE KEY for erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7----- +ODgxZTRhNGQ1ZDZmMjg5MmNlZGYxN2QwZDExMjlhMWNlZDk3NDFjYzhiZTc3Njc1 +M2EyNTdlYmM2YWMyYmYzMzI4NTYyNmRiYzI2NDIzODg0YTQ5M2YxZjU5NTJjNjE0 +ZTkyYzVhYWYyYzMyOTY5MGRhMzE3YTliNDkxNTc3Mjc= +-----END PRIVATE KEY for erd19ptzdk7zvs3csjjf8u04j5kxzn5jck409sefdyx6x9afkjg4wunsfw7rj7----- +-----BEGIN PRIVATE KEY for erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk----- +MmIzNTVjMGRiYmY4MmVkNTljNDVmNzkzMDcwMTRhNmNiN2MzYmU5YzQzMDI1OWZl +ZjkwMzc4ODZmNTQ4ZjVlYzAwOGE4MGM0ZThhYWEyNzFjNWZlZjM4MTU1ODcwZjkx +YmEwN2E0ZmVjM2Q2YTlhYWUzODliNDljYTRmNDVjN2Y= +-----END PRIVATE KEY for erd1qz9gp38g4238r3077wq4tpc0jxaq0f87c0t2n2hr3x6fef85t3lshq2ejk----- +-----BEGIN PRIVATE KEY for erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35----- +NDU4MmViYThmNTI5MDc2MDhmZThhNThhY2NhM2Y4NzgwM2Q2MjZlMGVjNjczZDRm +M2FkM2ZmNjQzZWIyZGJmODU4NTVkNGQ2NGM2ZGZjMWYxNzY0ZTUyZmE4MGQ3OGJk +ZWFhMGQzMzEwZTJlMDFlNjM5OTEwOTMyZWMxNzc3NjM= +-----END PRIVATE KEY for erd1tp2af4jvdh7p79myu5h6srtchh42p5e3pchqre3ejyyn9mqhwa3shpgj35----- +-----BEGIN PRIVATE KEY for erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84----- +NTlhYTVlOThlNTQ1MTVjYTEwMDFkNDU2ODAyNGRjNWNmMjI4MGE4ODFhMzNkOTQ3 +ZjFmMTQ1ZWZjZDY2YjEwNWNhOTJiOTU2ZjJhYzdmNjZmMWMxODE0Y2RkYWQxMjll +Zjg4YjVjYmI5YjQzN2FjZDU4MzI3NjlkNzEyYzlkNmQ= +-----END PRIVATE KEY for erd1e2ftj4hj43lkduwps9xdmtgjnmugkh9mndph4n2cxfmf6ufvn4ks0zut84----- +-----BEGIN PRIVATE KEY for erd1dzjes5c6a8ru45clgla3q0k3ezm06svefjz7vzs8pjfnrqa8tcasl4j8hs----- +OGZlOTExYjJmNjRhODRkYzI0MmMyZjNhZmIwNGJmY2QyZDRkOWM1ZDdiYzhmMGI0 +Mjc3NzVmZjU0NjkxYTFjOTY4YTU5ODUzMWFlOWM3Y2FkMzFmNDdmYjEwM2VkMWM4 +YjZmZDQxOTk0Yzg1ZTYwYTA3MGM5MzMxODNhNzVlM2I= +-----END PRIVATE KEY for erd1dzjes5c6a8ru45clgla3q0k3ezm06svefjz7vzs8pjfnrqa8tcasl4j8hs----- +-----BEGIN PRIVATE KEY for erd14gg3v6j4505ucx7t2wtl98tgupmyp748aq92jefmp5ha6e3pccgq9clwe9----- +ZDUwMzA4N2U4NWEyN2UyMDk0NDllMGIyZWFlN2M0Y2ViZmIwZTY0M2Q0MDg1NDZm +YzlkNTJmODJhOTBlMjg2MmFhMTExNjZhNTVhM2U5Y2MxYmNiNTM5N2YyOWQ2OGUw +NzY0MGZhYTdlODBhYTk2NTNiMGQyZmRkNjYyMWM2MTA= +-----END PRIVATE KEY for erd14gg3v6j4505ucx7t2wtl98tgupmyp748aq92jefmp5ha6e3pccgq9clwe9----- +-----BEGIN PRIVATE KEY for erd1xdfc44mk4ut5cv6l3mq0py6h88cty9ykacskm8xv3tvrp893kmxqppcefg----- +M2I0Y2M3NTQwNzA4ZGEwMWViOGMxNmY0MDFjMzAxZGFjNDI4Mzc5NjllNzU1MTJh +MjExZTBjMDBmMDI5YTRiODMzNTM4YWQ3NzZhZjE3NGMzMzVmOGVjMGYwOTM1NzM5 +ZjBiMjE0OTZlZTIxNmQ5Y2NjOGFkODMwOWNiMWI2Y2M= +-----END PRIVATE KEY for erd1xdfc44mk4ut5cv6l3mq0py6h88cty9ykacskm8xv3tvrp893kmxqppcefg----- +-----BEGIN PRIVATE KEY for erd1997jfwzrum4rrk59ar5supcyge9rpa73xgv2p45h3unt880v399svt8c9g----- +OTk0Yzg3YWFmOGMyYTI2ZmM5Yzc5YWJiODgwNDVmZGZhMWY5OTM0MjA5MTM3NDE0 +MWQwMWM1N2JiOGY5ODE0NjI5N2QyNGI4NDNlNmVhMzFkYTg1ZThlOTBlMDcwNDQ2 +NGEzMGY3ZDEzMjE4YTBkNjk3OGYyNmIzOWRlYzg5NGI= +-----END PRIVATE KEY for erd1997jfwzrum4rrk59ar5supcyge9rpa73xgv2p45h3unt880v399svt8c9g----- +-----BEGIN PRIVATE KEY for erd1e9cg9ys8fh77n9eaxpg47sxaes4fe9g2nvy6a65qpxykcx8grg9sv45lss----- +MjdlOTZjZDBjNGI0NTQxYjRkYzFjNjY4YjhmZDM0MWZhYWQ2MGM3M2NjNTM4YzM4 +M2QxZTBmYmRkN2I1NTk5N2M5NzA4MjkyMDc0ZGZkZTk5NzNkMzA1MTVmNDBkZGNj +MmE5Yzk1MGE5YjA5YWVlYTgwMDk4OTZjMThlODFhMGI= +-----END PRIVATE KEY for erd1e9cg9ys8fh77n9eaxpg47sxaes4fe9g2nvy6a65qpxykcx8grg9sv45lss----- +-----BEGIN PRIVATE KEY for erd1xdrltsygywhmtxzsmrgjlsxsxrf4y2ayv0z50y666dgsp66trxwqzajk96----- +Y2E2MzIxOGYzZGRjZjI1ZTIwZDM2MmQ3OWNjYWRiZDdhOTQ5ZWJjMjliYmE4YjZi +M2YyNDQyMWYwODgxNDJmMTMzNDdmNWMwODgyM2FmYjU5ODUwZDhkMTJmYzBkMDMw +ZDM1MjJiYTQ2M2M1NDc5MzVhZDM1MTAwZWI0YjE5OWM= +-----END PRIVATE KEY for erd1xdrltsygywhmtxzsmrgjlsxsxrf4y2ayv0z50y666dgsp66trxwqzajk96--- +-----BEGIN PRIVATE KEY for erd1lytewufjflpwl6gtf0faazjr59nd2fhfwlk7ew72hkpgdkmunl8qfrpywg----- +ZDFlNWMwZTA2NThlZmVmMjY3NWQ3YTBhYzUzZTY4MTJkYTdlMmNhNjhmNTRiMDdm +ZTRiMjYxYWFmZjM4Yzc2YmY5MTc5NzcxMzI0ZmMyZWZlOTBiNGJkM2RlOGE0M2Ex +NjZkNTI2ZTk3N2VkZWNiYmNhYmQ4Mjg2ZGI3YzlmY2U= +-----END PRIVATE KEY for erd1lytewufjflpwl6gtf0faazjr59nd2fhfwlk7ew72hkpgdkmunl8qfrpywg----- +-----BEGIN PRIVATE KEY for erd1s8tqztm4u4gw23489lps97qxe8vck8eln3a424y9c6yujsc96nas0l968d----- +OWZhYzA1YjhmOGEzNDEyYjkxMGQ0NjIyNzgwZjc4OGE1YmJiNThhNTlkODA3NmQz +YjFjMTNmZjM2MzdlZGYyYjgxZDYwMTJmNzVlNTUwZTU0NmE3MmZjMzAyZjgwNmM5 +ZDk4YjFmM2Y5YzdiNTU1NDg1YzY4OWM5NDMwNWQ0ZmI= +-----END PRIVATE KEY for erd1s8tqztm4u4gw23489lps97qxe8vck8eln3a424y9c6yujsc96nas0l968d----- +-----BEGIN PRIVATE KEY for erd1p7p0f3n8dxtj08hsp9hccqg932pd4f94rq3adg6g55etx8g4z8tsmg5e0g----- +NTI2NDc5M2JiMTgxZWY0YTAyNTIyYTUzNzUzYmYzODQ2M2FkODcwMmNlOWQwZWNl +MTQ1N2ExMDU0NmYyNzRmMTBmODJmNGM2Njc2OTk3Mjc5ZWYwMDk2ZjhjMDEwNThh +ODJkYWE0YjUxODIzZDZhMzQ4YTUzMmIzMWQxNTExZDc= +-----END PRIVATE KEY for erd1p7p0f3n8dxtj08hsp9hccqg932pd4f94rq3adg6g55etx8g4z8tsmg5e0g----- +-----BEGIN PRIVATE KEY for erd1uyeel03ea837dphrx2ak77hdvlhjdcqdwgyg6k99gqn602ymsn7qptmedj----- +ZTljNjFlM2QwMzQ3Y2QyMTc5MDI1YTM5NmVjNDYxZWU1NGU4ZGE0NzNjYzQyMTg1 +ZWUxNTFkOGM4ZjNkZDUzOGUxMzM5ZmJlMzllOWUzZTY4NmUzMzJiYjZmN2FlZDY3 +ZWYyNmUwMGQ3MjA4OGQ1OGE1NDAyN2E3YTg5Yjg0ZmM= +-----END PRIVATE KEY for erd1uyeel03ea837dphrx2ak77hdvlhjdcqdwgyg6k99gqn602ymsn7qptmedj----- +-----BEGIN PRIVATE KEY for erd1ftyzkdhl7rl782mrzrdc2jck3egydp0ydzhcjm9gc8s2jym5egrqadl4h6----- +YzI3YzY5MTgzMGUwYzJhNzlhZmVjYjI3N2UxMGRhOWZlNzZmYjUwZTJkMWQyNDc2 +YzZjNTgzNzVlMTgwZDc5NzRhYzgyYjM2ZmZmMGZmZTNhYjYzMTBkYjg1NGIxNjhl +NTA0Njg1ZTQ2OGFmODk2Y2E4YzFlMGE5MTM3NGNhMDY= +-----END PRIVATE KEY for erd1ftyzkdhl7rl782mrzrdc2jck3egydp0ydzhcjm9gc8s2jym5egrqadl4h6----- +-----BEGIN PRIVATE KEY for erd1rsl2sj5g87ltfq0hvrmgm35mlg4lzfs29p4gzxh0lh4vj2e8ykuqh69lha----- +NDg0MDgzZTIxMTk1ZGM2YjNjNmQwNTgwNWVmMGE2ZDhiYjdiMDYwMGZmMjFmMzIw +MGYwMzVhMTQwYjg2YTg2ODFjM2VhODRhODgzZmJlYjQ4MWY3NjBmNjhkYzY5YmZh +MmJmMTI2MGEyODZhODExYWVmZmRlYWM5MmIyNzI1Yjg= +-----END PRIVATE KEY for erd1rsl2sj5g87ltfq0hvrmgm35mlg4lzfs29p4gzxh0lh4vj2e8ykuqh69lha----- +-----BEGIN PRIVATE KEY for erd19yrjty2l4ytl6d3jynp5mqfekq4uf2x93akz60w7l3cp6qzny3psnfyerw----- +OGI3MDg3ZTk3NjQ3MmU0YzFiMDhmY2ZlNzQ5OGIwNDg5NTljYjZmYTlkMGExNjNl +YzFiMzk0M2NjMTk2N2Q4ZTI5MDcyNTkxNWZhOTE3ZmQzNjMyMjRjMzRkODEzOWIw +MmJjNGE4YzU4ZjZjMmQzZGRlZmM3MDFkMDA1MzI0NDM= +-----END PRIVATE KEY for erd19yrjty2l4ytl6d3jynp5mqfekq4uf2x93akz60w7l3cp6qzny3psnfyerw----- +-----BEGIN PRIVATE KEY for erd148lq42zdzz34y0yr8avldsy7gw0rmuvj4lmstzug77v08z3q0ncszfk8w9----- +ZjVlNTgzODEyZDIzNjgyNDlmMjczOTc1NGIwYWQ0NGY0ZWI0OTMyZDViZWJmMTM0 +ZjMyYzYzNDM0NDkyOTBhOGE5ZmUwYWE4NGQxMGEzNTIzYzgzM2Y1OWY2YzA5ZTQz +OWUzZGYxOTJhZmY3MDU4Yjg4Zjc5OGYzOGEyMDdjZjE= +-----END PRIVATE KEY for erd148lq42zdzz34y0yr8avldsy7gw0rmuvj4lmstzug77v08z3q0ncszfk8w9----- +-----BEGIN PRIVATE KEY for erd1k2v4h3805gnxf78c22g7lfe4pgq2lmr4ezmkk2rqkej6yjd7g5ssu88fme----- +YTEwMTM5NjQ0NjRlMzZhMDgyNTVkZTQyMTYyYmRhMjZiODVmNzEwOTgwZTAzM2M3 +ZGE0NjNjOTdlN2YyMzJkOGIyOTk1YmM0ZWZhMjI2NjRmOGY4NTI5MWVmYTczNTBh +MDBhZmVjNzVjOGI3NmIyODYwYjY2NWEyNDliZTQ1MjE= +-----END PRIVATE KEY for erd1k2v4h3805gnxf78c22g7lfe4pgq2lmr4ezmkk2rqkej6yjd7g5ssu88fme----- +-----BEGIN PRIVATE KEY for erd1nzjyj2ykpway04pczl42fgrlza2f0eaf97fxgnuuw39vyee36xlqccc3qz----- +Y2VlOGU0M2I4N2Q3YTBhM2E3ZmE3Y2ZiY2RhMTA0YjRhNGQ5YWUyMGNlZWZiODY5 +ODkyZmNiNWYxZTdjOGQzNjk4YTQ0OTI4OTYwYmJhNDdkNDM4MTdlYWE0YTA3ZjE3 +NTQ5N2U3YTkyZjkyNjQ0ZjljNzQ0YWMyNjczMWQxYmU= +-----END PRIVATE KEY for erd1nzjyj2ykpway04pczl42fgrlza2f0eaf97fxgnuuw39vyee36xlqccc3qz----- +-----BEGIN PRIVATE KEY for erd1yp0nvml5c45us3qzreqxkjxaakxn744t3gdva9s8xndcakzawutstepmm5----- +ZDA2NTdmMmU2ZTZmNjlkNTlkZjM0Mjc5NDhiODk5ODY3NDQ3ZmI4MDlhOTE3Yjcx +NjExZDg2ZGQ5ZjA4ZmMwMjIwNWYzNjZmZjRjNTY5Yzg0NDAyMWU0MDZiNDhkZGVk +OGQzZjU2YWI4YTFhY2U5NjA3MzRkYjhlZDg1ZDc3MTc= +-----END PRIVATE KEY for erd1yp0nvml5c45us3qzreqxkjxaakxn744t3gdva9s8xndcakzawutstepmm5----- +-----BEGIN PRIVATE KEY for erd1qyg80tr4rd65ur3hedm9h4yv3fcwmm6vnyrypnm972nd80889hxqdfgwrc----- +MTg4ZDlhNzE3NzAzNjYyMzY2YjE2NTIzYzI0MTliN2ExZjQ2OTk5Yzk5MmI5Mzcw +MDkxYTcxOGUwOTcxYjFkYjAxMTA3N2FjNzUxYjc1NGUwZTM3Y2I3NjViZDQ4Yzhh +NzBlZGVmNGM5OTA2NDBjZjY1ZjJhNmQzYmNlNzJkY2M= +-----END PRIVATE KEY for erd1qyg80tr4rd65ur3hedm9h4yv3fcwmm6vnyrypnm972nd80889hxqdfgwrc----- +-----BEGIN PRIVATE KEY for erd14x6d48q59zjh5p909fyw7e46czftgdawyf734cnmgk5e63ghrvvsqp254t----- +MzdmMDI3OGU4NGU3NjJlNzAzMzA3ZmY2MWQ4OGJlNjg5NDQ4MWVlNGNmZDI5NmQ1 +NjJmMjFkMWQ5MWE4OTFlOWE5YjRkYTljMTQyOGE1N2EwNGFmMmE0OGVmNjZiYWMw +OTJiNDM3YWUyMjdkMWFlMjdiNDVhOTlkNDUxNzFiMTk= +-----END PRIVATE KEY for erd14x6d48q59zjh5p909fyw7e46czftgdawyf734cnmgk5e63ghrvvsqp254t----- +-----BEGIN PRIVATE KEY for erd1wyxylus33e476h5kta7e0caeqvgvcgrxh0az33e7szya6g7mh2ws0n27sa----- +NTMwNjAxNzU5OThiYTIxNmRmN2EyN2E1Mjg3ZWMxODA4NjNiMTRkNjE5ZmFiY2U4 +ODhlMGU0MzIwNjFjMWM2MjcxMGM0ZmYyMTE4ZTZiZWQ1ZTk2NWY3ZDk3ZTNiOTAz +MTBjYzIwNjZiYmZhMjhjNzNlODA4OWRkMjNkYmJhOWQ= +-----END PRIVATE KEY for erd1wyxylus33e476h5kta7e0caeqvgvcgrxh0az33e7szya6g7mh2ws0n27sa----- +-----BEGIN PRIVATE KEY for erd1v3ylw7t6vzjzs06xjf6ccmf576ud38g2ws45tjkjg48s38jefpzqlwms9w----- +OWZhNzRmNTE2MTFiNDA5ZGU2YTIyZTI3NDQ5OTI0YmM2NDM4Y2E4ZWFjYzI0MTJj +Yzc0MjcwYjMzOGNlYTY5ZTY0NDlmNzc5N2E2MGE0MjgzZjQ2OTI3NThjNmQzNGY2 +YjhkODlkMGE3NDJiNDVjYWQyNDU0ZjA4OWU1OTQ4NDQ= +-----END PRIVATE KEY for erd1v3ylw7t6vzjzs06xjf6ccmf576ud38g2ws45tjkjg48s38jefpzqlwms9w----- +-----BEGIN PRIVATE KEY for erd1twel4azu6uptw878y063p93mjr84y5m4kpsww2aeqj4pg5jeplgst04rhg----- +MDNhOGM3OWQwM2M2MzljODUyZmFhNDlmZGFhODMyNjFhNGJjYjI4MDdmYWU1MGI1 +OTUyMzJjOGQwNTdiZWJkNDViYjNmYWY0NWNkNzAyYjcxZmM3MjNmNTEwOTYzYjkw +Y2Y1MjUzNzViMDYwZTcyYmI5MDRhYTE0NTI1OTBmZDE= +-----END PRIVATE KEY for erd1twel4azu6uptw878y063p93mjr84y5m4kpsww2aeqj4pg5jeplgst04rhg----- +-----BEGIN PRIVATE KEY for erd1q2se75ucl9as9j7e48v00jrnj6hvtk5vqxa4a3ag5729vctsdkasm20cyc----- +YjhiYjRhOTFmOTEyNjAwZWViYmI5N2MzYzBlOGQ1NTc3YzQ4OGE2M2IwZDhhZmY5 +ZjI2NjNhNzcyOWI5ZjMyZjAyYTE5ZjUzOThmOTdiMDJjYmQ5YTlkOGY3Yzg3Mzk2 +YWVjNWRhOGMwMWJiNWVjN2E4YTc5NDU2NjE3MDZkYmI= +-----END PRIVATE KEY for erd1q2se75ucl9as9j7e48v00jrnj6hvtk5vqxa4a3ag5729vctsdkasm20cyc----- +-----BEGIN PRIVATE KEY for erd18cc6cm35xhv7kzwsm79l4ma6jpz3ee5l0yjxuc66kh6rcgtawtuq6lzp9f----- +YWZjMGYzNmIwNWY3NGIwOGYyOWViMzMwZjkwZmU1ZTFmNmI4OWFlZDBkYzBjNjlk +OGY1NjJmMTk2MzA2ZWJiZDNlMzFhYzZlMzQzNWQ5ZWIwOWQwZGY4YmZhZWZiYTkw +NDUxY2U2OWY3OTI0NmU2MzVhYjVmNDNjMjE3ZDcyZjg= +-----END PRIVATE KEY for erd18cc6cm35xhv7kzwsm79l4ma6jpz3ee5l0yjxuc66kh6rcgtawtuq6lzp9f----- +-----BEGIN PRIVATE KEY for erd1psux99h4jljyt3nkw8pruv3spw5r0unqe4wk8837mm9my88gl28qj6mml5----- +YWMwMTM4NjU1MDVhMzM5MTEwZDJhOGI4N2E5ZDc3YWVlYjJiYmVjNjkwZjEzOWI3 +YjUwMDNkZTQzYzBjZDM2YzBjMzg2Mjk2ZjU5N2U0NDVjNjc2NzFjMjNlMzIzMDBi +YTgzN2YyNjBjZDVkNjM5ZTNlZGVjYmIyMWNlOGZhOGU= +-----END PRIVATE KEY for erd1psux99h4jljyt3nkw8pruv3spw5r0unqe4wk8837mm9my88gl28qj6mml5----- +-----BEGIN PRIVATE KEY for erd1vgm89ngmv2ghzsyq8xjtt45crekkxnhsq30yxzlq86uc3ra3r57qa3mw2p----- +N2E4YTViOGMzYjI3OWRmODMwYTkwNDI2YjI4MzU0NjE2MWJjOWIzN2NlYmE3Zjcy +NzFkYjk3YmIxZDM3YjUzZDYyMzY3MmNkMWI2MjkxNzE0MDgwMzlhNGI1ZDY5ODFl +NmQ2MzRlZjAwNDVlNDMwYmUwM2ViOTg4OGZiMTFkM2M= +-----END PRIVATE KEY for erd1vgm89ngmv2ghzsyq8xjtt45crekkxnhsq30yxzlq86uc3ra3r57qa3mw2p----- +-----BEGIN PRIVATE KEY for erd1k767vmmn8vg8xvuny32ppwr4dxrlgmpykn0u7nm92evlag3wkukqdgsf5u----- +ODkxZjVhZTdhOGE0ZTdiMDAxNzBmZWM1NGFhN2FjZDgzNDVlZGJlYjc4M2UwZDUw +ZTEwNGUyZmZlY2U2MTMwYWI3YjVlNjZmNzMzYjEwNzMzMzkzMjQ1NDEwYjg3NTY5 +ODdmNDZjMjRiNGRmY2Y0ZjY1NTY1OWZlYTIyZWI3MmM= +-----END PRIVATE KEY for erd1k767vmmn8vg8xvuny32ppwr4dxrlgmpykn0u7nm92evlag3wkukqdgsf5u----- +-----BEGIN PRIVATE KEY for erd1hwe8lskmzsdpuy3f6hldamvn0zrhzldec8m4tt8hupq58d7gyrequy8wsp----- +NjE0ZDc2YWVjOGE1MmI3NWU2MDI5ZWM4YjcyZWU1MTY1Mzg1OGQ2MzM4MmM1MmZl +MDc2MzI3ZWYxYTg1ZDk3ZGJiYjI3ZmMyZGIxNDFhMWUxMjI5ZDVmZWRlZWQ5Mzc4 +ODc3MTdkYjljMWY3NTVhY2Y3ZTA0MTQzYjdjODIwZjI= +-----END PRIVATE KEY for erd1hwe8lskmzsdpuy3f6hldamvn0zrhzldec8m4tt8hupq58d7gyrequy8wsp----- +-----BEGIN PRIVATE KEY for erd125eyrjk99zadr04gm9z2p4nckmnegexs5nyk7ek85rut2665t75sql3w88----- +ZWQ2YTFjNzAyMGMzMDc3ZGU5MGIzMTEyY2Y3NTAyYTgwNWM1MmQ0MDdhNWMyMDRj +NmYyNmNhNDNiNWEzYWU4OTU1MzI0MWNhYzUyOGJhZDFiZWE4ZDk0NGEwZDY3OGI2 +ZTc5NDY0ZDBhNGM5NmY2NmM3YTBmOGI1NmI1NDVmYTk= +-----END PRIVATE KEY for erd125eyrjk99zadr04gm9z2p4nckmnegexs5nyk7ek85rut2665t75sql3w88----- +-----BEGIN PRIVATE KEY for erd17ndrqg38lqf2zjgeqvle90rsn9ejrd9upx8evkyvh8e0m5xlph5scv9l6n----- +YzU3YjdlZGZkZWE3Nzk2MWI0N2Y1YmFkYmYzMTc0M2MwMmRmNjMzOGIyMWExYjFk +M2E5NWQyYWE2NmZkMjgzNWY0ZGEzMDIyMjdmODEyYTE0OTE5MDMzZjkyYmM3MDk5 +NzMyMWI0YmMwOThmOTY1ODhjYjlmMmZkZDBkZjBkZTk= +-----END PRIVATE KEY for erd17ndrqg38lqf2zjgeqvle90rsn9ejrd9upx8evkyvh8e0m5xlph5scv9l6n----- +-----BEGIN PRIVATE KEY for erd1zed89c8226rs7f59zh2xea39qk9ym9tsmt4s0sg2uw7u9nvtzt3q8fdj2e----- +ZTE5MGYwNDU0NjA0ZTI4ZjI5NzVlN2U5YTY1M2VhYjM2ZTdlOWRiZGEzYzQ2NjVk +MTk2MmMxMGMwZTU3Mjg3NzE2NWE3MmUwZWE1Njg3MGYyNjg1MTVkNDZjZjYyNTA1 +OGE0ZDk1NzBkYWViMDdjMTBhZTNiZGMyY2Q4YjEyZTI= +-----END PRIVATE KEY for erd1zed89c8226rs7f59zh2xea39qk9ym9tsmt4s0sg2uw7u9nvtzt3q8fdj2e----- From 6814c6a517e2e6ff0db9eb11dce11f469727e997 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 15:53:52 +0200 Subject: [PATCH 695/958] FEAT: Add auction list displayer component and disable it on api --- epochStart/metachain/auctionListDisplayer.go | 53 +++++++++++++------ epochStart/metachain/auctionListSelector.go | 50 +++++++++-------- .../metachain/auctionListSelector_test.go | 27 ++++++---- epochStart/metachain/auctionListSorting.go | 10 ++-- epochStart/metachain/errors.go | 2 + epochStart/metachain/interface.go | 19 +++++++ epochStart/metachain/systemSCs_test.go | 32 ++++++----- factory/disabled/auctionListDisplayer.go | 39 ++++++++++++++ factory/processing/blockProcessorCreator.go | 10 ++++ integrationTests/testProcessorNode.go | 16 +++--- .../vm/staking/systemSCCreator.go | 17 +++--- 11 files changed, 198 insertions(+), 77 deletions(-) create mode 100644 epochStart/metachain/interface.go create mode 100644 factory/disabled/auctionListDisplayer.go diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index ed612ce16d9..7cb511a5d65 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/display" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/state" logger "github.com/multiversx/mx-chain-logger-go" ) @@ -16,21 +17,36 @@ import ( const maxPubKeyDisplayableLen = 20 const maxNumOfDecimalsToDisplay = 5 -func (als *auctionListSelector) displayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int) { +type auctionListDisplayer struct { + softAuctionConfig *auctionConfig +} + +func NewAuctionListDisplayer(auctionConfig config.SoftAuctionConfig, denomination int) (*auctionListDisplayer, error) { + softAuctionConfig, err := getAuctionConfig(auctionConfig, denomination) + if err != nil { + return nil, err + } + + return &auctionListDisplayer{ + softAuctionConfig: softAuctionConfig, + }, nil +} + +func (ald *auctionListDisplayer) DisplayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int) { if log.GetLevel() > logger.LogDebug { return } - if topUp.Cmp(als.softAuctionConfig.minTopUp) > 0 { - topUp = big.NewInt(0).Sub(topUp, als.softAuctionConfig.step) + if topUp.Cmp(ald.softAuctionConfig.minTopUp) > 0 { + topUp = big.NewInt(0).Sub(topUp, ald.softAuctionConfig.step) } iteratedValues := big.NewInt(0).Sub(topUp, startTopUp) - iterations := big.NewInt(0).Div(iteratedValues, als.softAuctionConfig.step).Int64() + iterations := big.NewInt(0).Div(iteratedValues, ald.softAuctionConfig.step).Int64() iterations++ log.Debug("auctionListSelector: found min required", - "topUp", getPrettyValue(topUp, als.softAuctionConfig.denominator), + "topUp", getPrettyValue(topUp, ald.softAuctionConfig.denominator), "after num of iterations", iterations, ) } @@ -77,7 +93,7 @@ func getPrettyValue(val *big.Int, denominator *big.Int) string { return first + "." + second } -func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerAuctionData) { +func (ald *auctionListDisplayer) DisplayOwnersData(ownersData map[string]*OwnerAuctionData) { if log.GetLevel() > logger.LogDebug { return } @@ -99,8 +115,8 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerAu strconv.Itoa(int(owner.numStakedNodes)), strconv.Itoa(int(owner.numActiveNodes)), strconv.Itoa(int(owner.numAuctionNodes)), - getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denominator), - getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denominator), + getPrettyValue(owner.totalTopUp, ald.softAuctionConfig.denominator), + getPrettyValue(owner.topUpPerNode, ald.softAuctionConfig.denominator), getShortDisplayableBlsKeys(owner.auctionList), } lines = append(lines, display.NewLineData(false, line)) @@ -109,7 +125,7 @@ func (als *auctionListSelector) displayOwnersData(ownersData map[string]*ownerAu displayTable(tableHeader, lines, "Initial nodes config in auction list") } -func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string]*ownerAuctionData) { +func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(ownersData map[string]*OwnerAuctionData) { if log.GetLevel() > logger.LogDebug { return } @@ -131,12 +147,12 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string line := []string{ hex.EncodeToString([]byte(ownerPubKey)), strconv.Itoa(int(owner.numStakedNodes)), - getPrettyValue(owner.topUpPerNode, als.softAuctionConfig.denominator), - getPrettyValue(owner.totalTopUp, als.softAuctionConfig.denominator), + getPrettyValue(owner.topUpPerNode, ald.softAuctionConfig.denominator), + getPrettyValue(owner.totalTopUp, ald.softAuctionConfig.denominator), strconv.Itoa(int(owner.numAuctionNodes)), strconv.Itoa(int(owner.numQualifiedAuctionNodes)), strconv.Itoa(int(owner.numActiveNodes)), - getPrettyValue(owner.qualifiedTopUpPerNode, als.softAuctionConfig.denominator), + getPrettyValue(owner.qualifiedTopUpPerNode, ald.softAuctionConfig.denominator), getShortDisplayableBlsKeys(owner.auctionList[:owner.numQualifiedAuctionNodes]), } lines = append(lines, display.NewLineData(false, line)) @@ -145,9 +161,9 @@ func (als *auctionListSelector) displayOwnersSelectedNodes(ownersData map[string displayTable(tableHeader, lines, "Selected nodes config from auction list") } -func (als *auctionListSelector) displayAuctionList( +func (ald *auctionListDisplayer) DisplayAuctionList( auctionList []state.ValidatorInfoHandler, - ownersData map[string]*ownerAuctionData, + ownersData map[string]*OwnerAuctionData, numOfSelectedNodes uint32, ) { if log.GetLevel() > logger.LogDebug { @@ -171,7 +187,7 @@ func (als *auctionListSelector) displayAuctionList( line := display.NewLineData(horizontalLine, []string{ hex.EncodeToString([]byte(owner)), hex.EncodeToString(pubKey), - getPrettyValue(qualifiedTopUp, als.softAuctionConfig.denominator), + getPrettyValue(qualifiedTopUp, ald.softAuctionConfig.denominator), }) lines = append(lines, line) } @@ -179,7 +195,7 @@ func (als *auctionListSelector) displayAuctionList( displayTable(tableHeader, lines, "Final selected nodes from auction list") } -func getBlsKeyOwnerMap(ownersData map[string]*ownerAuctionData) map[string]string { +func getBlsKeyOwnerMap(ownersData map[string]*OwnerAuctionData) map[string]string { ret := make(map[string]string) for ownerPubKey, owner := range ownersData { for _, blsKey := range owner.auctionList { @@ -200,3 +216,8 @@ func displayTable(tableHeader []string, lines []*display.LineData, message strin msg := fmt.Sprintf("%s\n%s", message, table) log.Debug(msg) } + +// IsInterfaceNil checks if the underlying pointer is nil +func (ald *auctionListDisplayer) IsInterfaceNil() bool { + return ald == nil +} diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index b2e39ab14dc..e1db5006e74 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -15,7 +15,7 @@ import ( "github.com/multiversx/mx-chain-go/state" ) -type ownerAuctionData struct { +type OwnerAuctionData struct { numStakedNodes int64 numActiveNodes int64 numAuctionNodes int64 @@ -35,10 +35,11 @@ type auctionConfig struct { } type auctionListSelector struct { - shardCoordinator sharding.Coordinator - stakingDataProvider epochStart.StakingDataProvider - nodesConfigProvider epochStart.MaxNodesChangeConfigProvider - softAuctionConfig *auctionConfig + shardCoordinator sharding.Coordinator + stakingDataProvider epochStart.StakingDataProvider + nodesConfigProvider epochStart.MaxNodesChangeConfigProvider + auctionListDisplayer AuctionListDisplayHandler + softAuctionConfig *auctionConfig } // AuctionListSelectorArgs is a struct placeholder for all arguments required to create an auctionListSelector @@ -46,6 +47,7 @@ type AuctionListSelectorArgs struct { ShardCoordinator sharding.Coordinator StakingDataProvider epochStart.StakingDataProvider MaxNodesChangeConfigProvider epochStart.MaxNodesChangeConfigProvider + AuctionListDisplayHandler AuctionListDisplayHandler SoftAuctionConfig config.SoftAuctionConfig Denomination int } @@ -71,10 +73,11 @@ func NewAuctionListSelector(args AuctionListSelectorArgs) (*auctionListSelector, ) return &auctionListSelector{ - shardCoordinator: args.ShardCoordinator, - stakingDataProvider: args.StakingDataProvider, - nodesConfigProvider: args.MaxNodesChangeConfigProvider, - softAuctionConfig: softAuctionConfig, + shardCoordinator: args.ShardCoordinator, + stakingDataProvider: args.StakingDataProvider, + nodesConfigProvider: args.MaxNodesChangeConfigProvider, + auctionListDisplayer: args.AuctionListDisplayHandler, + softAuctionConfig: softAuctionConfig, }, nil } @@ -168,6 +171,9 @@ func checkNilArgs(args AuctionListSelectorArgs) error { if check.IfNil(args.MaxNodesChangeConfigProvider) { return epochStart.ErrNilMaxNodesChangeConfigProvider } + if check.IfNil(args.AuctionListDisplayHandler) { + return errNilAuctionListDisplayHandler + } return nil } @@ -222,7 +228,7 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( fmt.Sprintf("available slots (%v - %v)", maxNumNodes, numOfValidatorsAfterShuffling), availableSlots, ) - als.displayOwnersData(ownersData) + als.auctionListDisplayer.DisplayOwnersData(ownersData) numOfAvailableNodeSlots := core.MinUint32(auctionListSize, availableSlots) sw := core.NewStopWatch() @@ -235,15 +241,15 @@ func (als *auctionListSelector) SelectNodesFromAuctionList( return als.sortAuctionList(ownersData, numOfAvailableNodeSlots, validatorsInfoMap, randomness) } -func (als *auctionListSelector) getAuctionData() (map[string]*ownerAuctionData, uint32) { - ownersData := make(map[string]*ownerAuctionData) +func (als *auctionListSelector) getAuctionData() (map[string]*OwnerAuctionData, uint32) { + ownersData := make(map[string]*OwnerAuctionData) numOfNodesInAuction := uint32(0) for owner, ownerData := range als.stakingDataProvider.GetOwnersData() { if ownerData.Qualified && len(ownerData.AuctionList) > 0 { numAuctionNodes := len(ownerData.AuctionList) - ownersData[owner] = &ownerAuctionData{ + ownersData[owner] = &OwnerAuctionData{ numActiveNodes: ownerData.NumActiveNodes, numAuctionNodes: int64(numAuctionNodes), numQualifiedAuctionNodes: int64(numAuctionNodes), @@ -274,7 +280,7 @@ func safeSub(a, b uint32) (uint32, error) { } func (als *auctionListSelector) sortAuctionList( - ownersData map[string]*ownerAuctionData, + ownersData map[string]*OwnerAuctionData, numOfAvailableNodeSlots uint32, validatorsInfoMap state.ShardValidatorsInfoMapHandler, randomness []byte, @@ -285,9 +291,9 @@ func (als *auctionListSelector) sortAuctionList( } func (als *auctionListSelector) calcSoftAuctionNodesConfig( - data map[string]*ownerAuctionData, + data map[string]*OwnerAuctionData, numAvailableSlots uint32, -) map[string]*ownerAuctionData { +) map[string]*OwnerAuctionData { ownersData := copyOwnersData(data) minTopUp, maxTopUp := als.getMinMaxPossibleTopUp(ownersData) log.Debug("auctionListSelector: calc min and max possible top up", @@ -312,11 +318,11 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( maxNumberOfIterationsReached = iterationNumber >= als.softAuctionConfig.maxNumberOfIterations } - als.displayMinRequiredTopUp(topUp, minTopUp) + als.auctionListDisplayer.DisplayMinRequiredTopUp(topUp, minTopUp) return previousConfig } -func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*ownerAuctionData) (*big.Int, *big.Int) { +func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*OwnerAuctionData) (*big.Int, *big.Int) { min := big.NewInt(0).SetBytes(als.softAuctionConfig.maxTopUp.Bytes()) max := big.NewInt(0).SetBytes(als.softAuctionConfig.minTopUp.Bytes()) @@ -339,10 +345,10 @@ func (als *auctionListSelector) getMinMaxPossibleTopUp(ownersData map[string]*ow return min, max } -func copyOwnersData(ownersData map[string]*ownerAuctionData) map[string]*ownerAuctionData { - ret := make(map[string]*ownerAuctionData) +func copyOwnersData(ownersData map[string]*OwnerAuctionData) map[string]*OwnerAuctionData { + ret := make(map[string]*OwnerAuctionData) for owner, data := range ownersData { - ret[owner] = &ownerAuctionData{ + ret[owner] = &OwnerAuctionData{ numActiveNodes: data.numActiveNodes, numAuctionNodes: data.numAuctionNodes, numQualifiedAuctionNodes: data.numQualifiedAuctionNodes, @@ -358,7 +364,7 @@ func copyOwnersData(ownersData map[string]*ownerAuctionData) map[string]*ownerAu return ret } -func calcNodesConfig(ownersData map[string]*ownerAuctionData, topUp *big.Int) int64 { +func calcNodesConfig(ownersData map[string]*OwnerAuctionData, topUp *big.Int) int64 { numNodesQualifyingForTopUp := int64(0) for ownerPubKey, owner := range ownersData { diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 46073ffd37a..56ef74706a0 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -34,13 +34,16 @@ func createAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeC argsStakingDataProvider := createStakingDataProviderArgs() stakingSCProvider, _ := NewStakingDataProvider(argsStakingDataProvider) - shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) + + softAuctionCfg := createSoftAuctionConfig() + auctionDisplayer, _ := NewAuctionListDisplayer(softAuctionCfg, 0) return AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, - SoftAuctionConfig: createSoftAuctionConfig(), + AuctionListDisplayHandler: auctionDisplayer, + SoftAuctionConfig: softAuctionCfg, } } @@ -53,11 +56,15 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha EpochField: stakingV4Step2EnableEpoch, }) argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider + + softAuctionCfg := createSoftAuctionConfig() + auctionDisplayer, _ := NewAuctionListDisplayer(softAuctionCfg, 0) return AuctionListSelectorArgs{ ShardCoordinator: argsSystemSC.ShardCoordinator, StakingDataProvider: argsSystemSC.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, - SoftAuctionConfig: createSoftAuctionConfig(), + AuctionListDisplayHandler: auctionDisplayer, + SoftAuctionConfig: softAuctionCfg, }, argsSystemSC } @@ -430,7 +437,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -478,7 +485,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" owner3 := "owner3" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -540,7 +547,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -584,7 +591,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -629,7 +636,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -695,7 +702,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfigEdgeCases(t *testing.T) { owner1TopUp, _ := big.NewInt(0).SetString("32000000000000000000000000", 10) // 31 mil eGLD owner1 := "owner1" owner2 := "owner2" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 0, numAuctionNodes: 1, @@ -760,7 +767,7 @@ func TestAuctionListSelector_calcSoftAuctionNodesConfig(t *testing.T) { owner2 := "owner2" owner3 := "owner3" owner4 := "owner4" - ownersData := map[string]*ownerAuctionData{ + ownersData := map[string]*OwnerAuctionData{ owner1: { numActiveNodes: 2, numAuctionNodes: 2, diff --git a/epochStart/metachain/auctionListSorting.go b/epochStart/metachain/auctionListSorting.go index d871558b063..4759ec65bcb 100644 --- a/epochStart/metachain/auctionListSorting.go +++ b/epochStart/metachain/auctionListSorting.go @@ -9,7 +9,7 @@ import ( ) func (als *auctionListSelector) selectNodes( - ownersData map[string]*ownerAuctionData, + ownersData map[string]*OwnerAuctionData, numAvailableSlots uint32, randomness []byte, ) []state.ValidatorInfoHandler { @@ -25,14 +25,14 @@ func (als *auctionListSelector) selectNodes( selectedFromAuction = append(selectedFromAuction, owner.auctionList[:owner.numQualifiedAuctionNodes]...) } - als.displayOwnersSelectedNodes(ownersData) + als.auctionListDisplayer.DisplayOwnersSelectedNodes(ownersData) sortValidators(selectedFromAuction, validatorTopUpMap, normRand) - als.displayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) + als.auctionListDisplayer.DisplayAuctionList(selectedFromAuction, ownersData, numAvailableSlots) return selectedFromAuction[:numAvailableSlots] } -func getPubKeyLen(ownersData map[string]*ownerAuctionData) int { +func getPubKeyLen(ownersData map[string]*OwnerAuctionData) int { for _, owner := range ownersData { return len(owner.auctionList[0].GetPublicKey()) } @@ -62,7 +62,7 @@ func sortListByPubKey(list []state.ValidatorInfoHandler) { }) } -func addQualifiedValidatorsTopUpInMap(owner *ownerAuctionData, validatorTopUpMap map[string]*big.Int) { +func addQualifiedValidatorsTopUpInMap(owner *OwnerAuctionData, validatorTopUpMap map[string]*big.Int) { for i := int64(0); i < owner.numQualifiedAuctionNodes; i++ { validatorPubKey := string(owner.auctionList[i].GetPublicKey()) validatorTopUpMap[validatorPubKey] = big.NewInt(0).SetBytes(owner.qualifiedTopUpPerNode.Bytes()) diff --git a/epochStart/metachain/errors.go b/epochStart/metachain/errors.go index 9a6d1375024..3232029907c 100644 --- a/epochStart/metachain/errors.go +++ b/epochStart/metachain/errors.go @@ -5,3 +5,5 @@ import "errors" var errNilValidatorsInfoMap = errors.New("received nil shard validators info map") var errCannotComputeDenominator = errors.New("cannot compute denominator value") + +var errNilAuctionListDisplayHandler = errors.New("nil auction list display handler provided") diff --git a/epochStart/metachain/interface.go b/epochStart/metachain/interface.go new file mode 100644 index 00000000000..2dd9ebb0baf --- /dev/null +++ b/epochStart/metachain/interface.go @@ -0,0 +1,19 @@ +package metachain + +import ( + "math/big" + + "github.com/multiversx/mx-chain-go/state" +) + +type AuctionListDisplayHandler interface { + DisplayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int) + DisplayOwnersData(ownersData map[string]*OwnerAuctionData) + DisplayOwnersSelectedNodes(ownersData map[string]*OwnerAuctionData) + DisplayAuctionList( + auctionList []state.ValidatorInfoHandler, + ownersData map[string]*OwnerAuctionData, + numOfSelectedNodes uint32, + ) + IsInterfaceNil() bool +} diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 6979a357baa..c53dfbefbf7 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -901,16 +901,19 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) nodesConfigProvider, _ := notifier.NewNodesConfigProvider(en, nil) + auctionCfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + } + ald, _ := NewAuctionListDisplayer(auctionCfg, 0) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - MaxNumberOfIterations: 100000, - }, + AuctionListDisplayHandler: ald, + SoftAuctionConfig: auctionCfg, } als, _ := NewAuctionListSelector(argsAuctionListSelector) @@ -1910,16 +1913,21 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) nodesConfigProvider, _ := notifier.NewNodesConfigProvider(args.EpochNotifier, []config.MaxNodesChangeConfig{{MaxNumNodes: 8}}) + + auctionCfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + } + ald, _ := NewAuctionListDisplayer(auctionCfg, 0) + argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: args.ShardCoordinator, StakingDataProvider: args.StakingDataProvider, MaxNodesChangeConfigProvider: nodesConfigProvider, - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - MaxNumberOfIterations: 100000, - }, + SoftAuctionConfig: auctionCfg, + AuctionListDisplayHandler: ald, } als, _ := NewAuctionListSelector(argsAuctionListSelector) args.AuctionListSelector = als diff --git a/factory/disabled/auctionListDisplayer.go b/factory/disabled/auctionListDisplayer.go new file mode 100644 index 00000000000..d9cac9fa73b --- /dev/null +++ b/factory/disabled/auctionListDisplayer.go @@ -0,0 +1,39 @@ +package disabled + +import ( + "math/big" + + "github.com/multiversx/mx-chain-go/epochStart/metachain" + "github.com/multiversx/mx-chain-go/state" +) + +type auctionListDisplayer struct { +} + +func NewDisabledAuctionListDisplayer() *auctionListDisplayer { + return &auctionListDisplayer{} +} + +func (ald *auctionListDisplayer) DisplayMinRequiredTopUp(_ *big.Int, _ *big.Int) { + +} + +func (ald *auctionListDisplayer) DisplayOwnersData(_ map[string]*metachain.OwnerAuctionData) { + +} + +func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(_ map[string]*metachain.OwnerAuctionData) { + +} + +func (ald *auctionListDisplayer) DisplayAuctionList( + _ []state.ValidatorInfoHandler, + _ map[string]*metachain.OwnerAuctionData, + _ uint32, +) { +} + +// IsInterfaceNil checks if the underlying pointer is nil +func (ald *auctionListDisplayer) IsInterfaceNil() bool { + return ald == nil +} diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 38f5308bcdf..19a54e655ad 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -887,10 +887,19 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } + auctionListDisplayer, err := metachainEpochStart.NewAuctionListDisplayer( + pcf.systemSCConfig.SoftAuctionConfig, + pcf.economicsConfig.GlobalSettings.Denomination, + ) + if err != nil { + return nil, err + } + argsAuctionListSelector := metachainEpochStart.AuctionListSelectorArgs{ ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + AuctionListDisplayHandler: auctionListDisplayer, SoftAuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, Denomination: pcf.economicsConfig.GlobalSettings.Denomination, } @@ -905,6 +914,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, SoftAuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, Denomination: pcf.economicsConfig.GlobalSettings.Denomination, + AuctionListDisplayHandler: factoryDisabled.NewDisabledAuctionListDisplayer(), } auctionListSelectorAPI, err := metachainEpochStart.NewAuctionListSelector(argsAuctionListSelectorAPI) if err != nil { diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 33233498fdc..7c2988daf74 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2335,16 +2335,20 @@ func (tpn *TestProcessorNode) initBlockProcessor() { tpn.EpochNotifier, nil, ) + auctionCfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + } + ald, _ := metachain.NewAuctionListDisplayer(auctionCfg, 0) + argsAuctionListSelector := metachain.AuctionListSelectorArgs{ ShardCoordinator: tpn.ShardCoordinator, StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - MaxNumberOfIterations: 100000, - }, + AuctionListDisplayHandler: ald, + SoftAuctionConfig: auctionCfg, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 0fda20f4722..62d55482f3b 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -45,16 +45,21 @@ func createSystemSCProcessor( coreComponents.EpochNotifier(), maxNodesConfig, ) + + auctionCfg := config.SoftAuctionConfig{ + TopUpStep: "10", + MinTopUp: "1", + MaxTopUp: "32000000", + MaxNumberOfIterations: 100000, + } + ald, _ := metachain.NewAuctionListDisplayer(auctionCfg, 0) + argsAuctionListSelector := metachain.AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, StakingDataProvider: stakingDataProvider, MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, - SoftAuctionConfig: config.SoftAuctionConfig{ - TopUpStep: "10", - MinTopUp: "1", - MaxTopUp: "32000000", - MaxNumberOfIterations: 100000, - }, + AuctionListDisplayHandler: ald, + SoftAuctionConfig: auctionCfg, } auctionListSelector, _ := metachain.NewAuctionListSelector(argsAuctionListSelector) From 38057696d5263c1ef3b8b121f1ea6a99058c1a95 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 5 Feb 2024 15:54:27 +0200 Subject: [PATCH 696/958] - fixed p2p toml files --- cmd/node/config/fullArchiveP2P.toml | 6 +++--- cmd/node/config/p2p.toml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/node/config/fullArchiveP2P.toml b/cmd/node/config/fullArchiveP2P.toml index 0dd790a83f6..0a7ee26a73f 100644 --- a/cmd/node/config/fullArchiveP2P.toml +++ b/cmd/node/config/fullArchiveP2P.toml @@ -72,9 +72,9 @@ [Sharding] # The targeted number of peer connections TargetPeerCount = 36 - MaxIntraShardValidators = 7 - MaxCrossShardValidators = 15 - MaxIntraShardObservers = 2 + MaxIntraShardValidators = 6 + MaxCrossShardValidators = 13 + MaxIntraShardObservers = 5 MaxCrossShardObservers = 3 MaxSeeders = 2 diff --git a/cmd/node/config/p2p.toml b/cmd/node/config/p2p.toml index 62d30fd19f7..6e9931f9bc1 100644 --- a/cmd/node/config/p2p.toml +++ b/cmd/node/config/p2p.toml @@ -72,9 +72,9 @@ [Sharding] # The targeted number of peer connections TargetPeerCount = 36 - MaxIntraShardValidators = 7 - MaxCrossShardValidators = 15 - MaxIntraShardObservers = 2 + MaxIntraShardValidators = 6 + MaxCrossShardValidators = 13 + MaxIntraShardObservers = 5 MaxCrossShardObservers = 3 MaxSeeders = 2 From 4087dbf1232171ee62c66fe24815febe5b6e7df7 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 16:13:00 +0200 Subject: [PATCH 697/958] CLN: Auction list displayer --- epochStart/metachain/auctionListDisplayer.go | 103 ++++++++----------- epochStart/metachain/auctionListSelector.go | 5 +- epochStart/metachain/interface.go | 4 +- factory/disabled/auctionListDisplayer.go | 12 +-- 4 files changed, 53 insertions(+), 71 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 7cb511a5d65..091da141b27 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -21,6 +21,7 @@ type auctionListDisplayer struct { softAuctionConfig *auctionConfig } +// NewAuctionListDisplayer creates an auction list data displayer, useful for debugging purposes during selection process func NewAuctionListDisplayer(auctionConfig config.SoftAuctionConfig, denomination int) (*auctionListDisplayer, error) { softAuctionConfig, err := getAuctionConfig(auctionConfig, denomination) if err != nil { @@ -32,49 +33,37 @@ func NewAuctionListDisplayer(auctionConfig config.SoftAuctionConfig, denominatio }, nil } -func (ald *auctionListDisplayer) DisplayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int) { +// DisplayOwnersData will display initial owners data for auction selection +func (ald *auctionListDisplayer) DisplayOwnersData(ownersData map[string]*OwnerAuctionData) { if log.GetLevel() > logger.LogDebug { return } - if topUp.Cmp(ald.softAuctionConfig.minTopUp) > 0 { - topUp = big.NewInt(0).Sub(topUp, ald.softAuctionConfig.step) - } - - iteratedValues := big.NewInt(0).Sub(topUp, startTopUp) - iterations := big.NewInt(0).Div(iteratedValues, ald.softAuctionConfig.step).Int64() - iterations++ - - log.Debug("auctionListSelector: found min required", - "topUp", getPrettyValue(topUp, ald.softAuctionConfig.denominator), - "after num of iterations", iterations, - ) -} - -func getShortKey(pubKey []byte) string { - pubKeyHex := hex.EncodeToString(pubKey) - displayablePubKey := pubKeyHex - - pubKeyLen := len(displayablePubKey) - if pubKeyLen > maxPubKeyDisplayableLen { - displayablePubKey = pubKeyHex[:maxPubKeyDisplayableLen/2] + "..." + pubKeyHex[pubKeyLen-maxPubKeyDisplayableLen/2:] + tableHeader := []string{ + "Owner", + "Num staked nodes", + "Num active nodes", + "Num auction nodes", + "Total top up", + "Top up per node", + "Auction list nodes", } - return displayablePubKey -} - -func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { - pubKeys := "" - - for idx, validator := range list { - pubKeys += getShortKey(validator.GetPublicKey()) - addDelimiter := idx != len(list)-1 - if addDelimiter { - pubKeys += ", " + lines := make([]*display.LineData, 0, len(ownersData)) + for ownerPubKey, owner := range ownersData { + line := []string{ + hex.EncodeToString([]byte(ownerPubKey)), + strconv.Itoa(int(owner.numStakedNodes)), + strconv.Itoa(int(owner.numActiveNodes)), + strconv.Itoa(int(owner.numAuctionNodes)), + getPrettyValue(owner.totalTopUp, ald.softAuctionConfig.denominator), + getPrettyValue(owner.topUpPerNode, ald.softAuctionConfig.denominator), + getShortDisplayableBlsKeys(owner.auctionList), } + lines = append(lines, display.NewLineData(false, line)) } - return pubKeys + displayTable(tableHeader, lines, "Initial nodes config in auction list") } func getPrettyValue(val *big.Int, denominator *big.Int) string { @@ -93,38 +82,33 @@ func getPrettyValue(val *big.Int, denominator *big.Int) string { return first + "." + second } -func (ald *auctionListDisplayer) DisplayOwnersData(ownersData map[string]*OwnerAuctionData) { - if log.GetLevel() > logger.LogDebug { - return - } +func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { + pubKeys := "" - tableHeader := []string{ - "Owner", - "Num staked nodes", - "Num active nodes", - "Num auction nodes", - "Total top up", - "Top up per node", - "Auction list nodes", + for idx, validator := range list { + pubKeys += getShortKey(validator.GetPublicKey()) + addDelimiter := idx != len(list)-1 + if addDelimiter { + pubKeys += ", " + } } - lines := make([]*display.LineData, 0, len(ownersData)) - for ownerPubKey, owner := range ownersData { - line := []string{ - hex.EncodeToString([]byte(ownerPubKey)), - strconv.Itoa(int(owner.numStakedNodes)), - strconv.Itoa(int(owner.numActiveNodes)), - strconv.Itoa(int(owner.numAuctionNodes)), - getPrettyValue(owner.totalTopUp, ald.softAuctionConfig.denominator), - getPrettyValue(owner.topUpPerNode, ald.softAuctionConfig.denominator), - getShortDisplayableBlsKeys(owner.auctionList), - } - lines = append(lines, display.NewLineData(false, line)) + return pubKeys +} + +func getShortKey(pubKey []byte) string { + pubKeyHex := hex.EncodeToString(pubKey) + displayablePubKey := pubKeyHex + + pubKeyLen := len(displayablePubKey) + if pubKeyLen > maxPubKeyDisplayableLen { + displayablePubKey = pubKeyHex[:maxPubKeyDisplayableLen/2] + "..." + pubKeyHex[pubKeyLen-maxPubKeyDisplayableLen/2:] } - displayTable(tableHeader, lines, "Initial nodes config in auction list") + return displayablePubKey } +// DisplayOwnersSelectedNodes will display owners' selected nodes func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(ownersData map[string]*OwnerAuctionData) { if log.GetLevel() > logger.LogDebug { return @@ -161,6 +145,7 @@ func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(ownersData map[strin displayTable(tableHeader, lines, "Selected nodes config from auction list") } +// DisplayAuctionList will display the final selected auction nodes func (ald *auctionListDisplayer) DisplayAuctionList( auctionList []state.ValidatorInfoHandler, ownersData map[string]*OwnerAuctionData, diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index e1db5006e74..83df5e1f6b0 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -318,7 +318,10 @@ func (als *auctionListSelector) calcSoftAuctionNodesConfig( maxNumberOfIterationsReached = iterationNumber >= als.softAuctionConfig.maxNumberOfIterations } - als.auctionListDisplayer.DisplayMinRequiredTopUp(topUp, minTopUp) + log.Debug("auctionListSelector: found min required", + "topUp", getPrettyValue(topUp, als.softAuctionConfig.denominator), + "after num of iterations", iterationNumber, + ) return previousConfig } diff --git a/epochStart/metachain/interface.go b/epochStart/metachain/interface.go index 2dd9ebb0baf..b43720ea4e3 100644 --- a/epochStart/metachain/interface.go +++ b/epochStart/metachain/interface.go @@ -1,13 +1,11 @@ package metachain import ( - "math/big" - "github.com/multiversx/mx-chain-go/state" ) +// AuctionListDisplayHandler should be able to display auction list data during selection process type AuctionListDisplayHandler interface { - DisplayMinRequiredTopUp(topUp *big.Int, startTopUp *big.Int) DisplayOwnersData(ownersData map[string]*OwnerAuctionData) DisplayOwnersSelectedNodes(ownersData map[string]*OwnerAuctionData) DisplayAuctionList( diff --git a/factory/disabled/auctionListDisplayer.go b/factory/disabled/auctionListDisplayer.go index d9cac9fa73b..ec2d2f0774b 100644 --- a/factory/disabled/auctionListDisplayer.go +++ b/factory/disabled/auctionListDisplayer.go @@ -1,8 +1,6 @@ package disabled import ( - "math/big" - "github.com/multiversx/mx-chain-go/epochStart/metachain" "github.com/multiversx/mx-chain-go/state" ) @@ -10,22 +8,20 @@ import ( type auctionListDisplayer struct { } +// NewDisabledAuctionListDisplayer creates a disabled auction list displayer func NewDisabledAuctionListDisplayer() *auctionListDisplayer { return &auctionListDisplayer{} } -func (ald *auctionListDisplayer) DisplayMinRequiredTopUp(_ *big.Int, _ *big.Int) { - -} - +// DisplayOwnersData does nothing func (ald *auctionListDisplayer) DisplayOwnersData(_ map[string]*metachain.OwnerAuctionData) { - } +// DisplayOwnersSelectedNodes does nothing func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(_ map[string]*metachain.OwnerAuctionData) { - } +// DisplayAuctionList does nothing func (ald *auctionListDisplayer) DisplayAuctionList( _ []state.ValidatorInfoHandler, _ map[string]*metachain.OwnerAuctionData, From d7ead855daf09cb7bb2f55ed9bd5703f593fb1d0 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 17:43:02 +0200 Subject: [PATCH 698/958] FEAT: Auction list displayer unit tests --- .../metachain/auctionListDisplayer_test.go | 28 +++++++++++++++++++ .../metachain/auctionListSelector_test.go | 9 ++++++ 2 files changed, 37 insertions(+) diff --git a/epochStart/metachain/auctionListDisplayer_test.go b/epochStart/metachain/auctionListDisplayer_test.go index 34be106005e..0c3f5380bb1 100644 --- a/epochStart/metachain/auctionListDisplayer_test.go +++ b/epochStart/metachain/auctionListDisplayer_test.go @@ -8,7 +8,35 @@ import ( "github.com/stretchr/testify/require" ) +func TestNewAuctionListDisplayer(t *testing.T) { + t.Parallel() + + t.Run("invalid config", func(t *testing.T) { + cfg := createSoftAuctionConfig() + cfg.MaxNumberOfIterations = 0 + ald, err := NewAuctionListDisplayer(cfg, 0) + require.Nil(t, ald) + requireInvalidValueError(t, err, "for max number of iterations") + }) + + t.Run("should work", func(t *testing.T) { + cfg := createSoftAuctionConfig() + ald, err := NewAuctionListDisplayer(cfg, 0) + require.Nil(t, err) + require.False(t, ald.IsInterfaceNil()) + + require.NotPanics(t, func() { + ald.DisplayOwnersData(nil) + ald.DisplayOwnersSelectedNodes(nil) + ald.DisplayAuctionList(nil, nil, 0) + + }) + }) +} + func TestGetPrettyValue(t *testing.T) { + t.Parallel() + require.Equal(t, "1234.0", getPrettyValue(big.NewInt(1234), big.NewInt(1))) require.Equal(t, "123.4", getPrettyValue(big.NewInt(1234), big.NewInt(10))) require.Equal(t, "12.34", getPrettyValue(big.NewInt(1234), big.NewInt(100))) diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 56ef74706a0..acce7b66e04 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -105,6 +105,15 @@ func TestNewAuctionListSelector(t *testing.T) { require.Equal(t, epochStart.ErrNilMaxNodesChangeConfigProvider, err) }) + t.Run("nil auction list displayer", func(t *testing.T) { + t.Parallel() + args := createAuctionListSelectorArgs(nil) + args.AuctionListDisplayHandler = nil + als, err := NewAuctionListSelector(args) + require.Nil(t, als) + require.Equal(t, errNilAuctionListDisplayHandler, err) + }) + t.Run("invalid soft auction config", func(t *testing.T) { t.Parallel() args := createAuctionListSelectorArgs(nil) From 17cb759c57ff08fd72872d9d86419a9987ec9df8 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 5 Feb 2024 18:15:15 +0200 Subject: [PATCH 699/958] - skipped a few tests --- node/chainSimulator/chainSimulator_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 8eb7a48c21e..84798f97d09 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -25,6 +25,10 @@ const ( ) func TestNewChainSimulator(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ @@ -49,6 +53,10 @@ func TestNewChainSimulator(t *testing.T) { } func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ @@ -127,6 +135,10 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { } func TestChainSimulator_SetState(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ @@ -172,6 +184,10 @@ func TestChainSimulator_SetState(t *testing.T) { // 3. Do an unstake transaction (to make a place for the new validator) // 4. Check if the new validator has generated rewards func TestChainSimulator_AddValidatorKey(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ From 8c43424c8aeb7c3e8c2c7a124a660db07e16a4db Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 19:29:24 +0200 Subject: [PATCH 700/958] FEAT: Inject table displayer in auction list displayer --- epochStart/metachain/auctionListDisplayer.go | 44 ++++++++++++------- .../metachain/auctionListDisplayer_test.go | 27 ++++++------ epochStart/metachain/auctionListSelector.go | 1 + .../metachain/auctionListSelector_test.go | 10 ++++- epochStart/metachain/errors.go | 2 + epochStart/metachain/interface.go | 7 +++ epochStart/metachain/systemSCs_test.go | 10 ++++- epochStart/metachain/tableDisplayer.go | 32 ++++++++++++++ factory/processing/blockProcessorCreator.go | 10 +++-- integrationTests/testProcessorNode.go | 5 ++- .../vm/staking/systemSCCreator.go | 5 ++- 11 files changed, 113 insertions(+), 40 deletions(-) create mode 100644 epochStart/metachain/tableDisplayer.go diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 091da141b27..38f1ac6c2c3 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -2,12 +2,12 @@ package metachain import ( "encoding/hex" - "fmt" "math/big" "strconv" "strings" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/display" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/state" @@ -19,11 +19,24 @@ const maxNumOfDecimalsToDisplay = 5 type auctionListDisplayer struct { softAuctionConfig *auctionConfig + tableDisplayer tableDisplayer +} + +// ArgsAuctionListDisplayer is a struct placeholder for arguments needed to create an auction list displayer +type ArgsAuctionListDisplayer struct { + TableDisplayHandler TableDisplayHandler + AuctionConfig config.SoftAuctionConfig + Denomination int } // NewAuctionListDisplayer creates an auction list data displayer, useful for debugging purposes during selection process -func NewAuctionListDisplayer(auctionConfig config.SoftAuctionConfig, denomination int) (*auctionListDisplayer, error) { - softAuctionConfig, err := getAuctionConfig(auctionConfig, denomination) +func NewAuctionListDisplayer(args ArgsAuctionListDisplayer) (*auctionListDisplayer, error) { + softAuctionConfig, err := getAuctionConfig(args.AuctionConfig, args.Denomination) + if err != nil { + return nil, err + } + + err = checkDisplayerNilArgs(args) if err != nil { return nil, err } @@ -33,6 +46,14 @@ func NewAuctionListDisplayer(auctionConfig config.SoftAuctionConfig, denominatio }, nil } +func checkDisplayerNilArgs(args ArgsAuctionListDisplayer) error { + if check.IfNil(args.TableDisplayHandler) { + return errNilTableDisplayHandler + } + + return nil +} + // DisplayOwnersData will display initial owners data for auction selection func (ald *auctionListDisplayer) DisplayOwnersData(ownersData map[string]*OwnerAuctionData) { if log.GetLevel() > logger.LogDebug { @@ -63,7 +84,7 @@ func (ald *auctionListDisplayer) DisplayOwnersData(ownersData map[string]*OwnerA lines = append(lines, display.NewLineData(false, line)) } - displayTable(tableHeader, lines, "Initial nodes config in auction list") + ald.tableDisplayer.DisplayTable(tableHeader, lines, "Initial nodes config in auction list") } func getPrettyValue(val *big.Int, denominator *big.Int) string { @@ -142,7 +163,7 @@ func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(ownersData map[strin lines = append(lines, display.NewLineData(false, line)) } - displayTable(tableHeader, lines, "Selected nodes config from auction list") + ald.tableDisplayer.DisplayTable(tableHeader, lines, "Selected nodes config from auction list") } // DisplayAuctionList will display the final selected auction nodes @@ -177,7 +198,7 @@ func (ald *auctionListDisplayer) DisplayAuctionList( lines = append(lines, line) } - displayTable(tableHeader, lines, "Final selected nodes from auction list") + ald.tableDisplayer.DisplayTable(tableHeader, lines, "Final selected nodes from auction list") } func getBlsKeyOwnerMap(ownersData map[string]*OwnerAuctionData) map[string]string { @@ -191,17 +212,6 @@ func getBlsKeyOwnerMap(ownersData map[string]*OwnerAuctionData) map[string]strin return ret } -func displayTable(tableHeader []string, lines []*display.LineData, message string) { - table, err := display.CreateTableString(tableHeader, lines) - if err != nil { - log.Error("could not create table", "error", err) - return - } - - msg := fmt.Sprintf("%s\n%s", message, table) - log.Debug(msg) -} - // IsInterfaceNil checks if the underlying pointer is nil func (ald *auctionListDisplayer) IsInterfaceNil() bool { return ald == nil diff --git a/epochStart/metachain/auctionListDisplayer_test.go b/epochStart/metachain/auctionListDisplayer_test.go index 0c3f5380bb1..9a2e97a5878 100644 --- a/epochStart/metachain/auctionListDisplayer_test.go +++ b/epochStart/metachain/auctionListDisplayer_test.go @@ -8,29 +8,30 @@ import ( "github.com/stretchr/testify/require" ) +func createDisplayerArgs() ArgsAuctionListDisplayer { + return ArgsAuctionListDisplayer{ + TableDisplayHandler: NewTableDisplayer(), + AuctionConfig: createSoftAuctionConfig(), + Denomination: 0, + } +} + func TestNewAuctionListDisplayer(t *testing.T) { t.Parallel() - t.Run("invalid config", func(t *testing.T) { - cfg := createSoftAuctionConfig() - cfg.MaxNumberOfIterations = 0 - ald, err := NewAuctionListDisplayer(cfg, 0) + t.Run("invalid auction config", func(t *testing.T) { + cfg := createDisplayerArgs() + cfg.AuctionConfig.MaxNumberOfIterations = 0 + ald, err := NewAuctionListDisplayer(cfg) require.Nil(t, ald) requireInvalidValueError(t, err, "for max number of iterations") }) t.Run("should work", func(t *testing.T) { - cfg := createSoftAuctionConfig() - ald, err := NewAuctionListDisplayer(cfg, 0) + cfg := createDisplayerArgs() + ald, err := NewAuctionListDisplayer(cfg) require.Nil(t, err) require.False(t, ald.IsInterfaceNil()) - - require.NotPanics(t, func() { - ald.DisplayOwnersData(nil) - ald.DisplayOwnersSelectedNodes(nil) - ald.DisplayAuctionList(nil, nil, 0) - - }) }) } diff --git a/epochStart/metachain/auctionListSelector.go b/epochStart/metachain/auctionListSelector.go index 83df5e1f6b0..4b7c353a180 100644 --- a/epochStart/metachain/auctionListSelector.go +++ b/epochStart/metachain/auctionListSelector.go @@ -15,6 +15,7 @@ import ( "github.com/multiversx/mx-chain-go/state" ) +// OwnerAuctionData holds necessary auction data for an owner type OwnerAuctionData struct { numStakedNodes int64 numActiveNodes int64 diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index acce7b66e04..0caa62be704 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -37,7 +37,10 @@ func createAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeC shardCoordinator, _ := sharding.NewMultiShardCoordinator(3, core.MetachainShardId) softAuctionCfg := createSoftAuctionConfig() - auctionDisplayer, _ := NewAuctionListDisplayer(softAuctionCfg, 0) + auctionDisplayer, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ + TableDisplayHandler: NewTableDisplayer(), + AuctionConfig: softAuctionCfg, + }) return AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, @@ -58,7 +61,10 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha argsSystemSC.MaxNodesChangeConfigProvider = nodesConfigProvider softAuctionCfg := createSoftAuctionConfig() - auctionDisplayer, _ := NewAuctionListDisplayer(softAuctionCfg, 0) + auctionDisplayer, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ + TableDisplayHandler: NewTableDisplayer(), + AuctionConfig: softAuctionCfg, + }) return AuctionListSelectorArgs{ ShardCoordinator: argsSystemSC.ShardCoordinator, StakingDataProvider: argsSystemSC.StakingDataProvider, diff --git a/epochStart/metachain/errors.go b/epochStart/metachain/errors.go index 3232029907c..319bf83dafd 100644 --- a/epochStart/metachain/errors.go +++ b/epochStart/metachain/errors.go @@ -7,3 +7,5 @@ var errNilValidatorsInfoMap = errors.New("received nil shard validators info map var errCannotComputeDenominator = errors.New("cannot compute denominator value") var errNilAuctionListDisplayHandler = errors.New("nil auction list display handler provided") + +var errNilTableDisplayHandler = errors.New("nil table display handler provided") diff --git a/epochStart/metachain/interface.go b/epochStart/metachain/interface.go index b43720ea4e3..1e141fc079f 100644 --- a/epochStart/metachain/interface.go +++ b/epochStart/metachain/interface.go @@ -1,6 +1,7 @@ package metachain import ( + "github.com/multiversx/mx-chain-core-go/display" "github.com/multiversx/mx-chain-go/state" ) @@ -15,3 +16,9 @@ type AuctionListDisplayHandler interface { ) IsInterfaceNil() bool } + +// TableDisplayHandler should be able to display tables in log +type TableDisplayHandler interface { + DisplayTable(tableHeader []string, lines []*display.LineData, message string) + IsInterfaceNil() bool +} diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index c53dfbefbf7..f867e4f1b50 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -907,7 +907,10 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp MaxTopUp: "32000000", MaxNumberOfIterations: 100000, } - ald, _ := NewAuctionListDisplayer(auctionCfg, 0) + ald, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ + TableDisplayHandler: NewTableDisplayer(), + AuctionConfig: auctionCfg, + }) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, StakingDataProvider: stakingSCProvider, @@ -1920,7 +1923,10 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing MaxTopUp: "32000000", MaxNumberOfIterations: 100000, } - ald, _ := NewAuctionListDisplayer(auctionCfg, 0) + ald, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ + TableDisplayHandler: NewTableDisplayer(), + AuctionConfig: auctionCfg, + }) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: args.ShardCoordinator, diff --git a/epochStart/metachain/tableDisplayer.go b/epochStart/metachain/tableDisplayer.go new file mode 100644 index 00000000000..275805489dc --- /dev/null +++ b/epochStart/metachain/tableDisplayer.go @@ -0,0 +1,32 @@ +package metachain + +import ( + "fmt" + + "github.com/multiversx/mx-chain-core-go/display" +) + +type tableDisplayer struct { +} + +// NewTableDisplayer will create a component able to display tables in logger +func NewTableDisplayer() *tableDisplayer { + return &tableDisplayer{} +} + +// DisplayTable will display a table in the log +func (tb *tableDisplayer) DisplayTable(tableHeader []string, lines []*display.LineData, message string) { + table, err := display.CreateTableString(tableHeader, lines) + if err != nil { + log.Error("could not create table", "tableHeader", tableHeader, "error", err) + return + } + + msg := fmt.Sprintf("%s\n%s", message, table) + log.Debug(msg) +} + +// IsInterfaceNil checks if the underlying pointer is nil +func (tb *tableDisplayer) IsInterfaceNil() bool { + return tb == nil +} diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 19a54e655ad..d6e7d524fa3 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -887,10 +887,12 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } - auctionListDisplayer, err := metachainEpochStart.NewAuctionListDisplayer( - pcf.systemSCConfig.SoftAuctionConfig, - pcf.economicsConfig.GlobalSettings.Denomination, - ) + argsAuctionListDisplayer := metachainEpochStart.ArgsAuctionListDisplayer{ + TableDisplayHandler: metachainEpochStart.NewTableDisplayer(), + AuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, + Denomination: pcf.economicsConfig.GlobalSettings.Denomination, + } + auctionListDisplayer, err := metachainEpochStart.NewAuctionListDisplayer(argsAuctionListDisplayer) if err != nil { return nil, err } diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 7c2988daf74..69c19ff6af4 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2341,7 +2341,10 @@ func (tpn *TestProcessorNode) initBlockProcessor() { MaxTopUp: "32000000", MaxNumberOfIterations: 100000, } - ald, _ := metachain.NewAuctionListDisplayer(auctionCfg, 0) + ald, _ := metachain.NewAuctionListDisplayer(metachain.ArgsAuctionListDisplayer{ + TableDisplayHandler: metachain.NewTableDisplayer(), + AuctionConfig: auctionCfg, + }) argsAuctionListSelector := metachain.AuctionListSelectorArgs{ ShardCoordinator: tpn.ShardCoordinator, diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 62d55482f3b..361f190a405 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -52,7 +52,10 @@ func createSystemSCProcessor( MaxTopUp: "32000000", MaxNumberOfIterations: 100000, } - ald, _ := metachain.NewAuctionListDisplayer(auctionCfg, 0) + ald, _ := metachain.NewAuctionListDisplayer(metachain.ArgsAuctionListDisplayer{ + TableDisplayHandler: metachain.NewTableDisplayer(), + AuctionConfig: auctionCfg, + }) argsAuctionListSelector := metachain.AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, From 5c4337dc19fd584180eff94963ea55e9efb67d0e Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 19:43:17 +0200 Subject: [PATCH 701/958] FEAT: Inject address and validator pub key converter into auction displayer --- epochStart/metachain/auctionListDisplayer.go | 50 ++++++++++++------- .../metachain/auctionListDisplayer_test.go | 9 ++-- .../metachain/auctionListSelector_test.go | 12 +++-- epochStart/metachain/systemSCs_test.go | 14 ++++-- factory/processing/blockProcessorCreator.go | 8 +-- integrationTests/testProcessorNode.go | 6 ++- .../vm/staking/systemSCCreator.go | 6 ++- 7 files changed, 69 insertions(+), 36 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer.go b/epochStart/metachain/auctionListDisplayer.go index 38f1ac6c2c3..d64a156a51c 100644 --- a/epochStart/metachain/auctionListDisplayer.go +++ b/epochStart/metachain/auctionListDisplayer.go @@ -1,7 +1,6 @@ package metachain import ( - "encoding/hex" "math/big" "strconv" "strings" @@ -10,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/display" "github.com/multiversx/mx-chain-go/config" + errorsCommon "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/state" logger "github.com/multiversx/mx-chain-logger-go" ) @@ -18,15 +18,19 @@ const maxPubKeyDisplayableLen = 20 const maxNumOfDecimalsToDisplay = 5 type auctionListDisplayer struct { - softAuctionConfig *auctionConfig - tableDisplayer tableDisplayer + softAuctionConfig *auctionConfig + tableDisplayer TableDisplayHandler + validatorPubKeyConverter core.PubkeyConverter + addressPubKeyConverter core.PubkeyConverter } // ArgsAuctionListDisplayer is a struct placeholder for arguments needed to create an auction list displayer type ArgsAuctionListDisplayer struct { - TableDisplayHandler TableDisplayHandler - AuctionConfig config.SoftAuctionConfig - Denomination int + TableDisplayHandler TableDisplayHandler + ValidatorPubKeyConverter core.PubkeyConverter + AddressPubKeyConverter core.PubkeyConverter + AuctionConfig config.SoftAuctionConfig + Denomination int } // NewAuctionListDisplayer creates an auction list data displayer, useful for debugging purposes during selection process @@ -42,7 +46,10 @@ func NewAuctionListDisplayer(args ArgsAuctionListDisplayer) (*auctionListDisplay } return &auctionListDisplayer{ - softAuctionConfig: softAuctionConfig, + softAuctionConfig: softAuctionConfig, + tableDisplayer: args.TableDisplayHandler, + validatorPubKeyConverter: args.ValidatorPubKeyConverter, + addressPubKeyConverter: args.AddressPubKeyConverter, }, nil } @@ -50,6 +57,12 @@ func checkDisplayerNilArgs(args ArgsAuctionListDisplayer) error { if check.IfNil(args.TableDisplayHandler) { return errNilTableDisplayHandler } + if check.IfNil(args.ValidatorPubKeyConverter) { + return errorsCommon.ErrNilValidatorPublicKeyConverter + } + if check.IfNil(args.AddressPubKeyConverter) { + return errorsCommon.ErrNilAddressPublicKeyConverter + } return nil } @@ -73,13 +86,13 @@ func (ald *auctionListDisplayer) DisplayOwnersData(ownersData map[string]*OwnerA lines := make([]*display.LineData, 0, len(ownersData)) for ownerPubKey, owner := range ownersData { line := []string{ - hex.EncodeToString([]byte(ownerPubKey)), + ald.addressPubKeyConverter.SilentEncode([]byte(ownerPubKey), log), strconv.Itoa(int(owner.numStakedNodes)), strconv.Itoa(int(owner.numActiveNodes)), strconv.Itoa(int(owner.numAuctionNodes)), getPrettyValue(owner.totalTopUp, ald.softAuctionConfig.denominator), getPrettyValue(owner.topUpPerNode, ald.softAuctionConfig.denominator), - getShortDisplayableBlsKeys(owner.auctionList), + ald.getShortDisplayableBlsKeys(owner.auctionList), } lines = append(lines, display.NewLineData(false, line)) } @@ -103,11 +116,11 @@ func getPrettyValue(val *big.Int, denominator *big.Int) string { return first + "." + second } -func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { +func (ald *auctionListDisplayer) getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { pubKeys := "" for idx, validator := range list { - pubKeys += getShortKey(validator.GetPublicKey()) + pubKeys += ald.getShortKey(validator.GetPublicKey()) addDelimiter := idx != len(list)-1 if addDelimiter { pubKeys += ", " @@ -117,8 +130,8 @@ func getShortDisplayableBlsKeys(list []state.ValidatorInfoHandler) string { return pubKeys } -func getShortKey(pubKey []byte) string { - pubKeyHex := hex.EncodeToString(pubKey) +func (ald *auctionListDisplayer) getShortKey(pubKey []byte) string { + pubKeyHex := ald.validatorPubKeyConverter.SilentEncode(pubKey, log) displayablePubKey := pubKeyHex pubKeyLen := len(displayablePubKey) @@ -150,7 +163,7 @@ func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(ownersData map[strin lines := make([]*display.LineData, 0, len(ownersData)) for ownerPubKey, owner := range ownersData { line := []string{ - hex.EncodeToString([]byte(ownerPubKey)), + ald.addressPubKeyConverter.SilentEncode([]byte(ownerPubKey), log), strconv.Itoa(int(owner.numStakedNodes)), getPrettyValue(owner.topUpPerNode, ald.softAuctionConfig.denominator), getPrettyValue(owner.totalTopUp, ald.softAuctionConfig.denominator), @@ -158,7 +171,7 @@ func (ald *auctionListDisplayer) DisplayOwnersSelectedNodes(ownersData map[strin strconv.Itoa(int(owner.numQualifiedAuctionNodes)), strconv.Itoa(int(owner.numActiveNodes)), getPrettyValue(owner.qualifiedTopUpPerNode, ald.softAuctionConfig.denominator), - getShortDisplayableBlsKeys(owner.auctionList[:owner.numQualifiedAuctionNodes]), + ald.getShortDisplayableBlsKeys(owner.auctionList[:owner.numQualifiedAuctionNodes]), } lines = append(lines, display.NewLineData(false, line)) } @@ -181,18 +194,19 @@ func (ald *auctionListDisplayer) DisplayAuctionList( blsKeysOwnerMap := getBlsKeyOwnerMap(ownersData) for idx, validator := range auctionList { pubKey := validator.GetPublicKey() + pubKeyEncoded := ald.validatorPubKeyConverter.SilentEncode(pubKey, log) owner, found := blsKeysOwnerMap[string(pubKey)] if !found { log.Error("auctionListSelector.displayAuctionList could not find owner for", - "bls key", hex.EncodeToString(pubKey)) + "bls key", pubKeyEncoded) continue } qualifiedTopUp := ownersData[owner].qualifiedTopUpPerNode horizontalLine := uint32(idx) == numOfSelectedNodes-1 line := display.NewLineData(horizontalLine, []string{ - hex.EncodeToString([]byte(owner)), - hex.EncodeToString(pubKey), + ald.addressPubKeyConverter.SilentEncode([]byte(owner), log), + pubKeyEncoded, getPrettyValue(qualifiedTopUp, ald.softAuctionConfig.denominator), }) lines = append(lines, line) diff --git a/epochStart/metachain/auctionListDisplayer_test.go b/epochStart/metachain/auctionListDisplayer_test.go index 9a2e97a5878..d14482588d0 100644 --- a/epochStart/metachain/auctionListDisplayer_test.go +++ b/epochStart/metachain/auctionListDisplayer_test.go @@ -5,14 +5,17 @@ import ( "math/big" "testing" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/stretchr/testify/require" ) func createDisplayerArgs() ArgsAuctionListDisplayer { return ArgsAuctionListDisplayer{ - TableDisplayHandler: NewTableDisplayer(), - AuctionConfig: createSoftAuctionConfig(), - Denomination: 0, + TableDisplayHandler: NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: createSoftAuctionConfig(), + Denomination: 0, } } diff --git a/epochStart/metachain/auctionListSelector_test.go b/epochStart/metachain/auctionListSelector_test.go index 0caa62be704..25cced015fc 100644 --- a/epochStart/metachain/auctionListSelector_test.go +++ b/epochStart/metachain/auctionListSelector_test.go @@ -38,8 +38,10 @@ func createAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesChangeC softAuctionCfg := createSoftAuctionConfig() auctionDisplayer, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ - TableDisplayHandler: NewTableDisplayer(), - AuctionConfig: softAuctionCfg, + TableDisplayHandler: NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: softAuctionCfg, }) return AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, @@ -62,8 +64,10 @@ func createFullAuctionListSelectorArgs(maxNodesChangeConfig []config.MaxNodesCha softAuctionCfg := createSoftAuctionConfig() auctionDisplayer, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ - TableDisplayHandler: NewTableDisplayer(), - AuctionConfig: softAuctionCfg, + TableDisplayHandler: NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: softAuctionCfg, }) return AuctionListSelectorArgs{ ShardCoordinator: argsSystemSC.ShardCoordinator, diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index f867e4f1b50..87d5a2cd9f3 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -908,8 +908,11 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp MaxNumberOfIterations: 100000, } ald, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ - TableDisplayHandler: NewTableDisplayer(), - AuctionConfig: auctionCfg, + TableDisplayHandler: NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: auctionCfg, + Denomination: 0, }) argsAuctionListSelector := AuctionListSelectorArgs{ ShardCoordinator: shardCoordinator, @@ -1924,8 +1927,11 @@ func TestSystemSCProcessor_ProcessSystemSmartContractStakingV4Enabled(t *testing MaxNumberOfIterations: 100000, } ald, _ := NewAuctionListDisplayer(ArgsAuctionListDisplayer{ - TableDisplayHandler: NewTableDisplayer(), - AuctionConfig: auctionCfg, + TableDisplayHandler: NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: auctionCfg, + Denomination: 0, }) argsAuctionListSelector := AuctionListSelectorArgs{ diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index d6e7d524fa3..33201b74772 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -888,9 +888,11 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( } argsAuctionListDisplayer := metachainEpochStart.ArgsAuctionListDisplayer{ - TableDisplayHandler: metachainEpochStart.NewTableDisplayer(), - AuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, - Denomination: pcf.economicsConfig.GlobalSettings.Denomination, + TableDisplayHandler: metachainEpochStart.NewTableDisplayer(), + ValidatorPubKeyConverter: pcf.coreData.ValidatorPubKeyConverter(), + AddressPubKeyConverter: pcf.coreData.AddressPubKeyConverter(), + AuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, + Denomination: pcf.economicsConfig.GlobalSettings.Denomination, } auctionListDisplayer, err := metachainEpochStart.NewAuctionListDisplayer(argsAuctionListDisplayer) if err != nil { diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 69c19ff6af4..5f42185a6b2 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2342,8 +2342,10 @@ func (tpn *TestProcessorNode) initBlockProcessor() { MaxNumberOfIterations: 100000, } ald, _ := metachain.NewAuctionListDisplayer(metachain.ArgsAuctionListDisplayer{ - TableDisplayHandler: metachain.NewTableDisplayer(), - AuctionConfig: auctionCfg, + TableDisplayHandler: metachain.NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: auctionCfg, }) argsAuctionListSelector := metachain.AuctionListSelectorArgs{ diff --git a/integrationTests/vm/staking/systemSCCreator.go b/integrationTests/vm/staking/systemSCCreator.go index 361f190a405..cf18140797a 100644 --- a/integrationTests/vm/staking/systemSCCreator.go +++ b/integrationTests/vm/staking/systemSCCreator.go @@ -53,8 +53,10 @@ func createSystemSCProcessor( MaxNumberOfIterations: 100000, } ald, _ := metachain.NewAuctionListDisplayer(metachain.ArgsAuctionListDisplayer{ - TableDisplayHandler: metachain.NewTableDisplayer(), - AuctionConfig: auctionCfg, + TableDisplayHandler: metachain.NewTableDisplayer(), + ValidatorPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AddressPubKeyConverter: &testscommon.PubkeyConverterMock{}, + AuctionConfig: auctionCfg, }) argsAuctionListSelector := metachain.AuctionListSelectorArgs{ From ea4953c203156cfb69d0428a9e9b07192e6bee45 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 5 Feb 2024 20:03:57 +0200 Subject: [PATCH 702/958] FEAT: Unit test auction list displayer --- .../metachain/auctionListDisplayer_test.go | 211 +++++++++++++++++- testscommon/tableDisplayerMock.go | 19 ++ 2 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 testscommon/tableDisplayerMock.go diff --git a/epochStart/metachain/auctionListDisplayer_test.go b/epochStart/metachain/auctionListDisplayer_test.go index d14482588d0..467dfcc0aee 100644 --- a/epochStart/metachain/auctionListDisplayer_test.go +++ b/epochStart/metachain/auctionListDisplayer_test.go @@ -5,7 +5,11 @@ import ( "math/big" "testing" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/display" + "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" + logger "github.com/multiversx/mx-chain-logger-go" "github.com/stretchr/testify/require" ) @@ -23,21 +27,218 @@ func TestNewAuctionListDisplayer(t *testing.T) { t.Parallel() t.Run("invalid auction config", func(t *testing.T) { - cfg := createDisplayerArgs() - cfg.AuctionConfig.MaxNumberOfIterations = 0 - ald, err := NewAuctionListDisplayer(cfg) + args := createDisplayerArgs() + args.AuctionConfig.MaxNumberOfIterations = 0 + ald, err := NewAuctionListDisplayer(args) require.Nil(t, ald) requireInvalidValueError(t, err, "for max number of iterations") }) t.Run("should work", func(t *testing.T) { - cfg := createDisplayerArgs() - ald, err := NewAuctionListDisplayer(cfg) + args := createDisplayerArgs() + ald, err := NewAuctionListDisplayer(args) require.Nil(t, err) require.False(t, ald.IsInterfaceNil()) }) } +func TestAuctionListDisplayer_DisplayOwnersData(t *testing.T) { + t.Parallel() + + _ = logger.SetLogLevel("*:DEBUG") + defer func() { + _ = logger.SetLogLevel("*:INFO") + }() + + owner := []byte("owner") + validator := &state.ValidatorInfo{PublicKey: []byte("pubKey")} + wasDisplayCalled := false + + args := createDisplayerArgs() + args.AddressPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + require.Equal(t, owner, pkBytes) + return "ownerEncoded" + }, + } + args.ValidatorPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + require.Equal(t, validator.PublicKey, pkBytes) + return "pubKeyEncoded" + }, + } + args.TableDisplayHandler = &testscommon.TableDisplayerMock{ + DisplayTableCalled: func(tableHeader []string, lines []*display.LineData, message string) { + require.Equal(t, []string{ + "Owner", + "Num staked nodes", + "Num active nodes", + "Num auction nodes", + "Total top up", + "Top up per node", + "Auction list nodes", + }, tableHeader) + require.Equal(t, "Initial nodes config in auction list", message) + require.Equal(t, []*display.LineData{ + { + Values: []string{"ownerEncoded", "4", "4", "1", "100.0", "25.0", "pubKeyEncoded"}, + HorizontalRuleAfter: false, + }, + }, lines) + + wasDisplayCalled = true + }, + } + ald, _ := NewAuctionListDisplayer(args) + + ownersData := map[string]*OwnerAuctionData{ + "owner": { + numStakedNodes: 4, + numActiveNodes: 4, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 4, + totalTopUp: big.NewInt(100), + topUpPerNode: big.NewInt(25), + qualifiedTopUpPerNode: big.NewInt(15), + auctionList: []state.ValidatorInfoHandler{&state.ValidatorInfo{PublicKey: []byte("pubKey")}}, + }, + } + + ald.DisplayOwnersData(ownersData) + require.True(t, wasDisplayCalled) +} + +func TestAuctionListDisplayer_DisplayOwnersSelectedNodes(t *testing.T) { + t.Parallel() + + _ = logger.SetLogLevel("*:DEBUG") + defer func() { + _ = logger.SetLogLevel("*:INFO") + }() + + owner := []byte("owner") + validator := &state.ValidatorInfo{PublicKey: []byte("pubKey")} + wasDisplayCalled := false + + args := createDisplayerArgs() + args.AddressPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + require.Equal(t, owner, pkBytes) + return "ownerEncoded" + }, + } + args.ValidatorPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + require.Equal(t, validator.PublicKey, pkBytes) + return "pubKeyEncoded" + }, + } + args.TableDisplayHandler = &testscommon.TableDisplayerMock{ + DisplayTableCalled: func(tableHeader []string, lines []*display.LineData, message string) { + require.Equal(t, []string{ + "Owner", + "Num staked nodes", + "TopUp per node", + "Total top up", + "Num auction nodes", + "Num qualified auction nodes", + "Num active nodes", + "Qualified top up per node", + "Selected auction list nodes", + }, tableHeader) + require.Equal(t, "Selected nodes config from auction list", message) + require.Equal(t, []*display.LineData{ + { + Values: []string{"ownerEncoded", "4", "25.0", "100.0", "1", "1", "4", "15.0", "pubKeyEncoded"}, + HorizontalRuleAfter: false, + }, + }, lines) + + wasDisplayCalled = true + }, + } + ald, _ := NewAuctionListDisplayer(args) + + ownersData := map[string]*OwnerAuctionData{ + "owner": { + numStakedNodes: 4, + numActiveNodes: 4, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + totalTopUp: big.NewInt(100), + topUpPerNode: big.NewInt(25), + qualifiedTopUpPerNode: big.NewInt(15), + auctionList: []state.ValidatorInfoHandler{&state.ValidatorInfo{PublicKey: []byte("pubKey")}}, + }, + } + + ald.DisplayOwnersSelectedNodes(ownersData) + require.True(t, wasDisplayCalled) +} + +func TestAuctionListDisplayer_DisplayAuctionList(t *testing.T) { + t.Parallel() + + _ = logger.SetLogLevel("*:DEBUG") + defer func() { + _ = logger.SetLogLevel("*:INFO") + }() + + owner := []byte("owner") + validator := &state.ValidatorInfo{PublicKey: []byte("pubKey")} + wasDisplayCalled := false + + args := createDisplayerArgs() + args.AddressPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + require.Equal(t, owner, pkBytes) + return "ownerEncoded" + }, + } + args.ValidatorPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + require.Equal(t, validator.PublicKey, pkBytes) + return "pubKeyEncoded" + }, + } + args.TableDisplayHandler = &testscommon.TableDisplayerMock{ + DisplayTableCalled: func(tableHeader []string, lines []*display.LineData, message string) { + require.Equal(t, []string{ + "Owner", + "Registered key", + "Qualified TopUp per node", + }, tableHeader) + require.Equal(t, "Final selected nodes from auction list", message) + require.Equal(t, []*display.LineData{ + { + Values: []string{"ownerEncoded", "pubKeyEncoded", "15.0"}, + HorizontalRuleAfter: true, + }, + }, lines) + + wasDisplayCalled = true + }, + } + ald, _ := NewAuctionListDisplayer(args) + + auctionList := []state.ValidatorInfoHandler{&state.ValidatorInfo{PublicKey: []byte("pubKey")}} + ownersData := map[string]*OwnerAuctionData{ + "owner": { + numStakedNodes: 4, + numActiveNodes: 4, + numAuctionNodes: 1, + numQualifiedAuctionNodes: 1, + totalTopUp: big.NewInt(100), + topUpPerNode: big.NewInt(25), + qualifiedTopUpPerNode: big.NewInt(15), + auctionList: auctionList, + }, + } + + ald.DisplayAuctionList(auctionList, ownersData, 1) + require.True(t, wasDisplayCalled) +} + func TestGetPrettyValue(t *testing.T) { t.Parallel() diff --git a/testscommon/tableDisplayerMock.go b/testscommon/tableDisplayerMock.go new file mode 100644 index 00000000000..813c3e11fc5 --- /dev/null +++ b/testscommon/tableDisplayerMock.go @@ -0,0 +1,19 @@ +package testscommon + +import "github.com/multiversx/mx-chain-core-go/display" + +// TableDisplayerMock - +type TableDisplayerMock struct { + DisplayTableCalled func(tableHeader []string, lines []*display.LineData, message string) +} + +// DisplayTable - +func (mock *TableDisplayerMock) DisplayTable(tableHeader []string, lines []*display.LineData, message string) { + if mock.DisplayTableCalled != nil { + mock.DisplayTableCalled(tableHeader, lines, message) + } +} + +func (mock *TableDisplayerMock) IsInterfaceNil() bool { + return mock == nil +} From 9248d63e8ab112e2161914938ea690ea17d2be7c Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 5 Feb 2024 21:07:41 +0200 Subject: [PATCH 703/958] - fixed typo --- cmd/node/config/enableEpochs.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index a1ca0008fad..424dae563db 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -298,7 +298,7 @@ # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ - { EpochEnable = 0, MaxNumNodes = 48, NodesToShufflePerShard = 4 }, # 4 shuffled out keys / shard will not get reached normally + { EpochEnable = 0, MaxNumNodes = 48, NodesToShufflePerShard = 4 }, # 4 shuffled out keys / shard will not be reached normally { EpochEnable = 1, MaxNumNodes = 64, NodesToShufflePerShard = 2 } ] From 7e93488e47008d08865185a25d60f07c4a4d01ca Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 6 Feb 2024 09:17:17 +0200 Subject: [PATCH 704/958] refactoring and integration tests --- .../chainSimulator/helpers/helpers.go | 111 +++++++++ .../chainSimulator/helpers/interface.go | 11 + .../staking/stakeAndUnStake_test.go | 219 ++++++++++++++++++ node/chainSimulator/chainSimulator.go | 3 + node/chainSimulator/chainSimulator_test.go | 166 +------------ node/chainSimulator/configs/configs.go | 17 +- 6 files changed, 356 insertions(+), 171 deletions(-) create mode 100644 integrationTests/chainSimulator/helpers/helpers.go create mode 100644 integrationTests/chainSimulator/helpers/interface.go create mode 100644 integrationTests/chainSimulator/staking/stakeAndUnStake_test.go diff --git a/integrationTests/chainSimulator/helpers/helpers.go b/integrationTests/chainSimulator/helpers/helpers.go new file mode 100644 index 00000000000..07421e1dcaa --- /dev/null +++ b/integrationTests/chainSimulator/helpers/helpers.go @@ -0,0 +1,111 @@ +package helpers + +import ( + "encoding/base64" + "encoding/hex" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl" + logger "github.com/multiversx/mx-chain-logger-go" + "github.com/stretchr/testify/require" +) + +var log = logger.GetOrCreate("integrationTests/chainSimulator/helpers") + +func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) (string, error) { + txBytes, err := chainSimulator.GetNodeHandler(1).GetCoreComponents().InternalMarshalizer().Marshal(tx) + if err != nil { + return "", err + } + + txHasBytes := chainSimulator.GetNodeHandler(1).GetCoreComponents().Hasher().Compute(string(txBytes)) + return hex.EncodeToString(txHasBytes), nil +} + +// SendTxAndGenerateBlockTilTxIsExecuted will the provided transaction and generate block +func SendTxAndGenerateBlockTilTxIsExecuted( + t *testing.T, + chainSimulator ChainSimulator, + txToSend *transaction.Transaction, + maxNumOfBlockToGenerateWhenExecutingTx int, +) *transaction.ApiTransactionResult { + shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.SndAddr) + err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(txToSend) + require.Nil(t, err) + + txHash, err := computeTxHash(chainSimulator, txToSend) + require.Nil(t, err) + log.Info("############## send transaction ##############", "txHash", txHash) + + _, err = chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{txToSend}) + require.Nil(t, err) + + time.Sleep(100 * time.Millisecond) + + destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) + for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { + err = chainSimulator.GenerateBlocks(1) + require.Nil(t, err) + + tx, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) + if errGet == nil && tx.Status != transaction.TxStatusPending { + log.Info("############## transaction was executed ##############", "txHash", txHash) + return tx + } + } + + t.Error("something went wrong transaction is still in pending") + t.FailNow() + + return nil +} + +// AddValidatorKeysInMultiKey will add provided keys in the multi key handler +func AddValidatorKeysInMultiKey(t *testing.T, chainSimulator ChainSimulator, keysBase64 []string) [][]byte { + privateKeysHex := make([]string, 0, len(keysBase64)) + for _, keyBase64 := range keysBase64 { + privateKeyHex, err := base64.StdEncoding.DecodeString(keyBase64) + require.Nil(t, err) + + privateKeysHex = append(privateKeysHex, string(privateKeyHex)) + } + + privateKeysBytes := make([][]byte, 0, len(privateKeysHex)) + for _, keyHex := range privateKeysHex { + privateKeyBytes, err := hex.DecodeString(keyHex) + require.Nil(t, err) + + privateKeysBytes = append(privateKeysBytes, privateKeyBytes) + } + + err := chainSimulator.AddValidatorKeys(privateKeysBytes) + require.Nil(t, err) + + return privateKeysBytes +} + +// GenerateBlsPrivateKeys will generate bls keys +func GenerateBlsPrivateKeys(t *testing.T, numOfKeys int) ([][]byte, []string) { + blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) + + secretKeysBytes := make([][]byte, 0, numOfKeys) + blsKeysHex := make([]string, 0, numOfKeys) + for idx := 0; idx < numOfKeys; idx++ { + secretKey, publicKey := blockSigningGenerator.GeneratePair() + + secretKeyBytes, err := secretKey.ToByteArray() + require.Nil(t, err) + + secretKeysBytes = append(secretKeysBytes, secretKeyBytes) + + publicKeyBytes, err := publicKey.ToByteArray() + require.Nil(t, err) + + blsKeysHex = append(blsKeysHex, hex.EncodeToString(publicKeyBytes)) + } + + return secretKeysBytes, blsKeysHex +} diff --git a/integrationTests/chainSimulator/helpers/interface.go b/integrationTests/chainSimulator/helpers/interface.go new file mode 100644 index 00000000000..96d798e3261 --- /dev/null +++ b/integrationTests/chainSimulator/helpers/interface.go @@ -0,0 +1,11 @@ +package helpers + +import "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + +// ChainSimulator defines what a chain simulator should be able to do +type ChainSimulator interface { + GenerateBlocks(numOfBlocks int) error + GetNodeHandler(shardID uint32) process.NodeHandler + AddValidatorKeys(validatorsPrivateKeys [][]byte) error + IsInterfaceNil() bool +} diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go new file mode 100644 index 00000000000..35fcfcbb540 --- /dev/null +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -0,0 +1,219 @@ +package staking + +import ( + "encoding/hex" + "fmt" + "math/big" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + coreAPI "github.com/multiversx/mx-chain-core-go/data/api" + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator/helpers" + "github.com/multiversx/mx-chain-go/node/chainSimulator" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + logger "github.com/multiversx/mx-chain-logger-go" + "github.com/stretchr/testify/require" +) + +const ( + defaultPathToInitialConfig = "../../../cmd/node/config/" + maxNumOfBlockToGenerateWhenExecutingTx = 7 +) + +var log = logger.GetOrCreate("integrationTests/chainSimulator") + +// Test scenario +// 1. Add a new validator private key in the multi key handler +// 2. Do a stake transaction for the validator key +// 3. Do an unstake transaction (to make a place for the new validator) +// 4. Check if the new validator has generated rewards +func TestChainSimulator_AddValidatorKey(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + + cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + }) + require.Nil(t, err) + require.NotNil(t, cm) + + err = cm.GenerateBlocks(30) + require.Nil(t, err) + + // Step 1 --- add a new validator key in the chain simulator + privateKeyBase64 := "NjRhYjk3NmJjYWVjZTBjNWQ4YmJhNGU1NjZkY2VmYWFiYjcxNDI1Y2JiZDcwYzc1ODA2MGUxNTE5MGM2ZjE1Zg==" + helpers.AddValidatorKeysInMultiKey(t, cm, []string{privateKeyBase64}) + + newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" + newValidatorOwnerBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) + rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" + rcvAddrBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(rcv) + + // Step 2 --- set an initial balance for the address that will initialize all the transactions + err = cm.SetStateMultiple([]*dtos.AddressState{ + { + Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", + Balance: "10000000000000000000000", + }, + }) + require.Nil(t, err) + + blsKey := "9b7de1b2d2c90b7bea8f6855075c77d6c63b5dada29abb9b87c52cfae9d4112fcac13279e1a07d94672a5e62a83e3716555513014324d5c6bb4261b465f1b8549a7a338bc3ae8edc1e940958f9c2e296bd3c118a4466dec99dda0ceee3eb6a8c" + + // Step 3 --- generate and send a stake transaction with the BLS key of the validator key that was added at step 1 + stakeValue, _ := big.NewInt(0).SetString("2500000000000000000000", 10) + tx := &transaction.Transaction{ + Nonce: 0, + Value: stakeValue, + SndAddr: newValidatorOwnerBytes, + RcvAddr: rcvAddrBytes, + Data: []byte(fmt.Sprintf("stake@01@%s@010101", blsKey)), + GasLimit: 50_000_000, + GasPrice: 1000000000, + Signature: []byte("dummy"), + ChainID: []byte(configs.ChainID), + Version: 1, + } + _ = helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + + shardIDValidatorOwner := cm.GetNodeHandler(0).GetShardCoordinator().ComputeId(newValidatorOwnerBytes) + accountValidatorOwner, _, err := cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceBeforeActiveValidator := accountValidatorOwner.Balance + + // Step 5 --- create an unStake transaction with the bls key of an initial validator and execute the transaction to make place for the validator that was added at step 3 + firstValidatorKey, err := cm.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() + require.Nil(t, err) + + initialAddressWithValidators := cm.GetInitialWalletKeys().InitialWalletWithStake.Address + senderBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(initialAddressWithValidators) + shardID := cm.GetNodeHandler(0).GetShardCoordinator().ComputeId(senderBytes) + initialAccount, _, err := cm.GetNodeHandler(shardID).GetFacadeHandler().GetAccount(initialAddressWithValidators, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + tx = &transaction.Transaction{ + Nonce: initialAccount.Nonce, + Value: big.NewInt(0), + SndAddr: senderBytes, + RcvAddr: rcvAddrBytes, + Data: []byte(fmt.Sprintf("unStake@%s", hex.EncodeToString(firstValidatorKey))), + GasLimit: 50_000_000, + GasPrice: 1000000000, + Signature: []byte("dummy"), + ChainID: []byte(configs.ChainID), + Version: 1, + } + _ = helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + + // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards + err = cm.GenerateBlocks(50) + require.Nil(t, err) + + accountValidatorOwner, _, err = cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterActiveValidator := accountValidatorOwner.Balance + + log.Info("balance before validator", "value", balanceBeforeActiveValidator) + log.Info("balance after validator", "value", balanceAfterActiveValidator) + + balanceBeforeBig, _ := big.NewInt(0).SetString(balanceBeforeActiveValidator, 10) + balanceAfterBig, _ := big.NewInt(0).SetString(balanceAfterActiveValidator, 10) + diff := balanceAfterBig.Sub(balanceAfterBig, balanceBeforeBig) + log.Info("difference", "value", diff.String()) + + // Step 7 --- check the balance of the validator owner has been increased + require.True(t, diff.Cmp(big.NewInt(0)) > 0) +} + +func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + }) + require.Nil(t, err) + require.NotNil(t, cm) + + err = cm.GenerateBlocks(150) + require.Nil(t, err) + + // Step 1 --- add a new validator key in the chain simulator + numOfNodes := 10 + validatorSecretKeysBytes, blsKeys := helpers.GenerateBlsPrivateKeys(t, numOfNodes) + err = cm.AddValidatorKeys(validatorSecretKeysBytes) + require.Nil(t, err) + + newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" + newValidatorOwnerBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) + rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" + rcvAddrBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(rcv) + + // Step 2 --- set an initial balance for the address that will initialize all the transactions + err = cm.SetStateMultiple([]*dtos.AddressState{ + { + Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", + Balance: "100000000000000000000000", + }, + }) + require.Nil(t, err) + + // Step 3 --- generate and send a stake transaction with the BLS key of the validator key that was added at step 1 + validatorData := "" + for _, blsKey := range blsKeys { + validatorData += fmt.Sprintf("@%s@010101", blsKey) + } + + log.Warn("BLS KEYS", "keys", validatorData) + + numOfNodesHex := hex.EncodeToString(big.NewInt(int64(numOfNodes)).Bytes()) + stakeValue, _ := big.NewInt(0).SetString("25000000000000000000000", 10) + tx := &transaction.Transaction{ + Nonce: 0, + Value: stakeValue, + SndAddr: newValidatorOwnerBytes, + RcvAddr: rcvAddrBytes, + Data: []byte(fmt.Sprintf("stake@%s%s", numOfNodesHex, validatorData)), + GasLimit: 500_000_000, + GasPrice: 1000000000, + Signature: []byte("dummy"), + ChainID: []byte(configs.ChainID), + Version: 1, + } + + _ = logger.SetLogLevel("*:DEBUG") + + txFromNetwork := helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + require.NotNil(t, txFromNetwork) + + err = cm.GenerateBlocks(20) + require.Nil(t, err) +} diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index b3edda81eed..9a7d8011b3f 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" @@ -32,6 +33,7 @@ type ArgsChainSimulator struct { RoundDurationInMillis uint64 RoundsPerEpoch core.OptionalUint64 ApiInterface components.APIConfigurator + AlterConfigsFunction func(cfg *config.Configs) } type simulator struct { @@ -76,6 +78,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { MinNodesPerShard: args.MinNodesPerShard, MetaChainMinNodes: args.MetaChainMinNodes, RoundsPerEpoch: args.RoundsPerEpoch, + AlterConfigsFunction: args.AlterConfigsFunction, }) if err != nil { return err diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 8eb7a48c21e..c0048dc56c0 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -2,7 +2,6 @@ package chainSimulator import ( "encoding/base64" - "encoding/hex" "fmt" "math/big" "testing" @@ -10,9 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" coreAPI "github.com/multiversx/mx-chain-core-go/data/api" - "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" - "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/process" "github.com/stretchr/testify/assert" @@ -20,8 +17,7 @@ import ( ) const ( - defaultPathToInitialConfig = "../../cmd/node/config/" - maxNumOfBlockToGenerateWhenExecutingTx = 7 + defaultPathToInitialConfig = "../../cmd/node/config/" ) func TestNewChainSimulator(t *testing.T) { @@ -166,126 +162,6 @@ func TestChainSimulator_SetState(t *testing.T) { require.Equal(t, keyValueMap, keyValuePairs) } -// Test scenario -// 1. Add a new validator private key in the multi key handler -// 2. Do a stake transaction for the validator key -// 3. Do an unstake transaction (to make a place for the new validator) -// 4. Check if the new validator has generated rewards -func TestChainSimulator_AddValidatorKey(t *testing.T) { - startTime := time.Now().Unix() - roundDurationInMillis := uint64(6000) - roundsPerEpoch := core.OptionalUint64{ - HasValue: true, - Value: 20, - } - chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ - BypassTxSignatureCheck: false, - TempDir: t.TempDir(), - PathToInitialConfig: defaultPathToInitialConfig, - NumOfShards: 3, - GenesisTimestamp: startTime, - RoundDurationInMillis: roundDurationInMillis, - RoundsPerEpoch: roundsPerEpoch, - ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 3, - MetaChainMinNodes: 3, - }) - require.Nil(t, err) - require.NotNil(t, chainSimulator) - - err = chainSimulator.GenerateBlocks(30) - require.Nil(t, err) - - // Step 1 --- add a new validator key in the chain simulator - privateKeyBase64 := "NjRhYjk3NmJjYWVjZTBjNWQ4YmJhNGU1NjZkY2VmYWFiYjcxNDI1Y2JiZDcwYzc1ODA2MGUxNTE5MGM2ZjE1Zg==" - privateKeyHex, err := base64.StdEncoding.DecodeString(privateKeyBase64) - require.Nil(t, err) - privateKeyBytes, err := hex.DecodeString(string(privateKeyHex)) - require.Nil(t, err) - - err = chainSimulator.AddValidatorKeys([][]byte{privateKeyBytes}) - require.Nil(t, err) - - newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" - newValidatorOwnerBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) - rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" - rcvAddrBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(rcv) - - // Step 2 --- set an initial balance for the address that will initialize all the transactions - err = chainSimulator.SetStateMultiple([]*dtos.AddressState{ - { - Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", - Balance: "10000000000000000000000", - }, - }) - require.Nil(t, err) - - blsKey := "9b7de1b2d2c90b7bea8f6855075c77d6c63b5dada29abb9b87c52cfae9d4112fcac13279e1a07d94672a5e62a83e3716555513014324d5c6bb4261b465f1b8549a7a338bc3ae8edc1e940958f9c2e296bd3c118a4466dec99dda0ceee3eb6a8c" - - // Step 3 --- generate and send a stake transaction with the BLS key of the validator key that was added at step 1 - stakeValue, _ := big.NewInt(0).SetString("2500000000000000000000", 10) - tx := &transaction.Transaction{ - Nonce: 0, - Value: stakeValue, - SndAddr: newValidatorOwnerBytes, - RcvAddr: rcvAddrBytes, - Data: []byte(fmt.Sprintf("stake@01@%s@010101", blsKey)), - GasLimit: 50_000_000, - GasPrice: 1000000000, - Signature: []byte("dummy"), - ChainID: []byte(configs.ChainID), - Version: 1, - } - sendTxAndGenerateBlockTilTxIsExecuted(t, chainSimulator, tx) - - shardIDValidatorOwner := chainSimulator.nodes[0].GetShardCoordinator().ComputeId(newValidatorOwnerBytes) - accountValidatorOwner, _, err := chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) - require.Nil(t, err) - balanceBeforeActiveValidator := accountValidatorOwner.Balance - - // Step 5 --- create an unStake transaction with the bls key of an initial validator and execute the transaction to make place for the validator that was added at step 3 - firstValidatorKey, err := chainSimulator.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() - require.Nil(t, err) - - initialAddressWithValidators := chainSimulator.GetInitialWalletKeys().InitialWalletWithStake.Address - senderBytes, _ := chainSimulator.nodes[1].GetCoreComponents().AddressPubKeyConverter().Decode(initialAddressWithValidators) - shardID := chainSimulator.nodes[0].GetShardCoordinator().ComputeId(senderBytes) - initialAccount, _, err := chainSimulator.nodes[shardID].GetFacadeHandler().GetAccount(initialAddressWithValidators, coreAPI.AccountQueryOptions{}) - require.Nil(t, err) - tx = &transaction.Transaction{ - Nonce: initialAccount.Nonce, - Value: big.NewInt(0), - SndAddr: senderBytes, - RcvAddr: rcvAddrBytes, - Data: []byte(fmt.Sprintf("unStake@%s", hex.EncodeToString(firstValidatorKey))), - GasLimit: 50_000_000, - GasPrice: 1000000000, - Signature: []byte("dummy"), - ChainID: []byte(configs.ChainID), - Version: 1, - } - sendTxAndGenerateBlockTilTxIsExecuted(t, chainSimulator, tx) - - // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards - err = chainSimulator.GenerateBlocks(50) - require.Nil(t, err) - - accountValidatorOwner, _, err = chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) - require.Nil(t, err) - balanceAfterActiveValidator := accountValidatorOwner.Balance - - log.Info("balance before validator", "value", balanceBeforeActiveValidator) - log.Info("balance after validator", "value", balanceAfterActiveValidator) - - balanceBeforeBig, _ := big.NewInt(0).SetString(balanceBeforeActiveValidator, 10) - balanceAfterBig, _ := big.NewInt(0).SetString(balanceAfterActiveValidator, 10) - diff := balanceAfterBig.Sub(balanceAfterBig, balanceBeforeBig) - log.Info("difference", "value", diff.String()) - - // Step 7 --- check the balance of the validator owner has been increased - require.True(t, diff.Cmp(big.NewInt(0)) > 0) -} - func TestChainSimulator_SetEntireState(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -360,43 +236,3 @@ func TestChainSimulator_SetEntireState(t *testing.T) { require.Equal(t, accountState.Owner, account.OwnerAddress) require.Equal(t, accountState.RootHash, base64.StdEncoding.EncodeToString(account.RootHash)) } - -func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) (string, error) { - txBytes, err := chainSimulator.GetNodeHandler(1).GetCoreComponents().InternalMarshalizer().Marshal(tx) - if err != nil { - return "", err - } - - txHasBytes := chainSimulator.GetNodeHandler(1).GetCoreComponents().Hasher().Compute(string(txBytes)) - return hex.EncodeToString(txHasBytes), nil -} - -func sendTxAndGenerateBlockTilTxIsExecuted(t *testing.T, chainSimulator ChainSimulator, txToSend *transaction.Transaction) { - shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.SndAddr) - err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(txToSend) - require.Nil(t, err) - - txHash, err := computeTxHash(chainSimulator, txToSend) - require.Nil(t, err) - log.Info("############## send transaction ##############", "txHash", txHash) - - _, err = chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{txToSend}) - require.Nil(t, err) - - time.Sleep(100 * time.Millisecond) - - destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) - for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { - err = chainSimulator.GenerateBlocks(1) - require.Nil(t, err) - - tx, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) - if errGet == nil && tx.Status != transaction.TxStatusPending { - log.Info("############## transaction was executed ##############", "txHash", txHash) - return - } - } - - t.Error("something went wrong transaction is still in pending") - t.FailNow() -} diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index d904ce0b6a0..a6bcd160f5c 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -48,6 +48,7 @@ type ArgsChainSimulatorConfigs struct { MinNodesPerShard uint32 MetaChainMinNodes uint32 RoundsPerEpoch core.OptionalUint64 + AlterConfigsFunction func(cfg *config.Configs) } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -65,6 +66,10 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } + if args.AlterConfigsFunction != nil { + args.AlterConfigsFunction(configs) + } + configs.GeneralConfig.GeneralSettings.ChainID = ChainID // empty genesis smart contracts file @@ -95,16 +100,11 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } - gasScheduleName, err := GetLatestGasScheduleFilename(configs.ConfigurationPathsHolder.GasScheduleDirectoryName) - if err != nil { - return nil, err - } - configs.GeneralConfig.SmartContractsStorage.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) - maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + uint64(args.NumOfShards+1) + maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + 2*uint64(args.NumOfShards+1) configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes numMaxNumNodesEnableEpochs := len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) for idx := 0; idx < numMaxNumNodesEnableEpochs-1; idx++ { @@ -126,6 +126,11 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) } + gasScheduleName, err := GetLatestGasScheduleFilename(configs.ConfigurationPathsHolder.GasScheduleDirectoryName) + if err != nil { + return nil, err + } + return &ArgsConfigsSimulator{ Configs: *configs, ValidatorsPrivateKeys: privateKeys, From 180c7ea31faec3979ce3acc8d18a126c6edf8527 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 6 Feb 2024 10:20:11 +0200 Subject: [PATCH 705/958] todo and skip --- .../chainSimulator/staking/stakeAndUnStake_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 35fcfcbb540..a32631ef2e8 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -26,12 +26,20 @@ const ( var log = logger.GetOrCreate("integrationTests/chainSimulator") +// TODO scenarios +// Make a staking provider with max num of nodes +// DO a merge transaction + // Test scenario // 1. Add a new validator private key in the multi key handler // 2. Do a stake transaction for the validator key // 3. Do an unstake transaction (to make a place for the new validator) // 4. Check if the new validator has generated rewards func TestChainSimulator_AddValidatorKey(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ @@ -142,6 +150,10 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { } func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ From 94a2d4751abb0f30479294b75e7ff6b718040ad9 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 6 Feb 2024 14:54:26 +0200 Subject: [PATCH 706/958] - fixes --- factory/api/apiResolverFactory.go | 71 ++++++++------------ factory/api/export_test.go | 2 +- process/smartContract/scQueryService_test.go | 11 +-- state/accountsDBApi.go | 4 +- state/accountsDBApi_test.go | 42 +++++++++++- 5 files changed, 75 insertions(+), 55 deletions(-) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index bd5c1d4abc9..1ceee28a6ab 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -322,7 +322,7 @@ func createScQueryService( list := make([]process.SCQueryService, 0, numConcurrentVms) for i := 0; i < numConcurrentVms; i++ { argsQueryElem.index = i - scQueryService, err = createScQueryElement(argsQueryElem) + scQueryService, err = createScQueryElement(*argsQueryElem) if err != nil { return nil, err } @@ -339,7 +339,7 @@ func createScQueryService( } func createScQueryElement( - args *scQueryElementArgs, + args scQueryElementArgs, ) (process.SCQueryService, error) { var err error @@ -356,10 +356,20 @@ func createScQueryElement( return nil, errDecode } + apiBlockchain, err := blockchain.NewBlockChain(disabled.NewAppStatusHandler()) + if err != nil { + return nil, err + } + + accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) + if err != nil { + return nil, err + } + builtInFuncFactory, err := createBuiltinFuncs( args.gasScheduleNotifier, args.coreComponents.InternalMarshalizer(), - args.stateComponents.AccountsAdapterAPI(), + accountsAdapterApi, args.processComponents.ShardCoordinator(), args.coreComponents.EpochNotifier(), args.coreComponents.EnableEpochsHandler(), @@ -399,16 +409,17 @@ func createScQueryElement( GasSchedule: args.gasScheduleNotifier, Counter: counters.NewDisabledCounter(), MissingTrieNodesNotifier: syncer.NewMissingTrieNodesNotifier(), + Accounts: accountsAdapterApi, + BlockChain: apiBlockchain, } - var apiBlockchain data.ChainHandler var vmFactory process.VirtualMachinesContainerFactory maxGasForVmQueries := args.generalConfig.VirtualMachine.GasConfig.ShardMaxGasPerVmQuery if args.processComponents.ShardCoordinator().SelfId() == core.MetachainShardId { maxGasForVmQueries = args.generalConfig.VirtualMachine.GasConfig.MetaMaxGasPerVmQuery - apiBlockchain, vmFactory, err = createMetaVmContainerFactory(args, argsHook) + vmFactory, err = createMetaVmContainerFactory(args, argsHook) } else { - apiBlockchain, vmFactory, err = createShardVmContainerFactory(args, argsHook) + vmFactory, err = createShardVmContainerFactory(args, argsHook) } if err != nil { return nil, err @@ -452,23 +463,10 @@ func createScQueryElement( return smartContract.NewSCQueryService(argsNewSCQueryService) } -func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, error) { - apiBlockchain, err := blockchain.NewMetaChain(disabled.NewAppStatusHandler()) - if err != nil { - return nil, nil, err - } - - accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) - if err != nil { - return nil, nil, err - } - - argsHook.BlockChain = apiBlockchain - argsHook.Accounts = accountsAdapterApi - +func createMetaVmContainerFactory(args scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (process.VirtualMachinesContainerFactory, error) { blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook) if errBlockChainHook != nil { - return nil, nil, errBlockChainHook + return nil, errBlockChainHook } argsNewVmFactory := metachain.ArgsNewVMContainerFactory{ @@ -489,35 +487,22 @@ func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBl } vmFactory, err := metachain.NewVMContainerFactory(argsNewVmFactory) if err != nil { - return nil, nil, err + return nil, err } - return apiBlockchain, vmFactory, nil + return vmFactory, nil } -func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, error) { - apiBlockchain, err := blockchain.NewBlockChain(disabled.NewAppStatusHandler()) - if err != nil { - return nil, nil, err - } - - accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) - if err != nil { - return nil, nil, err - } - - argsHook.BlockChain = apiBlockchain - argsHook.Accounts = accountsAdapterApi - +func createShardVmContainerFactory(args scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (process.VirtualMachinesContainerFactory, error) { queryVirtualMachineConfig := args.generalConfig.VirtualMachine.Querying.VirtualMachineConfig esdtTransferParser, errParser := parsers.NewESDTTransferParser(args.coreComponents.InternalMarshalizer()) if errParser != nil { - return nil, nil, errParser + return nil, errParser } blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook) if errBlockChainHook != nil { - return nil, nil, errBlockChainHook + return nil, errBlockChainHook } argsNewVMFactory := shard.ArgVMContainerFactory{ @@ -539,13 +524,13 @@ func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgB vmFactory, err := shard.NewVMContainerFactory(argsNewVMFactory) if err != nil { - return nil, nil, err + return nil, err } - return apiBlockchain, vmFactory, nil + return vmFactory, nil } -func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.ChainHandler) (state.AccountsAdapterAPI, error) { +func createNewAccountsAdapterApi(args scQueryElementArgs, chainHandler data.ChainHandler) (state.AccountsAdapterAPI, error) { argsAccCreator := factoryState.ArgsAccountCreator{ Hasher: args.coreComponents.Hasher(), Marshaller: args.coreComponents.InternalMarshalizer(), @@ -622,7 +607,7 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha return state.NewAccountsDBApi(accounts, provider) } -func newStoragePruningManager(args *scQueryElementArgs) (state.StoragePruningManager, error) { +func newStoragePruningManager(args scQueryElementArgs) (state.StoragePruningManager, error) { argsMemEviction := evictionWaitingList.MemoryEvictionWaitingListArgs{ RootHashesSize: args.generalConfig.EvictionWaitingList.RootHashesSize, HashesSize: args.generalConfig.EvictionWaitingList.HashesSize, diff --git a/factory/api/export_test.go b/factory/api/export_test.go index 0164c0c2b10..092ab83df50 100644 --- a/factory/api/export_test.go +++ b/factory/api/export_test.go @@ -29,7 +29,7 @@ type SCQueryElementArgs struct { // CreateScQueryElement - func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, error) { - return createScQueryElement(&scQueryElementArgs{ + return createScQueryElement(scQueryElementArgs{ generalConfig: args.GeneralConfig, epochConfig: args.EpochConfig, coreComponents: args.CoreComponents, diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 0b76f3a739e..9e7a5d693fa 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -427,9 +427,9 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { } wasRecreateTrieCalled := false providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { wasRecreateTrieCalled = true - assert.Equal(t, providedRootHash, rootHash) + assert.Equal(t, providedRootHash, options.GetRootHash()) return nil }, } @@ -452,9 +452,10 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { BlockHash: providedHash, } - _, _, _ = target.ExecuteQuery(&query) + _, _, err := target.ExecuteQuery(&query) assert.True(t, runWasCalled) assert.True(t, wasRecreateTrieCalled) + assert.Nil(t, err) }) t.Run("block nonce should work", func(t *testing.T) { t.Parallel() @@ -521,9 +522,9 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { } wasRecreateTrieCalled := false providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { wasRecreateTrieCalled = true - assert.Equal(t, providedRootHash, rootHash) + assert.Equal(t, providedRootHash, options.GetRootHash()) return nil }, } diff --git a/state/accountsDBApi.go b/state/accountsDBApi.go index 8c73a6fac06..d9bd467d7d2 100644 --- a/state/accountsDBApi.go +++ b/state/accountsDBApi.go @@ -172,8 +172,6 @@ func (accountsDB *accountsDBApi) RecreateTrie(rootHash []byte) error { // RecreateTrieFromEpoch is a not permitted operation in this implementation and thus, will return an error func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(options common.RootHashHolder) error { - newBlockInfo := holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) - accountsDB.mutRecreatedTrieBlockInfo.Lock() defer accountsDB.mutRecreatedTrieBlockInfo.Unlock() @@ -183,7 +181,7 @@ func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(options common.RootHashHo return err } - accountsDB.blockInfo = newBlockInfo + accountsDB.blockInfo = holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) return nil } diff --git a/state/accountsDBApi_test.go b/state/accountsDBApi_test.go index 2792d18749a..1544e5691b1 100644 --- a/state/accountsDBApi_test.go +++ b/state/accountsDBApi_test.go @@ -16,7 +16,8 @@ import ( "github.com/multiversx/mx-chain-go/state/parsers" "github.com/multiversx/mx-chain-go/testscommon" mockState "github.com/multiversx/mx-chain-go/testscommon/state" - "github.com/multiversx/mx-chain-go/testscommon/trie" + testTrie "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" "github.com/stretchr/testify/require" @@ -195,7 +196,6 @@ func TestAccountsDBApi_NotPermittedOperations(t *testing.T) { assert.Equal(t, state.ErrOperationNotPermitted, accountsApi.SaveAccount(nil)) assert.Equal(t, state.ErrOperationNotPermitted, accountsApi.RemoveAccount(nil)) assert.Equal(t, state.ErrOperationNotPermitted, accountsApi.RevertToSnapshot(0)) - assert.Equal(t, state.ErrOperationNotPermitted, accountsApi.RecreateTrieFromEpoch(nil)) buff, err := accountsApi.CommitInEpoch(0, 0) assert.Nil(t, buff) @@ -226,6 +226,42 @@ func TestAccountsDBApi_RecreateTrie(t *testing.T) { assert.True(t, wasCalled) } +func TestAccountsDBApi_RecreateTrieFromEpoch(t *testing.T) { + t.Parallel() + + t.Run("should error if the roothash holder is nil", func(t *testing.T) { + wasCalled := false + accountsApi, _ := state.NewAccountsDBApi(&mockState.AccountsStub{ + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + wasCalled = true + return trie.ErrNilRootHashHolder + }, + }, createBlockInfoProviderStub(dummyRootHash)) + + err := accountsApi.RecreateTrieFromEpoch(nil) + assert.Equal(t, trie.ErrNilRootHashHolder, err) + assert.True(t, wasCalled) + }) + t.Run("should work", func(t *testing.T) { + wasCalled := false + rootHash := []byte("root hash") + epoch := core.OptionalUint32{Value: 37, HasValue: true} + accountsApi, _ := state.NewAccountsDBApi(&mockState.AccountsStub{ + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + wasCalled = true + assert.Equal(t, rootHash, options.GetRootHash()) + assert.Equal(t, epoch, options.GetEpoch()) + return nil + }, + }, createBlockInfoProviderStub(dummyRootHash)) + + holder := holders.NewRootHashHolder(rootHash, epoch) + err := accountsApi.RecreateTrieFromEpoch(holder) + assert.NoError(t, err) + assert.True(t, wasCalled) + }) +} + func TestAccountsDBApi_EmptyMethodsShouldNotPanic(t *testing.T) { t.Parallel() @@ -273,7 +309,7 @@ func TestAccountsDBApi_SimpleProxyMethodsShouldWork(t *testing.T) { }, GetTrieCalled: func(i []byte) (common.Trie, error) { getTrieCalled = true - return &trie.TrieStub{}, nil + return &testTrie.TrieStub{}, nil }, } From 927ae88ec19b6f071cb23baee4aeb56b8f17b709 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 6 Feb 2024 15:28:06 +0200 Subject: [PATCH 707/958] continue impl --- .../staking/stakeAndUnStake_test.go | 29 ++++++++++++------- .../components/processComponents.go | 17 ++++++----- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index a32631ef2e8..6123005e387 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" coreAPI "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator/helpers" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" @@ -169,8 +170,12 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 3, - MetaChainMinNodes: 3, + MinNodesPerShard: 100, + MetaChainMinNodes: 100, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.SystemSCConfig.StakingSystemSCConfig.NodeLimitPercentage = 1 + cfg.GeneralConfig.ValidatorStatistics.CacheRefreshIntervalInSec = 1 + }, }) require.Nil(t, err) require.NotNil(t, cm) @@ -179,7 +184,7 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { require.Nil(t, err) // Step 1 --- add a new validator key in the chain simulator - numOfNodes := 10 + numOfNodes := 20 validatorSecretKeysBytes, blsKeys := helpers.GenerateBlsPrivateKeys(t, numOfNodes) err = cm.AddValidatorKeys(validatorSecretKeysBytes) require.Nil(t, err) @@ -193,21 +198,19 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { err = cm.SetStateMultiple([]*dtos.AddressState{ { Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", - Balance: "100000000000000000000000", + Balance: "1000000000000000000000000", }, }) require.Nil(t, err) - // Step 3 --- generate and send a stake transaction with the BLS key of the validator key that was added at step 1 + // Step 3 --- generate and send a stake transaction with the BLS keys of the validators key that were added at step 1 validatorData := "" for _, blsKey := range blsKeys { validatorData += fmt.Sprintf("@%s@010101", blsKey) } - log.Warn("BLS KEYS", "keys", validatorData) - numOfNodesHex := hex.EncodeToString(big.NewInt(int64(numOfNodes)).Bytes()) - stakeValue, _ := big.NewInt(0).SetString("25000000000000000000000", 10) + stakeValue, _ := big.NewInt(0).SetString("51000000000000000000000", 10) tx := &transaction.Transaction{ Nonce: 0, Value: stakeValue, @@ -221,11 +224,15 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { Version: 1, } - _ = logger.SetLogLevel("*:DEBUG") - txFromNetwork := helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) require.NotNil(t, txFromNetwork) - err = cm.GenerateBlocks(20) + err = cm.GenerateBlocks(1) + require.Nil(t, err) + + _, err = cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() + require.Nil(t, err) + + err = cm.GenerateBlocks(100) require.Nil(t, err) } diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 27b1e358614..ab5e6e471c2 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -182,18 +182,11 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC EpochConfig: args.EpochConfig, PrefConfigs: args.PrefsConfig, ImportDBConfig: args.ImportDBConfig, + EconomicsConfig: args.EconomicsConfig, AccountsParser: accountsParser, SmartContractParser: smartContractParser, GasSchedule: gasScheduleNotifier, NodesCoordinator: args.NodesCoordinator, - Data: args.DataComponents, - CoreData: args.CoreComponents, - Crypto: args.CryptoComponents, - State: args.StateComponents, - Network: args.NetworkComponents, - BootstrapComponents: args.BootstrapComponents, - StatusComponents: args.StatusComponents, - StatusCoreComponents: args.StatusCoreComponents, RequestedItemsHandler: requestedItemsHandler, WhiteListHandler: whiteListRequest, WhiteListerVerifiedTxs: whiteListerVerifiedTxs, @@ -202,6 +195,14 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC ImportStartHandler: importStartHandler, HistoryRepo: historyRepository, FlagsConfig: args.FlagsConfig, + Data: args.DataComponents, + CoreData: args.CoreComponents, + Crypto: args.CryptoComponents, + State: args.StateComponents, + Network: args.NetworkComponents, + BootstrapComponents: args.BootstrapComponents, + StatusComponents: args.StatusComponents, + StatusCoreComponents: args.StatusCoreComponents, TxExecutionOrderHandler: txExecutionOrderHandler, } processComponentsFactory, err := processComp.NewProcessComponentsFactory(processArgs) From 8c7060ae6cd679d248ec1d0c7c99c454b2ac7cee Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 6 Feb 2024 15:41:02 +0200 Subject: [PATCH 708/958] extra checks test --- .../staking/stakeAndUnStake_test.go | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 6123005e387..3c15a4d78f2 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -100,7 +100,8 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ChainID: []byte(configs.ChainID), Version: 1, } - _ = helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + stakeTx := helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + require.NotNil(t, stakeTx) shardIDValidatorOwner := cm.GetNodeHandler(0).GetShardCoordinator().ComputeId(newValidatorOwnerBytes) accountValidatorOwner, _, err := cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) @@ -230,9 +231,33 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { err = cm.GenerateBlocks(1) require.Nil(t, err) - _, err = cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() + results, err := cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() require.Nil(t, err) + require.Equal(t, newValidatorOwner, results[0].Owner) + require.Equal(t, 20, len(results[0].AuctionList)) + totalQualified := 0 + for _, res := range results { + for _, node := range res.AuctionList { + if node.Qualified { + totalQualified++ + } + } + } + require.Equal(t, 8, totalQualified) err = cm.GenerateBlocks(100) require.Nil(t, err) + + results, err = cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() + require.Nil(t, err) + + totalQualified = 0 + for _, res := range results { + for _, node := range res.AuctionList { + if node.Qualified { + totalQualified++ + } + } + } + require.Equal(t, 0, totalQualified) } From f31383fa2cd3ee5c5ab6f8564e4cf59536e206d7 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 6 Feb 2024 16:28:33 +0200 Subject: [PATCH 709/958] - more fixes --- process/smartContract/scQueryService.go | 3 +-- process/smartContract/scQueryService_test.go | 14 ++------------ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 6b9b54ac82b..3aeb879f384 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -205,6 +205,7 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui if err != nil { return nil, nil, err } + service.blockChainHook.SetCurrentHeader(blockHeader) } shouldCheckRootHashChanges := query.SameScState @@ -214,8 +215,6 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui rootHashBeforeExecution = service.apiBlockChain.GetCurrentBlockRootHash() } - service.blockChainHook.SetCurrentHeader(service.mainBlockChain.GetCurrentBlockHeader()) - service.wasmVMChangeLocker.RLock() vm, _, err := scrCommon.FindVMByScAddress(service.vmContainer, query.ScAddress) if err != nil { diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 9e7a5d693fa..69672531752 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -41,7 +41,7 @@ func createMockArgumentsForSCQuery() ArgsNewSCQueryService { BlockChainHook: &testscommon.BlockChainHookStub{ GetAccountsAdapterCalled: func() state.AccountsAdapter { return &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { return nil }, } @@ -897,16 +897,6 @@ func TestSCQueryService_ShouldFailIfStateChanged(t *testing.T) { t.Parallel() args := createMockArgumentsForSCQuery() - args.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - return nil - }, - } - }, - } - rootHashCalledCounter := 0 args.APIBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockRootHashCalled: func() []byte { @@ -928,7 +918,7 @@ func TestSCQueryService_ShouldFailIfStateChanged(t *testing.T) { FuncName: "function", }) require.Nil(t, res) - require.True(t, errors.Is(err, process.ErrStateChangedWhileExecutingVmQuery)) + require.ErrorIs(t, err, process.ErrStateChangedWhileExecutingVmQuery) } func TestSCQueryService_ShouldWorkIfStateDidntChange(t *testing.T) { From 1113d6be52d3fb1f617cd36d6543aa96ae72a3ea Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Tue, 6 Feb 2024 17:28:43 +0200 Subject: [PATCH 710/958] simplify & add some comments --- .../executingMiniblocks_test.go | 87 +------------------ ...quest_test.go => metablockRequest_test.go} | 10 +-- ...uest_test.go => shardblockRequest_test.go} | 8 +- testscommon/dataRetriever/poolsHolderMock.go | 4 +- testscommon/pool/headersPoolStub.go | 66 +++++++------- 5 files changed, 46 insertions(+), 129 deletions(-) rename process/block/{metablock_request_test.go => metablockRequest_test.go} (98%) rename process/block/{shardblock_request_test.go => shardblockRequest_test.go} (99%) diff --git a/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go b/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go index 88e813c6cfb..eec61878296 100644 --- a/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go +++ b/integrationTests/multiShard/block/executingMiniblocks/executingMiniblocks_test.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "fmt" "math/big" - "sync" "testing" "time" @@ -14,13 +13,14 @@ import ( "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-crypto-go" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/process/factory" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/state" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestShouldProcessBlocksInMultiShardArchitecture(t *testing.T) { @@ -352,87 +352,6 @@ func TestSimpleTransactionsWithMoreValueThanBalanceYieldReceiptsInMultiShardedEn } } -func TestExecuteBlocksWithGapsBetweenBlocks(t *testing.T) { - // TODO fix this test - t.Skip("TODO fix this test") - if testing.Short() { - t.Skip("this is not a short test") - } - nodesPerShard := 2 - shardConsensusGroupSize := 2 - nbMetaNodes := 400 - nbShards := 1 - consensusGroupSize := 400 - - cacheMut := &sync.Mutex{} - - putCounter := 0 - cacheMap := make(map[string]interface{}) - - // create map of shard - testNodeProcessors for metachain and shard chain - nodesMap := integrationTests.CreateNodesWithNodesCoordinatorWithCacher( - nodesPerShard, - nbMetaNodes, - nbShards, - shardConsensusGroupSize, - consensusGroupSize, - ) - - roundsPerEpoch := uint64(1000) - maxGasLimitPerBlock := uint64(100000) - gasPrice := uint64(10) - gasLimit := uint64(100) - for _, nodes := range nodesMap { - integrationTests.SetEconomicsParameters(nodes, maxGasLimitPerBlock, gasPrice, gasLimit) - integrationTests.DisplayAndStartNodes(nodes[0:1]) - - for _, node := range nodes { - node.EpochStartTrigger.SetRoundsPerEpoch(roundsPerEpoch) - } - } - - defer func() { - for _, nodes := range nodesMap { - for _, n := range nodes { - n.Close() - } - } - }() - - round := uint64(1) - roundDifference := 10 - nonce := uint64(1) - - firstNodeOnMeta := nodesMap[core.MetachainShardId][0] - body, header, _ := firstNodeOnMeta.ProposeBlock(round, nonce) - - // set bitmap for all consensus nodes signing - bitmap := make([]byte, consensusGroupSize/8+1) - for i := range bitmap { - bitmap[i] = 0xFF - } - - bitmap[consensusGroupSize/8] >>= uint8(8 - (consensusGroupSize % 8)) - err := header.SetPubKeysBitmap(bitmap) - assert.Nil(t, err) - - firstNodeOnMeta.CommitBlock(body, header) - - round += uint64(roundDifference) - nonce++ - putCounter = 0 - - cacheMut.Lock() - for k := range cacheMap { - delete(cacheMap, k) - } - cacheMut.Unlock() - - firstNodeOnMeta.ProposeBlock(round, nonce) - - assert.Equal(t, roundDifference, putCounter) -} - // TestShouldSubtractTheCorrectTxFee uses the mock VM as it's gas model is predictable // The test checks the tx fee subtraction from the sender account when deploying a SC // It also checks the fee obtained by the leader is correct diff --git a/process/block/metablock_request_test.go b/process/block/metablockRequest_test.go similarity index 98% rename from process/block/metablock_request_test.go rename to process/block/metablockRequest_test.go index 0343a2cc57e..0718830a43c 100644 --- a/process/block/metablock_request_test.go +++ b/process/block/metablockRequest_test.go @@ -267,9 +267,7 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { // for requesting attestation header requestHandler.RequestShardHeaderByNonceCalled = func(shardID uint32, nonce uint64) { attestationNonce := td[shardID].attestationHeaderData.header.GetNonce() - if nonce != attestationNonce { - require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) - } + require.Equal(t, nonce, attestationNonce, fmt.Sprintf("nonce should have been %d", attestationNonce)) numCalls.Add(1) } @@ -442,11 +440,11 @@ func TestMetaProcessor_receivedShardHeader(t *testing.T) { }) } -type ReceivedAllHeadersSignaler interface { +type receivedAllHeadersSignaler interface { ChannelReceiveAllHeaders() chan bool } -func startWaitingForAllHeadersReceivedSignal(t *testing.T, mp ReceivedAllHeadersSignaler) *sync.WaitGroup { +func startWaitingForAllHeadersReceivedSignal(t *testing.T, mp receivedAllHeadersSignaler) *sync.WaitGroup { wg := &sync.WaitGroup{} wg.Add(1) go func(w *sync.WaitGroup) { @@ -471,7 +469,7 @@ func createPoolsHolderForHeaderRequests() dataRetriever.HeadersPool { mutHeadersInPool := sync.RWMutex{} errNotFound := errors.New("header not found") - return &pool.HeadersCacherStub{ + return &pool.HeadersPoolStub{ AddCalled: func(headerHash []byte, header data.HeaderHandler) { mutHeadersInPool.Lock() headersInPool[string(headerHash)] = header diff --git a/process/block/shardblock_request_test.go b/process/block/shardblockRequest_test.go similarity index 99% rename from process/block/shardblock_request_test.go rename to process/block/shardblockRequest_test.go index b4d8bd27a07..2440c6ecba5 100644 --- a/process/block/shardblock_request_test.go +++ b/process/block/shardblockRequest_test.go @@ -41,9 +41,7 @@ func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { } requestHandler.RequestMetaHeaderByNonceCalled = func(nonce uint64) { attestationNonce := metaChainData.headerData[1].header.GetNonce() - if nonce != attestationNonce { - require.Fail(t, fmt.Sprintf("nonce should have been %d", attestationNonce)) - } + require.Equal(t, attestationNonce, nonce, fmt.Sprintf("nonce should have been %d", attestationNonce)) numCalls.Add(1) } sp, _ := blproc.NewShardProcessor(arguments) @@ -521,7 +519,7 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { MiniBlockHeaders: []block.MiniBlockHeader{}, } - shar1Block1 := &block.Header{ + shard1Block1 := &block.Header{ ShardID: 1, PrevHash: shard1Block0Hash, MetaBlockHashes: [][]byte{prevMetaBlockHash}, @@ -560,7 +558,7 @@ func createShardProcessorTestData() map[uint32]*shardBlockTestData { headerData: []*headerData{ { hash: shard1Block1Hash, - header: shar1Block1, + header: shard1Block1, }, { hash: shard1Block2Hash, diff --git a/testscommon/dataRetriever/poolsHolderMock.go b/testscommon/dataRetriever/poolsHolderMock.go index f04528bc28c..d3d30562954 100644 --- a/testscommon/dataRetriever/poolsHolderMock.go +++ b/testscommon/dataRetriever/poolsHolderMock.go @@ -4,6 +4,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/dataPool" @@ -142,7 +143,8 @@ func (holder *PoolsHolderMock) Headers() dataRetriever.HeadersPool { return holder.headers } -func(holder *PoolsHolderMock) SetHeadersPool(headersPool dataRetriever.HeadersPool) { +// SetHeadersPool - +func (holder *PoolsHolderMock) SetHeadersPool(headersPool dataRetriever.HeadersPool) { holder.headers = headersPool } diff --git a/testscommon/pool/headersPoolStub.go b/testscommon/pool/headersPoolStub.go index c43943cc8c5..66c01d91c68 100644 --- a/testscommon/pool/headersPoolStub.go +++ b/testscommon/pool/headersPoolStub.go @@ -6,8 +6,8 @@ import ( "github.com/multiversx/mx-chain-core-go/data" ) -// HeadersCacherStub - -type HeadersCacherStub struct { +// HeadersPoolStub - +type HeadersPoolStub struct { AddCalled func(headerHash []byte, header data.HeaderHandler) RemoveHeaderByHashCalled func(headerHash []byte) RemoveHeaderByNonceAndShardIdCalled func(hdrNonce uint64, shardId uint32) @@ -22,83 +22,83 @@ type HeadersCacherStub struct { } // AddHeader - -func (hcs *HeadersCacherStub) AddHeader(headerHash []byte, header data.HeaderHandler) { - if hcs.AddCalled != nil { - hcs.AddCalled(headerHash, header) +func (hps *HeadersPoolStub) AddHeader(headerHash []byte, header data.HeaderHandler) { + if hps.AddCalled != nil { + hps.AddCalled(headerHash, header) } } // RemoveHeaderByHash - -func (hcs *HeadersCacherStub) RemoveHeaderByHash(headerHash []byte) { - if hcs.RemoveHeaderByHashCalled != nil { - hcs.RemoveHeaderByHashCalled(headerHash) +func (hps *HeadersPoolStub) RemoveHeaderByHash(headerHash []byte) { + if hps.RemoveHeaderByHashCalled != nil { + hps.RemoveHeaderByHashCalled(headerHash) } } // RemoveHeaderByNonceAndShardId - -func (hcs *HeadersCacherStub) RemoveHeaderByNonceAndShardId(hdrNonce uint64, shardId uint32) { - if hcs.RemoveHeaderByNonceAndShardIdCalled != nil { - hcs.RemoveHeaderByNonceAndShardIdCalled(hdrNonce, shardId) +func (hps *HeadersPoolStub) RemoveHeaderByNonceAndShardId(hdrNonce uint64, shardId uint32) { + if hps.RemoveHeaderByNonceAndShardIdCalled != nil { + hps.RemoveHeaderByNonceAndShardIdCalled(hdrNonce, shardId) } } // GetHeadersByNonceAndShardId - -func (hcs *HeadersCacherStub) GetHeadersByNonceAndShardId(hdrNonce uint64, shardId uint32) ([]data.HeaderHandler, [][]byte, error) { - if hcs.GetHeaderByNonceAndShardIdCalled != nil { - return hcs.GetHeaderByNonceAndShardIdCalled(hdrNonce, shardId) +func (hps *HeadersPoolStub) GetHeadersByNonceAndShardId(hdrNonce uint64, shardId uint32) ([]data.HeaderHandler, [][]byte, error) { + if hps.GetHeaderByNonceAndShardIdCalled != nil { + return hps.GetHeaderByNonceAndShardIdCalled(hdrNonce, shardId) } return nil, nil, errors.New("err") } // GetHeaderByHash - -func (hcs *HeadersCacherStub) GetHeaderByHash(hash []byte) (data.HeaderHandler, error) { - if hcs.GetHeaderByHashCalled != nil { - return hcs.GetHeaderByHashCalled(hash) +func (hps *HeadersPoolStub) GetHeaderByHash(hash []byte) (data.HeaderHandler, error) { + if hps.GetHeaderByHashCalled != nil { + return hps.GetHeaderByHashCalled(hash) } return nil, nil } // Clear - -func (hcs *HeadersCacherStub) Clear() { - if hcs.ClearCalled != nil { - hcs.ClearCalled() +func (hps *HeadersPoolStub) Clear() { + if hps.ClearCalled != nil { + hps.ClearCalled() } } // RegisterHandler - -func (hcs *HeadersCacherStub) RegisterHandler(handler func(header data.HeaderHandler, shardHeaderHash []byte)) { - if hcs.RegisterHandlerCalled != nil { - hcs.RegisterHandlerCalled(handler) +func (hps *HeadersPoolStub) RegisterHandler(handler func(header data.HeaderHandler, shardHeaderHash []byte)) { + if hps.RegisterHandlerCalled != nil { + hps.RegisterHandlerCalled(handler) } } // Nonces - -func (hcs *HeadersCacherStub) Nonces(shardId uint32) []uint64 { - if hcs.NoncesCalled != nil { - return hcs.NoncesCalled(shardId) +func (hps *HeadersPoolStub) Nonces(shardId uint32) []uint64 { + if hps.NoncesCalled != nil { + return hps.NoncesCalled(shardId) } return nil } // Len - -func (hcs *HeadersCacherStub) Len() int { +func (hps *HeadersPoolStub) Len() int { return 0 } // MaxSize - -func (hcs *HeadersCacherStub) MaxSize() int { +func (hps *HeadersPoolStub) MaxSize() int { return 100 } // IsInterfaceNil - -func (hcs *HeadersCacherStub) IsInterfaceNil() bool { - return hcs == nil +func (hps *HeadersPoolStub) IsInterfaceNil() bool { + return hps == nil } // GetNumHeaders - -func (hcs *HeadersCacherStub) GetNumHeaders(shardId uint32) int { - if hcs.GetNumHeadersCalled != nil { - return hcs.GetNumHeadersCalled(shardId) +func (hps *HeadersPoolStub) GetNumHeaders(shardId uint32) int { + if hps.GetNumHeadersCalled != nil { + return hps.GetNumHeadersCalled(shardId) } return 0 From aeaf00e76662fa6ef34c1babe4b43c1172144d14 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 6 Feb 2024 18:03:38 +0200 Subject: [PATCH 711/958] - try new p2p configs --- cmd/node/config/fullArchiveP2P.toml | 8 ++++---- cmd/node/config/p2p.toml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/node/config/fullArchiveP2P.toml b/cmd/node/config/fullArchiveP2P.toml index 0a7ee26a73f..ba6e76c4c01 100644 --- a/cmd/node/config/fullArchiveP2P.toml +++ b/cmd/node/config/fullArchiveP2P.toml @@ -71,10 +71,10 @@ [Sharding] # The targeted number of peer connections - TargetPeerCount = 36 - MaxIntraShardValidators = 6 - MaxCrossShardValidators = 13 - MaxIntraShardObservers = 5 + TargetPeerCount = 41 + MaxIntraShardValidators = 7 + MaxCrossShardValidators = 15 + MaxIntraShardObservers = 7 MaxCrossShardObservers = 3 MaxSeeders = 2 diff --git a/cmd/node/config/p2p.toml b/cmd/node/config/p2p.toml index 6e9931f9bc1..e8df20bef59 100644 --- a/cmd/node/config/p2p.toml +++ b/cmd/node/config/p2p.toml @@ -71,10 +71,10 @@ [Sharding] # The targeted number of peer connections - TargetPeerCount = 36 - MaxIntraShardValidators = 6 - MaxCrossShardValidators = 13 - MaxIntraShardObservers = 5 + TargetPeerCount = 41 + MaxIntraShardValidators = 7 + MaxCrossShardValidators = 15 + MaxIntraShardObservers = 7 MaxCrossShardObservers = 3 MaxSeeders = 2 From 413f2e0722bdbc3fbc5888057e3574b5c830babe Mon Sep 17 00:00:00 2001 From: robertsasu Date: Wed, 7 Feb 2024 10:48:25 +0200 Subject: [PATCH 712/958] fix no registration --- vm/systemSmartContracts/validator.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index e7e02c5e55e..693d5356b24 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -649,6 +649,10 @@ func (v *validatorSC) registerBLSKeys( } for _, blsKey := range newKeys { + if v.isNumberOfNodesTooHigh(registrationData) { + break + } + vmOutput, errExec := v.executeOnStakingSC([]byte("register@" + hex.EncodeToString(blsKey) + "@" + hex.EncodeToString(registrationData.RewardAddress) + "@" + @@ -1077,7 +1081,7 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod registrationData.RewardAddress, args.CallerAddr, ) - } else { + } else if len(newKeys) > 0 { numRegisteredBlsKeys := int64(len(registrationData.BlsPubKeys)) nodeLimit := int64(v.computeNodeLimit()) entry := &vmcommon.LogEntry{ From 9fee74d7c6318644a5687cf2ed9caaa2d428a9c1 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Wed, 7 Feb 2024 10:55:46 +0200 Subject: [PATCH 713/958] added test --- vm/systemSmartContracts/validator_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 3cb475eb9e2..cffce652ff5 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -466,6 +466,15 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { assert.Equal(t, entry.Topics[0], []byte(numberOfNodesTooHigh)) } + stakeCalledInStakingSC := false + eei.ExecuteOnDestContextCalled = func(destination, sender []byte, value *big.Int, input []byte) (*vmcommon.VMOutput, error) { + if strings.Contains(string(input), "stake") { + stakeCalledInStakingSC = true + assert.False(t, stakeCalledInStakingSC) + } + return &vmcommon.VMOutput{}, nil + } + key1 := []byte("Key1") key2 := []byte("Key2") key3 := []byte("Key3") From 172abc3d114fe60c253ca643675f6a36aec6cdf0 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 7 Feb 2024 11:13:16 +0200 Subject: [PATCH 714/958] add rating components --- .../staking/stakeAndUnStake_test.go | 36 ++++++++++---- node/chainSimulator/chainSimulator.go | 47 ++++++++++--------- .../components/coreComponents.go | 27 +++++++++-- .../components/testOnlyProcessingNode.go | 3 ++ node/chainSimulator/configs/configs.go | 32 ++++++++----- 5 files changed, 96 insertions(+), 49 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 3c15a4d78f2..918fdc0480b 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -49,16 +49,18 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { } cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - BypassTxSignatureCheck: false, - TempDir: t.TempDir(), - PathToInitialConfig: defaultPathToInitialConfig, - NumOfShards: 3, - GenesisTimestamp: startTime, - RoundDurationInMillis: roundDurationInMillis, - RoundsPerEpoch: roundsPerEpoch, - ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 3, - MetaChainMinNodes: 3, + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 1, + NumNodesWaitingListShard: 1, }) require.Nil(t, err) require.NotNil(t, cm) @@ -135,6 +137,20 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { err = cm.GenerateBlocks(50) require.Nil(t, err) + validatorStatistics, err := cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + + countRatingIncreased := 0 + for _, validatorInfo := range validatorStatistics { + validatorSignedAtLeastOneBlock := validatorInfo.NumValidatorSuccess > 0 || validatorInfo.NumLeaderSuccess > 0 + if !validatorSignedAtLeastOneBlock { + continue + } + countRatingIncreased++ + require.Greater(t, validatorInfo.TempRating, validatorInfo.Rating) + } + require.Greater(t, countRatingIncreased, 0) + accountValidatorOwner, _, err = cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) require.Nil(t, err) balanceAfterActiveValidator := accountValidatorOwner.Balance diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 9a7d8011b3f..ce8b9f4150a 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -22,18 +22,20 @@ var log = logger.GetOrCreate("chainSimulator") // ArgsChainSimulator holds the arguments needed to create a new instance of simulator type ArgsChainSimulator struct { - BypassTxSignatureCheck bool - TempDir string - PathToInitialConfig string - NumOfShards uint32 - MinNodesPerShard uint32 - MetaChainMinNodes uint32 - GenesisTimestamp int64 - InitialRound int64 - RoundDurationInMillis uint64 - RoundsPerEpoch core.OptionalUint64 - ApiInterface components.APIConfigurator - AlterConfigsFunction func(cfg *config.Configs) + BypassTxSignatureCheck bool + TempDir string + PathToInitialConfig string + NumOfShards uint32 + MinNodesPerShard uint32 + MetaChainMinNodes uint32 + NumNodesWaitingListShard uint32 + NumNodesWaitingListMeta uint32 + GenesisTimestamp int64 + InitialRound int64 + RoundDurationInMillis uint64 + RoundsPerEpoch core.OptionalUint64 + ApiInterface components.APIConfigurator + AlterConfigsFunction func(cfg *config.Configs) } type simulator struct { @@ -70,15 +72,17 @@ func NewChainSimulator(args ArgsChainSimulator) (*simulator, error) { func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ - NumOfShards: args.NumOfShards, - OriginalConfigsPath: args.PathToInitialConfig, - GenesisTimeStamp: computeStartTimeBaseOnInitialRound(args), - RoundDurationInMillis: args.RoundDurationInMillis, - TempDir: args.TempDir, - MinNodesPerShard: args.MinNodesPerShard, - MetaChainMinNodes: args.MetaChainMinNodes, - RoundsPerEpoch: args.RoundsPerEpoch, - AlterConfigsFunction: args.AlterConfigsFunction, + NumOfShards: args.NumOfShards, + OriginalConfigsPath: args.PathToInitialConfig, + GenesisTimeStamp: computeStartTimeBaseOnInitialRound(args), + RoundDurationInMillis: args.RoundDurationInMillis, + TempDir: args.TempDir, + MinNodesPerShard: args.MinNodesPerShard, + MetaChainMinNodes: args.MetaChainMinNodes, + RoundsPerEpoch: args.RoundsPerEpoch, + AlterConfigsFunction: args.AlterConfigsFunction, + NumNodesWaitingListShard: args.NumNodesWaitingListShard, + NumNodesWaitingListMeta: args.NumNodesWaitingListMeta, }) if err != nil { return err @@ -138,6 +142,7 @@ func (s *simulator) createTestNode( InitialRound: args.InitialRound, MinNodesPerShard: args.MinNodesPerShard, MinNodesMeta: args.MetaChainMinNodes, + RoundDurationInMillis: args.RoundDurationInMillis, } return components.NewTestOnlyProcessingNode(argsTestOnlyProcessorNode) diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 2c436453d59..492f9152c8e 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -28,6 +28,7 @@ import ( "github.com/multiversx/mx-chain-go/ntp" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/economics" + "github.com/multiversx/mx-chain-go/process/rating" "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" @@ -81,6 +82,7 @@ type ArgsCoreComponentsHolder struct { EnableEpochsConfig config.EnableEpochs RoundsConfig config.RoundConfig EconomicsConfig config.EconomicsConfig + RatingConfig config.RatingsConfig ChanStopNodeProcess chan endProcess.ArgEndProcess InitialRound int64 NodesSetupPath string @@ -88,8 +90,9 @@ type ArgsCoreComponentsHolder struct { NumShards uint32 WorkingDir string - MinNodesPerShard uint32 - MinNodesMeta uint32 + MinNodesPerShard uint32 + MinNodesMeta uint32 + RoundDurationInMs uint64 } // CreateCoreComponents will create a new instance of factory.CoreComponentsHolder @@ -199,9 +202,23 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents } instance.apiEconomicsData = instance.economicsData - // TODO check if we need this - instance.ratingsData = &testscommon.RatingsInfoMock{} - instance.rater = &testscommon.RaterMock{} + // TODO fix this min nodes pe shard to be configurable + instance.ratingsData, err = rating.NewRatingsData(rating.RatingsDataArg{ + Config: args.RatingConfig, + ShardConsensusSize: 1, + MetaConsensusSize: 1, + ShardMinNodes: args.MinNodesPerShard, + MetaMinNodes: args.MinNodesMeta, + RoundDurationMiliseconds: args.RoundDurationInMs, + }) + if err != nil { + return nil, err + } + + instance.rater, err = rating.NewBlockSigningRater(instance.ratingsData) + if err != nil { + return nil, err + } instance.nodesShuffler, err = nodesCoordinator.NewHashValidatorsShuffler(&nodesCoordinator.NodesShufflerArgs{ NodesShard: args.MinNodesPerShard, diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index c0f7e3523de..f9b4ab56cc4 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -45,6 +45,7 @@ type ArgsTestOnlyProcessingNode struct { BypassTxSignatureCheck bool MinNodesPerShard uint32 MinNodesMeta uint32 + RoundDurationInMillis uint64 } type testOnlyProcessingNode struct { @@ -96,6 +97,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces InitialRound: args.InitialRound, MinNodesPerShard: args.MinNodesPerShard, MinNodesMeta: args.MinNodesMeta, + RoundDurationInMs: args.RoundDurationInMillis, + RatingConfig: *args.Configs.RatingsConfig, }) if err != nil { return nil, err diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index a6bcd160f5c..e6785fee6f1 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -40,15 +40,17 @@ const ( // ArgsChainSimulatorConfigs holds all the components needed to create the chain simulator configs type ArgsChainSimulatorConfigs struct { - NumOfShards uint32 - OriginalConfigsPath string - GenesisTimeStamp int64 - RoundDurationInMillis uint64 - TempDir string - MinNodesPerShard uint32 - MetaChainMinNodes uint32 - RoundsPerEpoch core.OptionalUint64 - AlterConfigsFunction func(cfg *config.Configs) + NumOfShards uint32 + OriginalConfigsPath string + GenesisTimeStamp int64 + RoundDurationInMillis uint64 + TempDir string + MinNodesPerShard uint32 + MetaChainMinNodes uint32 + NumNodesWaitingListShard uint32 + NumNodesWaitingListMeta uint32 + RoundsPerEpoch core.OptionalUint64 + AlterConfigsFunction func(cfg *config.Configs) } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -104,7 +106,10 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) - maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + 2*uint64(args.NumOfShards+1) + maxNumNodes := uint64((args.MinNodesPerShard+args.NumNodesWaitingListShard)*args.NumOfShards) + + uint64(args.MetaChainMinNodes+args.NumNodesWaitingListMeta) + + 2*uint64(args.NumOfShards+1+args.NumNodesWaitingListShard+args.NumNodesWaitingListMeta) + configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes numMaxNumNodesEnableEpochs := len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) for idx := 0; idx < numMaxNumNodesEnableEpochs-1; idx++ { @@ -158,7 +163,7 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs addresses := make([]data.InitialAccount, 0) stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) - numOfNodes := args.MinNodesPerShard*args.NumOfShards + args.MetaChainMinNodes + numOfNodes := (args.NumNodesWaitingListShard+args.MinNodesPerShard)*args.NumOfShards + args.NumNodesWaitingListMeta + args.MetaChainMinNodes stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(numOfNodes))) // 2500 EGLD * number of nodes addresses = append(addresses, data.InitialAccount{ Address: initialAddressWithStake.Address, @@ -225,6 +230,7 @@ func generateValidatorsKeyAndUpdateFiles( nodes.RoundDuration = args.RoundDurationInMillis nodes.StartTime = args.GenesisTimeStamp + // TODO fix this to can be configurable nodes.ConsensusGroupSize = 1 nodes.MetaChainConsensusGroupSize = 1 @@ -235,7 +241,7 @@ func generateValidatorsKeyAndUpdateFiles( privateKeys := make([]crypto.PrivateKey, 0) publicKeys := make([]crypto.PublicKey, 0) // generate meta keys - for idx := uint32(0); idx < args.MetaChainMinNodes; idx++ { + for idx := uint32(0); idx < args.NumNodesWaitingListMeta+args.MetaChainMinNodes; idx++ { sk, pk := blockSigningGenerator.GeneratePair() privateKeys = append(privateKeys, sk) publicKeys = append(publicKeys, pk) @@ -253,7 +259,7 @@ func generateValidatorsKeyAndUpdateFiles( // generate shard keys for idx1 := uint32(0); idx1 < args.NumOfShards; idx1++ { - for idx2 := uint32(0); idx2 < args.MinNodesPerShard; idx2++ { + for idx2 := uint32(0); idx2 < args.NumNodesWaitingListShard+args.MinNodesPerShard; idx2++ { sk, pk := blockSigningGenerator.GeneratePair() privateKeys = append(privateKeys, sk) publicKeys = append(publicKeys, pk) From 15395ec612062ada96f7c269b81e3bc4ce37b339 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 7 Feb 2024 11:32:48 +0200 Subject: [PATCH 715/958] fix unit tests --- node/chainSimulator/components/testOnlyProcessingNode_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 64dbf32b8e3..5afb6a78b65 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -33,6 +33,9 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), APIInterface: api.NewNoApiInterface(), ShardIDStr: "0", + RoundDurationInMillis: 6000, + MinNodesMeta: 1, + MinNodesPerShard: 1, } } From 1e3d7008aaba9f2d947c519c2b0b57d8563e6b91 Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 7 Feb 2024 12:18:28 +0200 Subject: [PATCH 716/958] FIX: Possible fix previous list --- integrationTests/vm/staking/stakingV4_test.go | 106 ++++++++++++++++++ .../indexHashedNodesCoordinator.go | 23 ++-- state/accounts/peerAccount.go | 2 +- 3 files changed, 122 insertions(+), 9 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 1bf48bf404f..7030dda360f 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -2,6 +2,7 @@ package staking import ( "bytes" + "fmt" "math/big" "testing" @@ -1308,3 +1309,108 @@ func TestStakingV4_NewlyStakedNodesInStakingV4Step2ShouldBeSentToWaitingIfListIs epoch++ } } + +func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { + t.Parallel() + + pubKeys := generateAddresses(0, 20) + + owner1 := "owner1" + owner1Stats := &OwnerStats{ + EligibleBlsKeys: map[uint32][][]byte{ + core.MetachainShardId: pubKeys[:3], + 0: pubKeys[3:6], + 1: pubKeys[6:9], + 2: pubKeys[9:12], + }, + TotalStake: big.NewInt(12 * nodePrice), + } + + cfg := &InitialNodesConfig{ + MetaConsensusGroupSize: 3, + ShardConsensusGroupSize: 3, + MinNumberOfEligibleShardNodes: 3, + MinNumberOfEligibleMetaNodes: 3, + NumOfShards: 3, + Owners: map[string]*OwnerStats{ + owner1: owner1Stats, + }, + MaxNodesChangeConfig: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 16, + NodesToShufflePerShard: 4, + }, + { + EpochEnable: 1, + MaxNumNodes: 16, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: stakingV4Step3EnableEpoch, + MaxNumNodes: 8, + NodesToShufflePerShard: 2, + }, + }, + } + node := NewTestMetaProcessorWithCustomNodes(cfg) + node.EpochStartTrigger.SetRoundsPerEpoch(4) + + // 1. Check initial config is correct + currNodesConfig := node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 0) + require.Len(t, currNodesConfig.eligible[core.MetachainShardId], 3) + require.Len(t, currNodesConfig.waiting[core.MetachainShardId], 0) + require.Len(t, currNodesConfig.eligible[0], 3) + require.Len(t, currNodesConfig.waiting[0], 0) + require.Len(t, currNodesConfig.eligible[1], 3) + require.Len(t, currNodesConfig.waiting[1], 0) + require.Len(t, currNodesConfig.eligible[2], 3) + require.Len(t, currNodesConfig.waiting[2], 0) + require.Empty(t, currNodesConfig.shuffledOut) + require.Empty(t, currNodesConfig.auction) + + // NewOwner0 stakes 1 node with top up = 0 before staking v4; should be sent to staking queue + newOwner0 := "newOwner0" + newNodes0 := map[string]*NodesRegisterData{ + newOwner0: { + BLSKeys: [][]byte{generateAddress(101)}, + TotalStake: big.NewInt(nodePrice), + }, + } + + // 1.2 Check staked node before staking v4 is sent to staking queue + node.ProcessStake(t, newNodes0) + currNodesConfig = node.NodesConfig + requireSliceContainsNumOfElements(t, currNodesConfig.new, newNodes0[newOwner0].BLSKeys, 1) + + node.ProcessUnStake(t, map[string][][]byte{ + owner1: {owner1Stats.EligibleBlsKeys[core.MetachainShardId][0]}, + }) + currNodesConfig = node.NodesConfig + // 2. Check config after staking v4 init when a new node is staked + node.Process(t, 20) + + newOwner1 := "newOwner1" + newNodes1 := map[string]*NodesRegisterData{ + newOwner1: { + BLSKeys: generateAddresses(303, 6), + TotalStake: big.NewInt(nodePrice * 6), + }, + } + + // 1.2 Check staked node before staking v4 is sent to staking queue + node.ProcessStake(t, newNodes1) + currNodesConfig = node.NodesConfig + requireSliceContainsNumOfElements(t, currNodesConfig.auction, newNodes1[newOwner1].BLSKeys, 6) + + fmt.Println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") + + node.Process(t, 10) + node.ProcessUnStake(t, map[string][][]byte{ + newOwner1: newNodes1[newOwner1].BLSKeys[0:4], + }) + node.Process(t, 4) + //currNodesConfig = node.NodesConfig +} diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 0bfca899282..49691aedbc3 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -754,7 +754,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.EligibleList): eligibleMap[validatorInfo.ShardId] = append(eligibleMap[validatorInfo.ShardId], currentValidator) case string(common.LeavingList): - log.Debug("leaving node validatorInfo", + log.Info("leaving node validatorInfo", "pk", validatorInfo.PublicKey, "previous list", validatorInfo.PreviousList, "current index", validatorInfo.Index, @@ -825,19 +825,26 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( ) { shardId := validatorInfo.ShardId previousList := validatorInfo.PreviousList - if !ihnc.flagStakingV4Started.IsSet() || len(previousList) == 0 { + + log.Error("leaving node not found in eligible or waiting", + "current list", validatorInfo.List, + "previous list", previousList, + "current index", validatorInfo.Index, + "previous index", validatorInfo.PreviousIndex, + "pk", currentValidator.PubKey(), + "shardId", shardId) + + eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) + return + + if !ihnc.flagStakingV4Started.IsSet() || len(previousList) == 0 || previousList != string(common.AuctionList) { log.Debug("leaving node before staking v4 or with not previous list set node found in", "list", "eligible", "shardId", shardId, "previous list", previousList) eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) return } - if previousList == string(common.EligibleList) { - log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) - currentValidator.index = validatorInfo.PreviousIndex - eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) - return - } + return if previousList == string(common.WaitingList) { log.Debug("leaving node found in", "list", "waiting", "shardId", shardId) diff --git a/state/accounts/peerAccount.go b/state/accounts/peerAccount.go index 662e5449e76..406b197366b 100644 --- a/state/accounts/peerAccount.go +++ b/state/accounts/peerAccount.go @@ -101,7 +101,7 @@ func (pa *peerAccount) SetTempRating(rating uint32) { // SetListAndIndex will update the peer's list (eligible, waiting) and the index inside it with journal func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousValues bool) { - if updatePreviousValues { + if updatePreviousValues && list != pa.List { pa.PreviousList = pa.List pa.PreviousIndexInList = pa.IndexInList } From 537ba941260166641fd54a34af0d5e763329fb33 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 7 Feb 2024 12:55:01 +0200 Subject: [PATCH 717/958] fixes after review --- .../chainSimulator/helpers/helpers.go | 111 ------------------ .../chainSimulator/helpers/interface.go | 11 -- .../staking/stakeAndUnStake_test.go | 70 +++++------ node/chainSimulator/chainSimulator.go | 74 ++++++++++++ .../components/coreComponents.go | 2 +- 5 files changed, 112 insertions(+), 156 deletions(-) delete mode 100644 integrationTests/chainSimulator/helpers/helpers.go delete mode 100644 integrationTests/chainSimulator/helpers/interface.go diff --git a/integrationTests/chainSimulator/helpers/helpers.go b/integrationTests/chainSimulator/helpers/helpers.go deleted file mode 100644 index 07421e1dcaa..00000000000 --- a/integrationTests/chainSimulator/helpers/helpers.go +++ /dev/null @@ -1,111 +0,0 @@ -package helpers - -import ( - "encoding/base64" - "encoding/hex" - "testing" - "time" - - "github.com/multiversx/mx-chain-core-go/data/transaction" - "github.com/multiversx/mx-chain-crypto-go/signing" - "github.com/multiversx/mx-chain-crypto-go/signing/mcl" - logger "github.com/multiversx/mx-chain-logger-go" - "github.com/stretchr/testify/require" -) - -var log = logger.GetOrCreate("integrationTests/chainSimulator/helpers") - -func computeTxHash(chainSimulator ChainSimulator, tx *transaction.Transaction) (string, error) { - txBytes, err := chainSimulator.GetNodeHandler(1).GetCoreComponents().InternalMarshalizer().Marshal(tx) - if err != nil { - return "", err - } - - txHasBytes := chainSimulator.GetNodeHandler(1).GetCoreComponents().Hasher().Compute(string(txBytes)) - return hex.EncodeToString(txHasBytes), nil -} - -// SendTxAndGenerateBlockTilTxIsExecuted will the provided transaction and generate block -func SendTxAndGenerateBlockTilTxIsExecuted( - t *testing.T, - chainSimulator ChainSimulator, - txToSend *transaction.Transaction, - maxNumOfBlockToGenerateWhenExecutingTx int, -) *transaction.ApiTransactionResult { - shardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.SndAddr) - err := chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(txToSend) - require.Nil(t, err) - - txHash, err := computeTxHash(chainSimulator, txToSend) - require.Nil(t, err) - log.Info("############## send transaction ##############", "txHash", txHash) - - _, err = chainSimulator.GetNodeHandler(shardID).GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{txToSend}) - require.Nil(t, err) - - time.Sleep(100 * time.Millisecond) - - destinationShardID := chainSimulator.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) - for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { - err = chainSimulator.GenerateBlocks(1) - require.Nil(t, err) - - tx, errGet := chainSimulator.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) - if errGet == nil && tx.Status != transaction.TxStatusPending { - log.Info("############## transaction was executed ##############", "txHash", txHash) - return tx - } - } - - t.Error("something went wrong transaction is still in pending") - t.FailNow() - - return nil -} - -// AddValidatorKeysInMultiKey will add provided keys in the multi key handler -func AddValidatorKeysInMultiKey(t *testing.T, chainSimulator ChainSimulator, keysBase64 []string) [][]byte { - privateKeysHex := make([]string, 0, len(keysBase64)) - for _, keyBase64 := range keysBase64 { - privateKeyHex, err := base64.StdEncoding.DecodeString(keyBase64) - require.Nil(t, err) - - privateKeysHex = append(privateKeysHex, string(privateKeyHex)) - } - - privateKeysBytes := make([][]byte, 0, len(privateKeysHex)) - for _, keyHex := range privateKeysHex { - privateKeyBytes, err := hex.DecodeString(keyHex) - require.Nil(t, err) - - privateKeysBytes = append(privateKeysBytes, privateKeyBytes) - } - - err := chainSimulator.AddValidatorKeys(privateKeysBytes) - require.Nil(t, err) - - return privateKeysBytes -} - -// GenerateBlsPrivateKeys will generate bls keys -func GenerateBlsPrivateKeys(t *testing.T, numOfKeys int) ([][]byte, []string) { - blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) - - secretKeysBytes := make([][]byte, 0, numOfKeys) - blsKeysHex := make([]string, 0, numOfKeys) - for idx := 0; idx < numOfKeys; idx++ { - secretKey, publicKey := blockSigningGenerator.GeneratePair() - - secretKeyBytes, err := secretKey.ToByteArray() - require.Nil(t, err) - - secretKeysBytes = append(secretKeysBytes, secretKeyBytes) - - publicKeyBytes, err := publicKey.ToByteArray() - require.Nil(t, err) - - blsKeysHex = append(blsKeysHex, hex.EncodeToString(publicKeyBytes)) - } - - return secretKeysBytes, blsKeysHex -} diff --git a/integrationTests/chainSimulator/helpers/interface.go b/integrationTests/chainSimulator/helpers/interface.go deleted file mode 100644 index 96d798e3261..00000000000 --- a/integrationTests/chainSimulator/helpers/interface.go +++ /dev/null @@ -1,11 +0,0 @@ -package helpers - -import "github.com/multiversx/mx-chain-go/node/chainSimulator/process" - -// ChainSimulator defines what a chain simulator should be able to do -type ChainSimulator interface { - GenerateBlocks(numOfBlocks int) error - GetNodeHandler(shardID uint32) process.NodeHandler - AddValidatorKeys(validatorsPrivateKeys [][]byte) error - IsInterfaceNil() bool -} diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 918fdc0480b..c17b969c4d9 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -10,8 +10,9 @@ import ( "github.com/multiversx/mx-chain-core-go/core" coreAPI "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-core-go/data/validator" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" - "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator/helpers" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" @@ -69,8 +70,11 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.Nil(t, err) // Step 1 --- add a new validator key in the chain simulator - privateKeyBase64 := "NjRhYjk3NmJjYWVjZTBjNWQ4YmJhNGU1NjZkY2VmYWFiYjcxNDI1Y2JiZDcwYzc1ODA2MGUxNTE5MGM2ZjE1Zg==" - helpers.AddValidatorKeysInMultiKey(t, cm, []string{privateKeyBase64}) + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + err = cm.AddValidatorKeys(privateKey) + require.Nil(t, err) newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" newValidatorOwnerBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) @@ -86,8 +90,6 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { }) require.Nil(t, err) - blsKey := "9b7de1b2d2c90b7bea8f6855075c77d6c63b5dada29abb9b87c52cfae9d4112fcac13279e1a07d94672a5e62a83e3716555513014324d5c6bb4261b465f1b8549a7a338bc3ae8edc1e940958f9c2e296bd3c118a4466dec99dda0ceee3eb6a8c" - // Step 3 --- generate and send a stake transaction with the BLS key of the validator key that was added at step 1 stakeValue, _ := big.NewInt(0).SetString("2500000000000000000000", 10) tx := &transaction.Transaction{ @@ -95,14 +97,15 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { Value: stakeValue, SndAddr: newValidatorOwnerBytes, RcvAddr: rcvAddrBytes, - Data: []byte(fmt.Sprintf("stake@01@%s@010101", blsKey)), + Data: []byte(fmt.Sprintf("stake@01@%s@010101", blsKeys[0])), GasLimit: 50_000_000, GasPrice: 1000000000, Signature: []byte("dummy"), ChainID: []byte(configs.ChainID), Version: 1, } - stakeTx := helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + stakeTx, err := cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) require.NotNil(t, stakeTx) shardIDValidatorOwner := cm.GetNodeHandler(0).GetShardCoordinator().ComputeId(newValidatorOwnerBytes) @@ -131,7 +134,8 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ChainID: []byte(configs.ChainID), Version: 1, } - _ = helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + _, err = cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards err = cm.GenerateBlocks(50) @@ -139,17 +143,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { validatorStatistics, err := cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().ValidatorStatisticsApi() require.Nil(t, err) - - countRatingIncreased := 0 - for _, validatorInfo := range validatorStatistics { - validatorSignedAtLeastOneBlock := validatorInfo.NumValidatorSuccess > 0 || validatorInfo.NumLeaderSuccess > 0 - if !validatorSignedAtLeastOneBlock { - continue - } - countRatingIncreased++ - require.Greater(t, validatorInfo.TempRating, validatorInfo.Rating) - } - require.Greater(t, countRatingIncreased, 0) + checkValidatorsRating(t, validatorStatistics) accountValidatorOwner, _, err = cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) require.Nil(t, err) @@ -202,7 +196,8 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { // Step 1 --- add a new validator key in the chain simulator numOfNodes := 20 - validatorSecretKeysBytes, blsKeys := helpers.GenerateBlsPrivateKeys(t, numOfNodes) + validatorSecretKeysBytes, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(numOfNodes) + require.Nil(t, err) err = cm.AddValidatorKeys(validatorSecretKeysBytes) require.Nil(t, err) @@ -241,7 +236,8 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { Version: 1, } - txFromNetwork := helpers.SendTxAndGenerateBlockTilTxIsExecuted(t, cm, tx, maxNumOfBlockToGenerateWhenExecutingTx) + txFromNetwork, err := cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) require.NotNil(t, txFromNetwork) err = cm.GenerateBlocks(1) @@ -251,29 +247,37 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { require.Nil(t, err) require.Equal(t, newValidatorOwner, results[0].Owner) require.Equal(t, 20, len(results[0].AuctionList)) - totalQualified := 0 - for _, res := range results { - for _, node := range res.AuctionList { - if node.Qualified { - totalQualified++ - } - } - } - require.Equal(t, 8, totalQualified) + checkTotalQualified(t, results, 8) err = cm.GenerateBlocks(100) require.Nil(t, err) results, err = cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() require.Nil(t, err) + checkTotalQualified(t, results, 0) +} - totalQualified = 0 - for _, res := range results { +func checkTotalQualified(t *testing.T, auctionList []*common.AuctionListValidatorAPIResponse, expected int) { + totalQualified := 0 + for _, res := range auctionList { for _, node := range res.AuctionList { if node.Qualified { totalQualified++ } } } - require.Equal(t, 0, totalQualified) + require.Equal(t, expected, totalQualified) +} + +func checkValidatorsRating(t *testing.T, validatorStatistics map[string]*validator.ValidatorStatistics) { + countRatingIncreased := 0 + for _, validatorInfo := range validatorStatistics { + validatorSignedAtLeastOneBlock := validatorInfo.NumValidatorSuccess > 0 || validatorInfo.NumLeaderSuccess > 0 + if !validatorSignedAtLeastOneBlock { + continue + } + countRatingIncreased++ + require.Greater(t, validatorInfo.TempRating, validatorInfo.Rating) + } + require.Greater(t, countRatingIncreased, 0) } diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index ce8b9f4150a..dc7cdf98f8d 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -2,6 +2,8 @@ package chainSimulator import ( "bytes" + "encoding/hex" + "errors" "fmt" "sync" "time" @@ -9,7 +11,10 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-core-go/data/transaction" crypto "github.com/multiversx/mx-chain-crypto-go" + "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" @@ -302,6 +307,48 @@ func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { return nil } +// SendTxAndGenerateBlockTilTxIsExecuted will the provided transaction and generate block +func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) { + shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.SndAddr) + err := s.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(txToSend) + if err != nil { + return nil, err + } + + node := s.GetNodeHandler(shardID) + txHash, err := core.CalculateHash(node.GetCoreComponents().InternalMarshalizer(), node.GetCoreComponents().Hasher(), txToSend) + if err != nil { + return nil, err + } + + txHashHex := hex.EncodeToString(txHash) + + log.Info("############## send transaction ##############", "txHash", txHash) + + _, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{txToSend}) + if err != nil { + return nil, err + } + + time.Sleep(100 * time.Millisecond) + + destinationShardID := node.GetShardCoordinator().ComputeId(txToSend.RcvAddr) + for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { + err = s.GenerateBlocks(1) + if err != nil { + return nil, err + } + + tx, errGet := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHashHex, true) + if errGet == nil && tx.Status != transaction.TxStatusPending { + log.Info("############## transaction was executed ##############", "txHash", txHash) + return tx, nil + } + } + + return nil, errors.New("something went wrong transaction is still in pending") +} + func (s *simulator) setStateSystemAccount(state *dtos.AddressState) error { for shard, node := range s.nodes { err := node.SetStateForAddress(core.SystemAccountAddress, state) @@ -337,3 +384,30 @@ func (s *simulator) Close() error { func (s *simulator) IsInterfaceNil() bool { return s == nil } + +// GenerateBlsPrivateKeys will generate bls keys +func GenerateBlsPrivateKeys(numOfKeys int) ([][]byte, []string, error) { + blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) + + secretKeysBytes := make([][]byte, 0, numOfKeys) + blsKeysHex := make([]string, 0, numOfKeys) + for idx := 0; idx < numOfKeys; idx++ { + secretKey, publicKey := blockSigningGenerator.GeneratePair() + + secretKeyBytes, err := secretKey.ToByteArray() + if err != nil { + return nil, nil, err + } + + secretKeysBytes = append(secretKeysBytes, secretKeyBytes) + + publicKeyBytes, err := publicKey.ToByteArray() + if err != nil { + return nil, nil, err + } + + blsKeysHex = append(blsKeysHex, hex.EncodeToString(publicKeyBytes)) + } + + return secretKeysBytes, blsKeysHex, nil +} diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 492f9152c8e..384d4e03724 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -202,7 +202,7 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents } instance.apiEconomicsData = instance.economicsData - // TODO fix this min nodes pe shard to be configurable + // TODO fix this min nodes per shard to be configurable instance.ratingsData, err = rating.NewRatingsData(rating.RatingsDataArg{ Config: args.RatingConfig, ShardConsensusSize: 1, From c8823425fe0920535962943c1cf00f024b287909 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 7 Feb 2024 14:30:25 +0200 Subject: [PATCH 718/958] fix start is stuck problem --- node/chainSimulator/chainSimulator.go | 3 +++ node/chainSimulator/process/processor.go | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index dc7cdf98f8d..121032b9e3a 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -176,6 +176,9 @@ func (s *simulator) incrementRoundOnAllValidators() { func (s *simulator) allNodesCreateBlocks() error { for _, node := range s.handlers { + // TODO remove this when we remove all goroutines + time.Sleep(2 * time.Millisecond) + err := node.CreateNewBlock() if err != nil { return err diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index e47ccb92b50..2e88d3593d2 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -127,7 +127,12 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - return creator.nodeHandler.GetBroadcastMessenger().BroadcastBlockDataLeader(header, miniBlocks, transactions, blsKey.PubKey()) + err = creator.nodeHandler.GetBroadcastMessenger().BroadcastMiniBlocks(miniBlocks, blsKey.PubKey()) + if err != nil { + return err + } + + return creator.nodeHandler.GetBroadcastMessenger().BroadcastTransactions(transactions, blsKey.PubKey()) } func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prevHash, prevRandSeed []byte, epoch uint32) { From 9e8b3cabc57fffc83bd528638f12cc7c61493b9d Mon Sep 17 00:00:00 2001 From: MariusC Date: Wed, 7 Feb 2024 14:30:48 +0200 Subject: [PATCH 719/958] FIX: Possible fix previous list 2 --- integrationTests/vm/staking/stakingV4_test.go | 62 +++++++++++++------ .../indexHashedNodesCoordinator.go | 14 +++-- state/validatorInfo.go | 2 +- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 7030dda360f..f98ccdfa40f 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -2,7 +2,6 @@ package staking import ( "bytes" - "fmt" "math/big" "testing" @@ -748,7 +747,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { node.Process(t, 3) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 3) require.Len(t, getAllPubKeys(currNodesConfig.leaving), 3) // All unStaked nodes in previous epoch are now leaving requireMapContains(t, currNodesConfig.leaving, unStakedNodesInStakingV4Step1Epoch) @@ -1354,7 +1353,7 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { }, } node := NewTestMetaProcessorWithCustomNodes(cfg) - node.EpochStartTrigger.SetRoundsPerEpoch(4) + node.EpochStartTrigger.SetRoundsPerEpoch(5) // 1. Check initial config is correct currNodesConfig := node.NodesConfig @@ -1371,7 +1370,7 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { require.Empty(t, currNodesConfig.shuffledOut) require.Empty(t, currNodesConfig.auction) - // NewOwner0 stakes 1 node with top up = 0 before staking v4; should be sent to staking queue + // NewOwner0 stakes 1 node with top up = 0 before staking v4; should be sent to new nodes, since there are enough slots newOwner0 := "newOwner0" newNodes0 := map[string]*NodesRegisterData{ newOwner0: { @@ -1379,38 +1378,65 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { TotalStake: big.NewInt(nodePrice), }, } - - // 1.2 Check staked node before staking v4 is sent to staking queue + // Check staked node before staking v4 is sent to new node.ProcessStake(t, newNodes0) currNodesConfig = node.NodesConfig requireSliceContainsNumOfElements(t, currNodesConfig.new, newNodes0[newOwner0].BLSKeys, 1) + // UnStake one of the initial nodes node.ProcessUnStake(t, map[string][][]byte{ owner1: {owner1Stats.EligibleBlsKeys[core.MetachainShardId][0]}, }) + + // We should have 12 initial nodes + 1 extra waiting node that was forced to remain eligible + node.Process(t, 49) currNodesConfig = node.NodesConfig - // 2. Check config after staking v4 init when a new node is staked - node.Process(t, 20) + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 1) + // Stake 10 extra nodes and check that they are sent to auction newOwner1 := "newOwner1" newNodes1 := map[string]*NodesRegisterData{ newOwner1: { - BLSKeys: generateAddresses(303, 6), - TotalStake: big.NewInt(nodePrice * 6), + BLSKeys: generateAddresses(303, 10), + TotalStake: big.NewInt(nodePrice * 10), }, } - - // 1.2 Check staked node before staking v4 is sent to staking queue node.ProcessStake(t, newNodes1) currNodesConfig = node.NodesConfig - requireSliceContainsNumOfElements(t, currNodesConfig.auction, newNodes1[newOwner1].BLSKeys, 6) - - fmt.Println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") + requireSameSliceDifferentOrder(t, currNodesConfig.auction, newNodes1[newOwner1].BLSKeys) + // After 2 epochs, unStake all previously staked keys. Some of them have been already sent to eligible, but most + // of them are still in auction. Their status should be: leaving now, but their previous values were auction. + // We should not force/consider his auction nodes as being eligible in the next epoch node.Process(t, 10) + currNodesConfig = node.NodesConfig + newOwner1AuctionNodes := getSimilarValues(currNodesConfig.auction, newNodes1[newOwner1].BLSKeys) + newOwner1EligibleNodes := getSimilarValues(getAllPubKeys(currNodesConfig.eligible), newNodes1[newOwner1].BLSKeys) + newOwner1WaitingNodes := getSimilarValues(getAllPubKeys(currNodesConfig.waiting), newNodes1[newOwner1].BLSKeys) node.ProcessUnStake(t, map[string][][]byte{ - newOwner1: newNodes1[newOwner1].BLSKeys[0:4], + newOwner1: newNodes1[newOwner1].BLSKeys, }) - node.Process(t, 4) - //currNodesConfig = node.NodesConfig + + node.Process(t, 5) + currNodesConfig = node.NodesConfig + requireMapContains(t, currNodesConfig.leaving, newOwner1AuctionNodes) + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) + + //requireMapContains(t, currNodesConfig.eligible, newOwner1EligibleNodes) + + _ = newOwner1EligibleNodes + _ = newOwner1WaitingNodes + +} + +func getSimilarValues(slice1, slice2 [][]byte) [][]byte { + ret := make([][]byte, 0) + for _, value := range slice2 { + if searchInSlice(slice1, value) { + ret = append(ret, value) + } + } + + return ret } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 49691aedbc3..fd730752248 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -834,17 +834,19 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( "pk", currentValidator.PubKey(), "shardId", shardId) - eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) - return - - if !ihnc.flagStakingV4Started.IsSet() || len(previousList) == 0 || previousList != string(common.AuctionList) { + if !ihnc.flagStakingV4Started.IsSet() || len(previousList) == 0 { log.Debug("leaving node before staking v4 or with not previous list set node found in", "list", "eligible", "shardId", shardId, "previous list", previousList) eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) return } - return + if previousList == string(common.EligibleList) { + log.Debug("leaving node found in", "list", "eligible", "shardId", shardId) + currentValidator.index = validatorInfo.PreviousIndex + eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator) + return + } if previousList == string(common.WaitingList) { log.Debug("leaving node found in", "list", "waiting", "shardId", shardId) @@ -853,7 +855,7 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( return } - log.Debug("leaving node not found in eligible or waiting", + log.Error("leaving node not found in eligible or waiting", "previous list", previousList, "current index", validatorInfo.Index, "previous index", validatorInfo.PreviousIndex, diff --git a/state/validatorInfo.go b/state/validatorInfo.go index c6ea6d06001..931b81d66a3 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -25,7 +25,7 @@ func (vi *ValidatorInfo) SetPreviousList(list string) { } func (vi *ValidatorInfo) SetListAndIndex(list string, index uint32, updatePreviousValues bool) { - if updatePreviousValues { + if updatePreviousValues && list != vi.List { vi.PreviousIndex = vi.Index vi.PreviousList = vi.List } From d9115c11b6cb06b19f7e0d09380dfd22f7c6ac41 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Wed, 7 Feb 2024 14:35:55 +0200 Subject: [PATCH 720/958] more tests more code --- vm/systemSmartContracts/delegation_test.go | 2 +- vm/systemSmartContracts/validator.go | 94 +++++++++++++++------- vm/systemSmartContracts/validator_test.go | 54 ++++++++++++- 3 files changed, 119 insertions(+), 31 deletions(-) diff --git a/vm/systemSmartContracts/delegation_test.go b/vm/systemSmartContracts/delegation_test.go index 4dcab8d7e44..fe93b1c8368 100644 --- a/vm/systemSmartContracts/delegation_test.go +++ b/vm/systemSmartContracts/delegation_test.go @@ -5123,7 +5123,7 @@ func TestDelegationSystemSC_ExecuteAddNodesStakeNodesWithNodesLimit(t *testing.T output = d.Execute(vmInput) require.Equal(t, vmcommon.UserError, output) require.True(t, strings.Contains(eei.returnMessage, numberOfNodesTooHigh)) - require.True(t, strings.Contains(eei.returnMessage, "num registered bls keys: 4")) + require.True(t, strings.Contains(eei.returnMessage, "num registered bls keys: 3")) require.True(t, strings.Contains(eei.returnMessage, "node limit: 3")) dStatus, _ = d.getDelegationStatus() diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 693d5356b24..865e3fe148b 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -648,8 +648,9 @@ func (v *validatorSC) registerBLSKeys( return nil, nil, err } + newlyAddedKeys := make([][]byte, 0) for _, blsKey := range newKeys { - if v.isNumberOfNodesTooHigh(registrationData) { + if v.isNumberOfNodesTooHigh(len(registrationData.BlsPubKeys) + 1) { break } @@ -673,9 +674,10 @@ func (v *validatorSC) registerBLSKeys( } registrationData.BlsPubKeys = append(registrationData.BlsPubKeys, blsKey) + newlyAddedKeys = append(newlyAddedKeys, blsKey) } - return blsKeys, newKeys, nil + return blsKeys, newlyAddedKeys, nil } func (v *validatorSC) updateStakeValue(registrationData *ValidatorDataV2, caller []byte) vmcommon.ReturnCode { @@ -820,7 +822,7 @@ func (v *validatorSC) reStakeUnStakedNodes(args *vmcommon.ContractCallInput) vmc return vmcommon.UserError } - if v.isNumberOfNodesTooHigh(registrationData) { + if v.isNumberOfNodesTooHigh(len(registrationData.BlsPubKeys)) { v.eei.AddReturnMessage("number of nodes is too high") return vmcommon.UserError } @@ -935,12 +937,12 @@ func (v *validatorSC) isStakeTooHigh(registrationData *ValidatorDataV2) bool { return registrationData.TotalStakeValue.Cmp(v.totalStakeLimit) > 0 } -func (v *validatorSC) isNumberOfNodesTooHigh(registrationData *ValidatorDataV2) bool { +func (v *validatorSC) isNumberOfNodesTooHigh(numNodes int) bool { if !v.enableEpochsHandler.IsFlagEnabled(common.StakeLimitsFlag) { return false } - return len(registrationData.BlsPubKeys) > v.computeNodeLimit() + return numNodes > v.computeNodeLimit() } func (v *validatorSC) computeNodeLimit() int { @@ -1073,46 +1075,73 @@ func (v *validatorSC) stake(args *vmcommon.ContractCallInput) vmcommon.ReturnCod } } - if !v.isNumberOfNodesTooHigh(registrationData) { - v.activateStakingFor( - blsKeys, - registrationData, - validatorConfig.NodePrice, - registrationData.RewardAddress, - args.CallerAddr, - ) - } else if len(newKeys) > 0 { - numRegisteredBlsKeys := int64(len(registrationData.BlsPubKeys)) + v.activateNewBLSKeys(registrationData, blsKeys, newKeys, &validatorConfig, args) + + err = v.saveRegistrationData(args.CallerAddr, registrationData) + if err != nil { + v.eei.AddReturnMessage("cannot save registration data: error " + err.Error()) + return vmcommon.UserError + } + + return vmcommon.Ok +} + +func (v *validatorSC) activateNewBLSKeys( + registrationData *ValidatorDataV2, + blsKeys [][]byte, + newKeys [][]byte, + validatorConfig *ValidatorConfig, + args *vmcommon.ContractCallInput, +) { + numRegisteredBlsKeys := len(registrationData.BlsPubKeys) + numNodesTooHigh := v.activateStakingFor( + blsKeys, + newKeys, + registrationData, + validatorConfig.NodePrice, + registrationData.RewardAddress, + args.CallerAddr, + ) + + if numNodesTooHigh && len(blsKeys) > 0 { nodeLimit := int64(v.computeNodeLimit()) entry := &vmcommon.LogEntry{ Identifier: []byte(args.Function), Address: args.RecipientAddr, Topics: [][]byte{ []byte(numberOfNodesTooHigh), - big.NewInt(numRegisteredBlsKeys).Bytes(), + big.NewInt(int64(numRegisteredBlsKeys)).Bytes(), big.NewInt(nodeLimit).Bytes(), }, } v.eei.AddLogEntry(entry) } - err = v.saveRegistrationData(args.CallerAddr, registrationData) - if err != nil { - v.eei.AddReturnMessage("cannot save registration data: error " + err.Error()) - return vmcommon.UserError - } - - return vmcommon.Ok } func (v *validatorSC) activateStakingFor( blsKeys [][]byte, + newKeys [][]byte, registrationData *ValidatorDataV2, fixedStakeValue *big.Int, rewardAddress []byte, ownerAddress []byte, -) { - numRegistered := uint64(registrationData.NumRegistered) +) bool { + numActivatedKey := uint64(registrationData.NumRegistered) + + numRegisteredKeys := len(registrationData.BlsPubKeys) + if v.isNumberOfNodesTooHigh(numRegisteredKeys) { + return true + } + + maxNumNodesToActivate := len(blsKeys) + if v.enableEpochsHandler.IsFlagEnabled(common.StakeLimitsFlag) { + maxNumNodesToActivate = v.computeNodeLimit() - numRegisteredKeys + len(newKeys) + } + nodesActivated := 0 + if nodesActivated >= maxNumNodesToActivate && len(blsKeys) >= maxNumNodesToActivate { + return true + } for i := uint64(0); i < uint64(len(blsKeys)); i++ { currentBLSKey := blsKeys[i] @@ -1131,12 +1160,19 @@ func (v *validatorSC) activateStakingFor( } if stakedData.UnStakedNonce == 0 { - numRegistered++ + numActivatedKey++ + } + + nodesActivated++ + if nodesActivated >= maxNumNodesToActivate { + break } } - registrationData.NumRegistered = uint32(numRegistered) - registrationData.LockedStake.Mul(fixedStakeValue, big.NewInt(0).SetUint64(numRegistered)) + registrationData.NumRegistered = uint32(numActivatedKey) + registrationData.LockedStake.Mul(fixedStakeValue, big.NewInt(0).SetUint64(numActivatedKey)) + + return nodesActivated >= maxNumNodesToActivate && len(blsKeys) > maxNumNodesToActivate } func (v *validatorSC) stakeOneNode( @@ -2080,7 +2116,7 @@ func (v *validatorSC) mergeValidatorData(args *vmcommon.ContractCallInput) vmcom validatorConfig := v.getConfig(v.eei.BlockChainHook().CurrentEpoch()) finalValidatorData.LockedStake.Mul(validatorConfig.NodePrice, big.NewInt(int64(finalValidatorData.NumRegistered))) - if v.isNumberOfNodesTooHigh(finalValidatorData) { + if v.isNumberOfNodesTooHigh(len(finalValidatorData.BlsPubKeys)) { v.eei.AddReturnMessage("number of nodes is too high") return vmcommon.UserError } diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index cffce652ff5..8258d8bb27f 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -451,7 +451,7 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { args.StakingSCConfig.NodeLimitPercentage = 0.005 stakingValidatorSc, _ := NewValidatorSmartContract(args) - validatorData := createAValidatorData(25000000, 3, 12500000) + validatorData := createAValidatorData(75000000, 5, 12500000) validatorDataBytes, _ := json.Marshal(&validatorData) eei.GetStorageCalled = func(key []byte) []byte { @@ -487,6 +487,58 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { assert.True(t, called) } +func TestStakingValidatorSC_ExecuteStakeTooManyNodesAddOnly2(t *testing.T) { + t.Parallel() + + arguments := CreateVmContractCallInput() + + eei := &mock.SystemEIStub{} + + args := createMockArgumentsForValidatorSC() + args.Eei = eei + + args.NodesCoordinator = &mock.NodesCoordinatorStub{GetNumTotalEligibleCalled: func() uint64 { + return 1000 + }} + args.StakingSCConfig.NodeLimitPercentage = 0.005 + stakingValidatorSc, _ := NewValidatorSmartContract(args) + + validatorData := createAValidatorData(75000000, 3, 12500000) + validatorDataBytes, _ := json.Marshal(&validatorData) + + eei.GetStorageCalled = func(key []byte) []byte { + if bytes.Equal(key, arguments.CallerAddr) { + return validatorDataBytes + } + return nil + } + called := false + eei.AddLogEntryCalled = func(entry *vmcommon.LogEntry) { + called = true + assert.Equal(t, entry.Topics[0], []byte(numberOfNodesTooHigh)) + } + + stakeCalledInStakingSC := 0 + eei.ExecuteOnDestContextCalled = func(destination, sender []byte, value *big.Int, input []byte) (*vmcommon.VMOutput, error) { + if strings.Contains(string(input), "stake") { + stakeCalledInStakingSC++ + } + return &vmcommon.VMOutput{}, nil + } + + key1 := []byte("Key1") + key2 := []byte("Key2") + key3 := []byte("Key3") + arguments.Function = "stake" + arguments.CallValue = big.NewInt(0).Mul(big.NewInt(3), big.NewInt(10000000)) + arguments.Arguments = [][]byte{big.NewInt(3).Bytes(), key1, []byte("msg1"), key2, []byte("msg2"), key3, []byte("msg3")} + + errCode := stakingValidatorSc.Execute(arguments) + assert.Equal(t, vmcommon.Ok, errCode) + assert.True(t, called) + assert.Equal(t, 2, stakeCalledInStakingSC) +} + func TestStakingValidatorSC_ExecuteStakeAddedNewPubKeysShouldWork(t *testing.T) { t.Parallel() From 5d585835e526ef33927819a3af71078bd138d5ab Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 7 Feb 2024 14:36:04 +0200 Subject: [PATCH 721/958] fix --- node/chainSimulator/chainSimulator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 121032b9e3a..7c5317e52f2 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -176,7 +176,7 @@ func (s *simulator) incrementRoundOnAllValidators() { func (s *simulator) allNodesCreateBlocks() error { for _, node := range s.handlers { - // TODO remove this when we remove all goroutines + // TODO MX-15150 remove this when we remove all goroutines time.Sleep(2 * time.Millisecond) err := node.CreateNewBlock() From 16396d89db75b1645ed75244cba214f3e8e4ae70 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Wed, 7 Feb 2024 15:04:50 +0200 Subject: [PATCH 722/958] more tests more code --- vm/systemSmartContracts/validator_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vm/systemSmartContracts/validator_test.go b/vm/systemSmartContracts/validator_test.go index 8258d8bb27f..758e0167a9d 100644 --- a/vm/systemSmartContracts/validator_test.go +++ b/vm/systemSmartContracts/validator_test.go @@ -466,11 +466,9 @@ func TestStakingValidatorSC_ExecuteStakeTooManyNodes(t *testing.T) { assert.Equal(t, entry.Topics[0], []byte(numberOfNodesTooHigh)) } - stakeCalledInStakingSC := false eei.ExecuteOnDestContextCalled = func(destination, sender []byte, value *big.Int, input []byte) (*vmcommon.VMOutput, error) { if strings.Contains(string(input), "stake") { - stakeCalledInStakingSC = true - assert.False(t, stakeCalledInStakingSC) + assert.Fail(t, "should not stake nodes") } return &vmcommon.VMOutput{}, nil } From 77a8de5accb1eebeae971642b6821a2359e7d1e4 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Wed, 7 Feb 2024 15:54:42 +0200 Subject: [PATCH 723/958] refactored return --- vm/systemSmartContracts/validator.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vm/systemSmartContracts/validator.go b/vm/systemSmartContracts/validator.go index 865e3fe148b..37799ccc447 100644 --- a/vm/systemSmartContracts/validator.go +++ b/vm/systemSmartContracts/validator.go @@ -1094,7 +1094,7 @@ func (v *validatorSC) activateNewBLSKeys( args *vmcommon.ContractCallInput, ) { numRegisteredBlsKeys := len(registrationData.BlsPubKeys) - numNodesTooHigh := v.activateStakingFor( + allNodesActivated := v.activateStakingFor( blsKeys, newKeys, registrationData, @@ -1103,7 +1103,7 @@ func (v *validatorSC) activateNewBLSKeys( args.CallerAddr, ) - if numNodesTooHigh && len(blsKeys) > 0 { + if !allNodesActivated && len(blsKeys) > 0 { nodeLimit := int64(v.computeNodeLimit()) entry := &vmcommon.LogEntry{ Identifier: []byte(args.Function), @@ -1129,18 +1129,18 @@ func (v *validatorSC) activateStakingFor( ) bool { numActivatedKey := uint64(registrationData.NumRegistered) - numRegisteredKeys := len(registrationData.BlsPubKeys) - if v.isNumberOfNodesTooHigh(numRegisteredKeys) { - return true + numAllBLSKeys := len(registrationData.BlsPubKeys) + if v.isNumberOfNodesTooHigh(numAllBLSKeys) { + return false } maxNumNodesToActivate := len(blsKeys) if v.enableEpochsHandler.IsFlagEnabled(common.StakeLimitsFlag) { - maxNumNodesToActivate = v.computeNodeLimit() - numRegisteredKeys + len(newKeys) + maxNumNodesToActivate = v.computeNodeLimit() - numAllBLSKeys + len(newKeys) } nodesActivated := 0 if nodesActivated >= maxNumNodesToActivate && len(blsKeys) >= maxNumNodesToActivate { - return true + return false } for i := uint64(0); i < uint64(len(blsKeys)); i++ { @@ -1172,7 +1172,7 @@ func (v *validatorSC) activateStakingFor( registrationData.NumRegistered = uint32(numActivatedKey) registrationData.LockedStake.Mul(fixedStakeValue, big.NewInt(0).SetUint64(numActivatedKey)) - return nodesActivated >= maxNumNodesToActivate && len(blsKeys) > maxNumNodesToActivate + return nodesActivated < maxNumNodesToActivate || len(blsKeys) <= maxNumNodesToActivate } func (v *validatorSC) stakeOneNode( From 1b6f72efa0a37fe1aca41808c90d371161b591d6 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 7 Feb 2024 20:33:57 +0200 Subject: [PATCH 724/958] - minor fixes + wip fo the delegation scenario #10 --- integrationTests/chainSimulator/interface.go | 17 + .../chainSimulator/staking/delegation_test.go | 323 ++++++++++++++++++ node/chainSimulator/chainSimulator.go | 46 +++ node/chainSimulator/configs/configs.go | 3 +- process/interface.go | 1 + process/peer/validatorsProvider.go | 6 + .../stakingcommon/validatorsProviderStub.go | 10 + 7 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 integrationTests/chainSimulator/interface.go create mode 100644 integrationTests/chainSimulator/staking/delegation_test.go diff --git a/integrationTests/chainSimulator/interface.go b/integrationTests/chainSimulator/interface.go new file mode 100644 index 00000000000..c134f9dffca --- /dev/null +++ b/integrationTests/chainSimulator/interface.go @@ -0,0 +1,17 @@ +package chainSimulator + +import ( + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + "github.com/multiversx/mx-chain-go/node/chainSimulator/process" +) + +// ChainSimulator defines the operations for an entity that can simulate operations of a chain +type ChainSimulator interface { + GenerateBlocks(numOfBlocks int) error + GenerateBlocksUntilEpochIsReached(targetEpoch int32) error + AddValidatorKeys(validatorsPrivateKeys [][]byte) error + GetNodeHandler(shardID uint32) process.NodeHandler + SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) + SetStateMultiple(stateSlice []*dtos.AddressState) error +} diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go new file mode 100644 index 00000000000..8cca371340f --- /dev/null +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -0,0 +1,323 @@ +package staking + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "math/big" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/config" + chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" + "github.com/multiversx/mx-chain-go/node/chainSimulator" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/vm" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const walletAddressBytesLen = 32 +const mockBLSSignature = "010101" +const gasLimitForStakeOperation = 50_000_000 +const gasLimitForConvertOperation = 510_000_000 +const gasLimitForDelegate = 12_000_000 +const minGasPrice = 1000000000 +const txVersion = 1 +const mockTxSignature = "sig" +const queuedStatus = "queued" +const stakedStatus = "staked" +const okReturnCode = "ok" +const maxCap = "00" // no cap +const serviceFee = "0ea1" // 37.45% + +var zeroValue = big.NewInt(0) +var oneEGLD = big.NewInt(1000000000000000000) +var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) + +// Test description +// Test that delegation contract created with MakeNewContractFromValidatorData works properly +// Also check that delegate and undelegate works properly and the top-up remain the same if every delegator undelegates. +// Test that the top-up from normal stake will be transferred after creating the contract and will be used in auction list computing + +// Test scenario +// 1. Add a new validator private key in the multi key handler +// 2. Set the initial state for the owner and the 2 delegators +// 3. Do a stake transaction for the validator key and test that the new key is on queue / auction list and topup is 500 +// 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and topup is 500 +// 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700 +// 6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500 + +func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 1) + }) + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 2) + }) +} + +func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + log.Info("Step 1. Add a new validator private key in the multi key handler") + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + log.Info("Step 2. Set the initial state for the owner and the 2 delegators") + validatorOwner := generateWalletAddressBytes() + validatorOwnerBech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(validatorOwner, log) + mintValue := big.NewInt(3010) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + delegator1 := generateWalletAddressBytes() + delegator1Bech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegator1, log) + delegator2 := generateWalletAddressBytes() + delegator2Bech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegator2, log) + + err = cs.SetStateMultiple([]*dtos.AddressState{ + { + Address: validatorOwnerBech32, + Balance: mintValue.String(), + }, + { + Address: delegator1Bech32, + Balance: mintValue.String(), + }, + { + Address: delegator2Bech32, + Balance: mintValue.String(), + }, + }) + require.Nil(t, err) + + log.Info("working with the following addresses", + "newValidatorOwner", validatorOwnerBech32, "delegator1", delegator1Bech32, "delegator2", delegator2Bech32) + + log.Info("Step 3. Do a stake transaction for the validator key and test that the new key is on queue / auction list and the correct topup") + stakeValue := big.NewInt(0).Set(minimumStakeValue) + addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(500)) + stakeValue.Add(stakeValue, addedStakedValue) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(5) + assert.Nil(t, err) + + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + statistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + + _, found := statistics[blsKeys[0]] + require.False(t, found) + + decodedBLSKey, _ := hex.DecodeString(blsKeys[0]) + testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, addedStakedValue) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorOwner)) + + log.Info("Step 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and the correct topup") + txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) + txConvert := generateTransaction(validatorOwner, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) + convertTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, convertTx) + + delegationAddress := convertTx.Logs.Events[0].Topics[1] + delegationAddressBech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegationAddress, log) + log.Info("generated delegation address", "address", delegationAddressBech32) + + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + statistics, err = metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + + _, found = statistics[blsKeys[0]] + require.False(t, found) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, addedStakedValue) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, delegationAddress)) + + log.Info("Step 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700") + delegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) + txDelegate1 := generateTransaction(delegator1, 0, delegationAddress, delegateValue, "delegate", gasLimitForDelegate) + delegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, delegate1Tx) + + txDelegate2 := generateTransaction(delegator2, 0, delegationAddress, delegateValue, "delegate", gasLimitForDelegate) + delegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate2, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, delegate2Tx) + + expectedTopUp := big.NewInt(0).Mul(oneEGLD, big.NewInt(700)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, expectedTopUp) + assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationAddress)) + + log.Info("6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500") + unDelegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) + txDataField = fmt.Sprintf("unDelegate@%s", hex.EncodeToString(unDelegateValue.Bytes())) + txUnDelegate1 := generateTransaction(delegator1, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + unDelegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unDelegate1Tx) + + txDataField = fmt.Sprintf("unDelegate@%s", hex.EncodeToString(unDelegateValue.Bytes())) + txUnDelegate2 := generateTransaction(delegator2, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + unDelegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnDelegate2, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unDelegate2Tx) + + expectedTopUp = big.NewInt(0).Mul(oneEGLD, big.NewInt(500)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, expectedTopUp) + assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationAddress)) + +} + +func generateWalletAddressBytes() []byte { + buff := make([]byte, walletAddressBytesLen) + _, _ = rand.Read(buff) + + return buff +} + +func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte, topUpInAuctionList *big.Int) { + activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) + if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { + testBLSKeyIsInAuction(t, metachainNode, blsKey, topUpInAuctionList) + return + } + + require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, blsKey)) +} + +func testBLSKeyIsInAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte, topUpInAuctionList *big.Int) { + require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, blsKey)) + + err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + auctionList, err := metachainNode.GetProcessComponents().ValidatorsProvider().GetAuctionList() + require.Nil(t, err) + + require.Equal(t, 1, len(auctionList)) + require.Equal(t, 1, len(auctionList[0].AuctionList)) + require.Equal(t, topUpInAuctionList, auctionList[0].TopUpPerNode) +} + +func getBLSKeyStatus(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) string { + scQuery := &process.SCQuery{ + ScAddress: vm.StakingSCAddress, + FuncName: "getBLSKeyStatus", + CallerAddr: vm.StakingSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{blsKey}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + return string(result.ReturnData[0]) +} + +func getBLSTopUpValue(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte) *big.Int { + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStakedTopUpStakedBlsKeys", + CallerAddr: vm.StakingSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{address}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + return big.NewInt(0).SetBytes(result.ReturnData[0]) +} + +func generateTransaction(sender []byte, nonce uint64, receiver []byte, value *big.Int, data string, gasLimit uint64) *transaction.Transaction { + return &transaction.Transaction{ + Nonce: nonce, + Value: value, + SndAddr: sender, + RcvAddr: receiver, + Data: []byte(data), + GasLimit: gasLimit, + GasPrice: minGasPrice, + ChainID: []byte(configs.ChainID), + Version: txVersion, + Signature: []byte(mockTxSignature), + } +} diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index dc7cdf98f8d..74dcfa79cfb 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -168,6 +168,52 @@ func (s *simulator) GenerateBlocks(numOfBlocks int) error { return nil } +// GenerateBlocksUntilEpochIsReached will generate blocks until the epoch is reached +func (s *simulator) GenerateBlocksUntilEpochIsReached(targetEpoch int32) error { + s.mutex.Lock() + defer s.mutex.Unlock() + + maxNumberOfRounds := 10000 + for idx := 0; idx < maxNumberOfRounds; idx++ { + time.Sleep(time.Millisecond * 2) + s.incrementRoundOnAllValidators() + err := s.allNodesCreateBlocks() + if err != nil { + return err + } + + epochReachedOnAllNodes, err := s.isTargetEpochReached(targetEpoch) + if err != nil { + return err + } + + if epochReachedOnAllNodes { + return nil + } + } + return fmt.Errorf("exceeded rounds to generate blocks") +} + +func (s *simulator) isTargetEpochReached(targetEpoch int32) (bool, error) { + metachainNode := s.nodes[core.MetachainShardId] + metachainEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() + + for shardID, n := range s.nodes { + if shardID != core.MetachainShardId { + if int32(n.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch()) < int32(metachainEpoch-1) { + return false, fmt.Errorf("shard %d is with at least 2 epochs behind metachain shard node epoch %d, metachain node epoch %d", + shardID, n.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch(), metachainEpoch) + } + } + + if int32(n.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch()) < targetEpoch { + return false, nil + } + } + + return true, nil +} + func (s *simulator) incrementRoundOnAllValidators() { for _, node := range s.handlers { node.IncrementRound() diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index e6785fee6f1..59feda78dfd 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -107,8 +107,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) maxNumNodes := uint64((args.MinNodesPerShard+args.NumNodesWaitingListShard)*args.NumOfShards) + - uint64(args.MetaChainMinNodes+args.NumNodesWaitingListMeta) + - 2*uint64(args.NumOfShards+1+args.NumNodesWaitingListShard+args.NumNodesWaitingListMeta) + uint64(args.MetaChainMinNodes+args.NumNodesWaitingListMeta) configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes numMaxNumNodesEnableEpochs := len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) diff --git a/process/interface.go b/process/interface.go index 4ae7c1f178f..69b1b139e89 100644 --- a/process/interface.go +++ b/process/interface.go @@ -319,6 +319,7 @@ type TransactionLogProcessorDatabase interface { type ValidatorsProvider interface { GetLatestValidators() map[string]*validator.ValidatorStatistics GetAuctionList() ([]*common.AuctionListValidatorAPIResponse, error) + ForceUpdate() error IsInterfaceNil() bool Close() error } diff --git a/process/peer/validatorsProvider.go b/process/peer/validatorsProvider.go index 3509a45ad40..7c3b8505310 100644 --- a/process/peer/validatorsProvider.go +++ b/process/peer/validatorsProvider.go @@ -317,6 +317,12 @@ func shouldCombine(triePeerType common.PeerType, currentPeerType common.PeerType return isLeaving && isEligibleOrWaiting } +// ForceUpdate will trigger the update process of all caches +func (vp *validatorsProvider) ForceUpdate() error { + vp.updateCache() + return vp.updateAuctionListCache() +} + // IsInterfaceNil returns true if there is no value under the interface func (vp *validatorsProvider) IsInterfaceNil() bool { return vp == nil diff --git a/testscommon/stakingcommon/validatorsProviderStub.go b/testscommon/stakingcommon/validatorsProviderStub.go index 587fa0225ff..0db49b4fde8 100644 --- a/testscommon/stakingcommon/validatorsProviderStub.go +++ b/testscommon/stakingcommon/validatorsProviderStub.go @@ -9,6 +9,7 @@ import ( type ValidatorsProviderStub struct { GetLatestValidatorsCalled func() map[string]*validator.ValidatorStatistics GetAuctionListCalled func() ([]*common.AuctionListValidatorAPIResponse, error) + ForceUpdateCalled func() error } // GetLatestValidators - @@ -29,6 +30,15 @@ func (vp *ValidatorsProviderStub) GetAuctionList() ([]*common.AuctionListValidat return nil, nil } +// ForceUpdate - +func (vp *ValidatorsProviderStub) ForceUpdate() error { + if vp.ForceUpdateCalled != nil { + return vp.ForceUpdateCalled() + } + + return nil +} + // Close - func (vp *ValidatorsProviderStub) Close() error { return nil From 45a32353705d9311285b0c54a8318c154ceb971b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 8 Feb 2024 09:59:44 +0200 Subject: [PATCH 725/958] - finalized scenario --- .../chainSimulator/staking/delegation_test.go | 163 ++++++++++++++---- 1 file changed, 128 insertions(+), 35 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 8cca371340f..652938e1042 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-core-go/data/validator" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" @@ -34,6 +35,7 @@ const txVersion = 1 const mockTxSignature = "sig" const queuedStatus = "queued" const stakedStatus = "staked" +const auctionStatus = "auction" const okReturnCode = "ok" const maxCap = "00" // no cap const serviceFee = "0ea1" // 37.45% @@ -47,14 +49,6 @@ var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) // Also check that delegate and undelegate works properly and the top-up remain the same if every delegator undelegates. // Test that the top-up from normal stake will be transferred after creating the contract and will be used in auction list computing -// Test scenario -// 1. Add a new validator private key in the multi key handler -// 2. Set the initial state for the owner and the 2 delegators -// 3. Do a stake transaction for the validator key and test that the new key is on queue / auction list and topup is 500 -// 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and topup is 500 -// 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700 -// 6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500 - func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -63,9 +57,16 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ HasValue: true, - Value: 20, + Value: 30, } + // Test scenario done in staking 3.5 phase (staking v4 is not active) + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Do a stake transaction for the validator key and test that the new key is on queue and topup is 500 + // 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue and topup is 500 + // 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700 + // 6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500 t.Run("staking ph 4 is not active", func(t *testing.T) { cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, @@ -93,6 +94,14 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { testChainSimulatorMakeNewContractFromValidatorData(t, cs, 1) }) + + // Test scenario done in staking v4 phase step 1 + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Do a stake transaction for the validator key and test that the new key is on auction list and topup is 500 + // 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on auction list and topup is 500 + // 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700 + // 6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500 t.Run("staking ph 4 step 1 is active", func(t *testing.T) { cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, @@ -120,6 +129,76 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { testChainSimulatorMakeNewContractFromValidatorData(t, cs, 2) }) + + // Test scenario done in staking v4 phase step 2 + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Do a stake transaction for the validator key and test that the new key is on auction list and topup is 500 + // 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on auction list and topup is 500 + // 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700 + // 6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500 + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 3) + }) + + // Test scenario done in staking v4 phase step 3 + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Do a stake transaction for the validator key and test that the new key is on auction list and topup is 500 + // 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on auction list and topup is 500 + // 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700 + // 6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500 + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 4) + }) } func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { @@ -174,19 +253,10 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi require.Nil(t, err) require.NotNil(t, stakeTx) - err = cs.GenerateBlocks(5) + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) - err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() - require.Nil(t, err) - statistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() - require.Nil(t, err) - - _, found := statistics[blsKeys[0]] - require.False(t, found) - - decodedBLSKey, _ := hex.DecodeString(blsKeys[0]) - testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, addedStakedValue) + testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], addedStakedValue) assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorOwner)) log.Info("Step 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and the correct topup") @@ -202,13 +272,8 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) - statistics, err = metachainNode.GetFacadeHandler().ValidatorStatisticsApi() - require.Nil(t, err) - - _, found = statistics[blsKeys[0]] - require.False(t, found) - testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, addedStakedValue) + testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], addedStakedValue) assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, delegationAddress)) log.Info("Step 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700") @@ -224,7 +289,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi require.NotNil(t, delegate2Tx) expectedTopUp := big.NewInt(0).Mul(oneEGLD, big.NewInt(700)) - testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, expectedTopUp) + testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], expectedTopUp) assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationAddress)) log.Info("6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500") @@ -242,7 +307,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi require.NotNil(t, unDelegate2Tx) expectedTopUp = big.NewInt(0).Mul(oneEGLD, big.NewInt(500)) - testBLSKeyIsInQueueOrAuction(t, metachainNode, decodedBLSKey, expectedTopUp) + testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], expectedTopUp) assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationAddress)) } @@ -254,27 +319,55 @@ func generateWalletAddressBytes() []byte { return buff } -func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte, topUpInAuctionList *big.Int) { +func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey string, topUpInAuctionList *big.Int) { + decodedBLSKey, _ := hex.DecodeString(blsKey) + err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + statistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { - testBLSKeyIsInAuction(t, metachainNode, blsKey, topUpInAuctionList) + testBLSKeyIsInAuction(t, metachainNode, decodedBLSKey, blsKey, topUpInAuctionList, statistics) return } - require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, blsKey)) + // in staking ph 2/3.5 we do not find the bls key on the validator statistics + _, found := statistics[blsKey] + require.False(t, found) + require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey)) } -func testBLSKeyIsInAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte, topUpInAuctionList *big.Int) { - require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, blsKey)) +func testBLSKeyIsInAuction( + t *testing.T, + metachainNode chainSimulatorProcess.NodeHandler, + blsKeyBytes []byte, + blsKey string, + topUpInAuctionList *big.Int, + validatorStatistics map[string]*validator.ValidatorStatistics, +) { + require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, blsKeyBytes)) err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) auctionList, err := metachainNode.GetProcessComponents().ValidatorsProvider().GetAuctionList() require.Nil(t, err) - require.Equal(t, 1, len(auctionList)) + actionListSize := 1 + currentEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() + if metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step2Flag) <= currentEpoch { + // starting from phase 2, we have the shuffled out nodes from the previous epoch in the action list + actionListSize = 2 + } + + require.Equal(t, actionListSize, len(auctionList)) require.Equal(t, 1, len(auctionList[0].AuctionList)) - require.Equal(t, topUpInAuctionList, auctionList[0].TopUpPerNode) + require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) + + // in staking ph 4 we should find the key in the validators statics + validatorInfo, found := validatorStatistics[blsKey] + require.True(t, found) + require.Equal(t, auctionStatus, validatorInfo.ValidatorStatus) } func getBLSKeyStatus(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) string { From c754ca76d0489a7896beb3fb435447617c64879b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 8 Feb 2024 10:09:07 +0200 Subject: [PATCH 726/958] - added scenario number --- integrationTests/chainSimulator/staking/delegation_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 652938e1042..8a04af2c5f2 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -49,6 +49,7 @@ var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) // Also check that delegate and undelegate works properly and the top-up remain the same if every delegator undelegates. // Test that the top-up from normal stake will be transferred after creating the contract and will be used in auction list computing +// Internal test scenario #10 func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") From ec8ac54fef372775299ebd9d86ba96fbd1eb562b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 8 Feb 2024 11:59:57 +0200 Subject: [PATCH 727/958] - fixes --- integrationTests/chainSimulator/interface.go | 3 ++ .../chainSimulator/staking/delegation_test.go | 41 ++++------------ .../staking/stakeAndUnStake_test.go | 17 +++++-- node/chainSimulator/chainSimulator.go | 48 +++++++++++++++++++ node/chainSimulator/configs/configs.go | 33 +++++++------ 5 files changed, 94 insertions(+), 48 deletions(-) diff --git a/integrationTests/chainSimulator/interface.go b/integrationTests/chainSimulator/interface.go index c134f9dffca..34469ab7357 100644 --- a/integrationTests/chainSimulator/interface.go +++ b/integrationTests/chainSimulator/interface.go @@ -1,6 +1,8 @@ package chainSimulator import ( + "math/big" + "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/node/chainSimulator/process" @@ -14,4 +16,5 @@ type ChainSimulator interface { GetNodeHandler(shardID uint32) process.NodeHandler SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) SetStateMultiple(stateSlice []*dtos.AddressState) error + GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, error) } diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 8a04af2c5f2..4cc35700e76 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -1,7 +1,6 @@ package staking import ( - "crypto/rand" "encoding/hex" "fmt" "math/big" @@ -17,7 +16,6 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" - "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/vm" @@ -25,7 +23,6 @@ import ( "github.com/stretchr/testify/require" ) -const walletAddressBytesLen = 32 const mockBLSSignature = "010101" const gasLimitForStakeOperation = 50_000_000 const gasLimitForConvertOperation = 510_000_000 @@ -215,31 +212,20 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi metachainNode := cs.GetNodeHandler(core.MetachainShardId) log.Info("Step 2. Set the initial state for the owner and the 2 delegators") - validatorOwner := generateWalletAddressBytes() - validatorOwnerBech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(validatorOwner, log) mintValue := big.NewInt(3010) mintValue = mintValue.Mul(oneEGLD, mintValue) - delegator1 := generateWalletAddressBytes() - delegator1Bech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegator1, log) - delegator2 := generateWalletAddressBytes() - delegator2Bech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegator2, log) - - err = cs.SetStateMultiple([]*dtos.AddressState{ - { - Address: validatorOwnerBech32, - Balance: mintValue.String(), - }, - { - Address: delegator1Bech32, - Balance: mintValue.String(), - }, - { - Address: delegator2Bech32, - Balance: mintValue.String(), - }, - }) + validatorOwnerBech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + validatorOwner, err := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) + + delegator1Bech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + delegator1, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(delegator1Bech32) + + delegator2Bech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) + delegator2, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(delegator2Bech32) log.Info("working with the following addresses", "newValidatorOwner", validatorOwnerBech32, "delegator1", delegator1Bech32, "delegator2", delegator2Bech32) @@ -313,13 +299,6 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi } -func generateWalletAddressBytes() []byte { - buff := make([]byte, walletAddressBytesLen) - _, _ = rand.Read(buff) - - return buff -} - func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey string, topUpInAuctionList *big.Int) { decodedBLSKey, _ := hex.DecodeString(blsKey) err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index c17b969c4d9..2b25d5b9700 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -49,11 +49,12 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { Value: 20, } + numOfShards := uint32(3) cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, TempDir: t.TempDir(), PathToInitialConfig: defaultPathToInitialConfig, - NumOfShards: 3, + NumOfShards: numOfShards, GenesisTimestamp: startTime, RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, @@ -62,6 +63,10 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { MetaChainMinNodes: 3, NumNodesWaitingListMeta: 1, NumNodesWaitingListShard: 1, + AlterConfigsFunction: func(cfg *config.Configs) { + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue + configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) + }, }) require.Nil(t, err) require.NotNil(t, cm) @@ -172,11 +177,12 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { HasValue: true, Value: 20, } + numOfShards := uint32(3) cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, TempDir: t.TempDir(), PathToInitialConfig: defaultPathToInitialConfig, - NumOfShards: 3, + NumOfShards: numOfShards, GenesisTimestamp: startTime, RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, @@ -186,6 +192,8 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { AlterConfigsFunction: func(cfg *config.Configs) { cfg.SystemSCConfig.StakingSystemSCConfig.NodeLimitPercentage = 1 cfg.GeneralConfig.ValidatorStatistics.CacheRefreshIntervalInSec = 1 + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue + configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) }, }) require.Nil(t, err) @@ -243,7 +251,10 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { err = cm.GenerateBlocks(1) require.Nil(t, err) - results, err := cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() + metachainNode := cm.GetNodeHandler(core.MetachainShardId) + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + results, err := metachainNode.GetFacadeHandler().AuctionListApi() require.Nil(t, err) require.Equal(t, newValidatorOwner, results[0].Owner) require.Equal(t, 20, len(results[0].AuctionList)) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 587fd23757a..c308ba2f35f 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -2,13 +2,16 @@ package chainSimulator import ( "bytes" + "crypto/rand" "encoding/hex" "errors" "fmt" + "math/big" "sync" "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-core-go/data/transaction" @@ -20,6 +23,7 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + mxChainSharding "github.com/multiversx/mx-chain-go/sharding" logger "github.com/multiversx/mx-chain-logger-go" ) @@ -275,6 +279,50 @@ func (s *simulator) AddValidatorKeys(validatorsPrivateKeys [][]byte) error { return nil } +// GenerateAndMintWalletAddress will generate an address in the provided shard and will mint that address with the provided value +// if the target shard ID value does not correspond to a node handled by the chain simulator, the address will be generated in a random shard ID +func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, error) { + addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() + nodeHandler := s.GetNodeHandler(targetShardID) + var buff []byte + if check.IfNil(nodeHandler) { + buff = generateAddress(addressConverter.Len()) + } else { + buff = generateAddressInShard(nodeHandler.GetShardCoordinator(), addressConverter.Len()) + } + + address, err := addressConverter.Encode(buff) + if err != nil { + return "", err + } + + err = s.SetStateMultiple([]*dtos.AddressState{ + { + Address: address, + Balance: value.String(), + }, + }) + + return address, err +} + +func generateAddressInShard(shardCoordinator mxChainSharding.Coordinator, len int) []byte { + for { + buff := generateAddress(len) + shardID := shardCoordinator.ComputeId(buff) + if shardID == shardCoordinator.SelfId() { + return buff + } + } +} + +func generateAddress(len int) []byte { + buff := make([]byte, len) + _, _ = rand.Read(buff) + + return buff +} + func (s *simulator) setValidatorKeysForNode(node process.NodeHandler, validatorsPrivateKeys [][]byte) error { for idx, privateKey := range validatorsPrivateKeys { diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 59feda78dfd..5d9e42c80c8 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -68,10 +68,6 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } - if args.AlterConfigsFunction != nil { - args.AlterConfigsFunction(configs) - } - configs.GeneralConfig.GeneralSettings.ChainID = ChainID // empty genesis smart contracts file @@ -109,16 +105,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi maxNumNodes := uint64((args.MinNodesPerShard+args.NumNodesWaitingListShard)*args.NumOfShards) + uint64(args.MetaChainMinNodes+args.NumNodesWaitingListMeta) - configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes - numMaxNumNodesEnableEpochs := len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) - for idx := 0; idx < numMaxNumNodesEnableEpochs-1; idx++ { - configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[idx].MaxNumNodes = uint32(maxNumNodes) - } - - configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].EpochEnable = configs.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch - prevEntry := configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-2] - configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].NodesToShufflePerShard = prevEntry.NodesToShufflePerShard - configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].MaxNumNodes = prevEntry.MaxNumNodes - (args.NumOfShards+1)*prevEntry.NodesToShufflePerShard + SetMaxNumberOfNodesInConfigs(configs, maxNumNodes, args.NumOfShards) // set compatible trie configs configs.GeneralConfig.StateTriesConfig.SnapshotsEnabled = false @@ -135,6 +122,10 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } + if args.AlterConfigsFunction != nil { + args.AlterConfigsFunction(configs) + } + return &ArgsConfigsSimulator{ Configs: *configs, ValidatorsPrivateKeys: privateKeys, @@ -143,6 +134,20 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi }, nil } +// SetMaxNumberOfNodesInConfigs will correctly set the max number of nodes in configs +func SetMaxNumberOfNodesInConfigs(cfg *config.Configs, maxNumNodes uint64, numOfShards uint32) { + cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes + numMaxNumNodesEnableEpochs := len(cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) + for idx := 0; idx < numMaxNumNodesEnableEpochs-1; idx++ { + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[idx].MaxNumNodes = uint32(maxNumNodes) + } + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].EpochEnable = cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch + prevEntry := cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-2] + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].NodesToShufflePerShard = prevEntry.NodesToShufflePerShard + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].MaxNumNodes = prevEntry.MaxNumNodes - (numOfShards+1)*prevEntry.NodesToShufflePerShard +} + func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { addressConverter, err := factory.NewPubkeyConverter(configs.GeneralConfig.AddressPubkeyConverter) if err != nil { From c375bf555a88a30c108a7b7dd6afda6484e6dfcc Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 8 Feb 2024 12:03:49 +0200 Subject: [PATCH 728/958] - fixed linter issues --- integrationTests/chainSimulator/staking/delegation_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 4cc35700e76..74e9afde678 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -217,7 +217,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi validatorOwnerBech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - validatorOwner, err := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) + validatorOwner, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) delegator1Bech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) From 53d5a12ca8fcd1d67a4d470618187b51896056c8 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 13:37:25 +0200 Subject: [PATCH 729/958] jail and unJail testcase --- .../chainSimulator/staking/jail_test.go | 146 ++++++++++++++++++ node/chainSimulator/process/processor.go | 5 +- 2 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 integrationTests/chainSimulator/staking/jail_test.go diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go new file mode 100644 index 00000000000..b3728e803f7 --- /dev/null +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -0,0 +1,146 @@ +package staking + +import ( + "encoding/hex" + "fmt" + "math/big" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/config" + chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" + "github.com/multiversx/mx-chain-go/node/chainSimulator" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/vm" + "github.com/stretchr/testify/require" +) + +// Test scenario +// 1. generate a new validator key +// 2. do a stake transaction +// 3. check validator is in waiting list and wait till validator is jailed +// 4. do an unJail transaction +// 5. staking v4 not enabled --- node status should be new +// 6. activate staking v4 -- step 1 --- node should go in auction list +// 7. step 2 --- node should go in auction list +// 8. step 3 --- node should go in auction list +func TestChainSimulator_ValidatorJailUnJail(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + + numOfShards := uint32(3) + + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: numOfShards, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 1, + NumNodesWaitingListShard: 1, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 5 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 6 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 7 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 7 + + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue + configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) + + cfg.RatingsConfig.ShardChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 + cfg.RatingsConfig.ShardChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + cfg.RatingsConfig.MetaChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 + cfg.RatingsConfig.MetaChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + // testcase 1 + t.Run("staking ph 4 is not active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, cs, 4, "new") + }) + + t.Run("staking ph 4 step 1 active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, cs, 5, "auction") + }) + + t.Run("staking ph 4 step 2 active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, cs, 6, "auction") + }) + + t.Run("staking ph 4 step 3 active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, cs, 7, "auction") + }) +} + +func testChainSimulatorJailAndUnJail(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32, nodeStatusAfterUnJail string) { + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + err := cs.GenerateBlocks(30) + require.Nil(t, err) + + _, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + mintValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(3000)) + walletKeyBech, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + walletKey, err := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(walletKeyBech) + require.Nil(t, err) + + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(walletKey, 0, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + // wait node to be jailed + err = cs.GenerateBlocksUntilEpochIsReached(4) + require.Nil(t, err) + + decodedBLSKey, _ := hex.DecodeString(blsKeys[0]) + status := getBLSKeyStatus(t, metachainNode, decodedBLSKey) + require.Equal(t, "jailed", status) + + // do an unjail transaction + unJailValue, _ := big.NewInt(0).SetString("2500000000000000000", 10) + txUnJailDataField := fmt.Sprintf("unJail@%s", blsKeys[0]) + txUnJail := generateTransaction(walletKey, 1, vm.ValidatorSCAddress, unJailValue, txUnJailDataField, gasLimitForStakeOperation) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + unJailTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnJail, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unJailTx) + + // wait node to be jailed + err = cs.GenerateBlocks(1) + require.Nil(t, err) + + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey) + require.Equal(t, "staked", status) + + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + validatorsStatistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + require.Equal(t, nodeStatusAfterUnJail, validatorsStatistics[blsKeys[0]].ValidatorStatus) +} diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index 2e88d3593d2..f91edc182dd 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -38,8 +38,9 @@ func (creator *blocksCreator) IncrementRound() { func (creator *blocksCreator) CreateNewBlock() error { bp := creator.nodeHandler.GetProcessComponents().BlockProcessor() - nonce, round, prevHash, prevRandSeed, epoch := creator.getPreviousHeaderData() - newHeader, err := bp.CreateNewHeader(round+1, nonce+1) + nonce, _, prevHash, prevRandSeed, epoch := creator.getPreviousHeaderData() + round := creator.nodeHandler.GetCoreComponents().RoundHandler().Index() + newHeader, err := bp.CreateNewHeader(uint64(round), nonce+1) if err != nil { return err } From bdd0aa86f4ba0f99b16613f54696997eaafff015 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 13:48:21 +0200 Subject: [PATCH 730/958] FIX: Previous list --- integrationTests/vm/staking/stakingV4_test.go | 65 ++++++++++--------- node/chainSimulator/chainSimulator_test.go | 2 +- node/chainSimulator/configs/configs.go | 2 +- process/peer/process.go | 3 + .../indexHashedNodesCoordinator.go | 4 +- state/accounts/peerAccount.go | 4 ++ state/interface.go | 1 + state/validatorInfo.go | 4 +- testscommon/state/peerAccountHandlerMock.go | 8 ++- testscommon/transactionCoordinatorMock.go | 4 ++ 10 files changed, 62 insertions(+), 35 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index f98ccdfa40f..bc539c954a0 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" @@ -86,6 +87,19 @@ func remove(slice [][]byte, elem []byte) [][]byte { return ret } +func getSimilarValues(slice1, slice2 [][]byte) [][]byte { + ret := make([][]byte, 0) + for _, value := range slice2 { + if searchInSlice(slice1, value) { + copiedVal := make([]byte, len(value)) + copy(copiedVal, value) + ret = append(ret, copiedVal) + } + } + + return ret +} + func unStake(t *testing.T, owner []byte, accountsDB state.AccountsAdapter, marshaller marshal.Marshalizer, stake *big.Int) { validatorSC := stakingcommon.LoadUserAccount(accountsDB, vm.ValidatorSCAddress) ownerStoredData, _, err := validatorSC.RetrieveValue(owner) @@ -747,7 +761,7 @@ func TestStakingV4_UnStakeNodes(t *testing.T) { node.Process(t, 3) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 4) - require.Len(t, getAllPubKeys(currNodesConfig.waiting), 3) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 4) require.Len(t, getAllPubKeys(currNodesConfig.leaving), 3) // All unStaked nodes in previous epoch are now leaving requireMapContains(t, currNodesConfig.leaving, unStakedNodesInStakingV4Step1Epoch) @@ -1342,12 +1356,12 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { }, { EpochEnable: 1, - MaxNumNodes: 16, + MaxNumNodes: 18, NodesToShufflePerShard: 2, }, { EpochEnable: stakingV4Step3EnableEpoch, - MaxNumNodes: 8, + MaxNumNodes: 12, NodesToShufflePerShard: 2, }, }, @@ -1372,23 +1386,23 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { // NewOwner0 stakes 1 node with top up = 0 before staking v4; should be sent to new nodes, since there are enough slots newOwner0 := "newOwner0" - newNodes0 := map[string]*NodesRegisterData{ + newOwner0BlsKeys := [][]byte{generateAddress(101)} + node.ProcessStake(t, map[string]*NodesRegisterData{ newOwner0: { - BLSKeys: [][]byte{generateAddress(101)}, + BLSKeys: newOwner0BlsKeys, TotalStake: big.NewInt(nodePrice), }, - } - // Check staked node before staking v4 is sent to new - node.ProcessStake(t, newNodes0) + }) currNodesConfig = node.NodesConfig - requireSliceContainsNumOfElements(t, currNodesConfig.new, newNodes0[newOwner0].BLSKeys, 1) + requireSliceContainsNumOfElements(t, currNodesConfig.new, newOwner0BlsKeys, 1) // UnStake one of the initial nodes node.ProcessUnStake(t, map[string][][]byte{ owner1: {owner1Stats.EligibleBlsKeys[core.MetachainShardId][0]}, }) - // We should have 12 initial nodes + 1 extra waiting node that was forced to remain eligible + // Fast-forward few epochs such that the whole staking v4 is activated. + // We should have 12 initial nodes + 1 extra waiting node that was forced to remain eligible(because of legacy bug) node.Process(t, 49) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) @@ -1406,37 +1420,30 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { currNodesConfig = node.NodesConfig requireSameSliceDifferentOrder(t, currNodesConfig.auction, newNodes1[newOwner1].BLSKeys) - // After 2 epochs, unStake all previously staked keys. Some of them have been already sent to eligible, but most - // of them are still in auction. Their status should be: leaving now, but their previous values were auction. + // After 2 epochs, unStake all previously staked keys. Some of them have been already sent to eligible/waiting, but most + // of them are still in auction. UnStaked node's from auction status should be: leaving now, but their previous values were auction. // We should not force/consider his auction nodes as being eligible in the next epoch node.Process(t, 10) currNodesConfig = node.NodesConfig newOwner1AuctionNodes := getSimilarValues(currNodesConfig.auction, newNodes1[newOwner1].BLSKeys) newOwner1EligibleNodes := getSimilarValues(getAllPubKeys(currNodesConfig.eligible), newNodes1[newOwner1].BLSKeys) newOwner1WaitingNodes := getSimilarValues(getAllPubKeys(currNodesConfig.waiting), newNodes1[newOwner1].BLSKeys) + newOwner1ActiveNodes := append(newOwner1EligibleNodes, newOwner1WaitingNodes...) + + txCoordMock, _ := node.TxCoordinator.(*testscommon.TransactionCoordinatorMock) + txCoordMock.ClearStoredMbs() node.ProcessUnStake(t, map[string][][]byte{ newOwner1: newNodes1[newOwner1].BLSKeys, }) node.Process(t, 5) currNodesConfig = node.NodesConfig - requireMapContains(t, currNodesConfig.leaving, newOwner1AuctionNodes) require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) + requireMapContains(t, currNodesConfig.leaving, newOwner1AuctionNodes) + requireMapDoesNotContain(t, currNodesConfig.eligible, newOwner1AuctionNodes) + requireMapDoesNotContain(t, currNodesConfig.waiting, newOwner1AuctionNodes) - //requireMapContains(t, currNodesConfig.eligible, newOwner1EligibleNodes) - - _ = newOwner1EligibleNodes - _ = newOwner1WaitingNodes - -} - -func getSimilarValues(slice1, slice2 [][]byte) [][]byte { - ret := make([][]byte, 0) - for _, value := range slice2 { - if searchInSlice(slice1, value) { - ret = append(ret, value) - } - } - - return ret + allCurrentActiveNodes := append(getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(currNodesConfig.waiting)...) + owner1NodesThatAreStillRemaining := getSimilarValues(allCurrentActiveNodes, newOwner1ActiveNodes) + require.NotZero(t, len(owner1NodesThatAreStillRemaining)) } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 84798f97d09..f52ad839c31 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -283,7 +283,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { sendTxAndGenerateBlockTilTxIsExecuted(t, chainSimulator, tx) // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards - err = chainSimulator.GenerateBlocks(50) + err = chainSimulator.GenerateBlocks(1000) require.Nil(t, err) accountValidatorOwner, _, err = chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index d904ce0b6a0..24488d031b4 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -104,7 +104,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.SmartContractsStorageForSCQuery.DB.Type = string(storageunit.MemoryDB) configs.GeneralConfig.SmartContractsStorageSimulate.DB.Type = string(storageunit.MemoryDB) - maxNumNodes := uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + uint64(args.NumOfShards+1) + maxNumNodes := 2*uint64(args.MinNodesPerShard*args.NumOfShards+args.MetaChainMinNodes) + uint64(args.NumOfShards+1) configs.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake = maxNumNodes numMaxNumNodesEnableEpochs := len(configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch) for idx := 0; idx < numMaxNumNodesEnableEpochs-1; idx++ { diff --git a/process/peer/process.go b/process/peer/process.go index 2c2be271183..4c04de6a25d 100644 --- a/process/peer/process.go +++ b/process/peer/process.go @@ -255,6 +255,9 @@ func (vs *validatorStatistics) saveUpdatesForList( peerAcc.SetListAndIndex(shardID, string(common.JailedList), uint32(index), isStakingV4Started) } else if isNodeLeaving { peerAcc.SetListAndIndex(shardID, string(common.LeavingList), uint32(index), isStakingV4Started) + if isStakingV4Started { + peerAcc.SetPreviousList(string(peerType)) + } } else { peerAcc.SetListAndIndex(shardID, string(peerType), uint32(index), isStakingV4Started) } diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index fd730752248..b3afb3c7577 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -826,7 +826,7 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( shardId := validatorInfo.ShardId previousList := validatorInfo.PreviousList - log.Error("leaving node not found in eligible or waiting", + log.Debug("checking leaving node", "current list", validatorInfo.List, "previous list", previousList, "current index", validatorInfo.Index, @@ -861,6 +861,8 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( "previous index", validatorInfo.PreviousIndex, "pk", currentValidator.PubKey(), "shardId", shardId) + + return } func (ihnc *indexHashedNodesCoordinator) handleErrorLog(err error, message string) { diff --git a/state/accounts/peerAccount.go b/state/accounts/peerAccount.go index 406b197366b..7164bc5cb8d 100644 --- a/state/accounts/peerAccount.go +++ b/state/accounts/peerAccount.go @@ -163,6 +163,10 @@ func (pa *peerAccount) GetTotalValidatorSuccessRate() state.SignRate { return &pa.TotalValidatorSuccessRate } +func (pa *peerAccount) SetPreviousList(list string) { + pa.PreviousList = list +} + // IsInterfaceNil return if there is no value under the interface func (pa *peerAccount) IsInterfaceNil() bool { return pa == nil diff --git a/state/interface.go b/state/interface.go index e5dd0b3f9d8..bf515803346 100644 --- a/state/interface.go +++ b/state/interface.go @@ -60,6 +60,7 @@ type PeerAccountHandler interface { GetConsecutiveProposerMisses() uint32 SetConsecutiveProposerMisses(uint322 uint32) ResetAtNewEpoch() + SetPreviousList(list string) vmcommon.AccountHandler } diff --git a/state/validatorInfo.go b/state/validatorInfo.go index 931b81d66a3..924447955ca 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -25,9 +25,9 @@ func (vi *ValidatorInfo) SetPreviousList(list string) { } func (vi *ValidatorInfo) SetListAndIndex(list string, index uint32, updatePreviousValues bool) { - if updatePreviousValues && list != vi.List { - vi.PreviousIndex = vi.Index + if updatePreviousValues { vi.PreviousList = vi.List + vi.PreviousIndex = vi.Index } vi.List = list diff --git a/testscommon/state/peerAccountHandlerMock.go b/testscommon/state/peerAccountHandlerMock.go index 406e7b23fa7..870836cc00d 100644 --- a/testscommon/state/peerAccountHandlerMock.go +++ b/testscommon/state/peerAccountHandlerMock.go @@ -14,6 +14,7 @@ type PeerAccountHandlerMock struct { IncreaseValidatorSuccessRateValue uint32 DecreaseValidatorSuccessRateValue uint32 IncreaseValidatorIgnoredSignaturesValue uint32 + PreviousList string IncreaseLeaderSuccessRateCalled func(uint32) DecreaseLeaderSuccessRateCalled func(uint32) @@ -311,7 +312,12 @@ func (p *PeerAccountHandlerMock) SetListAndIndex(shardID uint32, list string, in } } +// SetPreviousList - +func (p *PeerAccountHandlerMock) SetPreviousList(list string) { + p.PreviousList = list +} + // IsInterfaceNil - func (p *PeerAccountHandlerMock) IsInterfaceNil() bool { - return false + return p == nil } diff --git a/testscommon/transactionCoordinatorMock.go b/testscommon/transactionCoordinatorMock.go index 0f087b40b16..cd25a769912 100644 --- a/testscommon/transactionCoordinatorMock.go +++ b/testscommon/transactionCoordinatorMock.go @@ -251,6 +251,10 @@ func (tcm *TransactionCoordinatorMock) AddTransactions(txHandlers []data.Transac tcm.AddTransactionsCalled(txHandlers, blockType) } +func (tcm *TransactionCoordinatorMock) ClearStoredMbs() { + tcm.miniBlocks = make([]*block.MiniBlock, 0) +} + // IsInterfaceNil returns true if there is no value under the interface func (tcm *TransactionCoordinatorMock) IsInterfaceNil() bool { return tcm == nil From b9abfe674365e6caacaa21cd71c5f02478e05059 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 13:50:16 +0200 Subject: [PATCH 731/958] small refactoring --- .../chainSimulator/staking/jail_test.go | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index b3728e803f7..d581454eec4 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/config" - chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" @@ -31,6 +31,25 @@ func TestChainSimulator_ValidatorJailUnJail(t *testing.T) { t.Skip("this is not a short test") } + // testcase 1 + t.Run("staking ph 4 is not active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, 4, "new") + }) + + t.Run("staking ph 4 step 1 active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, 5, "auction") + }) + + t.Run("staking ph 4 step 2 active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, 6, "auction") + }) + + t.Run("staking ph 4 step 3 active", func(t *testing.T) { + testChainSimulatorJailAndUnJail(t, 7, "auction") + }) +} + +func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatusAfterUnJail string) { startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ @@ -72,27 +91,8 @@ func TestChainSimulator_ValidatorJailUnJail(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) - // testcase 1 - t.Run("staking ph 4 is not active", func(t *testing.T) { - testChainSimulatorJailAndUnJail(t, cs, 4, "new") - }) - - t.Run("staking ph 4 step 1 active", func(t *testing.T) { - testChainSimulatorJailAndUnJail(t, cs, 5, "auction") - }) - - t.Run("staking ph 4 step 2 active", func(t *testing.T) { - testChainSimulatorJailAndUnJail(t, cs, 6, "auction") - }) - - t.Run("staking ph 4 step 3 active", func(t *testing.T) { - testChainSimulatorJailAndUnJail(t, cs, 7, "auction") - }) -} - -func testChainSimulatorJailAndUnJail(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32, nodeStatusAfterUnJail string) { metachainNode := cs.GetNodeHandler(core.MetachainShardId) - err := cs.GenerateBlocks(30) + err = cs.GenerateBlocks(30) require.Nil(t, err) _, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) @@ -130,6 +130,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, cs chainSimulatorIntegrationT unJailTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnJail, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, unJailTx) + require.Equal(t, transaction.TxStatusSuccess, unJailTx.Status) // wait node to be jailed err = cs.GenerateBlocks(1) From aba5176eacbebce9cdb88447a12cc8e1639d05ec Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 14:01:41 +0200 Subject: [PATCH 732/958] fix test --- integrationTests/chainSimulator/staking/jail_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index d581454eec4..464c64438dc 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -31,7 +31,6 @@ func TestChainSimulator_ValidatorJailUnJail(t *testing.T) { t.Skip("this is not a short test") } - // testcase 1 t.Run("staking ph 4 is not active", func(t *testing.T) { testChainSimulatorJailAndUnJail(t, 4, "new") }) @@ -90,6 +89,9 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus }) require.Nil(t, err) require.NotNil(t, cs) + defer func() { + _ = cs.Close() + }() metachainNode := cs.GetNodeHandler(core.MetachainShardId) err = cs.GenerateBlocks(30) From e6aaea33bd5afd1704169b9d0125d918f9c599ac Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 14:12:35 +0200 Subject: [PATCH 733/958] fixes --- .../chainSimulator/staking/jail_test.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index 464c64438dc..bf3fdce456f 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -17,15 +17,12 @@ import ( "github.com/stretchr/testify/require" ) -// Test scenario -// 1. generate a new validator key -// 2. do a stake transaction -// 3. check validator is in waiting list and wait till validator is jailed -// 4. do an unJail transaction -// 5. staking v4 not enabled --- node status should be new -// 6. activate staking v4 -- step 1 --- node should go in auction list -// 7. step 2 --- node should go in auction list -// 8. step 3 --- node should go in auction list +// Test description +// All test cases will do a stake transaction and wait till the new node is jailed +// testcase1 -- unJail transaction will be sent when staking v3.5 is still action --> node status should be `new` after unjail +// testcase2 -- unJail transaction will be sent when staking v4 step1 is action --> node status should be `auction` after unjail +// testcase3 -- unJail transaction will be sent when staking v4 step2 is action --> node status should be `auction` after unjail +// testcase4 -- unJail transaction will be sent when staking v4 step3 is action --> node status should be `auction` after unjail func TestChainSimulator_ValidatorJailUnJail(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -134,7 +131,6 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus require.NotNil(t, unJailTx) require.Equal(t, transaction.TxStatusSuccess, unJailTx.Status) - // wait node to be jailed err = cs.GenerateBlocks(1) require.Nil(t, err) From 6fb252137b8472888948cdf54ed164b83577bc4a Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 8 Feb 2024 14:23:17 +0200 Subject: [PATCH 734/958] - call chainSimulator.Close on all occasions to avoid resource leaks --- .../chainSimulator/staking/delegation_test.go | 8 +++ .../staking/stakeAndUnStake_test.go | 69 ++++++++++--------- node/chainSimulator/chainSimulator.go | 8 +-- node/chainSimulator/chainSimulator_test.go | 17 ++--- 4 files changed, 58 insertions(+), 44 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 74e9afde678..ed5425f092f 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -90,6 +90,8 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 1) }) @@ -125,6 +127,8 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 2) }) @@ -160,6 +164,8 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 3) }) @@ -195,6 +201,8 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMakeNewContractFromValidatorData(t, cs, 4) }) } diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 2b25d5b9700..e3ab27d7c25 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -50,7 +50,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { } numOfShards := uint32(3) - cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, TempDir: t.TempDir(), PathToInitialConfig: defaultPathToInitialConfig, @@ -69,25 +69,27 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { }, }) require.Nil(t, err) - require.NotNil(t, cm) + require.NotNil(t, cs) - err = cm.GenerateBlocks(30) + defer cs.Close() + + err = cs.GenerateBlocks(30) require.Nil(t, err) // Step 1 --- add a new validator key in the chain simulator privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) require.Nil(t, err) - err = cm.AddValidatorKeys(privateKey) + err = cs.AddValidatorKeys(privateKey) require.Nil(t, err) newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" - newValidatorOwnerBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) + newValidatorOwnerBytes, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" - rcvAddrBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(rcv) + rcvAddrBytes, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(rcv) // Step 2 --- set an initial balance for the address that will initialize all the transactions - err = cm.SetStateMultiple([]*dtos.AddressState{ + err = cs.SetStateMultiple([]*dtos.AddressState{ { Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", Balance: "10000000000000000000000", @@ -109,23 +111,23 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ChainID: []byte(configs.ChainID), Version: 1, } - stakeTx, err := cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeTx) - shardIDValidatorOwner := cm.GetNodeHandler(0).GetShardCoordinator().ComputeId(newValidatorOwnerBytes) - accountValidatorOwner, _, err := cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) + shardIDValidatorOwner := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(newValidatorOwnerBytes) + accountValidatorOwner, _, err := cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) require.Nil(t, err) balanceBeforeActiveValidator := accountValidatorOwner.Balance // Step 5 --- create an unStake transaction with the bls key of an initial validator and execute the transaction to make place for the validator that was added at step 3 - firstValidatorKey, err := cm.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() + firstValidatorKey, err := cs.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() require.Nil(t, err) - initialAddressWithValidators := cm.GetInitialWalletKeys().InitialWalletWithStake.Address - senderBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(initialAddressWithValidators) - shardID := cm.GetNodeHandler(0).GetShardCoordinator().ComputeId(senderBytes) - initialAccount, _, err := cm.GetNodeHandler(shardID).GetFacadeHandler().GetAccount(initialAddressWithValidators, coreAPI.AccountQueryOptions{}) + initialAddressWithValidators := cs.GetInitialWalletKeys().InitialWalletWithStake.Address + senderBytes, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(initialAddressWithValidators) + shardID := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(senderBytes) + initialAccount, _, err := cs.GetNodeHandler(shardID).GetFacadeHandler().GetAccount(initialAddressWithValidators, coreAPI.AccountQueryOptions{}) require.Nil(t, err) tx = &transaction.Transaction{ Nonce: initialAccount.Nonce, @@ -139,18 +141,21 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ChainID: []byte(configs.ChainID), Version: 1, } - _, err = cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) + _, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards - err = cm.GenerateBlocks(50) + err = cs.GenerateBlocks(50) require.Nil(t, err) - validatorStatistics, err := cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().ValidatorStatisticsApi() + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + validatorStatistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() require.Nil(t, err) checkValidatorsRating(t, validatorStatistics) - accountValidatorOwner, _, err = cm.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) require.Nil(t, err) balanceAfterActiveValidator := accountValidatorOwner.Balance @@ -178,7 +183,7 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { Value: 20, } numOfShards := uint32(3) - cm, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, TempDir: t.TempDir(), PathToInitialConfig: defaultPathToInitialConfig, @@ -197,25 +202,27 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { }, }) require.Nil(t, err) - require.NotNil(t, cm) + require.NotNil(t, cs) + + defer cs.Close() - err = cm.GenerateBlocks(150) + err = cs.GenerateBlocks(150) require.Nil(t, err) // Step 1 --- add a new validator key in the chain simulator numOfNodes := 20 validatorSecretKeysBytes, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(numOfNodes) require.Nil(t, err) - err = cm.AddValidatorKeys(validatorSecretKeysBytes) + err = cs.AddValidatorKeys(validatorSecretKeysBytes) require.Nil(t, err) newValidatorOwner := "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl" - newValidatorOwnerBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) + newValidatorOwnerBytes, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(newValidatorOwner) rcv := "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l" - rcvAddrBytes, _ := cm.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(rcv) + rcvAddrBytes, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(rcv) // Step 2 --- set an initial balance for the address that will initialize all the transactions - err = cm.SetStateMultiple([]*dtos.AddressState{ + err = cs.SetStateMultiple([]*dtos.AddressState{ { Address: "erd1l6xt0rqlyzw56a3k8xwwshq2dcjwy3q9cppucvqsmdyw8r98dz3sae0kxl", Balance: "1000000000000000000000000", @@ -244,14 +251,14 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { Version: 1, } - txFromNetwork, err := cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) + txFromNetwork, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, txFromNetwork) - err = cm.GenerateBlocks(1) + err = cs.GenerateBlocks(1) require.Nil(t, err) - metachainNode := cm.GetNodeHandler(core.MetachainShardId) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) results, err := metachainNode.GetFacadeHandler().AuctionListApi() @@ -260,10 +267,10 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { require.Equal(t, 20, len(results[0].AuctionList)) checkTotalQualified(t, results, 8) - err = cm.GenerateBlocks(100) + err = cs.GenerateBlocks(100) require.Nil(t, err) - results, err = cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() + results, err = cs.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().AuctionListApi() require.Nil(t, err) checkTotalQualified(t, results, 0) } diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index c308ba2f35f..e8c4bb33500 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -458,7 +458,7 @@ func (s *simulator) setStateSystemAccount(state *dtos.AddressState) error { } // Close will stop and close the simulator -func (s *simulator) Close() error { +func (s *simulator) Close() { s.mutex.Lock() defer s.mutex.Unlock() @@ -470,11 +470,9 @@ func (s *simulator) Close() error { } } - if len(errorStrings) == 0 { - return nil + if len(errorStrings) != 0 { + log.Error("error closing chain simulator", "error", components.AggregateErrors(errorStrings, components.ErrClose)) } - - return components.AggregateErrors(errorStrings, components.ErrClose) } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index ab9d4bc2d91..b0758044fa4 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -44,8 +44,7 @@ func TestNewChainSimulator(t *testing.T) { time.Sleep(time.Second) - err = chainSimulator.Close() - assert.Nil(t, err) + chainSimulator.Close() } func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { @@ -71,13 +70,12 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { require.Nil(t, err) require.NotNil(t, chainSimulator) + defer chainSimulator.Close() + time.Sleep(time.Second) err = chainSimulator.GenerateBlocks(30) require.Nil(t, err) - - err = chainSimulator.Close() - assert.Nil(t, err) } func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { @@ -106,6 +104,8 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { require.Nil(t, err) require.NotNil(t, chainSimulator) + defer chainSimulator.Close() + facade, err := NewChainSimulatorFacade(chainSimulator) require.Nil(t, err) @@ -125,9 +125,6 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { fmt.Sprintf("initial balance %s, balance after rewards %s", initialAccount.GetBalance().String(), accountAfterRewards.GetBalance().String())) fmt.Println(chainSimulator.GetRestAPIInterfaces()) - - err = chainSimulator.Close() - assert.Nil(t, err) } func TestChainSimulator_SetState(t *testing.T) { @@ -156,6 +153,8 @@ func TestChainSimulator_SetState(t *testing.T) { require.Nil(t, err) require.NotNil(t, chainSimulator) + defer chainSimulator.Close() + keyValueMap := map[string]string{ "01": "01", "02": "02", @@ -200,6 +199,8 @@ func TestChainSimulator_SetEntireState(t *testing.T) { require.Nil(t, err) require.NotNil(t, chainSimulator) + defer chainSimulator.Close() + balance := "431271308732096033771131" contractAddress := "erd1qqqqqqqqqqqqqpgqmzzm05jeav6d5qvna0q2pmcllelkz8xddz3syjszx5" accountState := &dtos.AddressState{ From b98d0af02eab10c00e39d2b156ec335b4dee4cfa Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Thu, 8 Feb 2024 15:48:02 +0200 Subject: [PATCH 735/958] MX-15154: test CreateNewDelegationContract works properly --- .../chainSimulator/staking/delegation_test.go | 473 +++++++++++++++++- 1 file changed, 459 insertions(+), 14 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 74e9afde678..55c734c4ffc 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -1,21 +1,28 @@ package staking import ( + "crypto/rand" "encoding/hex" "fmt" "math/big" + "strings" "testing" "time" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-core-go/data/validator" + dataVm "github.com/multiversx/mx-chain-core-go/data/vm" + "github.com/multiversx/mx-chain-crypto-go/signing" + "github.com/multiversx/mx-chain-crypto-go/signing/mcl" + mclsig "github.com/multiversx/mx-chain-crypto-go/signing/mcl/singlesig" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/vm" @@ -26,6 +33,9 @@ import ( const mockBLSSignature = "010101" const gasLimitForStakeOperation = 50_000_000 const gasLimitForConvertOperation = 510_000_000 +const gasLimitForDelegationContractCreationOperation = 500_000_000 +const gasLimitForAddNodesOperation = 500_000_000 +const gasLimitForUndelegateOperation = 500_000_000 const gasLimitForDelegate = 12_000_000 const minGasPrice = 1000000000 const txVersion = 1 @@ -36,7 +46,9 @@ const auctionStatus = "auction" const okReturnCode = "ok" const maxCap = "00" // no cap const serviceFee = "0ea1" // 37.45% +const walletAddressBytesLen = 32 +var stakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) // 1250 EGLD var zeroValue = big.NewInt(0) var oneEGLD = big.NewInt(1000000000000000000) var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) @@ -243,8 +255,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) - testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], addedStakedValue) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorOwner)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorOwner, blsKeys[0], addedStakedValue, 1) log.Info("Step 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and the correct topup") txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) @@ -260,8 +271,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) - testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], addedStakedValue) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, delegationAddress)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], addedStakedValue, 1) log.Info("Step 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700") delegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) @@ -276,8 +286,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi require.NotNil(t, delegate2Tx) expectedTopUp := big.NewInt(0).Mul(oneEGLD, big.NewInt(700)) - testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], expectedTopUp) - assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationAddress)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], expectedTopUp, 1) log.Info("6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500") unDelegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) @@ -294,21 +303,21 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi require.NotNil(t, unDelegate2Tx) expectedTopUp = big.NewInt(0).Mul(oneEGLD, big.NewInt(500)) - testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], expectedTopUp) - assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationAddress)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], expectedTopUp, 1) } -func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey string, topUpInAuctionList *big.Int) { +func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte, blsKey string, expectedTopUp *big.Int, actionListSize int) { decodedBLSKey, _ := hex.DecodeString(blsKey) err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) statistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() require.Nil(t, err) + assert.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, address)) activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { - testBLSKeyIsInAuction(t, metachainNode, decodedBLSKey, blsKey, topUpInAuctionList, statistics) + testBLSKeyIsInAuction(t, metachainNode, decodedBLSKey, blsKey, expectedTopUp, actionListSize, statistics) return } @@ -324,6 +333,7 @@ func testBLSKeyIsInAuction( blsKeyBytes []byte, blsKey string, topUpInAuctionList *big.Int, + actionListSize int, validatorStatistics map[string]*validator.ValidatorStatistics, ) { require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, blsKeyBytes)) @@ -333,16 +343,17 @@ func testBLSKeyIsInAuction( auctionList, err := metachainNode.GetProcessComponents().ValidatorsProvider().GetAuctionList() require.Nil(t, err) - actionListSize := 1 currentEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() if metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step2Flag) <= currentEpoch { // starting from phase 2, we have the shuffled out nodes from the previous epoch in the action list - actionListSize = 2 + actionListSize += 1 } require.Equal(t, actionListSize, len(auctionList)) - require.Equal(t, 1, len(auctionList[0].AuctionList)) - require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) + if actionListSize != 0 { + require.Equal(t, 1, len(auctionList[0].AuctionList)) + require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) + } // in staking ph 4 we should find the key in the validators statics validatorInfo, found := validatorStatistics[blsKey] @@ -350,6 +361,440 @@ func testBLSKeyIsInAuction( require.Equal(t, auctionStatus, validatorInfo.ValidatorStatus) } +// Test description +// Test the creation of a new delegation contract, adding nodes to it, delegating, and undelegating. + +// Test scenario +// 1. Initialize the chain simulator +// 2. Generate blocks to activate staking phases +// 3. Create a new delegation contract +// 4. Add validator nodes to the delegation contract +// 5. Perform delegation operations +// 6. Perform undelegation operations +// 7. Validate the results at each step + +func TestChainSimulator_CreateNewDelegationContract(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test scenario done in staking 3.5 phase (staking v4 is not active) + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Create a new delegation contract with 1250 egld + // 3. Add node to the delegation contract + // 4. Execute 2 delegation operations of 1250 EGLD each, check the topup is 3750 + // 5. Stake node, check the topup is 1250, check the node is staked + // 5. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 1250 + // 6. Check the node is unstaked in the next epoch + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorCreateNewDelegationContract(t, cs, 1) + }) + + // Test scenario done in staking v4 phase step 1 + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Create a new delegation contract with 1250 egld + // 3. Add node to the delegation contract + // 4. Execute 2 delegation operations of 1250 EGLD each, check the topup is 3750 + // 5. Stake node, check the topup is 1250, check the node is in action list + // 5. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 1250 + // 6. Check the node is unstaked in the next epoch + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorCreateNewDelegationContract(t, cs, 2) + }) + + // Test scenario done in staking v4 phase step 2 + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Create a new delegation contract with 1250 egld + // 3. Add node to the delegation contract + // 4. Execute 2 delegation operations of 1250 EGLD each, check the topup is 3750 + // 5. Stake node, check the topup is 1250, check the node is in action list + // 5. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 1250 + // 6. Check the node is unstaked in the next epoch + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorCreateNewDelegationContract(t, cs, 3) + }) + + // Test scenario done in staking v4 phase step 3 + // 1. Add a new validator private key in the multi key handler + // 2. Set the initial state for the owner and the 2 delegators + // 3. Create a new delegation contract with 1250 egld + // 3. Add node to the delegation contract + // 4. Execute 2 delegation operations of 1250 EGLD each, check the topup is 3750 + // 5. Stake node, check the topup is 1250, check the node is in action list + // 5. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 1250 + // 6. Check the node is unstaked in the next epoch + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorCreateNewDelegationContract(t, cs, 4) + }) + +} + +func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + // Create new validator owner and delegators with initial funds + validatorOwnerBytes := generateWalletAddressBytes() + validatorOwner, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(validatorOwnerBytes) + delegator1Bytes := generateWalletAddressBytes() + delegator1, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(delegator1Bytes) + delegator2Bytes := generateWalletAddressBytes() + delegator2, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(delegator2Bytes) + initialFunds := big.NewInt(0).Mul(oneEGLD, big.NewInt(10000)) // 10000 EGLD for each + addresses := []*dtos.AddressState{ + {Address: validatorOwner, Balance: initialFunds.String()}, + {Address: delegator1, Balance: initialFunds.String()}, + {Address: delegator2, Balance: initialFunds.String()}, + } + err = cs.SetStateMultiple(addresses) + require.Nil(t, err) + + // Step 3: Create a new delegation contract + maxDelegationCap := big.NewInt(0).Mul(oneEGLD, big.NewInt(51000)) // 51000 EGLD cap + serviceFee := big.NewInt(100) // 100 as service fee + txCreateDelegationContract := generateTransaction(validatorOwnerBytes, 0, vm.DelegationManagerSCAddress, stakeValue, + fmt.Sprintf("createNewDelegationContract@%s@%s", hex.EncodeToString(maxDelegationCap.Bytes()), hex.EncodeToString(serviceFee.Bytes())), + gasLimitForDelegationContractCreationOperation) + createDelegationContractTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txCreateDelegationContract, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, createDelegationContractTx) + + // Check delegation contract creation was successful + data := createDelegationContractTx.SmartContractResults[0].Data + parts := strings.Split(data, "@") + require.Equal(t, 3, len(parts)) + + require.Equal(t, hex.EncodeToString([]byte("ok")), parts[1]) + delegationContractAddressHex, _ := hex.DecodeString(parts[2]) + delegationContractAddress, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(delegationContractAddressHex) + + output, err := executeQuery(cs, core.MetachainShardId, vm.DelegationManagerSCAddress, "getAllContractAddresses", nil) + require.Nil(t, err) + returnAddress, err := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(output.ReturnData[0]) + require.Equal(t, delegationContractAddress, returnAddress) + delegationContractAddressBytes := output.ReturnData[0] + + // Step 2: Add validator nodes to the delegation contract + // This step requires generating BLS keys for validators, signing messages, and sending the "addNodes" transaction. + // Add checks to verify nodes are added successfully. + validatorSecretKeysBytes, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + err = cs.AddValidatorKeys(validatorSecretKeysBytes) + require.Nil(t, err) + + signatures := getSignatures(delegationContractAddressBytes, validatorSecretKeysBytes) + txAddNodes := generateTransaction(validatorOwnerBytes, 1, delegationContractAddressBytes, zeroValue, addNodesTxData(blsKeys, signatures), gasLimitForAddNodesOperation) + addNodesTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txAddNodes, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, addNodesTx) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) + require.Nil(t, err) + stakedKeys, notStakedKeys, unStakedKeys := getNodesFromContract(output.ReturnData) + require.Equal(t, 0, len(stakedKeys)) + require.Equal(t, 1, len(notStakedKeys)) + require.Equal(t, blsKeys[0], hex.EncodeToString(notStakedKeys[0])) + require.Equal(t, 0, len(unStakedKeys)) + + expectedTopUp := new(big.Int).Set(stakeValue) + expectedTotalStaked := new(big.Int).Set(stakeValue) + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) + require.Nil(t, err) + require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{validatorOwnerBytes}) + require.Nil(t, err) + require.Equal(t, stakeValue, big.NewInt(0).SetBytes(output.ReturnData[0])) + + // Step 3: Perform delegation operations + txDelegate1 := generateTransaction(delegator1Bytes, 0, delegationContractAddressBytes, stakeValue, "delegate", gasLimitForDelegate) + delegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, delegate1Tx) + + expectedTopUp = expectedTopUp.Add(expectedTopUp, stakeValue) + expectedTotalStaked = expectedTotalStaked.Add(expectedTotalStaked, stakeValue) + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) + require.Nil(t, err) + require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator1Bytes}) + require.Nil(t, err) + require.Equal(t, stakeValue, big.NewInt(0).SetBytes(output.ReturnData[0])) + + txDelegate2 := generateTransaction(delegator2Bytes, 0, delegationContractAddressBytes, stakeValue, "delegate", gasLimitForDelegate) + delegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate2, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, delegate2Tx) + + expectedTopUp = expectedTopUp.Add(expectedTopUp, stakeValue) + expectedTotalStaked = expectedTopUp.Add(expectedTotalStaked, stakeValue) + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) + require.Nil(t, err) + require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator2Bytes}) + require.Nil(t, err) + require.Equal(t, stakeValue, big.NewInt(0).SetBytes(output.ReturnData[0])) + + // Step 4: Perform stakeNodes + + txStakeNodes := generateTransaction(validatorOwnerBytes, 2, delegationContractAddressBytes, zeroValue, fmt.Sprintf("stakeNodes@%s", blsKeys[0]), gasLimitForDelegate) + stakeNodesTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStakeNodes, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeNodesTx) + + expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) + expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) + require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) + require.Nil(t, err) + stakedKeys, notStakedKeys, unStakedKeys = getNodesFromContract(output.ReturnData) + require.Equal(t, 1, len(stakedKeys)) + require.Equal(t, blsKeys[0], hex.EncodeToString(stakedKeys[0])) + require.Equal(t, 0, len(notStakedKeys)) + require.Equal(t, 0, len(unStakedKeys)) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationContractAddressBytes, blsKeys[0], expectedTopUp, 0) + + // Step 5: Perform unDelegate from 1 user + // The nodes should remain in the staked state + // The total active stake should be reduced by the amount undelegated + + txUndelegate1 := generateTransaction(delegator1Bytes, 1, delegationContractAddressBytes, zeroValue, fmt.Sprintf("unDelegate@%s", hex.EncodeToString(stakeValue.Bytes())), gasLimitForUndelegateOperation) + undelegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUndelegate1, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, undelegate1Tx) + + expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) + expectedTotalStaked = expectedTopUp.Sub(expectedTotalStaked, stakeValue) + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) + require.Nil(t, err) + require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator1Bytes}) + require.Nil(t, err) + require.Equal(t, "0", big.NewInt(0).SetBytes(output.ReturnData[0])) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) + require.Nil(t, err) + stakedKeys, notStakedKeys, unStakedKeys = getNodesFromContract(output.ReturnData) + require.Equal(t, 1, len(stakedKeys)) + require.Equal(t, blsKeys[0], hex.EncodeToString(stakedKeys[0])) + require.Equal(t, 0, len(notStakedKeys)) + require.Equal(t, 0, len(unStakedKeys)) + + // Step 6: Perform unDelegate from last user + // The nodes should remain in the unStaked state + // The total active stake should be reduced by the amount undelegated + + txUndelegate2 := generateTransaction(delegator2Bytes, 1, delegationContractAddressBytes, zeroValue, fmt.Sprintf("unDelegate@%s", hex.EncodeToString(stakeValue.Bytes())), gasLimitForUndelegateOperation) + undelegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUndelegate2, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, undelegate2Tx) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) + require.Nil(t, err) + require.Equal(t, "1250000000000000000000", big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, zeroValue, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator2Bytes}) + require.Nil(t, err) + require.Equal(t, "0", big.NewInt(0).SetBytes(output.ReturnData[0])) + + // still staked until epoch change + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) + require.Nil(t, err) + stakedKeys, notStakedKeys, unStakedKeys = getNodesFromContract(output.ReturnData) + require.Equal(t, 1, len(stakedKeys)) + require.Equal(t, blsKeys[0], hex.EncodeToString(stakedKeys[0])) + require.Equal(t, 0, len(notStakedKeys)) + require.Equal(t, 0, len(unStakedKeys)) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) + require.Nil(t, err) + stakedKeys, notStakedKeys, unStakedKeys = getNodesFromContract(output.ReturnData) + require.Equal(t, 0, len(stakedKeys)) + require.Equal(t, 0, len(notStakedKeys)) + require.Equal(t, 1, len(unStakedKeys)) + require.Equal(t, blsKeys[0], hex.EncodeToString(unStakedKeys[0])) +} + +func generateWalletAddressBytes() []byte { + buff := make([]byte, walletAddressBytesLen) + _, _ = rand.Read(buff) + + return buff +} + +func executeQuery(cs chainSimulatorIntegrationTests.ChainSimulator, shardID uint32, scAddress []byte, funcName string, args [][]byte) (*dataVm.VMOutputApi, error) { + output, _, err := cs.GetNodeHandler(shardID).GetFacadeHandler().ExecuteSCQuery(&process.SCQuery{ + ScAddress: scAddress, + FuncName: funcName, + Arguments: args, + }) + return output, err +} + +func addNodesTxData(blsKeys []string, sigs [][]byte) string { + txData := "addNodes" + + for i := range blsKeys { + txData = txData + "@" + blsKeys[i] + "@" + hex.EncodeToString(sigs[i]) + } + + return txData +} + +func getSignatures(msg []byte, blsKeys [][]byte) [][]byte { + signer := mclsig.NewBlsSigner() + + signatures := make([][]byte, len(blsKeys)) + for i, blsKey := range blsKeys { + sk, _ := signing.NewKeyGenerator(mcl.NewSuiteBLS12()).PrivateKeyFromByteArray(blsKey) + signatures[i], _ = signer.Sign(sk, msg) + } + + return signatures +} + +func getNodesFromContract(returnData [][]byte) ([][]byte, [][]byte, [][]byte) { + var stakedKeys, notStakedKeys, unStakedKeys [][]byte + + // Placeholder for the current list being populated + var currentList *[][]byte + + for _, data := range returnData { + switch string(data) { + case "staked": + currentList = &stakedKeys + case "notStaked": + currentList = ¬StakedKeys + case "unStaked": + currentList = &unStakedKeys + default: + if currentList != nil { + *currentList = append(*currentList, data) + } + } + } + return stakedKeys, notStakedKeys, unStakedKeys +} + func getBLSKeyStatus(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) string { scQuery := &process.SCQuery{ ScAddress: vm.StakingSCAddress, From ee628b99eeb7f5980c302605cdffdc532620d523 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 15:52:12 +0200 Subject: [PATCH 736/958] FEAT: Extend extra edge case leaving nodes --- integrationTests/vm/staking/stakingV4_test.go | 67 ++++++++++++++----- .../testMetaProcessorWithCustomNodesConfig.go | 2 +- node/chainSimulator/chainSimulator_test.go | 2 +- .../indexHashedNodesCoordinator.go | 4 +- state/accounts/peerAccount.go | 2 +- 5 files changed, 57 insertions(+), 20 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index bc539c954a0..542a8e2313a 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -87,7 +87,7 @@ func remove(slice [][]byte, elem []byte) [][]byte { return ret } -func getSimilarValues(slice1, slice2 [][]byte) [][]byte { +func getIntersection(slice1, slice2 [][]byte) [][]byte { ret := make([][]byte, 0) for _, value := range slice2 { if searchInSlice(slice1, value) { @@ -1402,7 +1402,8 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { }) // Fast-forward few epochs such that the whole staking v4 is activated. - // We should have 12 initial nodes + 1 extra waiting node that was forced to remain eligible(because of legacy bug) + // We should have 12 initial nodes + 1 extra waiting node that was forced to remain eligible(because of legacy code + // where all leaving nodes were considered to be eligible) node.Process(t, 49) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) @@ -1410,30 +1411,32 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { // Stake 10 extra nodes and check that they are sent to auction newOwner1 := "newOwner1" - newNodes1 := map[string]*NodesRegisterData{ + newOwner1BlsKeys := generateAddresses(303, 10) + node.ProcessStake(t, map[string]*NodesRegisterData{ newOwner1: { - BLSKeys: generateAddresses(303, 10), + BLSKeys: newOwner1BlsKeys, TotalStake: big.NewInt(nodePrice * 10), }, - } - node.ProcessStake(t, newNodes1) + }) currNodesConfig = node.NodesConfig - requireSameSliceDifferentOrder(t, currNodesConfig.auction, newNodes1[newOwner1].BLSKeys) + requireSameSliceDifferentOrder(t, currNodesConfig.auction, newOwner1BlsKeys) // After 2 epochs, unStake all previously staked keys. Some of them have been already sent to eligible/waiting, but most - // of them are still in auction. UnStaked node's from auction status should be: leaving now, but their previous values were auction. - // We should not force/consider his auction nodes as being eligible in the next epoch + // of them are still in auction. UnStaked node's from auction status should be: leaving now, but their previous list was auction. + // We should not force his auction nodes as being eligible in the next epoch. We should only force his existing active + // nodes to remain in the system. node.Process(t, 10) currNodesConfig = node.NodesConfig - newOwner1AuctionNodes := getSimilarValues(currNodesConfig.auction, newNodes1[newOwner1].BLSKeys) - newOwner1EligibleNodes := getSimilarValues(getAllPubKeys(currNodesConfig.eligible), newNodes1[newOwner1].BLSKeys) - newOwner1WaitingNodes := getSimilarValues(getAllPubKeys(currNodesConfig.waiting), newNodes1[newOwner1].BLSKeys) + newOwner1AuctionNodes := getIntersection(currNodesConfig.auction, newOwner1BlsKeys) + newOwner1EligibleNodes := getIntersection(getAllPubKeys(currNodesConfig.eligible), newOwner1BlsKeys) + newOwner1WaitingNodes := getIntersection(getAllPubKeys(currNodesConfig.waiting), newOwner1BlsKeys) newOwner1ActiveNodes := append(newOwner1EligibleNodes, newOwner1WaitingNodes...) + require.Equal(t, len(newOwner1AuctionNodes)+len(newOwner1ActiveNodes), len(newOwner1BlsKeys)) // sanity check txCoordMock, _ := node.TxCoordinator.(*testscommon.TransactionCoordinatorMock) txCoordMock.ClearStoredMbs() node.ProcessUnStake(t, map[string][][]byte{ - newOwner1: newNodes1[newOwner1].BLSKeys, + newOwner1: newOwner1BlsKeys, }) node.Process(t, 5) @@ -1444,6 +1447,40 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { requireMapDoesNotContain(t, currNodesConfig.waiting, newOwner1AuctionNodes) allCurrentActiveNodes := append(getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(currNodesConfig.waiting)...) - owner1NodesThatAreStillRemaining := getSimilarValues(allCurrentActiveNodes, newOwner1ActiveNodes) - require.NotZero(t, len(owner1NodesThatAreStillRemaining)) + owner1NodesThatAreStillForcedToRemain := getIntersection(allCurrentActiveNodes, newOwner1ActiveNodes) + require.NotZero(t, len(owner1NodesThatAreStillForcedToRemain)) + + // Fast-forward some epochs, no error should occur, and we should have our initial config of: + // - 12 eligible nodes + // - 1 waiting list + // - some forced nodes to remain from newOwner1 + node.Process(t, 10) + currNodesConfig = node.NodesConfig + require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) + require.Len(t, getAllPubKeys(currNodesConfig.waiting), 1) + allCurrentActiveNodes = append(getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(currNodesConfig.waiting)...) + owner1NodesThatAreStillForcedToRemain = getIntersection(allCurrentActiveNodes, newOwner1ActiveNodes) + require.NotZero(t, len(owner1NodesThatAreStillForcedToRemain)) + + // Stake 10 extra nodes such that the forced eligible nodes from previous newOwner1 can leave the system + // and are replaced by new nodes + newOwner2 := "newOwner2" + newOwner2BlsKeys := generateAddresses(403, 10) + node.ProcessStake(t, map[string]*NodesRegisterData{ + newOwner2: { + BLSKeys: newOwner2BlsKeys, + TotalStake: big.NewInt(nodePrice * 10), + }, + }) + currNodesConfig = node.NodesConfig + requireSliceContains(t, currNodesConfig.auction, newOwner2BlsKeys) + + // Fas-forward multiple epochs and check that newOwner1's forced nodes from previous epochs left + node.Process(t, 20) + currNodesConfig = node.NodesConfig + allCurrentNodesInSystem := append(getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(currNodesConfig.waiting)...) + allCurrentNodesInSystem = append(allCurrentNodesInSystem, getAllPubKeys(currNodesConfig.leaving)...) + allCurrentNodesInSystem = append(allCurrentNodesInSystem, currNodesConfig.auction...) + owner1LeftNodes := getIntersection(owner1NodesThatAreStillForcedToRemain, allCurrentNodesInSystem) + require.Zero(t, len(owner1LeftNodes)) } diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index 80d0238b17b..c46fb8c58c8 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -161,7 +161,7 @@ func (tmp *TestMetaProcessor) doUnStake( CallerAddr: owner, Arguments: blsKeys, CallValue: big.NewInt(0), - GasProvided: 10, + GasProvided: 100, }, RecipientAddr: vm.ValidatorSCAddress, Function: "unStake", diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index f52ad839c31..0221bbe0920 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -283,7 +283,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { sendTxAndGenerateBlockTilTxIsExecuted(t, chainSimulator, tx) // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards - err = chainSimulator.GenerateBlocks(1000) + err = chainSimulator.GenerateBlocks(500) require.Nil(t, err) accountValidatorOwner, _, err = chainSimulator.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(newValidatorOwner, coreAPI.AccountQueryOptions{}) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index b3afb3c7577..2e253d1d865 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -754,7 +754,7 @@ func (ihnc *indexHashedNodesCoordinator) computeNodesConfigFromList( case string(common.EligibleList): eligibleMap[validatorInfo.ShardId] = append(eligibleMap[validatorInfo.ShardId], currentValidator) case string(common.LeavingList): - log.Info("leaving node validatorInfo", + log.Debug("leaving node validatorInfo", "pk", validatorInfo.PublicKey, "previous list", validatorInfo.PreviousList, "current index", validatorInfo.Index, @@ -855,7 +855,7 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( return } - log.Error("leaving node not found in eligible or waiting", + log.Debug("leaving node not found in eligible or waiting", "previous list", previousList, "current index", validatorInfo.Index, "previous index", validatorInfo.PreviousIndex, diff --git a/state/accounts/peerAccount.go b/state/accounts/peerAccount.go index 7164bc5cb8d..5511e2ca714 100644 --- a/state/accounts/peerAccount.go +++ b/state/accounts/peerAccount.go @@ -101,7 +101,7 @@ func (pa *peerAccount) SetTempRating(rating uint32) { // SetListAndIndex will update the peer's list (eligible, waiting) and the index inside it with journal func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousValues bool) { - if updatePreviousValues && list != pa.List { + if updatePreviousValues { pa.PreviousList = pa.List pa.PreviousIndexInList = pa.IndexInList } From 94f70eaffee67728971bf7bab0adfbe1b10323d9 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 15:58:38 +0200 Subject: [PATCH 737/958] fixes after second review --- integrationTests/chainSimulator/interface.go | 2 +- .../chainSimulator/staking/delegation_test.go | 9 +-- .../chainSimulator/staking/jail_test.go | 64 ++++++++++++------- node/chainSimulator/chainSimulator.go | 6 +- 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/integrationTests/chainSimulator/interface.go b/integrationTests/chainSimulator/interface.go index 34469ab7357..252332b1393 100644 --- a/integrationTests/chainSimulator/interface.go +++ b/integrationTests/chainSimulator/interface.go @@ -16,5 +16,5 @@ type ChainSimulator interface { GetNodeHandler(shardID uint32) process.NodeHandler SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) SetStateMultiple(stateSlice []*dtos.AddressState) error - GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, error) + GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, []byte, error) } diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 74e9afde678..bea85e3084d 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -215,17 +215,14 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi mintValue := big.NewInt(3010) mintValue = mintValue.Mul(oneEGLD, mintValue) - validatorOwnerBech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + validatorOwnerBech32, validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - validatorOwner, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) - delegator1Bech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + delegator1Bech32, delegator1, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - delegator1, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(delegator1Bech32) - delegator2Bech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + delegator2Bech32, delegator2, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - delegator2, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(delegator2Bech32) log.Info("working with the following addresses", "newValidatorOwner", validatorOwnerBech32, "delegator1", delegator1Bech32, "delegator2", delegator2Bech32) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index bf3fdce456f..03cd9c3a640 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/config" + chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" @@ -17,6 +18,14 @@ import ( "github.com/stretchr/testify/require" ) +const ( + stakingV4JailUnJailStep1EnableEpoch = 5 + stakingV4JailUnJailStep2EnableEpoch = 6 + stakingV4JailUnJailStep3EnableEpoch = 7 + + epochWhenNodeIsJailed = 4 +) + // Test description // All test cases will do a stake transaction and wait till the new node is jailed // testcase1 -- unJail transaction will be sent when staking v3.5 is still action --> node status should be `new` after unjail @@ -56,22 +65,20 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus numOfShards := uint32(3) cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - BypassTxSignatureCheck: false, - TempDir: t.TempDir(), - PathToInitialConfig: defaultPathToInitialConfig, - NumOfShards: numOfShards, - GenesisTimestamp: startTime, - RoundDurationInMillis: roundDurationInMillis, - RoundsPerEpoch: roundsPerEpoch, - ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 3, - MetaChainMinNodes: 3, - NumNodesWaitingListMeta: 1, - NumNodesWaitingListShard: 1, + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: numOfShards, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, AlterConfigsFunction: func(cfg *config.Configs) { - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 5 - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 6 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 7 + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = stakingV4JailUnJailStep1EnableEpoch + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = stakingV4JailUnJailStep2EnableEpoch + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = stakingV4JailUnJailStep3EnableEpoch cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 7 @@ -98,10 +105,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus require.Nil(t, err) mintValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(3000)) - walletKeyBech, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) - require.Nil(t, err) - - walletKey, err := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(walletKeyBech) + _, walletKey, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) @@ -111,7 +115,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus require.NotNil(t, stakeTx) // wait node to be jailed - err = cs.GenerateBlocksUntilEpochIsReached(4) + err = cs.GenerateBlocksUntilEpochIsReached(epochWhenNodeIsJailed) require.Nil(t, err) decodedBLSKey, _ := hex.DecodeString(blsKeys[0]) @@ -137,9 +141,23 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus status = getBLSKeyStatus(t, metachainNode, decodedBLSKey) require.Equal(t, "staked", status) - err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + checkValidatorStatus(t, cs, blsKeys[0], nodeStatusAfterUnJail) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + checkValidatorStatus(t, cs, blsKeys[0], "waiting") + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 2) + require.Nil(t, err) + + checkValidatorStatus(t, cs, blsKeys[0], "eligible") +} + +func checkValidatorStatus(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, blsKey string, expectedStatus string) { + err := cs.GetNodeHandler(core.MetachainShardId).GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) - validatorsStatistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + validatorsStatistics, err := cs.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().ValidatorStatisticsApi() require.Nil(t, err) - require.Equal(t, nodeStatusAfterUnJail, validatorsStatistics[blsKeys[0]].ValidatorStatus) + require.Equal(t, expectedStatus, validatorsStatistics[blsKey].ValidatorStatus) } diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index c308ba2f35f..e2473017e0e 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -281,7 +281,7 @@ func (s *simulator) AddValidatorKeys(validatorsPrivateKeys [][]byte) error { // GenerateAndMintWalletAddress will generate an address in the provided shard and will mint that address with the provided value // if the target shard ID value does not correspond to a node handled by the chain simulator, the address will be generated in a random shard ID -func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, error) { +func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, []byte, error) { addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() nodeHandler := s.GetNodeHandler(targetShardID) var buff []byte @@ -293,7 +293,7 @@ func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *bi address, err := addressConverter.Encode(buff) if err != nil { - return "", err + return "", nil, err } err = s.SetStateMultiple([]*dtos.AddressState{ @@ -303,7 +303,7 @@ func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *bi }, }) - return address, err + return address, buff, err } func generateAddressInShard(shardCoordinator mxChainSharding.Coordinator, len int) []byte { From 53b860d2c82b8ee054033670108f17b8ebbe0143 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 16:05:24 +0200 Subject: [PATCH 738/958] CLN: Leaving nodes edge cases --- epochStart/metachain/auctionListDisplayer_test.go | 6 ------ integrationTests/vm/staking/stakingV4_test.go | 12 +++++------- .../testMetaProcessorWithCustomNodesConfig.go | 6 ++++++ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/epochStart/metachain/auctionListDisplayer_test.go b/epochStart/metachain/auctionListDisplayer_test.go index 467dfcc0aee..68d74e08e41 100644 --- a/epochStart/metachain/auctionListDisplayer_test.go +++ b/epochStart/metachain/auctionListDisplayer_test.go @@ -43,8 +43,6 @@ func TestNewAuctionListDisplayer(t *testing.T) { } func TestAuctionListDisplayer_DisplayOwnersData(t *testing.T) { - t.Parallel() - _ = logger.SetLogLevel("*:DEBUG") defer func() { _ = logger.SetLogLevel("*:INFO") @@ -109,8 +107,6 @@ func TestAuctionListDisplayer_DisplayOwnersData(t *testing.T) { } func TestAuctionListDisplayer_DisplayOwnersSelectedNodes(t *testing.T) { - t.Parallel() - _ = logger.SetLogLevel("*:DEBUG") defer func() { _ = logger.SetLogLevel("*:INFO") @@ -177,8 +173,6 @@ func TestAuctionListDisplayer_DisplayOwnersSelectedNodes(t *testing.T) { } func TestAuctionListDisplayer_DisplayAuctionList(t *testing.T) { - t.Parallel() - _ = logger.SetLogLevel("*:DEBUG") defer func() { _ = logger.SetLogLevel("*:INFO") diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 542a8e2313a..372354642f9 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -9,7 +9,6 @@ import ( "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/state" - "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" "github.com/multiversx/mx-chain-go/vm" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts" @@ -1394,7 +1393,7 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { }, }) currNodesConfig = node.NodesConfig - requireSliceContainsNumOfElements(t, currNodesConfig.new, newOwner0BlsKeys, 1) + requireSameSliceDifferentOrder(t, currNodesConfig.new, newOwner0BlsKeys) // UnStake one of the initial nodes node.ProcessUnStake(t, map[string][][]byte{ @@ -1402,8 +1401,8 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { }) // Fast-forward few epochs such that the whole staking v4 is activated. - // We should have 12 initial nodes + 1 extra waiting node that was forced to remain eligible(because of legacy code - // where all leaving nodes were considered to be eligible) + // We should have same 12 initial nodes + 1 extra node (because of legacy code where all leaving nodes were + // considered to be eligible and the unStaked node was forced to remain eligible) node.Process(t, 49) currNodesConfig = node.NodesConfig require.Len(t, getAllPubKeys(currNodesConfig.eligible), 12) @@ -1422,7 +1421,7 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { requireSameSliceDifferentOrder(t, currNodesConfig.auction, newOwner1BlsKeys) // After 2 epochs, unStake all previously staked keys. Some of them have been already sent to eligible/waiting, but most - // of them are still in auction. UnStaked node's from auction status should be: leaving now, but their previous list was auction. + // of them are still in auction. UnStaked nodes' status from auction should be: leaving now, but their previous list was auction. // We should not force his auction nodes as being eligible in the next epoch. We should only force his existing active // nodes to remain in the system. node.Process(t, 10) @@ -1433,8 +1432,7 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { newOwner1ActiveNodes := append(newOwner1EligibleNodes, newOwner1WaitingNodes...) require.Equal(t, len(newOwner1AuctionNodes)+len(newOwner1ActiveNodes), len(newOwner1BlsKeys)) // sanity check - txCoordMock, _ := node.TxCoordinator.(*testscommon.TransactionCoordinatorMock) - txCoordMock.ClearStoredMbs() + node.ClearStoredMbs() node.ProcessUnStake(t, map[string][][]byte{ newOwner1: newOwner1BlsKeys, }) diff --git a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go index c46fb8c58c8..a966a499454 100644 --- a/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go +++ b/integrationTests/vm/staking/testMetaProcessorWithCustomNodesConfig.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/smartContract" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/require" @@ -214,6 +215,11 @@ func (tmp *TestMetaProcessor) ProcessUnJail(t *testing.T, blsKeys [][]byte) { tmp.commitBlockTxs(t, txHashes, header) } +func (tmp *TestMetaProcessor) ClearStoredMbs() { + txCoordMock, _ := tmp.TxCoordinator.(*testscommon.TransactionCoordinatorMock) + txCoordMock.ClearStoredMbs() +} + func (tmp *TestMetaProcessor) doUnJail( t *testing.T, blsKey []byte, From 6d70aecda706aa4f597d888e2952238a98c90559 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 16:14:20 +0200 Subject: [PATCH 739/958] CLN: Leaving nodes edge cases --- integrationTests/vm/staking/stakingV4_test.go | 2 +- sharding/nodesCoordinator/indexHashedNodesCoordinator.go | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/integrationTests/vm/staking/stakingV4_test.go b/integrationTests/vm/staking/stakingV4_test.go index 372354642f9..45cc1bcd85e 100644 --- a/integrationTests/vm/staking/stakingV4_test.go +++ b/integrationTests/vm/staking/stakingV4_test.go @@ -1473,7 +1473,7 @@ func TestStakingV4_LeavingNodesEdgeCases(t *testing.T) { currNodesConfig = node.NodesConfig requireSliceContains(t, currNodesConfig.auction, newOwner2BlsKeys) - // Fas-forward multiple epochs and check that newOwner1's forced nodes from previous epochs left + // Fast-forward multiple epochs and check that newOwner1's forced nodes from previous epochs left node.Process(t, 20) currNodesConfig = node.NodesConfig allCurrentNodesInSystem := append(getAllPubKeys(currNodesConfig.eligible), getAllPubKeys(currNodesConfig.waiting)...) diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go index 2e253d1d865..f70bce06b04 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinator.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinator.go @@ -861,8 +861,6 @@ func (ihnc *indexHashedNodesCoordinator) addValidatorToPreviousMap( "previous index", validatorInfo.PreviousIndex, "pk", currentValidator.PubKey(), "shardId", shardId) - - return } func (ihnc *indexHashedNodesCoordinator) handleErrorLog(err error, message string) { From ff5d1c168fc0c636b3d6339382c53f06cd399a39 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 16:15:30 +0200 Subject: [PATCH 740/958] CLN: Leaving nodes edge cases --- state/validatorInfo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state/validatorInfo.go b/state/validatorInfo.go index 924447955ca..c6ea6d06001 100644 --- a/state/validatorInfo.go +++ b/state/validatorInfo.go @@ -26,8 +26,8 @@ func (vi *ValidatorInfo) SetPreviousList(list string) { func (vi *ValidatorInfo) SetListAndIndex(list string, index uint32, updatePreviousValues bool) { if updatePreviousValues { - vi.PreviousList = vi.List vi.PreviousIndex = vi.Index + vi.PreviousList = vi.List } vi.List = list From 52ef363296ce87e955ffe9ef8aa257539320c9e7 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 16:27:25 +0200 Subject: [PATCH 741/958] FIX: Edge waiting list --- .../chainSimulator/staking/stakeAndUnStake_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 2b25d5b9700..92b8a133fe2 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -61,10 +61,10 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { ApiInterface: api.NewNoApiInterface(), MinNodesPerShard: 3, MetaChainMinNodes: 3, - NumNodesWaitingListMeta: 1, - NumNodesWaitingListShard: 1, + NumNodesWaitingListMeta: 0, + NumNodesWaitingListShard: 0, AlterConfigsFunction: func(cfg *config.Configs) { - newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) }, }) @@ -143,7 +143,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { require.Nil(t, err) // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards - err = cm.GenerateBlocks(50) + err = cm.GenerateBlocksUntilEpochIsReached(8) require.Nil(t, err) validatorStatistics, err := cm.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().ValidatorStatisticsApi() From eaceaf7cf4c291e74ce9c2d7a16e827e0aa53e2a Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Thu, 8 Feb 2024 16:29:10 +0200 Subject: [PATCH 742/958] MX-15154: fix tests --- .../chainSimulator/staking/delegation_test.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 55c734c4ffc..92c65fea744 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -418,6 +418,8 @@ func TestChainSimulator_CreateNewDelegationContract(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorCreateNewDelegationContract(t, cs, 1) }) @@ -455,6 +457,8 @@ func TestChainSimulator_CreateNewDelegationContract(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorCreateNewDelegationContract(t, cs, 2) }) @@ -492,6 +496,8 @@ func TestChainSimulator_CreateNewDelegationContract(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorCreateNewDelegationContract(t, cs, 3) }) @@ -529,6 +535,8 @@ func TestChainSimulator_CreateNewDelegationContract(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorCreateNewDelegationContract(t, cs, 4) }) @@ -602,8 +610,8 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat require.Equal(t, blsKeys[0], hex.EncodeToString(notStakedKeys[0])) require.Equal(t, 0, len(unStakedKeys)) - expectedTopUp := new(big.Int).Set(stakeValue) - expectedTotalStaked := new(big.Int).Set(stakeValue) + expectedTopUp := big.NewInt(0).Set(stakeValue) + expectedTotalStaked := big.NewInt(0).Set(stakeValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -636,7 +644,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat require.NotNil(t, delegate2Tx) expectedTopUp = expectedTopUp.Add(expectedTopUp, stakeValue) - expectedTotalStaked = expectedTopUp.Add(expectedTotalStaked, stakeValue) + expectedTotalStaked = expectedTotalStaked.Add(expectedTotalStaked, stakeValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -677,7 +685,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat require.NotNil(t, undelegate1Tx) expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) - expectedTotalStaked = expectedTopUp.Sub(expectedTotalStaked, stakeValue) + expectedTotalStaked = expectedTotalStaked.Sub(expectedTotalStaked, stakeValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -685,7 +693,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator1Bytes}) require.Nil(t, err) - require.Equal(t, "0", big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, zeroValue, big.NewInt(0).SetBytes(output.ReturnData[0])) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) require.Nil(t, err) From 2deee372f5ccee6a0e8424a92c8d92bc2b01ce7c Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 8 Feb 2024 16:47:09 +0200 Subject: [PATCH 743/958] - small refactor in chain simulator --- integrationTests/chainSimulator/interface.go | 2 +- .../chainSimulator/staking/delegation_test.go | 22 +++++++++---------- .../chainSimulator/staking/jail_test.go | 6 ++--- node/chainSimulator/chainSimulator.go | 9 +++++--- node/chainSimulator/dtos/wallet.go | 6 +++++ 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/integrationTests/chainSimulator/interface.go b/integrationTests/chainSimulator/interface.go index 252332b1393..90d3793378e 100644 --- a/integrationTests/chainSimulator/interface.go +++ b/integrationTests/chainSimulator/interface.go @@ -16,5 +16,5 @@ type ChainSimulator interface { GetNodeHandler(shardID uint32) process.NodeHandler SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) SetStateMultiple(stateSlice []*dtos.AddressState) error - GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, []byte, error) + GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (dtos.WalletAddress, error) } diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index bea85e3084d..258af468f27 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -215,24 +215,24 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi mintValue := big.NewInt(3010) mintValue = mintValue.Mul(oneEGLD, mintValue) - validatorOwnerBech32, validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - delegator1Bech32, delegator1, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + delegator1, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - delegator2Bech32, delegator2, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + delegator2, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) log.Info("working with the following addresses", - "newValidatorOwner", validatorOwnerBech32, "delegator1", delegator1Bech32, "delegator2", delegator2Bech32) + "newValidatorOwner", validatorOwner.Bech32, "delegator1", delegator1.Bech32, "delegator2", delegator2.Bech32) log.Info("Step 3. Do a stake transaction for the validator key and test that the new key is on queue / auction list and the correct topup") stakeValue := big.NewInt(0).Set(minimumStakeValue) addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(500)) stakeValue.Add(stakeValue, addedStakedValue) txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) - txStake := generateTransaction(validatorOwner, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeTx) @@ -241,11 +241,11 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi assert.Nil(t, err) testBLSKeyIsInQueueOrAuction(t, metachainNode, blsKeys[0], addedStakedValue) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorOwner)) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorOwner.Bytes)) log.Info("Step 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and the correct topup") txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) - txConvert := generateTransaction(validatorOwner, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) + txConvert := generateTransaction(validatorOwner.Bytes, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) convertTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, convertTx) @@ -262,12 +262,12 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi log.Info("Step 5. Execute 2 delegation operations of 100 EGLD each, check the topup is 700") delegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) - txDelegate1 := generateTransaction(delegator1, 0, delegationAddress, delegateValue, "delegate", gasLimitForDelegate) + txDelegate1 := generateTransaction(delegator1.Bytes, 0, delegationAddress, delegateValue, "delegate", gasLimitForDelegate) delegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, delegate1Tx) - txDelegate2 := generateTransaction(delegator2, 0, delegationAddress, delegateValue, "delegate", gasLimitForDelegate) + txDelegate2 := generateTransaction(delegator2.Bytes, 0, delegationAddress, delegateValue, "delegate", gasLimitForDelegate) delegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate2, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, delegate2Tx) @@ -279,13 +279,13 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi log.Info("6. Execute 2 unDelegate operations of 100 EGLD each, check the topup is back to 500") unDelegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) txDataField = fmt.Sprintf("unDelegate@%s", hex.EncodeToString(unDelegateValue.Bytes())) - txUnDelegate1 := generateTransaction(delegator1, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + txUnDelegate1 := generateTransaction(delegator1.Bytes, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) unDelegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, unDelegate1Tx) txDataField = fmt.Sprintf("unDelegate@%s", hex.EncodeToString(unDelegateValue.Bytes())) - txUnDelegate2 := generateTransaction(delegator2, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + txUnDelegate2 := generateTransaction(delegator2.Bytes, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) unDelegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnDelegate2, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, unDelegate2Tx) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index 03cd9c3a640..e8cce72117d 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -105,11 +105,11 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus require.Nil(t, err) mintValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(3000)) - _, walletKey, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + walletAddress, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) - txStake := generateTransaction(walletKey, 0, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) + txStake := generateTransaction(walletAddress.Bytes, 0, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeTx) @@ -125,7 +125,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus // do an unjail transaction unJailValue, _ := big.NewInt(0).SetString("2500000000000000000", 10) txUnJailDataField := fmt.Sprintf("unJail@%s", blsKeys[0]) - txUnJail := generateTransaction(walletKey, 1, vm.ValidatorSCAddress, unJailValue, txUnJailDataField, gasLimitForStakeOperation) + txUnJail := generateTransaction(walletAddress.Bytes, 1, vm.ValidatorSCAddress, unJailValue, txUnJailDataField, gasLimitForStakeOperation) err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index e2473017e0e..abd0f43984a 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -281,7 +281,7 @@ func (s *simulator) AddValidatorKeys(validatorsPrivateKeys [][]byte) error { // GenerateAndMintWalletAddress will generate an address in the provided shard and will mint that address with the provided value // if the target shard ID value does not correspond to a node handled by the chain simulator, the address will be generated in a random shard ID -func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (string, []byte, error) { +func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (dtos.WalletAddress, error) { addressConverter := s.nodes[core.MetachainShardId].GetCoreComponents().AddressPubKeyConverter() nodeHandler := s.GetNodeHandler(targetShardID) var buff []byte @@ -293,7 +293,7 @@ func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *bi address, err := addressConverter.Encode(buff) if err != nil { - return "", nil, err + return dtos.WalletAddress{}, err } err = s.SetStateMultiple([]*dtos.AddressState{ @@ -303,7 +303,10 @@ func (s *simulator) GenerateAndMintWalletAddress(targetShardID uint32, value *bi }, }) - return address, buff, err + return dtos.WalletAddress{ + Bech32: address, + Bytes: buff, + }, err } func generateAddressInShard(shardCoordinator mxChainSharding.Coordinator, len int) []byte { diff --git a/node/chainSimulator/dtos/wallet.go b/node/chainSimulator/dtos/wallet.go index a007bc8b735..27e5740f08d 100644 --- a/node/chainSimulator/dtos/wallet.go +++ b/node/chainSimulator/dtos/wallet.go @@ -11,3 +11,9 @@ type InitialWalletKeys struct { InitialWalletWithStake *WalletKey `json:"initialWalletWithStake"` ShardWallets map[uint32]*WalletKey `json:"shardWallets"` } + +// WalletAddress holds the address in multiple formats +type WalletAddress struct { + Bech32 string + Bytes []byte +} From 6c2a1569c977f5dbed3be49c5a13c4af60cdecf1 Mon Sep 17 00:00:00 2001 From: MariusC Date: Thu, 8 Feb 2024 16:53:20 +0200 Subject: [PATCH 744/958] FIX: Restore comm --- .../chainSimulator/staking/stakeAndUnStake_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 92b8a133fe2..b759a349f5f 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -64,7 +64,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { NumNodesWaitingListMeta: 0, NumNodesWaitingListShard: 0, AlterConfigsFunction: func(cfg *config.Configs) { - newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) }, }) @@ -142,7 +142,7 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { _, err = cm.SendTxAndGenerateBlockTilTxIsExecuted(tx, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) - // Step 6 --- generate 50 blocks to pass 2 epochs and the validator to generate rewards + // Step 6 --- generate 8 epochs to get rewards err = cm.GenerateBlocksUntilEpochIsReached(8) require.Nil(t, err) From a39f12eb79cf165776515844482142fd5cef45e1 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 17:27:48 +0200 Subject: [PATCH 745/958] fix close --- integrationTests/chainSimulator/staking/jail_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index e8cce72117d..3714aabfc74 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -93,9 +93,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus }) require.Nil(t, err) require.NotNil(t, cs) - defer func() { - _ = cs.Close() - }() + defer cs.Close() metachainNode := cs.GetNodeHandler(core.MetachainShardId) err = cs.GenerateBlocks(30) From 755e982b26f3ca669b94b5ea1b85b1f49ebd7dc7 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 8 Feb 2024 18:12:12 +0200 Subject: [PATCH 746/958] fixes after merge --- .../components/coreComponents.go | 32 +++---------------- .../components/testOnlyProcessingNode.go | 16 ++++------ 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 373e34de033..a8fef547003 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -28,7 +28,6 @@ import ( "github.com/multiversx/mx-chain-go/ntp" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/economics" - "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/statusHandler" @@ -159,38 +158,15 @@ func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponents return nil, err } - argsGasSchedule := forking.ArgsNewGasScheduleNotifier{ - GasScheduleConfig: config.GasScheduleConfig{ - GasScheduleByEpochs: []config.GasScheduleByEpochs{ - { - StartEpoch: 0, - FileName: args.GasScheduleFilename, - }, - }, - }, - ConfigDir: "", - EpochNotifier: instance.epochNotifier, - WasmVMChangeLocker: instance.wasmVMChangeLocker, - } - gasScheduleNotifier, err := forking.NewGasScheduleNotifier(argsGasSchedule) - if err != nil { - return nil, err - } - - builtInCostHandler, err := economics.NewBuiltInFunctionsCost(&economics.ArgsBuiltInFunctionCost{ - ArgsParser: smartContract.NewArgumentParser(), - GasSchedule: gasScheduleNotifier, - }) if err != nil { return nil, err } argsEconomicsHandler := economics.ArgsNewEconomicsData{ - TxVersionChecker: instance.txVersionChecker, - BuiltInFunctionsCostHandler: builtInCostHandler, - Economics: &args.EconomicsConfig, - EpochNotifier: instance.epochNotifier, - EnableEpochsHandler: instance.enableEpochsHandler, + TxVersionChecker: instance.txVersionChecker, + Economics: &args.EconomicsConfig, + EpochNotifier: instance.epochNotifier, + EnableEpochsHandler: instance.enableEpochsHandler, } instance.economicsData, err = economics.NewEconomicsData(argsEconomicsHandler) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 14ec26cba86..7db7a86653c 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -23,7 +23,6 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/postprocess" - "github.com/multiversx/mx-chain-go/process/economics" "github.com/multiversx/mx-chain-go/process/smartContract" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" @@ -59,14 +58,13 @@ type testOnlyProcessingNode struct { ProcessComponentsHolder factory.ProcessComponentsHandler DataComponentsHolder factory.DataComponentsHandler - NodesCoordinator nodesCoordinator.NodesCoordinator - ChainHandler chainData.ChainHandler - ArgumentsParser process.ArgumentsParser - TransactionFeeHandler process.TransactionFeeHandler - StoreService dataRetriever.StorageService - BuiltinFunctionsCostHandler economics.BuiltInFunctionsCostHandler - DataPool dataRetriever.PoolsHolder - broadcastMessenger consensus.BroadcastMessenger + NodesCoordinator nodesCoordinator.NodesCoordinator + ChainHandler chainData.ChainHandler + ArgumentsParser process.ArgumentsParser + TransactionFeeHandler process.TransactionFeeHandler + StoreService dataRetriever.StorageService + DataPool dataRetriever.PoolsHolder + broadcastMessenger consensus.BroadcastMessenger httpServer shared.UpgradeableHttpServerHandler facadeHandler shared.FacadeHandler From a6b9d47161f5357b923864877e9289356b01aa6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 9 Feb 2024 00:14:55 +0200 Subject: [PATCH 747/958] Add integration test for deep queries. --- integrationTests/oneNodeNetwork.go | 23 +- .../vm/wasm/queries/queries_test.go | 206 ++++++++++++++++++ .../vm/wasm/testdata/history/history.c | 51 +++++ .../vm/wasm/testdata/history/history.export | 5 + .../wasm/testdata/history/output/history.wasm | Bin 0 -> 660 bytes 5 files changed, 274 insertions(+), 11 deletions(-) create mode 100644 integrationTests/vm/wasm/queries/queries_test.go create mode 100644 integrationTests/vm/wasm/testdata/history/history.c create mode 100644 integrationTests/vm/wasm/testdata/history/history.export create mode 100755 integrationTests/vm/wasm/testdata/history/output/history.wasm diff --git a/integrationTests/oneNodeNetwork.go b/integrationTests/oneNodeNetwork.go index 720ff0529c6..184f5989f61 100644 --- a/integrationTests/oneNodeNetwork.go +++ b/integrationTests/oneNodeNetwork.go @@ -9,16 +9,17 @@ import ( "github.com/multiversx/mx-chain-go/process" ) -type oneNodeNetwork struct { +// OneNodeNetwork is a one-node network, useful for some integration tests +type OneNodeNetwork struct { Round uint64 Nonce uint64 Node *TestProcessorNode } -// NewOneNodeNetwork creates a one-node network, useful for some integration tests -func NewOneNodeNetwork() *oneNodeNetwork { - n := &oneNodeNetwork{} +// NewOneNodeNetwork creates a OneNodeNetwork +func NewOneNodeNetwork() *OneNodeNetwork { + n := &OneNodeNetwork{} nodes := CreateNodes( 1, @@ -31,38 +32,38 @@ func NewOneNodeNetwork() *oneNodeNetwork { } // Stop stops the test network -func (n *oneNodeNetwork) Stop() { +func (n *OneNodeNetwork) Stop() { n.Node.Close() } // Mint mints the given address -func (n *oneNodeNetwork) Mint(address []byte, value *big.Int) { +func (n *OneNodeNetwork) Mint(address []byte, value *big.Int) { MintAddress(n.Node.AccntState, address, value) } // GetMinGasPrice returns the min gas price -func (n *oneNodeNetwork) GetMinGasPrice() uint64 { +func (n *OneNodeNetwork) GetMinGasPrice() uint64 { return n.Node.EconomicsData.GetMinGasPrice() } // MaxGasLimitPerBlock returns the max gas per block -func (n *oneNodeNetwork) MaxGasLimitPerBlock() uint64 { +func (n *OneNodeNetwork) MaxGasLimitPerBlock() uint64 { return n.Node.EconomicsData.MaxGasLimitPerBlock(0) - 1 } // GoToRoundOne advances processing to block and round 1 -func (n *oneNodeNetwork) GoToRoundOne() { +func (n *OneNodeNetwork) GoToRoundOne() { n.Round = IncrementAndPrintRound(n.Round) n.Nonce++ } // Continue advances processing with a number of rounds -func (n *oneNodeNetwork) Continue(t *testing.T, numRounds int) { +func (n *OneNodeNetwork) Continue(t *testing.T, numRounds int) { n.Nonce, n.Round = WaitOperationToBeDone(t, []*TestProcessorNode{n.Node}, numRounds, n.Nonce, n.Round, []int{0}) } // AddTxToPool adds a transaction to the pool (skips signature checks and interceptors) -func (n *oneNodeNetwork) AddTxToPool(tx *transaction.Transaction) { +func (n *OneNodeNetwork) AddTxToPool(tx *transaction.Transaction) { txHash, _ := core.CalculateHash(TestMarshalizer, TestHasher, tx) sourceShard := n.Node.ShardCoordinator.ComputeId(tx.SndAddr) cacheIdentifier := process.ShardCacherIdentifier(sourceShard, sourceShard) diff --git a/integrationTests/vm/wasm/queries/queries_test.go b/integrationTests/vm/wasm/queries/queries_test.go new file mode 100644 index 00000000000..541c88f8310 --- /dev/null +++ b/integrationTests/vm/wasm/queries/queries_test.go @@ -0,0 +1,206 @@ +//go:build !race + +// TODO remove build condition above to allow -race -short, after Wasm VM fix + +package upgrades + +import ( + "encoding/hex" + "fmt" + "math/big" + "testing" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/integrationTests" + "github.com/multiversx/mx-chain-go/integrationTests/vm" + "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/process/factory" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/require" +) + +type now struct { + blockNonce uint64 + stateRootHash []byte +} + +func TestQueries(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + snapshotsOfGetNow := make(map[uint64]now) + snapshotsOfGetState := make(map[uint64]int) + historyOfGetNow := make(map[uint64]now) + historyOfGetState := make(map[uint64]int) + + scOwner := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + scOwnerNonce := uint64(0) + + network := integrationTests.NewOneNodeNetwork() + defer network.Stop() + + network.Mint(scOwner, big.NewInt(10000000000000)) + network.GoToRoundOne() + + // Block 0 + + scAddress := deploy(network, scOwner, "../testdata/history/output/history.wasm", &scOwnerNonce) + network.Continue(t, 1) + + // Block 1 + + now := queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + snapshotsOfGetNow[1] = now + network.Continue(t, 1) + + // Block 2 + + now = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + snapshotsOfGetNow[2] = now + setState(network, scAddress, scOwner, 42, &scOwnerNonce) + network.Continue(t, 1) + + // Block 3 + + state := getState(t, network.Node, scAddress, core.OptionalUint64{}) + snapshotsOfGetState[3] = state + now = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + snapshotsOfGetNow[3] = now + setState(network, scAddress, scOwner, 43, &scOwnerNonce) + network.Continue(t, 1) + + // Block 4 + + state = getState(t, network.Node, scAddress, core.OptionalUint64{}) + snapshotsOfGetState[4] = state + now = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + snapshotsOfGetNow[4] = now + network.Continue(t, 1) + + // Check snapshots + block1, _ := network.Node.GetShardHeader(1) + block2, _ := network.Node.GetShardHeader(2) + block3, _ := network.Node.GetShardHeader(3) + block4, _ := network.Node.GetShardHeader(4) + + require.Equal(t, uint64(1), snapshotsOfGetNow[1].blockNonce) + require.Equal(t, uint64(2), snapshotsOfGetNow[2].blockNonce) + require.Equal(t, uint64(3), snapshotsOfGetNow[3].blockNonce) + require.Equal(t, uint64(4), snapshotsOfGetNow[4].blockNonce) + + require.Equal(t, block1.GetRootHash(), snapshotsOfGetNow[1].stateRootHash) + require.Equal(t, block1.GetRootHash(), snapshotsOfGetNow[2].stateRootHash) + require.NotEqual(t, block2.GetRootHash(), snapshotsOfGetNow[3].stateRootHash) + require.NotEqual(t, block3.GetRootHash(), snapshotsOfGetNow[4].stateRootHash) + + require.Equal(t, 42, snapshotsOfGetState[3]) + require.Equal(t, 43, snapshotsOfGetState[4]) + + // Check history + historyOfGetState[1] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 1}) + historyOfGetNow[1] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 1}) + + historyOfGetState[2] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 2}) + historyOfGetNow[2] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 2}) + + historyOfGetState[3] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 3}) + historyOfGetNow[3] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 3}) + + historyOfGetState[4] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 4}) + historyOfGetNow[4] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 4}) + + require.Equal(t, snapshotsOfGetState[1], historyOfGetState[1]) + require.Equal(t, snapshotsOfGetNow[1].blockNonce, historyOfGetNow[1].blockNonce) + // This does not seem right! + require.Equal(t, block4.GetRootHash(), historyOfGetNow[1].stateRootHash) + + require.Equal(t, snapshotsOfGetState[2], historyOfGetState[2]) + require.Equal(t, snapshotsOfGetNow[2].blockNonce, historyOfGetNow[2].blockNonce) + // This does not seem right! + require.Equal(t, block4.GetRootHash(), historyOfGetNow[2].stateRootHash) + + require.Equal(t, snapshotsOfGetState[3], historyOfGetState[3]) + require.Equal(t, snapshotsOfGetNow[3].blockNonce, historyOfGetNow[3].blockNonce) + // This does not seem right! + require.Equal(t, block4.GetRootHash(), historyOfGetNow[3].stateRootHash) + + require.Equal(t, snapshotsOfGetState[4], historyOfGetState[4]) + require.Equal(t, snapshotsOfGetNow[4].blockNonce, historyOfGetNow[4].blockNonce) + // This does not seem right! + require.Equal(t, block4.GetRootHash(), historyOfGetNow[4].stateRootHash) +} + +func deploy(network *integrationTests.OneNodeNetwork, sender []byte, codePath string, accountNonce *uint64) []byte { + code := wasm.GetSCCode(codePath) + data := fmt.Sprintf("%s@%s@0100", code, hex.EncodeToString(factory.WasmVirtualMachine)) + + network.AddTxToPool(&transaction.Transaction{ + Nonce: *accountNonce, + Value: big.NewInt(0), + RcvAddr: vm.CreateEmptyAddress(), + SndAddr: sender, + GasPrice: network.GetMinGasPrice(), + GasLimit: network.MaxGasLimitPerBlock(), + Data: []byte(data), + }) + + *accountNonce++ + + scAddress, _ := network.Node.BlockchainHook.NewAddress(sender, 0, factory.WasmVirtualMachine) + + return scAddress +} + +func setState(network *integrationTests.OneNodeNetwork, scAddress, sender []byte, value uint64, accountNonce *uint64) { + data := fmt.Sprintf("setState@%x", value) + + network.AddTxToPool(&transaction.Transaction{ + Nonce: *accountNonce, + Value: big.NewInt(0), + RcvAddr: scAddress, + SndAddr: sender, + GasPrice: network.GetMinGasPrice(), + GasLimit: network.MaxGasLimitPerBlock(), + Data: []byte(data), + }) + + *accountNonce++ +} + +func getState(t *testing.T, node *integrationTests.TestProcessorNode, scAddress []byte, blockNonce core.OptionalUint64) int { + scQuery := node.SCQueryService + vmOutput, _, err := scQuery.ExecuteQuery(&process.SCQuery{ + ScAddress: scAddress, + FuncName: "getState", + Arguments: [][]byte{}, + BlockNonce: blockNonce, + }) + + require.Nil(t, err) + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + data := vmOutput.ReturnData + + return int(big.NewInt(0).SetBytes(data[0]).Uint64()) +} + +func queryHistoryGetNow(t *testing.T, node *integrationTests.TestProcessorNode, scAddress []byte, blockNonce core.OptionalUint64) now { + scQuery := node.SCQueryService + vmOutput, _, err := scQuery.ExecuteQuery(&process.SCQuery{ + ScAddress: scAddress, + FuncName: "getNow", + Arguments: [][]byte{}, + BlockNonce: blockNonce, + }) + + require.Nil(t, err) + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + data := vmOutput.ReturnData + + return now{ + blockNonce: big.NewInt(0).SetBytes(data[0]).Uint64(), + stateRootHash: data[1], + } +} diff --git a/integrationTests/vm/wasm/testdata/history/history.c b/integrationTests/vm/wasm/testdata/history/history.c new file mode 100644 index 00000000000..322e216aca8 --- /dev/null +++ b/integrationTests/vm/wasm/testdata/history/history.c @@ -0,0 +1,51 @@ +typedef unsigned char byte; +typedef unsigned int i32; +typedef unsigned long long i64; + +int getArgument(int argumentIndex, byte *argument); +long long int64getArgument(int argumentIndex); +long long getBlockNonce(); +long long getBlockEpoch(); +void getStateRootHash(byte *hash); + +int int64storageStore(byte *key, int keyLength, long long value); +long long int64storageLoad(byte *key, int keyLength); + +void finish(byte *data, int length); +void int64finish(long long value); + +byte zero32_buffer_a[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +byte zero32_buffer_b[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +byte zero32_buffer_c[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +byte storageKey[] = "state"; + +void init() +{ +} + +void upgrade() +{ +} + +void setState() +{ + i64 state = int64getArgument(0); + int64storageStore(storageKey, sizeof(storageKey) - 1, state); +} + +void getState() +{ + i64 state = int64storageLoad(storageKey, sizeof(storageKey) - 1); + int64finish(state); +} + +void getNow() +{ + i64 nonce = getBlockNonce(); + + byte *stateRootHash = zero32_buffer_a; + getStateRootHash(stateRootHash); + + int64finish(nonce); + finish(stateRootHash, 32); +} diff --git a/integrationTests/vm/wasm/testdata/history/history.export b/integrationTests/vm/wasm/testdata/history/history.export new file mode 100644 index 00000000000..b6646aa3aef --- /dev/null +++ b/integrationTests/vm/wasm/testdata/history/history.export @@ -0,0 +1,5 @@ +init +upgrade +getNow +setState +getState diff --git a/integrationTests/vm/wasm/testdata/history/output/history.wasm b/integrationTests/vm/wasm/testdata/history/output/history.wasm new file mode 100755 index 0000000000000000000000000000000000000000..5e34d9a0ab0e8c746ca2b9f9c3b007f8757e2908 GIT binary patch literal 660 zcmaKp&raMh5XQ$I|I0>*^xD%{AOUv-Qg805hl&Hdz((LMyRZq`1gc&(OKB?(JlU=xB$r}6f%`?rF;;iQ zv}%tIC$SBS$?ZH=EkKe#^m5bIi*gdrI7AR{>1+LKU0#4pa^9zZn^x225-=%SjQo6E zpI@ES)p-Qf7qfQOmTf$(>-I~@sXEDKU1!i}o0dia(m0+YJU^=3ellhr=k?-;1jQCD zSbKXjS(FzMoNLxh$lL}GBg4m&`a9&K7pW1p^R%x~b#ke?ofR+e5DG5{NL+bIa<>-) zcqA-_1Vxh6F*=e5=)4ZA$5dv5_LdA;(#3rOePj;jkem68vVpUmN7QU4-!&V6$UsF% zs`%OWrJ1E)Z4H^?A?fU5`NhuI%xzr$3XS~1lJ~oF6~B5kG5{GJp88Sx0gohyeW|?W qfqtj7Vcu8c;nfCWV@t01v+gEiST^$`8g07Cw*-Wh%T1F$8U6#AZ Date: Fri, 9 Feb 2024 10:58:37 +0200 Subject: [PATCH 748/958] new VM 1.5.27 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fbd61b07d8d..fc99478d2d5 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.3.0 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.11 - github.com/multiversx/mx-chain-vm-go v1.5.26 + github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240206121310-ce5f10e5fe16 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 diff --git a/go.sum b/go.sum index b7cb342ed43..0e5e120d68b 100644 --- a/go.sum +++ b/go.sum @@ -401,8 +401,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0Oab github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.11 h1:rAQR00ALKOmWAuNA8XW8hR02M9gmrAE4WZwyJH4dMMU= github.com/multiversx/mx-chain-vm-common-go v1.5.11/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= -github.com/multiversx/mx-chain-vm-go v1.5.26 h1:ZjUJTG9cO2h5WNRIZ50ZSZNsTEPqXXPGS9Y/SAGyC2A= -github.com/multiversx/mx-chain-vm-go v1.5.26/go.mod h1:gNZ/s4Z6OHg6ZeBsW6aDxWQduXsRS0Bsv4pfkmHeRzs= +github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240206121310-ce5f10e5fe16 h1:mSUJjgaSLmspQRNbqU0Aw3v9cuXtPnlUDTchFiipuZQ= +github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240206121310-ce5f10e5fe16/go.mod h1:gNZ/s4Z6OHg6ZeBsW6aDxWQduXsRS0Bsv4pfkmHeRzs= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 h1:TxFjQH0dXC/ACQxlIgJbO7pVoh00rcqeKSnIjWTDMxg= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 h1:xgrXfHKa0Za4xjFj5W0FcYEivjrQIhLvGEFXXa1uQZU= From 7d7292573c6e74a48e874162b759e561d8ac2c4d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 9 Feb 2024 11:40:48 +0200 Subject: [PATCH 749/958] scenario nr 2 --- .../chainSimulator/staking/jail_test.go | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index 3714aabfc74..c903de61729 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -152,9 +152,117 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus checkValidatorStatus(t, cs, blsKeys[0], "eligible") } +// Test description +// Add a new node and wait until the node get jailed +// Add a second node to take the place of the jailed node +// UnJail the first node --> should go in queue +// Activate staking v4 step 1 --> node should be moved from queue to auction list +func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + + numOfShards := uint32(3) + + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: numOfShards, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = stakingV4JailUnJailStep1EnableEpoch + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = stakingV4JailUnJailStep2EnableEpoch + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = stakingV4JailUnJailStep3EnableEpoch + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = stakingV4JailUnJailStep3EnableEpoch + + cfg.RatingsConfig.ShardChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 + cfg.RatingsConfig.ShardChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + cfg.RatingsConfig.MetaChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 + cfg.RatingsConfig.MetaChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 1 + configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + defer cs.Close() + + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + err = cs.GenerateBlocks(30) + require.Nil(t, err) + + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + require.Nil(t, err) + + err = cs.AddValidatorKeys([][]byte{privateKeys[1]}) + require.Nil(t, err) + + mintValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(6000)) + walletAddress, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(walletAddress.Bytes, 0, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + // wait node to be jailed + err = cs.GenerateBlocksUntilEpochIsReached(epochWhenNodeIsJailed) + require.Nil(t, err) + + decodedBLSKey1, _ := hex.DecodeString(blsKeys[0]) + status := getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + require.Equal(t, "jailed", status) + + // add one more node + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) + txStake = generateTransaction(walletAddress.Bytes, 1, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + decodedBLSKey2, _ := hex.DecodeString(blsKeys[1]) + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey2) + require.Equal(t, "staked", status) + + // unJail the first node + unJailValue, _ := big.NewInt(0).SetString("2500000000000000000", 10) + txUnJailDataField := fmt.Sprintf("unJail@%s", blsKeys[0]) + txUnJail := generateTransaction(walletAddress.Bytes, 2, vm.ValidatorSCAddress, unJailValue, txUnJailDataField, gasLimitForStakeOperation) + + unJailTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnJail, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unJailTx) + require.Equal(t, transaction.TxStatusSuccess, unJailTx.Status) + + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + require.Equal(t, "queued", status) + + err = cs.GenerateBlocksUntilEpochIsReached(stakingV4JailUnJailStep1EnableEpoch) + require.Nil(t, err) + + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + require.Equal(t, "staked", status) + + checkValidatorStatus(t, cs, blsKeys[0], "auction") +} + func checkValidatorStatus(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, blsKey string, expectedStatus string) { err := cs.GetNodeHandler(core.MetachainShardId).GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) + validatorsStatistics, err := cs.GetNodeHandler(core.MetachainShardId).GetFacadeHandler().ValidatorStatisticsApi() require.Nil(t, err) require.Equal(t, expectedStatus, validatorsStatistics[blsKey].ValidatorStatus) From e029b1bebf9529ede8f2291c3584ee0b6c0fd68f Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 9 Feb 2024 12:39:39 +0200 Subject: [PATCH 750/958] FIX: Unit tests --- .../chainSimulator/staking/delegation_test.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 92c65fea744..96f0ff0bae0 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -304,7 +304,6 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi expectedTopUp = big.NewInt(0).Mul(oneEGLD, big.NewInt(500)) testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], expectedTopUp, 1) - } func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte, blsKey string, expectedTopUp *big.Int, actionListSize int) { @@ -372,7 +371,6 @@ func testBLSKeyIsInAuction( // 5. Perform delegation operations // 6. Perform undelegation operations // 7. Validate the results at each step - func TestChainSimulator_CreateNewDelegationContract(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -673,7 +671,11 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat require.Equal(t, 0, len(notStakedKeys)) require.Equal(t, 0, len(unStakedKeys)) - testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationContractAddressBytes, blsKeys[0], expectedTopUp, 0) + // Make block finalized + err = cs.GenerateBlocks(1) + require.Nil(t, err) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationContractAddressBytes, blsKeys[0], expectedTopUp, 1) // Step 5: Perform unDelegate from 1 user // The nodes should remain in the staked state @@ -689,7 +691,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) - require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) + require.Equal(t, expectedTopUp.String(), getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes).String()) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator1Bytes}) require.Nil(t, err) @@ -714,12 +716,12 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) - require.Equal(t, "1250000000000000000000", big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, "1250000000000000000000", big.NewInt(0).SetBytes(output.ReturnData[0]).String()) require.Equal(t, zeroValue, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator2Bytes}) require.Nil(t, err) - require.Equal(t, "0", big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, "0", big.NewInt(0).SetBytes(output.ReturnData[0]).String()) // still staked until epoch change output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) @@ -830,6 +832,10 @@ func getBLSTopUpValue(t *testing.T, metachainNode chainSimulatorProcess.NodeHand require.Nil(t, err) require.Equal(t, okReturnCode, result.ReturnCode) + if len(result.ReturnData[0]) == 0 { + return big.NewInt(0) + } + return big.NewInt(0).SetBytes(result.ReturnData[0]) } From d8ca65622fbe98402405d69850619cd2918c24ca Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 9 Feb 2024 12:58:52 +0200 Subject: [PATCH 751/958] reset processing stats on new epoch --- state/accountsDB.go | 1 + 1 file changed, 1 insertion(+) diff --git a/state/accountsDB.go b/state/accountsDB.go index 06fb88eac3a..7f02197adbb 100644 --- a/state/accountsDB.go +++ b/state/accountsDB.go @@ -787,6 +787,7 @@ func (adb *AccountsDB) CommitInEpoch(currentEpoch uint32, epochToCommit uint32) adb.mainTrie.GetStorageManager().SetEpochForPutOperation(currentEpoch) adb.mutOp.Unlock() adb.loadCodeMeasurements.resetAndPrint() + adb.mainTrie.GetStorageManager().GetStateStatsHandler().Reset() }() adb.mainTrie.GetStorageManager().SetEpochForPutOperation(epochToCommit) From 65de2fe5cdcc87f0835dac220aaa6a6db4ced171 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 9 Feb 2024 13:21:05 +0200 Subject: [PATCH 752/958] reset processing stats on new epoch - move under protection --- state/accountsDB.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state/accountsDB.go b/state/accountsDB.go index 7f02197adbb..249dd64f471 100644 --- a/state/accountsDB.go +++ b/state/accountsDB.go @@ -785,9 +785,9 @@ func (adb *AccountsDB) CommitInEpoch(currentEpoch uint32, epochToCommit uint32) adb.mutOp.Lock() defer func() { adb.mainTrie.GetStorageManager().SetEpochForPutOperation(currentEpoch) + adb.mainTrie.GetStorageManager().GetStateStatsHandler().Reset() adb.mutOp.Unlock() adb.loadCodeMeasurements.resetAndPrint() - adb.mainTrie.GetStorageManager().GetStateStatsHandler().Reset() }() adb.mainTrie.GetStorageManager().SetEpochForPutOperation(epochToCommit) From 9de76e07af8c0b9610be230f536712e59c1554a2 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 9 Feb 2024 16:27:54 +0200 Subject: [PATCH 753/958] fix scripts for local testnet in multikey mode --- scripts/testnet/include/config.sh | 1 + scripts/testnet/include/observers.sh | 10 +++++++++- scripts/testnet/variables.sh | 4 ---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/testnet/include/config.sh b/scripts/testnet/include/config.sh index 56d792dc7ed..5397f12e329 100644 --- a/scripts/testnet/include/config.sh +++ b/scripts/testnet/include/config.sh @@ -3,6 +3,7 @@ generateConfig() { TMP_SHARD_OBSERVERCOUNT=$SHARD_OBSERVERCOUNT TMP_META_OBSERVERCOUNT=$META_OBSERVERCOUNT + # set num of observers to 0, they will start with generated keys if [[ $MULTI_KEY_NODES -eq 1 ]]; then TMP_SHARD_OBSERVERCOUNT=0 TMP_META_OBSERVERCOUNT=0 diff --git a/scripts/testnet/include/observers.sh b/scripts/testnet/include/observers.sh index 6ba9ff9293a..50e7f5ade03 100644 --- a/scripts/testnet/include/observers.sh +++ b/scripts/testnet/include/observers.sh @@ -82,10 +82,18 @@ assembleCommand_startObserverNode() { let "KEY_INDEX=$TOTAL_NODECOUNT - $OBSERVER_INDEX - 1" WORKING_DIR=$TESTNETDIR/node_working_dirs/observer$OBSERVER_INDEX + KEYS_FLAGS="-validator-key-pem-file ./config/validatorKey.pem -sk-index $KEY_INDEX" + # if node is running in multi key mode, in order to avoid loading the common allValidatorKeys.pem file + # and force generating a new key for observers, simply provide an invalid path + if [[ $MULTI_KEY_NODES -eq 1 ]]; then + TMP_MISSING_PEM="missing-file.pem" + KEYS_FLAGS="-all-validator-keys-pem-file $TMP_MISSING_PEM -validator-key-pem-file $TMP_MISSING_PEM" + fi + local nodeCommand="./node \ -port $PORT --profile-mode -log-save -log-level $LOGLEVEL --log-logger-name --log-correlation --use-health-service -rest-api-interface localhost:$RESTAPIPORT \ -destination-shard-as-observer $SHARD \ - -sk-index $KEY_INDEX \ + $KEYS_FLAGS \ -working-directory $WORKING_DIR -config ./config/config_observer.toml $EXTRA_OBSERVERS_FLAGS" if [ -n "$NODE_NICENESS" ] diff --git a/scripts/testnet/variables.sh b/scripts/testnet/variables.sh index 1dc3c7cc65c..f3fb44c5866 100644 --- a/scripts/testnet/variables.sh +++ b/scripts/testnet/variables.sh @@ -170,10 +170,6 @@ export TOTAL_OBSERVERCOUNT=$total_observer_count # to enable the full archive feature on the observers, please use the --full-archive flag export EXTRA_OBSERVERS_FLAGS="-operation-mode db-lookup-extension" -if [[ $MULTI_KEY_NODES -eq 1 ]]; then - EXTRA_OBSERVERS_FLAGS="--no-key" -fi - # Leave unchanged. let "total_node_count = $SHARD_VALIDATORCOUNT * $SHARDCOUNT + $META_VALIDATORCOUNT + $TOTAL_OBSERVERCOUNT" export TOTAL_NODECOUNT=$total_node_count From e44a0de90f555f942dca45606f0068e8489d8ac6 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 9 Feb 2024 17:34:38 +0200 Subject: [PATCH 754/958] scenario nr 3 --- .../chainSimulator/staking/jail_test.go | 4 + .../staking/simpleStake_test.go | 133 ++++++++++++++++++ node/chainSimulator/chainSimulator.go | 22 +-- node/chainSimulator/send_and_execute.go | 73 ++++++++++ 4 files changed, 213 insertions(+), 19 deletions(-) create mode 100644 integrationTests/chainSimulator/staking/simpleStake_test.go create mode 100644 node/chainSimulator/send_and_execute.go diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index c903de61729..facd5f06cf8 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -158,6 +158,10 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus // UnJail the first node --> should go in queue // Activate staking v4 step 1 --> node should be moved from queue to auction list func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) roundsPerEpoch := core.OptionalUint64{ diff --git a/integrationTests/chainSimulator/staking/simpleStake_test.go b/integrationTests/chainSimulator/staking/simpleStake_test.go new file mode 100644 index 00000000000..73be7082aaa --- /dev/null +++ b/integrationTests/chainSimulator/staking/simpleStake_test.go @@ -0,0 +1,133 @@ +package staking + +import ( + "encoding/hex" + "fmt" + "math/big" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/node/chainSimulator" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/vm" + "github.com/stretchr/testify/require" +) + +// Test scenarios +// Do 3 stake transactions from 3 different wallets - tx value 2499, 2500, 2501 +// testcase1 -- staking v3.5 --> tx1 fail, tx2 - node in queue, tx3 - node in queue with topUp 1 +// testcase2 -- staking v4 step1 --> tx1 fail, tx2 - node in auction, tx3 - node in auction with topUp 1 +// testcase3 -- staking v4 step2 --> tx1 fail, tx2 - node in auction, tx3 - node in auction with topUp 1 +// testcase4 -- staking v3.step3 --> tx1 fail, tx2 - node in auction, tx3 - node in auction with topUp 1 +func TestChainSimulator_SimpleStake(t *testing.T) { + t.Run("staking ph 4 is not active", func(t *testing.T) { + testChainSimulatorSimpleStake(t, 1, "queued") + }) + + t.Run("staking ph 4 step1", func(t *testing.T) { + testChainSimulatorSimpleStake(t, 2, "auction") + }) + + t.Run("staking ph 4 step2", func(t *testing.T) { + testChainSimulatorSimpleStake(t, 3, "auction") + }) + + t.Run("staking ph 4 step3", func(t *testing.T) { + testChainSimulatorSimpleStake(t, 4, "auction") + }) +} + +func testChainSimulatorSimpleStake(t *testing.T, targetEpoch int32, nodesStatus string) { + if testing.Short() { + t.Skip("this is not a short test") + } + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + + numOfShards := uint32(3) + + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: numOfShards, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + defer cs.Close() + + mintValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(3000)) + wallet1, err := cs.GenerateAndMintWalletAddress(0, mintValue) + require.Nil(t, err) + wallet2, err := cs.GenerateAndMintWalletAddress(0, mintValue) + require.Nil(t, err) + wallet3, err := cs.GenerateAndMintWalletAddress(0, mintValue) + require.Nil(t, err) + + _, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(3) + require.Nil(t, err) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + dataFieldTx1 := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + tx1Value := big.NewInt(0).Mul(big.NewInt(2499), oneEGLD) + tx1 := generateTransaction(wallet1.Bytes, 0, vm.ValidatorSCAddress, tx1Value, dataFieldTx1, gasLimitForStakeOperation) + + dataFieldTx2 := fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) + tx2 := generateTransaction(wallet3.Bytes, 0, vm.ValidatorSCAddress, minimumStakeValue, dataFieldTx2, gasLimitForStakeOperation) + + dataFieldTx3 := fmt.Sprintf("stake@01@%s@%s", blsKeys[2], mockBLSSignature) + tx3Value := big.NewInt(0).Mul(big.NewInt(2501), oneEGLD) + tx3 := generateTransaction(wallet2.Bytes, 0, vm.ValidatorSCAddress, tx3Value, dataFieldTx3, gasLimitForStakeOperation) + + results, err := cs.SendTxsAndGenerateBlockTilTxIsExecuted([]*transaction.Transaction{tx1, tx2, tx3}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 3, len(results)) + require.NotNil(t, results) + + // tx1 should fail + require.Equal(t, "insufficient stake value: expected 2500000000000000000000, got 2499000000000000000000", string(results[0].Logs.Events[0].Topics[1])) + + _ = cs.GenerateBlocks(1) + + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + if targetEpoch < 2 { + bls1, _ := hex.DecodeString(blsKeys[1]) + bls2, _ := hex.DecodeString(blsKeys[2]) + + blsKeyStatus := getBLSKeyStatus(t, metachainNode, bls1) + require.Equal(t, nodesStatus, blsKeyStatus) + + blsKeyStatus = getBLSKeyStatus(t, metachainNode, bls2) + require.Equal(t, nodesStatus, blsKeyStatus) + } else { + // tx2 -- validator should be in queue + checkValidatorStatus(t, cs, blsKeys[1], nodesStatus) + // tx3 -- validator should be in queue + checkValidatorStatus(t, cs, blsKeys[2], nodesStatus) + } +} diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 3f1fa308eaa..e1e0508b2b4 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -409,30 +409,14 @@ func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { // SendTxAndGenerateBlockTilTxIsExecuted will the provided transaction and generate block func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) { - shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.SndAddr) - err := s.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(txToSend) - if err != nil { - return nil, err - } - - node := s.GetNodeHandler(shardID) - txHash, err := core.CalculateHash(node.GetCoreComponents().InternalMarshalizer(), node.GetCoreComponents().Hasher(), txToSend) - if err != nil { - return nil, err - } - - txHashHex := hex.EncodeToString(txHash) - - log.Info("############## send transaction ##############", "txHash", txHash) - - _, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{txToSend}) + txHashHex, err := s.sendTx(txToSend) if err != nil { return nil, err } time.Sleep(100 * time.Millisecond) - destinationShardID := node.GetShardCoordinator().ComputeId(txToSend.RcvAddr) + destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { err = s.GenerateBlocks(1) if err != nil { @@ -441,7 +425,7 @@ func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction. tx, errGet := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHashHex, true) if errGet == nil && tx.Status != transaction.TxStatusPending { - log.Info("############## transaction was executed ##############", "txHash", txHash) + log.Info("############## transaction was executed ##############", "txHash", txHashHex) return tx, nil } } diff --git a/node/chainSimulator/send_and_execute.go b/node/chainSimulator/send_and_execute.go new file mode 100644 index 00000000000..c782f749bd1 --- /dev/null +++ b/node/chainSimulator/send_and_execute.go @@ -0,0 +1,73 @@ +package chainSimulator + +import ( + "encoding/hex" + "errors" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data/transaction" +) + +func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { + shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) + err := s.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) + if err != nil { + return "", err + } + + node := s.GetNodeHandler(shardID) + txHash, err := core.CalculateHash(node.GetCoreComponents().InternalMarshalizer(), node.GetCoreComponents().Hasher(), tx) + if err != nil { + return "", err + } + + txHashHex := hex.EncodeToString(txHash) + _, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) + if err != nil { + return "", err + } + + log.Info("############## send transaction ##############", "txHash", txHashHex) + + return txHashHex, nil +} + +func (s *simulator) SendTxsAndGenerateBlockTilTxIsExecuted(txsToSend []*transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) ([]*transaction.ApiTransactionResult, error) { + hashTxIndex := make(map[string]int) + for idx, txToSend := range txsToSend { + txHashHex, err := s.sendTx(txToSend) + if err != nil { + return nil, err + } + + hashTxIndex[txHashHex] = idx + } + + time.Sleep(100 * time.Millisecond) + + txsFromAPI := make([]*transaction.ApiTransactionResult, 3) + for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { + err := s.GenerateBlocks(1) + if err != nil { + return nil, err + } + + for txHash := range hashTxIndex { + destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txsToSend[hashTxIndex[txHash]].RcvAddr) + tx, errGet := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) + if errGet == nil && tx.Status != transaction.TxStatusPending { + log.Info("############## transaction was executed ##############", "txHash", txHash) + + txsFromAPI[hashTxIndex[txHash]] = tx + delete(hashTxIndex, txHash) + continue + } + } + if len(hashTxIndex) == 0 { + return txsFromAPI, nil + } + } + + return nil, errors.New("something went wrong transactions are still in pending") +} From 17b4aa85e89e6e692c3068314cbea89bb3740020 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 9 Feb 2024 18:48:03 +0200 Subject: [PATCH 755/958] merging delegation scenario - initial impl --- .../chainSimulator/staking/delegation_test.go | 257 ++++++++++++++++++ 1 file changed, 257 insertions(+) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 96f0ff0bae0..75624541854 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -36,6 +36,8 @@ const gasLimitForConvertOperation = 510_000_000 const gasLimitForDelegationContractCreationOperation = 500_000_000 const gasLimitForAddNodesOperation = 500_000_000 const gasLimitForUndelegateOperation = 500_000_000 +const gasLimitForMergeOperation = 500_000_000 +const gasLimitForGetNumNodes = 100_000_000 const gasLimitForDelegate = 12_000_000 const minGasPrice = 1000000000 const txVersion = 1 @@ -853,3 +855,258 @@ func generateTransaction(sender []byte, nonce uint64, receiver []byte, value *bi Signature: []byte(mockTxSignature), } } + +// Test description +// Test that merging delegation with whiteListForMerge and +// mergeValidatorToDelegationWithWhitelist contracts still works properly + +// Test that their topups will merge too and will be used by auction list computing. + +// Internal test scenario #12 +func TestChainSimulator_MergeDelegation(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMergingDelegation(t, cs, 1) + }) + + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMergingDelegation(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMergingDelegation(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + testChainSimulatorMergingDelegation(t, cs, 4) + }) +} + +func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(3) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKeys) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + log.Info("Preconditions. Pick 2 users and mint both with 3000 egld") + mintValue := big.NewInt(3000) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwnerBech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + validatorA, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) + + validatorOwnerBech32, err = cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + validatorB, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) + + log.Info("Step 1. User A: - stake 1 node to have 100 egld more") + stakeValue := big.NewInt(0).Set(minimumStakeValue) + addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) + stakeValue.Add(stakeValue, addedStakedValue) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorA, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorA, blsKeys[0], addedStakedValue, 1) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorA)) + + log.Info("Step 2. Execute MakeNewContractFromValidatorData for User A") + txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) + txConvert := generateTransaction(validatorA, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) + convertTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, convertTx) + + delegationAddress := convertTx.Logs.Events[0].Topics[1] + delegationAddressBech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegationAddress, log) + log.Info("generated delegation address", "address", delegationAddressBech32) + + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], addedStakedValue, 1) + + log.Info("Step 3. User B: - stake 1 node to have 100 egld more") + stakeValue = big.NewInt(0).Set(minimumStakeValue) + addedStakedValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) + stakeValue.Add(stakeValue, addedStakedValue) + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) + txStake = generateTransaction(validatorB, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorB, blsKeys[1], addedStakedValue, 2) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorB)) + + decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) + // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey0)) + require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) + + decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) + // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey1)) + require.Equal(t, validatorB, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) + + log.Info("Step 4. User B : whitelistForMerge@addressA") + txDataField = fmt.Sprintf("whitelistForMerge@%s", hex.EncodeToString(validatorA)) + whitelistForMerge := generateTransaction(validatorB, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + whitelistForMergeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(whitelistForMerge, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, whitelistForMergeTx) + + log.Info("Step 5. User A : mergeValidatorToDelegationWithWhitelist") + txDataField = fmt.Sprintf("mergeValidatorToDelegationWithWhitelist@%s", hex.EncodeToString(validatorB)) + + txConvert = generateTransaction(validatorA, 2, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForMergeOperation) + convertTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, convertTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + decodedBLSKey0, _ = hex.DecodeString(blsKeys[0]) + // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey0)) + require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) + + decodedBLSKey1, _ = hex.DecodeString(blsKeys[1]) + // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey1)) + require.Equal(t, validatorB, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) +} + +func getBLSKeyOwner(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) []byte { + scQuery := &process.SCQuery{ + ScAddress: vm.StakingSCAddress, + FuncName: "getOwner", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{blsKey}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + return result.ReturnData[0] +} From 73dfdcfb95be4b021c31da04e96b86d86aa6ed5b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 9 Feb 2024 23:29:16 +0200 Subject: [PATCH 756/958] - removed unnecessary heartbeat components --- factory/heartbeat/heartbeatV2Components.go | 26 -- .../heartbeat/heartbeatV2Components_test.go | 21 -- .../monitor/crossShardPeerTopicNotifier.go | 111 ------- .../crossShardPeerTopicNotifier_test.go | 273 ------------------ integrationTests/testHeartbeatNode.go | 33 +-- 5 files changed, 7 insertions(+), 457 deletions(-) delete mode 100644 heartbeat/monitor/crossShardPeerTopicNotifier.go delete mode 100644 heartbeat/monitor/crossShardPeerTopicNotifier_test.go diff --git a/factory/heartbeat/heartbeatV2Components.go b/factory/heartbeat/heartbeatV2Components.go index a551f22e869..97164a7240e 100644 --- a/factory/heartbeat/heartbeatV2Components.go +++ b/factory/heartbeat/heartbeatV2Components.go @@ -272,32 +272,6 @@ func (hcf *heartbeatV2ComponentsFactory) Create() (*heartbeatV2Components, error return nil, err } - argsMainCrossShardPeerTopicNotifier := monitor.ArgsCrossShardPeerTopicNotifier{ - ShardCoordinator: hcf.processComponents.ShardCoordinator(), - PeerShardMapper: hcf.processComponents.PeerShardMapper(), - } - mainCrossShardPeerTopicNotifier, err := monitor.NewCrossShardPeerTopicNotifier(argsMainCrossShardPeerTopicNotifier) - if err != nil { - return nil, err - } - err = hcf.networkComponents.NetworkMessenger().AddPeerTopicNotifier(mainCrossShardPeerTopicNotifier) - if err != nil { - return nil, err - } - - argsFullArchiveCrossShardPeerTopicNotifier := monitor.ArgsCrossShardPeerTopicNotifier{ - ShardCoordinator: hcf.processComponents.ShardCoordinator(), - PeerShardMapper: hcf.processComponents.FullArchivePeerShardMapper(), - } - fullArchiveCrossShardPeerTopicNotifier, err := monitor.NewCrossShardPeerTopicNotifier(argsFullArchiveCrossShardPeerTopicNotifier) - if err != nil { - return nil, err - } - err = hcf.networkComponents.FullArchiveNetworkMessenger().AddPeerTopicNotifier(fullArchiveCrossShardPeerTopicNotifier) - if err != nil { - return nil, err - } - return &heartbeatV2Components{ sender: heartbeatV2Sender, peerAuthRequestsProcessor: paRequestsProcessor, diff --git a/factory/heartbeat/heartbeatV2Components_test.go b/factory/heartbeat/heartbeatV2Components_test.go index f013294a7d1..6b5088cab5b 100644 --- a/factory/heartbeat/heartbeatV2Components_test.go +++ b/factory/heartbeat/heartbeatV2Components_test.go @@ -11,7 +11,6 @@ import ( errorsMx "github.com/multiversx/mx-chain-go/errors" heartbeatComp "github.com/multiversx/mx-chain-go/factory/heartbeat" testsMocks "github.com/multiversx/mx-chain-go/integrationTests/mock" - "github.com/multiversx/mx-chain-go/p2p" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/testscommon" @@ -504,26 +503,6 @@ func TestHeartbeatV2Components_Create(t *testing.T) { assert.Nil(t, hc) assert.Error(t, err) }) - t.Run("AddPeerTopicNotifier fails should error", func(t *testing.T) { - t.Parallel() - - args := createMockHeartbeatV2ComponentsFactoryArgs() - args.NetworkComponents = &testsMocks.NetworkComponentsStub{ - Messenger: &p2pmocks.MessengerStub{ - AddPeerTopicNotifierCalled: func(notifier p2p.PeerTopicNotifier) error { - return expectedErr - }, - }, - FullArchiveNetworkMessengerField: &p2pmocks.MessengerStub{}, - } - hcf, err := heartbeatComp.NewHeartbeatV2ComponentsFactory(args) - assert.NotNil(t, hcf) - assert.NoError(t, err) - - hc, err := hcf.Create() - assert.Nil(t, hc) - assert.Equal(t, expectedErr, err) - }) t.Run("should work", func(t *testing.T) { t.Parallel() diff --git a/heartbeat/monitor/crossShardPeerTopicNotifier.go b/heartbeat/monitor/crossShardPeerTopicNotifier.go deleted file mode 100644 index aa25995fc71..00000000000 --- a/heartbeat/monitor/crossShardPeerTopicNotifier.go +++ /dev/null @@ -1,111 +0,0 @@ -package monitor - -import ( - "fmt" - "strconv" - "strings" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/heartbeat" - "github.com/multiversx/mx-chain-go/sharding" -) - -const topicSeparator = "_" - -// ArgsCrossShardPeerTopicNotifier represents the arguments for the cross shard peer topic notifier -type ArgsCrossShardPeerTopicNotifier struct { - ShardCoordinator sharding.Coordinator - PeerShardMapper heartbeat.PeerShardMapper -} - -type crossShardPeerTopicNotifier struct { - shardCoordinator sharding.Coordinator - peerShardMapper heartbeat.PeerShardMapper -} - -// NewCrossShardPeerTopicNotifier create a new cross shard peer topic notifier instance -func NewCrossShardPeerTopicNotifier(args ArgsCrossShardPeerTopicNotifier) (*crossShardPeerTopicNotifier, error) { - err := checkArgsCrossShardPeerTopicNotifier(args) - if err != nil { - return nil, err - } - - notifier := &crossShardPeerTopicNotifier{ - shardCoordinator: args.ShardCoordinator, - peerShardMapper: args.PeerShardMapper, - } - - return notifier, nil -} - -func checkArgsCrossShardPeerTopicNotifier(args ArgsCrossShardPeerTopicNotifier) error { - if check.IfNil(args.PeerShardMapper) { - return heartbeat.ErrNilPeerShardMapper - } - if check.IfNil(args.ShardCoordinator) { - return heartbeat.ErrNilShardCoordinator - } - - return nil -} - -// NewPeerFound is called whenever a new peer was found -func (notifier *crossShardPeerTopicNotifier) NewPeerFound(pid core.PeerID, topic string) { - splt := strings.Split(topic, topicSeparator) - if len(splt) != 3 { - // not a cross shard peer or the topic is global - return - } - - shardID1, err := notifier.getShardID(splt[1]) - if err != nil { - log.Error("failed to extract first shard for topic", "topic", topic, "error", err.Error()) - return - } - - shardID2, err := notifier.getShardID(splt[2]) - if err != nil { - log.Error("failed to extract second shard for topic", "topic", topic, "error", err.Error()) - return - } - if shardID1 == shardID2 { - return - } - notifier.checkAndAddShardID(pid, shardID1, topic, shardID2) - notifier.checkAndAddShardID(pid, shardID2, topic, shardID1) -} - -// TODO make a standalone component out of this -func (notifier *crossShardPeerTopicNotifier) getShardID(data string) (uint32, error) { - if data == common.MetachainTopicIdentifier { - return common.MetachainShardId, nil - } - val, err := strconv.Atoi(data) - if err != nil { - return 0, err - } - if uint32(val) >= notifier.shardCoordinator.NumberOfShards() || val < 0 { - return 0, fmt.Errorf("invalid value in crossShardPeerTopicNotifier.getShardID %d", val) - } - - return uint32(val), nil -} - -func (notifier *crossShardPeerTopicNotifier) checkAndAddShardID(pid core.PeerID, shardID1 uint32, topic string, shardID2 uint32) { - if shardID1 != notifier.shardCoordinator.SelfId() { - return - } - - log.Trace("crossShardPeerTopicNotifier.NewPeerFound found a cross shard peer", - "topic", topic, - "pid", pid.Pretty(), - "shard", shardID2) - notifier.peerShardMapper.PutPeerIdShardId(pid, shardID2) -} - -// IsInterfaceNil returns true if there is no value under the interface -func (notifier *crossShardPeerTopicNotifier) IsInterfaceNil() bool { - return notifier == nil -} diff --git a/heartbeat/monitor/crossShardPeerTopicNotifier_test.go b/heartbeat/monitor/crossShardPeerTopicNotifier_test.go deleted file mode 100644 index e4951586852..00000000000 --- a/heartbeat/monitor/crossShardPeerTopicNotifier_test.go +++ /dev/null @@ -1,273 +0,0 @@ -package monitor - -import ( - "math" - "testing" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/heartbeat" - "github.com/multiversx/mx-chain-go/process/mock" - "github.com/multiversx/mx-chain-go/testscommon" - "github.com/stretchr/testify/assert" -) - -func createMockArgsCrossShardPeerTopicNotifier() ArgsCrossShardPeerTopicNotifier { - return ArgsCrossShardPeerTopicNotifier{ - ShardCoordinator: &testscommon.ShardsCoordinatorMock{ - NoShards: 3, - CurrentShard: 1, - }, - PeerShardMapper: &mock.PeerShardMapperStub{}, - } -} - -func TestNewCrossShardPeerTopicNotifier(t *testing.T) { - t.Parallel() - - t.Run("nil sharding coordinator should error", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.ShardCoordinator = nil - - notifier, err := NewCrossShardPeerTopicNotifier(args) - assert.True(t, check.IfNil(notifier)) - assert.Equal(t, heartbeat.ErrNilShardCoordinator, err) - }) - t.Run("nil peer shard mapper should error", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = nil - - notifier, err := NewCrossShardPeerTopicNotifier(args) - assert.True(t, check.IfNil(notifier)) - assert.Equal(t, heartbeat.ErrNilPeerShardMapper, err) - }) - t.Run("should work", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - - notifier, err := NewCrossShardPeerTopicNotifier(args) - assert.False(t, check.IfNil(notifier)) - assert.Nil(t, err) - }) -} - -func TestCrossShardPeerTopicNotifier_NewPeerFound(t *testing.T) { - t.Parallel() - - testTopic := "test" - t.Run("global topic should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - notifier.NewPeerFound("pid", "random topic") - }) - t.Run("intra-shard topic should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + core.CommunicationIdentifierBetweenShards(0, 0) - notifier.NewPeerFound("pid", topic) - }) - t.Run("cross-shard topic but not relevant to current node should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + core.CommunicationIdentifierBetweenShards(0, 2) - notifier.NewPeerFound("pid", topic) - }) - t.Run("first shard ID is a NaN should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + "_NaN_1" - notifier.NewPeerFound("pid", topic) - }) - t.Run("second shard ID is a NaN should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + "_1_NaN" - notifier.NewPeerFound("pid", topic) - }) - t.Run("second shard ID is a negative value should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + "_1_-1" - notifier.NewPeerFound("pid", topic) - }) - t.Run("second shard ID is an out of range value should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + "_1_4" - notifier.NewPeerFound("pid", topic) - }) - t.Run("same shard IDs should not notice", func(t *testing.T) { - t.Parallel() - - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Fail(t, "should have not called PutPeerIdShardId") - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + "_0_0" - notifier.NewPeerFound("pid", topic) - }) - t.Run("cross-shard between 0 and 1 should notice", func(t *testing.T) { - t.Parallel() - - expectedPid := core.PeerID("pid") - notifiedShardID := uint32(math.MaxUint32) - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Equal(t, pid, expectedPid) - notifiedShardID = shardId - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + core.CommunicationIdentifierBetweenShards(0, 1) - notifier.NewPeerFound("pid", topic) - assert.Equal(t, uint32(0), notifiedShardID) - }) - t.Run("cross-shard between 1 and 2 should notice", func(t *testing.T) { - t.Parallel() - - expectedPid := core.PeerID("pid") - notifiedShardID := uint32(math.MaxUint32) - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Equal(t, pid, expectedPid) - notifiedShardID = shardId - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + core.CommunicationIdentifierBetweenShards(1, 2) - notifier.NewPeerFound("pid", topic) - assert.Equal(t, uint32(2), notifiedShardID) - }) - t.Run("cross-shard between 1 and META should notice", func(t *testing.T) { - t.Parallel() - - expectedPid := core.PeerID("pid") - notifiedShardID := uint32(math.MaxUint32) - args := createMockArgsCrossShardPeerTopicNotifier() - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Equal(t, pid, expectedPid) - notifiedShardID = shardId - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + core.CommunicationIdentifierBetweenShards(1, common.MetachainShardId) - notifier.NewPeerFound("pid", topic) - assert.Equal(t, common.MetachainShardId, notifiedShardID) - }) - t.Run("cross-shard between META and 1 should notice", func(t *testing.T) { - t.Parallel() - - expectedPid := core.PeerID("pid") - notifiedShardID := uint32(math.MaxUint32) - args := createMockArgsCrossShardPeerTopicNotifier() - args.ShardCoordinator = &testscommon.ShardsCoordinatorMock{ - NoShards: 3, - CurrentShard: common.MetachainShardId, - } - args.PeerShardMapper = &mock.PeerShardMapperStub{ - PutPeerIdShardIdCalled: func(pid core.PeerID, shardId uint32) { - assert.Equal(t, pid, expectedPid) - notifiedShardID = shardId - }, - } - - notifier, _ := NewCrossShardPeerTopicNotifier(args) - topic := testTopic + core.CommunicationIdentifierBetweenShards(common.MetachainShardId, 1) - notifier.NewPeerFound("pid", topic) - assert.Equal(t, uint32(1), notifiedShardID) - }) -} - -func BenchmarkCrossShardPeerTopicNotifier_NewPeerFound(b *testing.B) { - args := createMockArgsCrossShardPeerTopicNotifier() - notifier, _ := NewCrossShardPeerTopicNotifier(args) - - for i := 0; i < b.N; i++ { - switch i % 6 { - case 0: - notifier.NewPeerFound("pid", "global") - case 2: - notifier.NewPeerFound("pid", "intrashard_1") - case 3: - notifier.NewPeerFound("pid", "crossshard_1_2") - case 4: - notifier.NewPeerFound("pid", "crossshard_1_META") - case 5: - notifier.NewPeerFound("pid", "crossshard_META_1") - case 6: - notifier.NewPeerFound("pid", "crossshard_2_META") - } - } -} diff --git a/integrationTests/testHeartbeatNode.go b/integrationTests/testHeartbeatNode.go index 51c3091292c..b4620f50b34 100644 --- a/integrationTests/testHeartbeatNode.go +++ b/integrationTests/testHeartbeatNode.go @@ -29,7 +29,6 @@ import ( "github.com/multiversx/mx-chain-go/dataRetriever/factory/resolverscontainer" "github.com/multiversx/mx-chain-go/dataRetriever/requestHandlers" "github.com/multiversx/mx-chain-go/epochStart/notifier" - "github.com/multiversx/mx-chain-go/heartbeat/monitor" "github.com/multiversx/mx-chain-go/heartbeat/processor" "github.com/multiversx/mx-chain-go/heartbeat/sender" "github.com/multiversx/mx-chain-go/integrationTests/mock" @@ -445,7 +444,6 @@ func (thn *TestHeartbeatNode) InitTestHeartbeatNode(tb testing.TB, minPeersWaiti thn.initResolversAndRequesters() thn.initInterceptors() thn.initShardSender(tb) - thn.initCrossShardPeerTopicNotifier(tb) thn.initDirectConnectionProcessor(tb) for len(thn.MainMessenger.Peers()) < minPeersWaiting { @@ -791,29 +789,6 @@ func (thn *TestHeartbeatNode) initDirectConnectionProcessor(tb testing.TB) { require.Nil(tb, err) } -func (thn *TestHeartbeatNode) initCrossShardPeerTopicNotifier(tb testing.TB) { - argsCrossShardPeerTopicNotifier := monitor.ArgsCrossShardPeerTopicNotifier{ - ShardCoordinator: thn.ShardCoordinator, - PeerShardMapper: thn.MainPeerShardMapper, - } - crossShardPeerTopicNotifier, err := monitor.NewCrossShardPeerTopicNotifier(argsCrossShardPeerTopicNotifier) - require.Nil(tb, err) - - err = thn.MainMessenger.AddPeerTopicNotifier(crossShardPeerTopicNotifier) - require.Nil(tb, err) - - argsCrossShardPeerTopicNotifier = monitor.ArgsCrossShardPeerTopicNotifier{ - ShardCoordinator: thn.ShardCoordinator, - PeerShardMapper: thn.FullArchivePeerShardMapper, - } - fullArchiveCrossShardPeerTopicNotifier, err := monitor.NewCrossShardPeerTopicNotifier(argsCrossShardPeerTopicNotifier) - require.Nil(tb, err) - - err = thn.FullArchiveMessenger.AddPeerTopicNotifier(fullArchiveCrossShardPeerTopicNotifier) - require.Nil(tb, err) - -} - // ConnectOnMain will try to initiate a connection to the provided parameter on the main messenger func (thn *TestHeartbeatNode) ConnectOnMain(connectable Connectable) error { if check.IfNil(connectable) { @@ -859,13 +834,19 @@ func MakeDisplayTableForHeartbeatNodes(nodes map[uint32][]*TestHeartbeatNode) st for _, n := range nodesList { buffPk, _ := n.NodeKeys.MainKey.Pk.ToByteArray() + validatorMarker := "" + v, _, _ := n.NodesCoordinator.GetValidatorWithPublicKey(buffPk) + if v != nil { + validatorMarker = "*" + } + peerInfo := n.MainMessenger.GetConnectedPeersInfo() pid := n.MainMessenger.ID().Pretty() lineData := display.NewLineData( false, []string{ - core.GetTrimmedPk(hex.EncodeToString(buffPk)), + core.GetTrimmedPk(hex.EncodeToString(buffPk)) + validatorMarker, pid[len(pid)-6:], fmt.Sprintf("%d", shardId), fmt.Sprintf("%d", n.CountGlobalMessages()), From 0710ad56ac82e74eedd6a383b3b17b3475214d53 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Sat, 10 Feb 2024 01:16:37 +0200 Subject: [PATCH 757/958] new route /node/loaded-keys --- api/groups/nodeGroup.go | 20 ++++++++ api/groups/nodeGroup_test.go | 38 +++++++++++++++ api/mock/facadeStub.go | 9 ++++ api/shared/interface.go | 1 + cmd/node/config/api.toml | 3 ++ common/interface.go | 2 + facade/initial/initialNodeFacade.go | 7 ++- facade/initial/initialNodeFacade_test.go | 17 +++++++ facade/interface.go | 1 + facade/mock/apiResolverStub.go | 9 ++++ facade/nodeFacade.go | 13 ++++-- facade/nodeFacade_test.go | 46 +++++++++++++++++++ heartbeat/interface.go | 1 + integrationTests/interface.go | 1 + .../testProcessorNodeWithTestWebServer.go | 2 +- keysManagement/managedPeersHolder.go | 20 +++++++- keysManagement/managedPeersHolder_test.go | 18 ++++++++ keysManagement/managedPeersMonitor.go | 7 ++- keysManagement/managedPeersMonitor_test.go | 17 +++++++ node/external/nodeApiResolver.go | 8 +++- node/external/nodeApiResolver_test.go | 29 ++++++++++++ testscommon/managedPeersHolderStub.go | 9 ++++ testscommon/managedPeersMonitorStub.go | 9 ++++ 23 files changed, 279 insertions(+), 8 deletions(-) diff --git a/api/groups/nodeGroup.go b/api/groups/nodeGroup.go index 021ad389ed7..af87d97326f 100644 --- a/api/groups/nodeGroup.go +++ b/api/groups/nodeGroup.go @@ -28,6 +28,7 @@ const ( bootstrapStatusPath = "/bootstrapstatus" connectedPeersRatingsPath = "/connected-peers-ratings" managedKeys = "/managed-keys" + loadedKeys = "/loaded-keys" managedKeysCount = "/managed-keys/count" eligibleManagedKeys = "/managed-keys/eligible" waitingManagedKeys = "/managed-keys/waiting" @@ -43,6 +44,7 @@ type nodeFacadeHandler interface { GetConnectedPeersRatingsOnMainNetwork() (string, error) GetManagedKeysCount() int GetManagedKeys() []string + GetLoadedKeys() []string GetEligibleManagedKeys() ([]string, error) GetWaitingManagedKeys() ([]string, error) IsInterfaceNil() bool @@ -127,6 +129,11 @@ func NewNodeGroup(facade nodeFacadeHandler) (*nodeGroup, error) { Method: http.MethodGet, Handler: ng.managedKeys, }, + { + Path: loadedKeys, + Method: http.MethodGet, + Handler: ng.loadedKeys, + }, { Path: eligibleManagedKeys, Method: http.MethodGet, @@ -404,6 +411,19 @@ func (ng *nodeGroup) managedKeys(c *gin.Context) { ) } +// loadedKeys returns all keys loaded by the current node +func (ng *nodeGroup) loadedKeys(c *gin.Context) { + keys := ng.getFacade().GetLoadedKeys() + c.JSON( + http.StatusOK, + shared.GenericAPIResponse{ + Data: gin.H{"loadedKeys": keys}, + Error: "", + Code: shared.ReturnCodeSuccess, + }, + ) +} + // managedKeysEligible returns the node's eligible managed keys func (ng *nodeGroup) managedKeysEligible(c *gin.Context) { keys, err := ng.getFacade().GetEligibleManagedKeys() diff --git a/api/groups/nodeGroup_test.go b/api/groups/nodeGroup_test.go index a46d140e598..483f0139009 100644 --- a/api/groups/nodeGroup_test.go +++ b/api/groups/nodeGroup_test.go @@ -81,6 +81,13 @@ type managedKeysResponse struct { generalResponse } +type loadedKeysResponse struct { + Data struct { + LoadedKeys []string `json:"loadedKeys"` + } `json:"data"` + generalResponse +} + type managedEligibleKeysResponse struct { Data struct { Keys []string `json:"eligibleKeys"` @@ -733,6 +740,36 @@ func TestNodeGroup_ManagedKeys(t *testing.T) { assert.Equal(t, providedKeys, response.Data.ManagedKeys) } +func TestNodeGroup_LoadedKeys(t *testing.T) { + t.Parallel() + + providedKeys := []string{ + "pk1", + "pk2", + } + facade := mock.FacadeStub{ + GetLoadedKeysCalled: func() []string { + return providedKeys + }, + } + + nodeGroup, err := groups.NewNodeGroup(&facade) + require.NoError(t, err) + + ws := startWebServer(nodeGroup, "node", getNodeRoutesConfig()) + + req, _ := http.NewRequest("GET", "/node/loaded-keys", nil) + resp := httptest.NewRecorder() + ws.ServeHTTP(resp, req) + + response := &loadedKeysResponse{} + loadResponse(resp.Body, response) + + assert.Equal(t, http.StatusOK, resp.Code) + assert.Equal(t, "", response.Error) + assert.Equal(t, providedKeys, response.Data.LoadedKeys) +} + func TestNodeGroup_ManagedKeysEligible(t *testing.T) { t.Parallel() @@ -960,6 +997,7 @@ func getNodeRoutesConfig() config.ApiRoutesConfig { {Name: "/connected-peers-ratings", Open: true}, {Name: "/managed-keys/count", Open: true}, {Name: "/managed-keys", Open: true}, + {Name: "/loaded-keys", Open: true}, {Name: "/managed-keys/eligible", Open: true}, {Name: "/managed-keys/waiting", Open: true}, }, diff --git a/api/mock/facadeStub.go b/api/mock/facadeStub.go index 366af9dd218..e42534a1e57 100644 --- a/api/mock/facadeStub.go +++ b/api/mock/facadeStub.go @@ -91,6 +91,7 @@ type FacadeStub struct { IsDataTrieMigratedCalled func(address string, options api.AccountQueryOptions) (bool, error) GetManagedKeysCountCalled func() int GetManagedKeysCalled func() []string + GetLoadedKeysCalled func() []string GetEligibleManagedKeysCalled func() ([]string, error) GetWaitingManagedKeysCalled func() ([]string, error) } @@ -594,6 +595,14 @@ func (f *FacadeStub) GetManagedKeys() []string { return make([]string, 0) } +// GetLoadedKeys - +func (f *FacadeStub) GetLoadedKeys() []string { + if f.GetLoadedKeysCalled != nil { + return f.GetLoadedKeysCalled() + } + return make([]string, 0) +} + // GetEligibleManagedKeys - func (f *FacadeStub) GetEligibleManagedKeys() ([]string, error) { if f.GetEligibleManagedKeysCalled != nil { diff --git a/api/shared/interface.go b/api/shared/interface.go index 0b199393b96..0f278fbe95c 100644 --- a/api/shared/interface.go +++ b/api/shared/interface.go @@ -130,6 +130,7 @@ type FacadeHandler interface { IsDataTrieMigrated(address string, options api.AccountQueryOptions) (bool, error) GetManagedKeysCount() int GetManagedKeys() []string + GetLoadedKeys() []string GetEligibleManagedKeys() ([]string, error) GetWaitingManagedKeys() ([]string, error) IsInterfaceNil() bool diff --git a/cmd/node/config/api.toml b/cmd/node/config/api.toml index e444d9d5c65..f7d2d66cb8c 100644 --- a/cmd/node/config/api.toml +++ b/cmd/node/config/api.toml @@ -43,6 +43,9 @@ # /node/managed-keys will return the keys managed by the node { Name = "/managed-keys", Open = true }, + # /node/loaded-keys will return the keys loaded by the node + { Name = "/loaded-keys", Open = true }, + # /node/managed-keys/count will return the number of keys managed by the node { Name = "/managed-keys/count", Open = true }, diff --git a/common/interface.go b/common/interface.go index 010d55e22d5..2e14c33730e 100644 --- a/common/interface.go +++ b/common/interface.go @@ -414,6 +414,7 @@ type ManagedPeersHolder interface { IncrementRoundsWithoutReceivedMessages(pkBytes []byte) ResetRoundsWithoutReceivedMessages(pkBytes []byte, pid core.PeerID) GetManagedKeysByCurrentNode() map[string]crypto.PrivateKey + GetLoadedKeysByCurrentNode() [][]byte IsKeyManagedByCurrentNode(pkBytes []byte) bool IsKeyRegistered(pkBytes []byte) bool IsPidManagedByCurrentNode(pid core.PeerID) bool @@ -443,6 +444,7 @@ type StateSyncNotifierSubscriber interface { type ManagedPeersMonitor interface { GetManagedKeysCount() int GetManagedKeys() [][]byte + GetLoadedKeys() [][]byte GetEligibleManagedKeys() ([][]byte, error) GetWaitingManagedKeys() ([][]byte, error) IsInterfaceNil() bool diff --git a/facade/initial/initialNodeFacade.go b/facade/initial/initialNodeFacade.go index a8e04f2c0bd..a2237f20805 100644 --- a/facade/initial/initialNodeFacade.go +++ b/facade/initial/initialNodeFacade.go @@ -76,7 +76,7 @@ func (inf *initialNodeFacade) SetSyncer(_ ntp.SyncTimer) { } // RestAPIServerDebugMode returns false -//TODO: remove in the future +// TODO: remove in the future func (inf *initialNodeFacade) RestAPIServerDebugMode() bool { return false } @@ -416,6 +416,11 @@ func (inf *initialNodeFacade) GetManagedKeys() []string { return nil } +// GetLoadedKeys returns nil +func (inf *initialNodeFacade) GetLoadedKeys() []string { + return nil +} + // GetEligibleManagedKeys returns nil and error func (inf *initialNodeFacade) GetEligibleManagedKeys() ([]string, error) { return nil, errNodeStarting diff --git a/facade/initial/initialNodeFacade_test.go b/facade/initial/initialNodeFacade_test.go index 7298b001ba3..3c13175b6e9 100644 --- a/facade/initial/initialNodeFacade_test.go +++ b/facade/initial/initialNodeFacade_test.go @@ -316,6 +316,23 @@ func TestInitialNodeFacade_AllMethodsShouldNotPanic(t *testing.T) { assert.Nil(t, txPoolGaps) assert.Equal(t, errNodeStarting, err) + count := inf.GetManagedKeysCount() + assert.Zero(t, count) + + keys := inf.GetManagedKeys() + assert.Nil(t, keys) + + keys = inf.GetLoadedKeys() + assert.Nil(t, keys) + + keys, err = inf.GetEligibleManagedKeys() + assert.Nil(t, keys) + assert.Equal(t, errNodeStarting, err) + + keys, err = inf.GetWaitingManagedKeys() + assert.Nil(t, keys) + assert.Equal(t, errNodeStarting, err) + assert.NotNil(t, inf) } diff --git a/facade/interface.go b/facade/interface.go index 910948b57a7..32ef8b01c94 100644 --- a/facade/interface.go +++ b/facade/interface.go @@ -142,6 +142,7 @@ type ApiResolver interface { GetGasConfigs() map[string]map[string]uint64 GetManagedKeysCount() int GetManagedKeys() []string + GetLoadedKeys() []string GetEligibleManagedKeys() ([]string, error) GetWaitingManagedKeys() ([]string, error) Close() error diff --git a/facade/mock/apiResolverStub.go b/facade/mock/apiResolverStub.go index ef71463c320..aed1ffb56bd 100644 --- a/facade/mock/apiResolverStub.go +++ b/facade/mock/apiResolverStub.go @@ -46,6 +46,7 @@ type ApiResolverStub struct { GetGasConfigsCalled func() map[string]map[string]uint64 GetManagedKeysCountCalled func() int GetManagedKeysCalled func() []string + GetLoadedKeysCalled func() []string GetEligibleManagedKeysCalled func() ([]string, error) GetWaitingManagedKeysCalled func() ([]string, error) } @@ -308,6 +309,14 @@ func (ars *ApiResolverStub) GetManagedKeys() []string { return make([]string, 0) } +// GetLoadedKeys - +func (ars *ApiResolverStub) GetLoadedKeys() []string { + if ars.GetLoadedKeysCalled != nil { + return ars.GetLoadedKeysCalled() + } + return make([]string, 0) +} + // GetEligibleManagedKeys - func (ars *ApiResolverStub) GetEligibleManagedKeys() ([]string, error) { if ars.GetEligibleManagedKeysCalled != nil { diff --git a/facade/nodeFacade.go b/facade/nodeFacade.go index 77ca17669a2..9234d636336 100644 --- a/facade/nodeFacade.go +++ b/facade/nodeFacade.go @@ -36,7 +36,8 @@ import ( const DefaultRestInterface = "localhost:8080" // DefaultRestPortOff is the default value that should be passed if it is desired -// to start the node without a REST endpoint available +// +// to start the node without a REST endpoint available const DefaultRestPortOff = "off" var log = logger.GetOrCreate("facade") @@ -163,7 +164,8 @@ func (nf *nodeFacade) RestAPIServerDebugMode() bool { // RestApiInterface returns the interface on which the rest API should start on, based on the config file provided. // The API will start on the DefaultRestInterface value unless a correct value is passed or -// the value is explicitly set to off, in which case it will not start at all +// +// the value is explicitly set to off, in which case it will not start at all func (nf *nodeFacade) RestApiInterface() string { if nf.config.RestApiInterface == "" { return DefaultRestInterface @@ -590,11 +592,16 @@ func (nf *nodeFacade) GetManagedKeysCount() int { return nf.apiResolver.GetManagedKeysCount() } -// GetManagedKeys returns all keys managed by the current node when running in multikey mode +// GetManagedKeys returns all keys that should act as validator(main or backup that took over) and will be managed by this node func (nf *nodeFacade) GetManagedKeys() []string { return nf.apiResolver.GetManagedKeys() } +// GetLoadedKeys returns all keys that were loaded and will be managed by this node +func (nf *nodeFacade) GetLoadedKeys() []string { + return nf.apiResolver.GetLoadedKeys() +} + // GetEligibleManagedKeys returns the eligible managed keys when node is running in multikey mode func (nf *nodeFacade) GetEligibleManagedKeys() ([]string, error) { return nf.apiResolver.GetEligibleManagedKeys() diff --git a/facade/nodeFacade_test.go b/facade/nodeFacade_test.go index b2f069f673b..9082283d945 100644 --- a/facade/nodeFacade_test.go +++ b/facade/nodeFacade_test.go @@ -2225,6 +2225,52 @@ func TestNodeFacade_GetInternalStartOfEpochMetaBlock(t *testing.T) { require.Equal(t, providedResponse, response) } +func TestNodeFacade_GetManagedKeys(t *testing.T) { + t.Parallel() + + providedCount := 100 + providedManagedKeys := []string{"pk1", "pk2"} + providedLoadedKeys := []string{"pk3", "pk4"} + providedEligibleKeys := []string{"pk5", "pk6"} + providedWaitingKeys := []string{"pk7", "pk8"} + arg := createMockArguments() + arg.ApiResolver = &mock.ApiResolverStub{ + GetManagedKeysCountCalled: func() int { + return providedCount + }, + GetManagedKeysCalled: func() []string { + return providedManagedKeys + }, + GetLoadedKeysCalled: func() []string { + return providedLoadedKeys + }, + GetEligibleManagedKeysCalled: func() ([]string, error) { + return providedEligibleKeys, nil + }, + GetWaitingManagedKeysCalled: func() ([]string, error) { + return providedWaitingKeys, nil + }, + } + nf, _ := NewNodeFacade(arg) + + count := nf.GetManagedKeysCount() + require.Equal(t, providedCount, count) + + keys := nf.GetManagedKeys() + require.Equal(t, providedManagedKeys, keys) + + keys = nf.GetLoadedKeys() + require.Equal(t, providedLoadedKeys, keys) + + keys, err := nf.GetEligibleManagedKeys() + require.Equal(t, providedEligibleKeys, keys) + require.Nil(t, err) + + keys, err = nf.GetWaitingManagedKeys() + require.Equal(t, providedWaitingKeys, keys) + require.Nil(t, err) +} + func TestNodeFacade_Close(t *testing.T) { t.Parallel() diff --git a/heartbeat/interface.go b/heartbeat/interface.go index 12eb29a5d61..3652170d8ba 100644 --- a/heartbeat/interface.go +++ b/heartbeat/interface.go @@ -83,6 +83,7 @@ type ManagedPeersHolder interface { IncrementRoundsWithoutReceivedMessages(pkBytes []byte) ResetRoundsWithoutReceivedMessages(pkBytes []byte, pid core.PeerID) GetManagedKeysByCurrentNode() map[string]crypto.PrivateKey + GetLoadedKeysByCurrentNode() [][]byte IsKeyManagedByCurrentNode(pkBytes []byte) bool IsKeyRegistered(pkBytes []byte) bool IsPidManagedByCurrentNode(pid core.PeerID) bool diff --git a/integrationTests/interface.go b/integrationTests/interface.go index ddce1ebf3d4..373067f28b3 100644 --- a/integrationTests/interface.go +++ b/integrationTests/interface.go @@ -113,6 +113,7 @@ type Facade interface { IsDataTrieMigrated(address string, options api.AccountQueryOptions) (bool, error) GetManagedKeysCount() int GetManagedKeys() []string + GetLoadedKeys() []string GetEligibleManagedKeys() ([]string, error) GetWaitingManagedKeys() ([]string, error) IsInterfaceNil() bool diff --git a/integrationTests/testProcessorNodeWithTestWebServer.go b/integrationTests/testProcessorNodeWithTestWebServer.go index f177c08cfd8..84428a770b2 100644 --- a/integrationTests/testProcessorNodeWithTestWebServer.go +++ b/integrationTests/testProcessorNodeWithTestWebServer.go @@ -101,7 +101,7 @@ func createFacadeArg(tpn *TestProcessorNode) nodeFacade.ArgNodeFacade { func createTestApiConfig() config.ApiRoutesConfig { routes := map[string][]string{ - "node": {"/status", "/metrics", "/heartbeatstatus", "/statistics", "/p2pstatus", "/debug", "/peerinfo", "/bootstrapstatus", "/connected-peers-ratings", "/managed-keys/count", "/managed-keys", "/managed-keys/eligible", "/managed-keys/waiting"}, + "node": {"/status", "/metrics", "/heartbeatstatus", "/statistics", "/p2pstatus", "/debug", "/peerinfo", "/bootstrapstatus", "/connected-peers-ratings", "/managed-keys/count", "/managed-keys", "/loaded-keys", "/managed-keys/eligible", "/managed-keys/waiting"}, "address": {"/:address", "/:address/balance", "/:address/username", "/:address/code-hash", "/:address/key/:key", "/:address/esdt", "/:address/esdt/:tokenIdentifier"}, "hardfork": {"/trigger"}, "network": {"/status", "/total-staked", "/economics", "/config"}, diff --git a/keysManagement/managedPeersHolder.go b/keysManagement/managedPeersHolder.go index a347f4f2a53..8156b64c8eb 100644 --- a/keysManagement/managedPeersHolder.go +++ b/keysManagement/managedPeersHolder.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "sort" "sync" "time" @@ -281,7 +282,7 @@ func (holder *managedPeersHolder) ResetRoundsWithoutReceivedMessages(pkBytes []b pInfo.resetRoundsWithoutReceivedMessages() } -// GetManagedKeysByCurrentNode returns all keys that will be managed by this node +// GetManagedKeysByCurrentNode returns all keys that should act as validator(main or backup that took over) and will be managed by this node func (holder *managedPeersHolder) GetManagedKeysByCurrentNode() map[string]crypto.PrivateKey { holder.mut.RLock() defer holder.mut.RUnlock() @@ -299,6 +300,23 @@ func (holder *managedPeersHolder) GetManagedKeysByCurrentNode() map[string]crypt return allManagedKeys } +// GetLoadedKeysByCurrentNode returns all keys that were loaded and will be managed by this node +func (holder *managedPeersHolder) GetLoadedKeysByCurrentNode() [][]byte { + holder.mut.RLock() + defer holder.mut.RUnlock() + + allLoadedKeys := make([][]byte, 0, len(holder.data)) + for pk := range holder.data { + allLoadedKeys = append(allLoadedKeys, []byte(pk)) + } + + sort.Slice(allLoadedKeys, func(i, j int) bool { + return string(allLoadedKeys[i]) < string(allLoadedKeys[j]) + }) + + return allLoadedKeys +} + // IsKeyManagedByCurrentNode returns true if the key is managed by the current node func (holder *managedPeersHolder) IsKeyManagedByCurrentNode(pkBytes []byte) bool { pInfo := holder.getPeerInfo(pkBytes) diff --git a/keysManagement/managedPeersHolder_test.go b/keysManagement/managedPeersHolder_test.go index 81f0dfff86b..fa7d84209a2 100644 --- a/keysManagement/managedPeersHolder_test.go +++ b/keysManagement/managedPeersHolder_test.go @@ -751,6 +751,24 @@ func TestManagedPeersHolder_GetManagedKeysByCurrentNode(t *testing.T) { }) } +func TestManagedPeersHolder_GetLoadedKeysByCurrentNode(t *testing.T) { + t.Parallel() + + args := createMockArgsManagedPeersHolder() + holder, _ := keysManagement.NewManagedPeersHolder(args) + _ = holder.AddManagedPeer(skBytes1) + _ = holder.AddManagedPeer(skBytes0) + + for i := 0; i < 10; i++ { + holder.IncrementRoundsWithoutReceivedMessages(pkBytes0) + } + + result := holder.GetLoadedKeysByCurrentNode() + assert.Equal(t, 2, len(result)) + assert.Equal(t, pkBytes0, result[0]) + assert.Equal(t, pkBytes1, result[1]) +} + func TestManagedPeersHolder_IsKeyManagedByCurrentNode(t *testing.T) { t.Parallel() diff --git a/keysManagement/managedPeersMonitor.go b/keysManagement/managedPeersMonitor.go index 2c2eef290b4..5f9f117cc2b 100644 --- a/keysManagement/managedPeersMonitor.go +++ b/keysManagement/managedPeersMonitor.go @@ -60,7 +60,7 @@ func (monitor *managedPeersMonitor) GetManagedKeysCount() int { return len(monitor.managedPeersHolder.GetManagedKeysByCurrentNode()) } -// GetManagedKeys returns all keys managed by the current node +// GetManagedKeys returns all keys that should act as validator(main or backup that took over) and will be managed by this node func (monitor *managedPeersMonitor) GetManagedKeys() [][]byte { managedKeysMap := monitor.managedPeersHolder.GetManagedKeysByCurrentNode() managedKeys := make([][]byte, 0, len(managedKeysMap)) @@ -75,6 +75,11 @@ func (monitor *managedPeersMonitor) GetManagedKeys() [][]byte { return managedKeys } +// GetLoadedKeys returns all keys that were loaded and will be managed by this node +func (monitor *managedPeersMonitor) GetLoadedKeys() [][]byte { + return monitor.managedPeersHolder.GetLoadedKeysByCurrentNode() +} + // GetEligibleManagedKeys returns eligible keys that are managed by the current node in the current epoch func (monitor *managedPeersMonitor) GetEligibleManagedKeys() ([][]byte, error) { epoch := monitor.epochProvider.CurrentEpoch() diff --git a/keysManagement/managedPeersMonitor_test.go b/keysManagement/managedPeersMonitor_test.go index 9ec9dbcd8ad..4be6a5282ca 100644 --- a/keysManagement/managedPeersMonitor_test.go +++ b/keysManagement/managedPeersMonitor_test.go @@ -281,3 +281,20 @@ func TestManagedPeersMonitor_GetManagedKeys(t *testing.T) { keys := monitor.GetManagedKeys() require.Equal(t, expectedManagedKeys, keys) } + +func TestManagedPeersMonitor_GetLoadedKeys(t *testing.T) { + t.Parallel() + + loadedKeys := [][]byte{[]byte("pk1"), []byte("pk2"), []byte("pk3")} + args := createMockArgManagedPeersMonitor() + args.ManagedPeersHolder = &testscommon.ManagedPeersHolderStub{ + GetLoadedKeysByCurrentNodeCalled: func() [][]byte { + return loadedKeys + }, + } + monitor, err := NewManagedPeersMonitor(args) + require.NoError(t, err) + + keys := monitor.GetLoadedKeys() + require.Equal(t, loadedKeys, keys) +} diff --git a/node/external/nodeApiResolver.go b/node/external/nodeApiResolver.go index 15d7f445962..937c335650d 100644 --- a/node/external/nodeApiResolver.go +++ b/node/external/nodeApiResolver.go @@ -339,12 +339,18 @@ func (nar *nodeApiResolver) GetManagedKeysCount() int { return nar.managedPeersMonitor.GetManagedKeysCount() } -// GetManagedKeys returns all keys managed by the current node when running in multikey mode +// GetManagedKeys returns all keys that should act as validator(main or backup that took over) and will be managed by this node func (nar *nodeApiResolver) GetManagedKeys() []string { managedKeys := nar.managedPeersMonitor.GetManagedKeys() return nar.parseKeys(managedKeys) } +// GetLoadedKeys returns all keys that were loaded and will be managed by this node +func (nar *nodeApiResolver) GetLoadedKeys() []string { + loadedKeys := nar.managedPeersMonitor.GetLoadedKeys() + return nar.parseKeys(loadedKeys) +} + // GetEligibleManagedKeys returns the eligible managed keys when node is running in multikey mode func (nar *nodeApiResolver) GetEligibleManagedKeys() ([]string, error) { eligibleKeys, err := nar.managedPeersMonitor.GetEligibleManagedKeys() diff --git a/node/external/nodeApiResolver_test.go b/node/external/nodeApiResolver_test.go index 207ff020400..244c180e6c1 100644 --- a/node/external/nodeApiResolver_test.go +++ b/node/external/nodeApiResolver_test.go @@ -726,6 +726,35 @@ func TestNodeApiResolver_GetManagedKeys(t *testing.T) { require.Equal(t, expectedKeys, keys) } +func TestNodeApiResolver_GetLoadedKeys(t *testing.T) { + t.Parallel() + + providedKeys := [][]byte{ + []byte("pk1"), + []byte("pk2"), + } + expectedKeys := []string{ + "pk1", + "pk2", + } + args := createMockArgs() + args.ManagedPeersMonitor = &testscommon.ManagedPeersMonitorStub{ + GetLoadedKeysCalled: func() [][]byte { + return providedKeys + }, + } + args.ValidatorPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + return string(pkBytes) + }, + } + nar, err := external.NewNodeApiResolver(args) + require.NoError(t, err) + + keys := nar.GetLoadedKeys() + require.Equal(t, expectedKeys, keys) +} + func TestNodeApiResolver_GetEligibleManagedKeys(t *testing.T) { t.Parallel() diff --git a/testscommon/managedPeersHolderStub.go b/testscommon/managedPeersHolderStub.go index 0bd1948d813..ef9a550fe2b 100644 --- a/testscommon/managedPeersHolderStub.go +++ b/testscommon/managedPeersHolderStub.go @@ -17,6 +17,7 @@ type ManagedPeersHolderStub struct { IncrementRoundsWithoutReceivedMessagesCalled func(pkBytes []byte) ResetRoundsWithoutReceivedMessagesCalled func(pkBytes []byte, pid core.PeerID) GetManagedKeysByCurrentNodeCalled func() map[string]crypto.PrivateKey + GetLoadedKeysByCurrentNodeCalled func() [][]byte IsKeyManagedByCurrentNodeCalled func(pkBytes []byte) bool IsKeyRegisteredCalled func(pkBytes []byte) bool IsPidManagedByCurrentNodeCalled func(pid core.PeerID) bool @@ -90,6 +91,14 @@ func (stub *ManagedPeersHolderStub) GetManagedKeysByCurrentNode() map[string]cry return nil } +// GetLoadedKeysByCurrentNode - +func (stub *ManagedPeersHolderStub) GetLoadedKeysByCurrentNode() [][]byte { + if stub.GetLoadedKeysByCurrentNodeCalled != nil { + return stub.GetLoadedKeysByCurrentNodeCalled() + } + return make([][]byte, 0) +} + // IsKeyManagedByCurrentNode - func (stub *ManagedPeersHolderStub) IsKeyManagedByCurrentNode(pkBytes []byte) bool { if stub.IsKeyManagedByCurrentNodeCalled != nil { diff --git a/testscommon/managedPeersMonitorStub.go b/testscommon/managedPeersMonitorStub.go index 2ae60ccc55e..43aea679c14 100644 --- a/testscommon/managedPeersMonitorStub.go +++ b/testscommon/managedPeersMonitorStub.go @@ -6,6 +6,7 @@ type ManagedPeersMonitorStub struct { GetEligibleManagedKeysCalled func() ([][]byte, error) GetWaitingManagedKeysCalled func() ([][]byte, error) GetManagedKeysCalled func() [][]byte + GetLoadedKeysCalled func() [][]byte } // GetManagedKeys - @@ -16,6 +17,14 @@ func (stub *ManagedPeersMonitorStub) GetManagedKeys() [][]byte { return make([][]byte, 0) } +// GetLoadedKeys - +func (stub *ManagedPeersMonitorStub) GetLoadedKeys() [][]byte { + if stub.GetLoadedKeysCalled != nil { + return stub.GetLoadedKeysCalled() + } + return make([][]byte, 0) +} + // GetManagedKeysCount - func (stub *ManagedPeersMonitorStub) GetManagedKeysCount() int { if stub.GetManagedKeysCountCalled != nil { From f69194c629eed39680d0f49103794edd43117471 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Sun, 11 Feb 2024 08:40:59 +0200 Subject: [PATCH 758/958] configurable epoch change delay --- cmd/node/config/config.toml | 1 + config/config.go | 13 ++++++----- epochStart/shardchain/trigger.go | 22 +++++++++++------- factory/processing/processComponents.go | 31 +++++++++++++------------ node/chainSimulator/configs/configs.go | 2 ++ 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 85fde2e08cf..57fee3a8778 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -629,6 +629,7 @@ MinNumConnectedPeersToStart = 2 MinNumOfPeersToConsiderBlockValid = 2 + ExtraDelayForRequestBlockInfoInMilliseconds = 3000 # ResourceStats, if enabled, will output in a folder called "stats" # resource statistics. For example: number of active go routines, memory allocation, number of GC sweeps, etc. diff --git a/config/config.go b/config/config.go index 6b76bbfe2ad..1a4f5a625c1 100644 --- a/config/config.go +++ b/config/config.go @@ -88,12 +88,13 @@ type EvictionWaitingListConfig struct { // EpochStartConfig will hold the configuration of EpochStart settings type EpochStartConfig struct { - MinRoundsBetweenEpochs int64 - RoundsPerEpoch int64 - MinShuffledOutRestartThreshold float64 - MaxShuffledOutRestartThreshold float64 - MinNumConnectedPeersToStart int - MinNumOfPeersToConsiderBlockValid int + MinRoundsBetweenEpochs int64 + RoundsPerEpoch int64 + MinShuffledOutRestartThreshold float64 + MaxShuffledOutRestartThreshold float64 + MinNumConnectedPeersToStart int + MinNumOfPeersToConsiderBlockValid int + ExtraDelayForRequestBlockInfoInMilliseconds int } // BlockSizeThrottleConfig will hold the configuration for adaptive block size throttle diff --git a/epochStart/shardchain/trigger.go b/epochStart/shardchain/trigger.go index e3f09fdf2a0..fdd535143fb 100644 --- a/epochStart/shardchain/trigger.go +++ b/epochStart/shardchain/trigger.go @@ -46,14 +46,15 @@ type ArgsShardEpochStartTrigger struct { HeaderValidator epochStart.HeaderValidator Uint64Converter typeConverters.Uint64ByteSliceConverter - DataPool dataRetriever.PoolsHolder - Storage dataRetriever.StorageService - RequestHandler epochStart.RequestHandler - EpochStartNotifier epochStart.Notifier - PeerMiniBlocksSyncer process.ValidatorInfoSyncer - RoundHandler process.RoundHandler - AppStatusHandler core.AppStatusHandler - EnableEpochsHandler common.EnableEpochsHandler + DataPool dataRetriever.PoolsHolder + Storage dataRetriever.StorageService + RequestHandler epochStart.RequestHandler + EpochStartNotifier epochStart.Notifier + PeerMiniBlocksSyncer process.ValidatorInfoSyncer + RoundHandler process.RoundHandler + AppStatusHandler core.AppStatusHandler + EnableEpochsHandler common.EnableEpochsHandler + ExtraDelayForRequestBlockInfo time.Duration Epoch uint32 Validity uint64 @@ -112,6 +113,8 @@ type trigger struct { mutMissingMiniBlocks sync.RWMutex mutMissingValidatorsInfo sync.RWMutex cancelFunc func() + + extraDelayForRequestBlockInfo time.Duration } type metaInfo struct { @@ -260,6 +263,7 @@ func NewEpochStartTrigger(args *ArgsShardEpochStartTrigger) (*trigger, error) { appStatusHandler: args.AppStatusHandler, roundHandler: args.RoundHandler, enableEpochsHandler: args.EnableEpochsHandler, + extraDelayForRequestBlockInfo: args.ExtraDelayForRequestBlockInfo, } t.headersPool.RegisterHandler(t.receivedMetaBlock) @@ -586,7 +590,7 @@ func (t *trigger) receivedMetaBlock(headerHandler data.HeaderHandler, metaBlockH t.newEpochHdrReceived = true t.mapEpochStartHdrs[string(metaBlockHash)] = metaHdr // waiting for late broadcast of mini blocks and transactions to be done and received - wait := common.ExtraDelayForRequestBlockInfo + wait := t.extraDelayForRequestBlockInfo roundDifferences := t.roundHandler.Index() - int64(headerHandler.GetRound()) if roundDifferences > 1 { wait = 0 diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index db15b0c0d88..e6896dd975c 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -810,21 +810,22 @@ func (pcf *processComponentsFactory) newEpochStartTrigger(requestHandler epochSt } argEpochStart := &shardchain.ArgsShardEpochStartTrigger{ - Marshalizer: pcf.coreData.InternalMarshalizer(), - Hasher: pcf.coreData.Hasher(), - HeaderValidator: headerValidator, - Uint64Converter: pcf.coreData.Uint64ByteSliceConverter(), - DataPool: pcf.data.Datapool(), - Storage: pcf.data.StorageService(), - RequestHandler: requestHandler, - Epoch: pcf.bootstrapComponents.EpochBootstrapParams().Epoch(), - EpochStartNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), - Validity: process.MetaBlockValidity, - Finality: process.BlockFinality, - PeerMiniBlocksSyncer: peerMiniBlockSyncer, - RoundHandler: pcf.coreData.RoundHandler(), - AppStatusHandler: pcf.statusCoreComponents.AppStatusHandler(), - EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), + Marshalizer: pcf.coreData.InternalMarshalizer(), + Hasher: pcf.coreData.Hasher(), + HeaderValidator: headerValidator, + Uint64Converter: pcf.coreData.Uint64ByteSliceConverter(), + DataPool: pcf.data.Datapool(), + Storage: pcf.data.StorageService(), + RequestHandler: requestHandler, + Epoch: pcf.bootstrapComponents.EpochBootstrapParams().Epoch(), + EpochStartNotifier: pcf.coreData.EpochStartNotifierWithConfirm(), + Validity: process.MetaBlockValidity, + Finality: process.BlockFinality, + PeerMiniBlocksSyncer: peerMiniBlockSyncer, + RoundHandler: pcf.coreData.RoundHandler(), + AppStatusHandler: pcf.statusCoreComponents.AppStatusHandler(), + EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), + ExtraDelayForRequestBlockInfo: time.Duration(pcf.config.EpochStartConfig.ExtraDelayForRequestBlockInfoInMilliseconds) * time.Millisecond, } return shardchain.NewEpochStartTrigger(argEpochStart) } diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 329436a000d..edee6506f1e 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -116,6 +116,8 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi // enable db lookup extension configs.GeneralConfig.DbLookupExtensions.Enabled = true + configs.GeneralConfig.EpochStartConfig.ExtraDelayForRequestBlockInfoInMilliseconds = 1 + if args.RoundsPerEpoch.HasValue { configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) } From 0dc18e15bc130b39e9d36289192146ca8cfc735d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 12 Feb 2024 10:18:03 +0200 Subject: [PATCH 759/958] fixes after review --- epochStart/shardchain/trigger.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/epochStart/shardchain/trigger.go b/epochStart/shardchain/trigger.go index fdd535143fb..496702b8d81 100644 --- a/epochStart/shardchain/trigger.go +++ b/epochStart/shardchain/trigger.go @@ -224,10 +224,14 @@ func NewEpochStartTrigger(args *ArgsShardEpochStartTrigger) (*trigger, error) { return nil, err } - trigggerStateKey := common.TriggerRegistryInitialKeyPrefix + fmt.Sprintf("%d", args.Epoch) + if args.ExtraDelayForRequestBlockInfo != common.ExtraDelayForRequestBlockInfo { + log.Warn("different delay for request block info: the epoch change trigger might not behave normally", + "value from config", args.ExtraDelayForRequestBlockInfo.String(), "expected", common.ExtraDelayForRequestBlockInfo.String()) + } + triggerStateKey := common.TriggerRegistryInitialKeyPrefix + fmt.Sprintf("%d", args.Epoch) t := &trigger{ - triggerStateKey: []byte(trigggerStateKey), + triggerStateKey: []byte(triggerStateKey), epoch: args.Epoch, metaEpoch: args.Epoch, currentRoundIndex: 0, From 28cbb9fa8d246f052a0055365a707b55689cef4b Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 12 Feb 2024 10:21:27 +0200 Subject: [PATCH 760/958] fix after review, return the main public key while in single key mode --- facade/nodeFacade.go | 5 +- factory/api/apiResolverFactory.go | 1 + node/external/nodeApiResolver.go | 12 ++++- node/external/nodeApiResolver_test.go | 70 ++++++++++++++++++--------- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/facade/nodeFacade.go b/facade/nodeFacade.go index 9234d636336..00902f8ed55 100644 --- a/facade/nodeFacade.go +++ b/facade/nodeFacade.go @@ -36,8 +36,7 @@ import ( const DefaultRestInterface = "localhost:8080" // DefaultRestPortOff is the default value that should be passed if it is desired -// -// to start the node without a REST endpoint available +// to start the node without a REST endpoint available const DefaultRestPortOff = "off" var log = logger.GetOrCreate("facade") @@ -597,7 +596,7 @@ func (nf *nodeFacade) GetManagedKeys() []string { return nf.apiResolver.GetManagedKeys() } -// GetLoadedKeys returns all keys that were loaded and will be managed by this node +// GetLoadedKeys returns all keys that were loaded by this node func (nf *nodeFacade) GetLoadedKeys() []string { return nf.apiResolver.GetLoadedKeys() } diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index bd5c1d4abc9..ceaaa093fa6 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -284,6 +284,7 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { AccountsParser: args.ProcessComponents.AccountsParser(), GasScheduleNotifier: args.GasScheduleNotifier, ManagedPeersMonitor: args.StatusComponents.ManagedPeersMonitor(), + PublicKey: args.CryptoComponents.PublicKeyString(), } return external.NewNodeApiResolver(argsApiResolver) diff --git a/node/external/nodeApiResolver.go b/node/external/nodeApiResolver.go index 937c335650d..ec1f414a286 100644 --- a/node/external/nodeApiResolver.go +++ b/node/external/nodeApiResolver.go @@ -40,6 +40,7 @@ type ArgNodeApiResolver struct { AccountsParser genesis.AccountsParser GasScheduleNotifier common.GasScheduleNotifierAPI ManagedPeersMonitor common.ManagedPeersMonitor + PublicKey string } // nodeApiResolver can resolve API requests @@ -58,6 +59,7 @@ type nodeApiResolver struct { accountsParser genesis.AccountsParser gasScheduleNotifier common.GasScheduleNotifierAPI managedPeersMonitor common.ManagedPeersMonitor + publicKey string } // NewNodeApiResolver creates a new nodeApiResolver instance @@ -120,6 +122,7 @@ func NewNodeApiResolver(arg ArgNodeApiResolver) (*nodeApiResolver, error) { accountsParser: arg.AccountsParser, gasScheduleNotifier: arg.GasScheduleNotifier, managedPeersMonitor: arg.ManagedPeersMonitor, + publicKey: arg.PublicKey, }, nil } @@ -345,10 +348,15 @@ func (nar *nodeApiResolver) GetManagedKeys() []string { return nar.parseKeys(managedKeys) } -// GetLoadedKeys returns all keys that were loaded and will be managed by this node +// GetLoadedKeys returns all keys that were loaded by this node func (nar *nodeApiResolver) GetLoadedKeys() []string { loadedKeys := nar.managedPeersMonitor.GetLoadedKeys() - return nar.parseKeys(loadedKeys) + if len(loadedKeys) > 0 { + return nar.parseKeys(loadedKeys) + } + + // node is in single key mode, returning the main public key + return []string{nar.publicKey} } // GetEligibleManagedKeys returns the eligible managed keys when node is running in multikey mode diff --git a/node/external/nodeApiResolver_test.go b/node/external/nodeApiResolver_test.go index 244c180e6c1..390e945bdab 100644 --- a/node/external/nodeApiResolver_test.go +++ b/node/external/nodeApiResolver_test.go @@ -729,30 +729,54 @@ func TestNodeApiResolver_GetManagedKeys(t *testing.T) { func TestNodeApiResolver_GetLoadedKeys(t *testing.T) { t.Parallel() - providedKeys := [][]byte{ - []byte("pk1"), - []byte("pk2"), - } - expectedKeys := []string{ - "pk1", - "pk2", - } - args := createMockArgs() - args.ManagedPeersMonitor = &testscommon.ManagedPeersMonitorStub{ - GetLoadedKeysCalled: func() [][]byte { - return providedKeys - }, - } - args.ValidatorPubKeyConverter = &testscommon.PubkeyConverterStub{ - SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { - return string(pkBytes) - }, - } - nar, err := external.NewNodeApiResolver(args) - require.NoError(t, err) + t.Run("multikey should work", func(t *testing.T) { + t.Parallel() - keys := nar.GetLoadedKeys() - require.Equal(t, expectedKeys, keys) + providedKeys := [][]byte{ + []byte("pk1"), + []byte("pk2"), + } + expectedKeys := []string{ + "pk1", + "pk2", + } + args := createMockArgs() + args.ManagedPeersMonitor = &testscommon.ManagedPeersMonitorStub{ + GetLoadedKeysCalled: func() [][]byte { + return providedKeys + }, + } + args.ValidatorPubKeyConverter = &testscommon.PubkeyConverterStub{ + SilentEncodeCalled: func(pkBytes []byte, log core.Logger) string { + return string(pkBytes) + }, + } + nar, err := external.NewNodeApiResolver(args) + require.NoError(t, err) + + keys := nar.GetLoadedKeys() + require.Equal(t, expectedKeys, keys) + }) + t.Run("single key should work", func(t *testing.T) { + t.Parallel() + + providedKey := "pk1" + expectedKeys := []string{ + "pk1", + } + args := createMockArgs() + args.PublicKey = providedKey + args.ManagedPeersMonitor = &testscommon.ManagedPeersMonitorStub{ + GetLoadedKeysCalled: func() [][]byte { + return [][]byte{} + }, + } + nar, err := external.NewNodeApiResolver(args) + require.NoError(t, err) + + keys := nar.GetLoadedKeys() + require.Equal(t, expectedKeys, keys) + }) } func TestNodeApiResolver_GetEligibleManagedKeys(t *testing.T) { From 8ea966e1193bcc66f4727368cb7674a39b5a955c Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 12 Feb 2024 10:29:56 +0200 Subject: [PATCH 761/958] fix shard is stuck rc/v1.7.0 --- node/chainSimulator/chainSimulator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index b3edda81eed..8fe3b0b506e 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -163,6 +163,7 @@ func (s *simulator) incrementRoundOnAllValidators() { func (s *simulator) allNodesCreateBlocks() error { for _, node := range s.handlers { + time.Sleep(2 * time.Millisecond) err := node.CreateNewBlock() if err != nil { return err From 9b5f0ab6cf866b828549bda6be873098a43d7608 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 12 Feb 2024 10:34:48 +0200 Subject: [PATCH 762/958] fix --- node/chainSimulator/chainSimulator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 8fe3b0b506e..dcd09ce4b65 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -163,6 +163,7 @@ func (s *simulator) incrementRoundOnAllValidators() { func (s *simulator) allNodesCreateBlocks() error { for _, node := range s.handlers { + // TODO MX-15150 remove this when we remove all goroutines time.Sleep(2 * time.Millisecond) err := node.CreateNewBlock() if err != nil { From 313190532167f1ca9a39ceace1c329617daf3e52 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 12 Feb 2024 12:17:21 +0200 Subject: [PATCH 763/958] FIX: Duplicated pub key --- epochStart/metachain/legacySystemSCs.go | 10 ++++++++++ epochStart/metachain/validators.go | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index e5432faa41e..b1a6e319013 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -1231,6 +1231,16 @@ func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( RewardAddress: rewardAddress, AccumulatedFees: big.NewInt(0), } + + existingValidator := validatorsInfoMap.GetValidator(validatorInfo.GetPublicKey()) + // This fix might not be backwards incompatible + if !check.IfNil(existingValidator) && s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { + err = validatorsInfoMap.Delete(existingValidator) + if err != nil { + return err + } + } + err = validatorsInfoMap.Add(validatorInfo) if err != nil { return err diff --git a/epochStart/metachain/validators.go b/epochStart/metachain/validators.go index 6518ae8384e..e8eff547a09 100644 --- a/epochStart/metachain/validators.go +++ b/epochStart/metachain/validators.go @@ -178,7 +178,8 @@ func (vic *validatorInfoCreator) deterministicSortValidators(validators []state. bValidatorString := validators[b].GoString() // possible issues as we have 2 entries with the same public key. Print & assure deterministic sorting log.Warn("found 2 entries in validatorInfoCreator.deterministicSortValidators with the same public key", - "validator a", aValidatorString, "validator b", bValidatorString) + "validator a", aValidatorString, "validator b", bValidatorString, + "validator a pub key", validators[a].GetPublicKey(), "validator b pub key", validators[b].GetPublicKey()) // since the GoString will include all fields, we do not need to marshal the struct again. Strings comparison will // suffice in this case. From 8e483acb8296b56671050590421aaac4676cf533 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 12 Feb 2024 13:01:33 +0200 Subject: [PATCH 764/958] - fixed the p2p configs --- cmd/node/config/p2p.toml | 9 +++++---- config/tomlConfig_test.go | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/node/config/p2p.toml b/cmd/node/config/p2p.toml index 62d30fd19f7..3d3961ec0e5 100644 --- a/cmd/node/config/p2p.toml +++ b/cmd/node/config/p2p.toml @@ -23,10 +23,11 @@ [Node.Transports.TCP] ListenAddress = "/ip4/0.0.0.0/tcp/%d" # TCP listen address PreventPortReuse = false - [Node.ResourceLimiter] - Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". - ManualSystemMemoryInMB = 0 # not taken into account if the type is not "default with manual scale" - ManualMaximumFD = 0 # not taken into account if the type is not "default with manual scale" + + [Node.ResourceLimiter] + Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". + ManualSystemMemoryInMB = 0 # not taken into account if the type is not "default with manual scale" + ManualMaximumFD = 0 # not taken into account if the type is not "default with manual scale" # P2P peer discovery section diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 5b8fa879f6e..eff3c510ccb 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -493,10 +493,11 @@ func TestP2pConfig(t *testing.T) { [Node.Transports.TCP] ListenAddress = "/ip4/0.0.0.0/tcp/%d" PreventPortReuse = true - [Node.ResourceLimiter] - Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". - ManualSystemMemoryInMB = 1 # not taken into account if the type is not "default with manual scale" - ManualMaximumFD = 2 # not taken into account if the type is not "default with manual scale" + + [Node.ResourceLimiter] + Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". + ManualSystemMemoryInMB = 1 # not taken into account if the type is not "default with manual scale" + ManualMaximumFD = 2 # not taken into account if the type is not "default with manual scale" [KadDhtPeerDiscovery] Enabled = false From f848c97a63086054f963619ca50a252530cdd7db Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 12 Feb 2024 13:07:38 +0200 Subject: [PATCH 765/958] FEAT: Unit tests fix existing validator --- epochStart/metachain/legacySystemSCs.go | 2 +- epochStart/metachain/systemSCs_test.go | 54 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index b1a6e319013..5cc0ac96d84 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -1233,7 +1233,7 @@ func (s *legacySystemSCProcessor) addNewlyStakedNodesToValidatorTrie( } existingValidator := validatorsInfoMap.GetValidator(validatorInfo.GetPublicKey()) - // This fix might not be backwards incompatible + // This fix is not be backwards incompatible if !check.IfNil(existingValidator) && s.enableEpochsHandler.IsFlagEnabled(common.StakingV4StartedFlag) { err = validatorsInfoMap.Delete(existingValidator) if err != nil { diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 87d5a2cd9f3..6fbffd7b598 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -2201,7 +2201,61 @@ func TestSystemSCProcessor_ProcessSystemSmartContractNilInputValues(t *testing.T err := s.ProcessSystemSmartContract(validatorsInfoMap, nil) require.Equal(t, process.ErrNilHeaderHandler, err) }) +} + +func TestLegacySystemSCProcessor_addNewlyStakedNodesToValidatorTrie(t *testing.T) { + t.Parallel() + + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{}, testscommon.CreateMemUnit()) + sysProc, _ := NewSystemSCProcessor(args) + + pubKey := []byte("pubKey") + existingValidator := &state.ValidatorInfo{ + PublicKey: pubKey, + List: "inactive", + } + + nonce := uint64(4) + newList := common.AuctionList + newlyAddedValidator := &state.ValidatorInfo{ + PublicKey: pubKey, + List: string(newList), + Index: uint32(nonce), + TempRating: sysProc.startRating, + Rating: sysProc.startRating, + RewardAddress: pubKey, + AccumulatedFees: big.NewInt(0), + } + // Check before stakingV4, we should have both validators + validatorsInfo := state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(existingValidator) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4Step1EnableEpoch - 1, Nonce: 1}) + err := sysProc.addNewlyStakedNodesToValidatorTrie( + validatorsInfo, + [][]byte{pubKey, pubKey}, + nonce, + newList, + ) + require.Nil(t, err) + require.Equal(t, map[uint32][]state.ValidatorInfoHandler{ + 0: {existingValidator, newlyAddedValidator}, + }, validatorsInfo.GetShardValidatorsInfoMap()) + + // Check after stakingV4, we should only have the new one + validatorsInfo = state.NewShardValidatorsInfoMap() + _ = validatorsInfo.Add(existingValidator) + args.EpochNotifier.CheckEpoch(&block.Header{Epoch: stakingV4Step1EnableEpoch, Nonce: 1}) + err = sysProc.addNewlyStakedNodesToValidatorTrie( + validatorsInfo, + [][]byte{pubKey, pubKey}, + nonce, + newList, + ) + require.Nil(t, err) + require.Equal(t, map[uint32][]state.ValidatorInfoHandler{ + 0: {newlyAddedValidator}, + }, validatorsInfo.GetShardValidatorsInfoMap()) } func requireTopUpPerNodes(t *testing.T, s epochStart.StakingDataProvider, stakedPubKeys [][]byte, topUp *big.Int) { From 6a4f66a76a2bd8639b377760cc136d1292fad36e Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 12 Feb 2024 13:29:46 +0200 Subject: [PATCH 766/958] - fixes after review --- cmd/node/config/fullArchiveP2P.toml | 9 +++++---- cmd/seednode/config/p2p.toml | 9 +++++---- config/tomlConfig_test.go | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cmd/node/config/fullArchiveP2P.toml b/cmd/node/config/fullArchiveP2P.toml index 0dd790a83f6..dcf9120563b 100644 --- a/cmd/node/config/fullArchiveP2P.toml +++ b/cmd/node/config/fullArchiveP2P.toml @@ -23,10 +23,11 @@ [Node.Transports.TCP] ListenAddress = "/ip4/0.0.0.0/tcp/%d" # TCP listen address PreventPortReuse = false - [Node.ResourceLimiter] - Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". - ManualSystemMemoryInMB = 0 # not taken into account if the type is not "default with manual scale" - ManualMaximumFD = 0 # not taken into account if the type is not "default with manual scale" + + [Node.ResourceLimiter] + Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". + ManualSystemMemoryInMB = 0 # not taken into account if the type is not "default with manual scale" + ManualMaximumFD = 0 # not taken into account if the type is not "default with manual scale" # P2P peer discovery section diff --git a/cmd/seednode/config/p2p.toml b/cmd/seednode/config/p2p.toml index 2c1a92717c9..8ddd4a72e4a 100644 --- a/cmd/seednode/config/p2p.toml +++ b/cmd/seednode/config/p2p.toml @@ -22,10 +22,11 @@ [Node.Transports.TCP] ListenAddress = "/ip4/0.0.0.0/tcp/%d" # TCP listen address PreventPortReuse = true # seeder nodes will need to enable this option - [Node.ResourceLimiter] - Type = "default with manual scale" - ManualSystemMemoryInMB = 65536 # pretend that the host running the seeder has more RAM so it can handle more connections - ManualMaximumFD = 1048576 + + [Node.ResourceLimiter] + Type = "default with manual scale" + ManualSystemMemoryInMB = 65536 # pretend that the host running the seeder has more RAM so it can handle more connections + ManualMaximumFD = 1048576 # P2P peer discovery section diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index eff3c510ccb..d2edb2a4bbf 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -496,8 +496,8 @@ func TestP2pConfig(t *testing.T) { [Node.ResourceLimiter] Type = "default autoscale" #available options "default autoscale", "infinite", "default with manual scale". - ManualSystemMemoryInMB = 1 # not taken into account if the type is not "default with manual scale" - ManualMaximumFD = 2 # not taken into account if the type is not "default with manual scale" + ManualSystemMemoryInMB = 1 # not taken into account if the type is not "default with manual scale" + ManualMaximumFD = 2 # not taken into account if the type is not "default with manual scale" [KadDhtPeerDiscovery] Enabled = false From cfc4a5f308e88ad8fb2c2511e7cd638e29887b4a Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 12 Feb 2024 14:34:02 +0200 Subject: [PATCH 767/958] staking for direct staked nodes - stake funds happy flow --- .../staking/stakeAndUnStake_test.go | 229 ++++++++++++++++++ 1 file changed, 229 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index e3ab27d7c25..11f942eadc7 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -13,11 +13,15 @@ import ( "github.com/multiversx/mx-chain-core-go/data/validator" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" + chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/vm" logger "github.com/multiversx/mx-chain-logger-go" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -299,3 +303,228 @@ func checkValidatorsRating(t *testing.T, validatorStatistics map[string]*validat } require.Greater(t, countRatingIncreased, 0) } + +// Test description +// Stake funds - happy flow +// +// Preconditions: have an account with egld and 2 staked nodes (2500 stake per node) - directly staked, and no unstake +// +// 1. Check the stake amount for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance +// 2. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network +// 3. Check the outcome of the TX & verify new stake state with vmquery + +// Internal test scenario #24 +func TestChainSimulator_DirectStakingNodes_StakeFunds(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedNodesStakingFunds(t, cs, 1) + }) + + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedNodesStakingFunds(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedNodesStakingFunds(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedNodesStakingFunds(t, cs, 4) + }) +} + +func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + log.Info("Preconditions. Have an account with 2 staked nodes") + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(5010) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Set(minimumStakeValue) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + stakeValue = big.NewInt(0).Set(minimumStakeValue) + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) + txStake = generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + log.Info("Step 1. Check the stake amount for the owner of the staked nodes") + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked := big.NewInt(5000) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + log.Info("Step 2. Create from the owner of the staked nodes a tx to stake 1 EGLD") + + stakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1)) + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake = generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + log.Info("Step 3. Check the stake amount for the owner of the staked nodes") + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked = big.NewInt(5001) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) +} From eb2e06c06dcba098b5bd353d8fba83d7d16a80dc Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 12 Feb 2024 14:45:24 +0200 Subject: [PATCH 768/958] - fixes after review --- cmd/node/config/genesis.json | 2 +- cmd/node/config/nodesSetup.json | 2 +- cmd/node/config/testKeys/validatorKey.pem | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/node/config/genesis.json b/cmd/node/config/genesis.json index 15b2d785964..27f74229b85 100644 --- a/cmd/node/config/genesis.json +++ b/cmd/node/config/genesis.json @@ -494,4 +494,4 @@ "value": "0" } } -] \ No newline at end of file +] diff --git a/cmd/node/config/nodesSetup.json b/cmd/node/config/nodesSetup.json index beabb167872..741d9009ad8 100644 --- a/cmd/node/config/nodesSetup.json +++ b/cmd/node/config/nodesSetup.json @@ -392,4 +392,4 @@ "initialRating": 5000001 } ] -} \ No newline at end of file +} diff --git a/cmd/node/config/testKeys/validatorKey.pem b/cmd/node/config/testKeys/validatorKey.pem index b6039543aa4..397c6629e6d 100644 --- a/cmd/node/config/testKeys/validatorKey.pem +++ b/cmd/node/config/testKeys/validatorKey.pem @@ -93,4 +93,4 @@ NTYwMzU0YjllNWQ3YjYyYw== -----BEGIN PRIVATE KEY for 0382c11222db8a15e42e3ff64893df46c7720b439fb2a546462815ac0a8fa3bed99fceae5da9b68524e36f61cc074d09ceafec274c54f182c56a77583f9421f19c777265c43da1d5747304b36f0367cf3e8e5f63f41dad1a4362d9e1997a9e16----- ZTUxOWQwNzcwZWRlZDhhNTFiMzIwN2M4MWRmMDhjMWZlMWZhMTQ1ZjFmYWQwNDU3 YzI4NzRiNWQzYmY3Y2MwMw== ------END PRIVATE KEY for 0382c11222db8a15e42e3ff64893df46c7720b439fb2a546462815ac0a8fa3bed99fceae5da9b68524e36f61cc074d09ceafec274c54f182c56a77583f9421f19c777265c43da1d5747304b36f0367cf3e8e5f63f41dad1a4362d9e1997a9e16----- \ No newline at end of file +-----END PRIVATE KEY for 0382c11222db8a15e42e3ff64893df46c7720b439fb2a546462815ac0a8fa3bed99fceae5da9b68524e36f61cc074d09ceafec274c54f182c56a77583f9421f19c777265c43da1d5747304b36f0367cf3e8e5f63f41dad1a4362d9e1997a9e16----- From 7c45e492e1007cfec758f055fa10971bad9dd0b9 Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 12 Feb 2024 15:21:23 +0200 Subject: [PATCH 769/958] FIX: Add comm to exported func --- state/accounts/peerAccount.go | 1 + 1 file changed, 1 insertion(+) diff --git a/state/accounts/peerAccount.go b/state/accounts/peerAccount.go index 5511e2ca714..8900edc6f1b 100644 --- a/state/accounts/peerAccount.go +++ b/state/accounts/peerAccount.go @@ -163,6 +163,7 @@ func (pa *peerAccount) GetTotalValidatorSuccessRate() state.SignRate { return &pa.TotalValidatorSuccessRate } +// SetPreviousList sets validator's previous list func (pa *peerAccount) SetPreviousList(list string) { pa.PreviousList = list } From 014c3c39212a501bc7cbe7db307023ddc28d6daf Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 12 Feb 2024 15:59:25 +0200 Subject: [PATCH 770/958] fixes after review --- .../chainSimulator/staking/jail_test.go | 41 ++++++------------- .../staking/simpleStake_test.go | 10 ++--- node/chainSimulator/chainSimulator.go | 3 +- node/chainSimulator/configs/configs.go | 35 ++++++++++++++++ node/chainSimulator/send_and_execute.go | 4 +- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index facd5f06cf8..c15f8b09c86 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -20,8 +20,6 @@ import ( const ( stakingV4JailUnJailStep1EnableEpoch = 5 - stakingV4JailUnJailStep2EnableEpoch = 6 - stakingV4JailUnJailStep3EnableEpoch = 7 epochWhenNodeIsJailed = 4 ) @@ -76,19 +74,10 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus MinNodesPerShard: 3, MetaChainMinNodes: 3, AlterConfigsFunction: func(cfg *config.Configs) { - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = stakingV4JailUnJailStep1EnableEpoch - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = stakingV4JailUnJailStep2EnableEpoch - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = stakingV4JailUnJailStep3EnableEpoch - - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 7 - + configs.SetStakingV4ActivationEpoch(cfg, stakingV4JailUnJailStep1EnableEpoch) newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) - - cfg.RatingsConfig.ShardChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 - cfg.RatingsConfig.ShardChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 - cfg.RatingsConfig.MetaChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 - cfg.RatingsConfig.MetaChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + configs.SetQuickJailRatingConfig(cfg) }, }) require.Nil(t, err) @@ -157,6 +146,8 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus // Add a second node to take the place of the jailed node // UnJail the first node --> should go in queue // Activate staking v4 step 1 --> node should be moved from queue to auction list + +// Internal test scenario #2 func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -183,16 +174,8 @@ func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { MinNodesPerShard: 3, MetaChainMinNodes: 3, AlterConfigsFunction: func(cfg *config.Configs) { - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = stakingV4JailUnJailStep1EnableEpoch - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = stakingV4JailUnJailStep2EnableEpoch - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = stakingV4JailUnJailStep3EnableEpoch - - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = stakingV4JailUnJailStep3EnableEpoch - - cfg.RatingsConfig.ShardChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 - cfg.RatingsConfig.ShardChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 - cfg.RatingsConfig.MetaChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 - cfg.RatingsConfig.MetaChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + configs.SetStakingV4ActivationEpoch(cfg, stakingV4JailUnJailStep1EnableEpoch) + configs.SetQuickJailRatingConfig(cfg) newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 1 configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) @@ -226,8 +209,8 @@ func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { err = cs.GenerateBlocksUntilEpochIsReached(epochWhenNodeIsJailed) require.Nil(t, err) - decodedBLSKey1, _ := hex.DecodeString(blsKeys[0]) - status := getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) + status := getBLSKeyStatus(t, metachainNode, decodedBLSKey0) require.Equal(t, "jailed", status) // add one more node @@ -237,8 +220,8 @@ func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { require.Nil(t, err) require.NotNil(t, stakeTx) - decodedBLSKey2, _ := hex.DecodeString(blsKeys[1]) - status = getBLSKeyStatus(t, metachainNode, decodedBLSKey2) + decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey1) require.Equal(t, "staked", status) // unJail the first node @@ -251,13 +234,13 @@ func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { require.NotNil(t, unJailTx) require.Equal(t, transaction.TxStatusSuccess, unJailTx.Status) - status = getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey0) require.Equal(t, "queued", status) err = cs.GenerateBlocksUntilEpochIsReached(stakingV4JailUnJailStep1EnableEpoch) require.Nil(t, err) - status = getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + status = getBLSKeyStatus(t, metachainNode, decodedBLSKey0) require.Equal(t, "staked", status) checkValidatorStatus(t, cs, blsKeys[0], "auction") diff --git a/integrationTests/chainSimulator/staking/simpleStake_test.go b/integrationTests/chainSimulator/staking/simpleStake_test.go index 73be7082aaa..424b7d30e08 100644 --- a/integrationTests/chainSimulator/staking/simpleStake_test.go +++ b/integrationTests/chainSimulator/staking/simpleStake_test.go @@ -12,6 +12,7 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/vm" "github.com/stretchr/testify/require" ) @@ -22,6 +23,8 @@ import ( // testcase2 -- staking v4 step1 --> tx1 fail, tx2 - node in auction, tx3 - node in auction with topUp 1 // testcase3 -- staking v4 step2 --> tx1 fail, tx2 - node in auction, tx3 - node in auction with topUp 1 // testcase4 -- staking v3.step3 --> tx1 fail, tx2 - node in auction, tx3 - node in auction with topUp 1 + +// // Internal test scenario #3 func TestChainSimulator_SimpleStake(t *testing.T) { t.Run("staking ph 4 is not active", func(t *testing.T) { testChainSimulatorSimpleStake(t, 1, "queued") @@ -67,12 +70,7 @@ func testChainSimulatorSimpleStake(t *testing.T, targetEpoch int32, nodesStatus NumNodesWaitingListMeta: 3, NumNodesWaitingListShard: 3, AlterConfigsFunction: func(cfg *config.Configs) { - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - + configs.SetStakingV4ActivationEpochs(cfg, 2) }, }) require.Nil(t, err) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index e1e0508b2b4..75665170856 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -179,7 +179,6 @@ func (s *simulator) GenerateBlocksUntilEpochIsReached(targetEpoch int32) error { maxNumberOfRounds := 10000 for idx := 0; idx < maxNumberOfRounds; idx++ { - time.Sleep(time.Millisecond * 2) s.incrementRoundOnAllValidators() err := s.allNodesCreateBlocks() if err != nil { @@ -414,7 +413,7 @@ func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction. return nil, err } - time.Sleep(100 * time.Millisecond) + time.Sleep(delayPropagateTxsThroughNetwork) destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 48825da205b..e4538b18a04 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -150,6 +150,41 @@ func SetMaxNumberOfNodesInConfigs(cfg *config.Configs, maxNumNodes uint64, numOf cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[numMaxNumNodesEnableEpochs-1].MaxNumNodes = prevEntry.MaxNumNodes - (numOfShards+1)*prevEntry.NodesToShufflePerShard } +// SetQuickJailRatingConfig will set the rating config in a way that leads to rapid jailing of a node +func SetQuickJailRatingConfig(cfg *config.Configs) { + cfg.RatingsConfig.ShardChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 + cfg.RatingsConfig.ShardChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 + cfg.RatingsConfig.MetaChain.RatingSteps.ConsecutiveMissedBlocksPenalty = 100 + cfg.RatingsConfig.MetaChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 +} + +// SetStakingV4ActivationEpoch will set the action epoch for staking v4 +// step1 will be provided epoch +// step2 will be provided epoch + 1 +// step3 will be provided epoch + 2 +// MaxNodesChangeEnableEpoch[2] will be provided epoch + 2 +func SetStakingV4ActivationEpoch(cfg *config.Configs, epoch uint32) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = epoch + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = epoch + 1 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = epoch + 2 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = epoch + 2 +} + +// SetStakingV4ActivationEpochs configures activation epochs for Staking V4. +// It takes an initial epoch and sets three consecutive steps for enabling Staking V4 features: +// - Step 1 activation epoch +// - Step 2 activation epoch +// - Step 3 activation epoch +func SetStakingV4ActivationEpochs(cfg *config.Configs, initialEpoch uint32) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = initialEpoch + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = initialEpoch + 1 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = initialEpoch + 2 + + // Set the MaxNodesChange enable epoch for index 2 + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = initialEpoch + 2 +} + func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { addressConverter, err := factory.NewPubkeyConverter(configs.GeneralConfig.AddressPubkeyConverter) if err != nil { diff --git a/node/chainSimulator/send_and_execute.go b/node/chainSimulator/send_and_execute.go index c782f749bd1..4c1a88a502e 100644 --- a/node/chainSimulator/send_and_execute.go +++ b/node/chainSimulator/send_and_execute.go @@ -9,6 +9,8 @@ import ( "github.com/multiversx/mx-chain-core-go/data/transaction" ) +const delayPropagateTxsThroughNetwork = time.Duration(50) * time.Millisecond + func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) err := s.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) @@ -44,7 +46,7 @@ func (s *simulator) SendTxsAndGenerateBlockTilTxIsExecuted(txsToSend []*transact hashTxIndex[txHashHex] = idx } - time.Sleep(100 * time.Millisecond) + time.Sleep(delayPropagateTxsThroughNetwork) txsFromAPI := make([]*transaction.ApiTransactionResult, 3) for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { From 9cf080762b40b49ee5ea32336713e7f187d683af Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 12 Feb 2024 16:00:29 +0200 Subject: [PATCH 771/958] remove duplicated function --- .../chainSimulator/staking/jail_test.go | 4 ++-- node/chainSimulator/configs/configs.go | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index c15f8b09c86..824b746c385 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -74,7 +74,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus MinNodesPerShard: 3, MetaChainMinNodes: 3, AlterConfigsFunction: func(cfg *config.Configs) { - configs.SetStakingV4ActivationEpoch(cfg, stakingV4JailUnJailStep1EnableEpoch) + configs.SetStakingV4ActivationEpochs(cfg, stakingV4JailUnJailStep1EnableEpoch) newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) configs.SetQuickJailRatingConfig(cfg) @@ -174,7 +174,7 @@ func TestChainSimulator_FromQueueToAuctionList(t *testing.T) { MinNodesPerShard: 3, MetaChainMinNodes: 3, AlterConfigsFunction: func(cfg *config.Configs) { - configs.SetStakingV4ActivationEpoch(cfg, stakingV4JailUnJailStep1EnableEpoch) + configs.SetStakingV4ActivationEpochs(cfg, stakingV4JailUnJailStep1EnableEpoch) configs.SetQuickJailRatingConfig(cfg) newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 1 diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index e4538b18a04..b16ba736101 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -158,19 +158,6 @@ func SetQuickJailRatingConfig(cfg *config.Configs) { cfg.RatingsConfig.MetaChain.RatingSteps.HoursToMaxRatingFromStartRating = 1 } -// SetStakingV4ActivationEpoch will set the action epoch for staking v4 -// step1 will be provided epoch -// step2 will be provided epoch + 1 -// step3 will be provided epoch + 2 -// MaxNodesChangeEnableEpoch[2] will be provided epoch + 2 -func SetStakingV4ActivationEpoch(cfg *config.Configs, epoch uint32) { - cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = epoch - cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = epoch + 1 - cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = epoch + 2 - - cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = epoch + 2 -} - // SetStakingV4ActivationEpochs configures activation epochs for Staking V4. // It takes an initial epoch and sets three consecutive steps for enabling Staking V4 features: // - Step 1 activation epoch From 6e5c6b3eab0317cdcd93c9cf031546432422bb79 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 12 Feb 2024 16:22:59 +0200 Subject: [PATCH 772/958] rename and change delay --- node/chainSimulator/chainSimulator.go | 2 +- node/chainSimulator/send_and_execute.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 75665170856..66b43fcec21 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -413,7 +413,7 @@ func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction. return nil, err } - time.Sleep(delayPropagateTxsThroughNetwork) + time.Sleep(delaySendTxs) destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { diff --git a/node/chainSimulator/send_and_execute.go b/node/chainSimulator/send_and_execute.go index 4c1a88a502e..09e15a58c13 100644 --- a/node/chainSimulator/send_and_execute.go +++ b/node/chainSimulator/send_and_execute.go @@ -9,7 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/transaction" ) -const delayPropagateTxsThroughNetwork = time.Duration(50) * time.Millisecond +const delaySendTxs = time.Millisecond func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) @@ -46,7 +46,7 @@ func (s *simulator) SendTxsAndGenerateBlockTilTxIsExecuted(txsToSend []*transact hashTxIndex[txHashHex] = idx } - time.Sleep(delayPropagateTxsThroughNetwork) + time.Sleep(delaySendTxs) txsFromAPI := make([]*transaction.ApiTransactionResult, 3) for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { From 72089b9587e4122ecd7bcd952c3eceda4d51bf0b Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 12 Feb 2024 16:47:37 +0200 Subject: [PATCH 773/958] FIX: Rename auction list nodes to nodes --- api/groups/validatorGroup_test.go | 6 +++--- common/dtos.go | 2 +- .../chainSimulator/staking/delegation_test.go | 2 +- .../chainSimulator/staking/stakeAndUnStake_test.go | 4 ++-- process/peer/validatorsProviderAuction.go | 10 +++++----- process/peer/validatorsProvider_test.go | 12 ++++++------ 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/api/groups/validatorGroup_test.go b/api/groups/validatorGroup_test.go index ff17095b852..0bbd1ebf742 100644 --- a/api/groups/validatorGroup_test.go +++ b/api/groups/validatorGroup_test.go @@ -40,7 +40,7 @@ type validatorStatisticsResponse struct { Error string `json:"error"` } -type auctionListReponse struct { +type auctionListResponse struct { Data struct { Result []*common.AuctionListValidatorAPIResponse `json:"auctionList"` } `json:"data"` @@ -216,7 +216,7 @@ func TestAuctionList_ErrorWhenFacadeFails(t *testing.T) { resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) - response := auctionListReponse{} + response := auctionListResponse{} loadResponse(resp.Body, &response) assert.Equal(t, http.StatusBadRequest, resp.Code) @@ -249,7 +249,7 @@ func TestAuctionList_ReturnsSuccessfully(t *testing.T) { resp := httptest.NewRecorder() ws.ServeHTTP(resp, req) - response := auctionListReponse{} + response := auctionListResponse{} loadResponse(resp.Body, &response) assert.Equal(t, http.StatusOK, resp.Code) diff --git a/common/dtos.go b/common/dtos.go index 67efb68d3c9..50cf1109017 100644 --- a/common/dtos.go +++ b/common/dtos.go @@ -89,5 +89,5 @@ type AuctionListValidatorAPIResponse struct { TotalTopUp string `json:"totalTopUp"` TopUpPerNode string `json:"topUpPerNode"` QualifiedTopUp string `json:"qualifiedTopUp"` - AuctionList []*AuctionNode `json:"auctionList"` + Nodes []*AuctionNode `json:"nodes"` } diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index a6843a0955a..cb3ed9fc09a 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -346,7 +346,7 @@ func testBLSKeyIsInAuction( } require.Equal(t, actionListSize, len(auctionList)) - require.Equal(t, 1, len(auctionList[0].AuctionList)) + require.Equal(t, 1, len(auctionList[0].Nodes)) require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) // in staking ph 4 we should find the key in the validators statics diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index e3ab27d7c25..a7e2cfeb1b7 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -264,7 +264,7 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { results, err := metachainNode.GetFacadeHandler().AuctionListApi() require.Nil(t, err) require.Equal(t, newValidatorOwner, results[0].Owner) - require.Equal(t, 20, len(results[0].AuctionList)) + require.Equal(t, 20, len(results[0].Nodes)) checkTotalQualified(t, results, 8) err = cs.GenerateBlocks(100) @@ -278,7 +278,7 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { func checkTotalQualified(t *testing.T, auctionList []*common.AuctionListValidatorAPIResponse, expected int) { totalQualified := 0 for _, res := range auctionList { - for _, node := range res.AuctionList { + for _, node := range res.Nodes { if node.Qualified { totalQualified++ } diff --git a/process/peer/validatorsProviderAuction.go b/process/peer/validatorsProviderAuction.go index b7df20f12bc..144ace850fb 100644 --- a/process/peer/validatorsProviderAuction.go +++ b/process/peer/validatorsProviderAuction.go @@ -137,8 +137,8 @@ func compareByNumQualified(owner1Nodes, owner2Nodes *common.AuctionListValidator return owner1Qualified } - owner1NumQualified := getNumQualified(owner1Nodes.AuctionList) - owner2NumQualified := getNumQualified(owner2Nodes.AuctionList) + owner1NumQualified := getNumQualified(owner1Nodes.Nodes) + owner2NumQualified := getNumQualified(owner2Nodes.Nodes) return owner1NumQualified > owner2NumQualified } @@ -170,7 +170,7 @@ func (vp *validatorsProvider) getAuctionListValidatorsAPIResponse( TotalTopUp: ownerData.TotalTopUp.String(), TopUpPerNode: ownerData.TopUpPerNode.String(), QualifiedTopUp: ownerData.TopUpPerNode.String(), - AuctionList: make([]*common.AuctionNode, 0, numAuctionNodes), + Nodes: make([]*common.AuctionNode, 0, numAuctionNodes), } vp.fillAuctionQualifiedValidatorAPIData(selectedNodes, ownerData, auctionValidator) auctionListValidators = append(auctionListValidators, auctionValidator) @@ -187,7 +187,7 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( ownerData *epochStart.OwnerData, auctionValidatorAPI *common.AuctionListValidatorAPIResponse, ) { - auctionValidatorAPI.AuctionList = make([]*common.AuctionNode, 0, len(ownerData.AuctionList)) + auctionValidatorAPI.Nodes = make([]*common.AuctionNode, 0, len(ownerData.AuctionList)) numOwnerQualifiedNodes := int64(0) for _, nodeInAuction := range ownerData.AuctionList { auctionNode := &common.AuctionNode{ @@ -199,7 +199,7 @@ func (vp *validatorsProvider) fillAuctionQualifiedValidatorAPIData( numOwnerQualifiedNodes++ } - auctionValidatorAPI.AuctionList = append(auctionValidatorAPI.AuctionList, auctionNode) + auctionValidatorAPI.Nodes = append(auctionValidatorAPI.Nodes, auctionNode) } if numOwnerQualifiedNodes > 0 { diff --git a/process/peer/validatorsProvider_test.go b/process/peer/validatorsProvider_test.go index 1f8dc3e45bd..931567a2435 100644 --- a/process/peer/validatorsProvider_test.go +++ b/process/peer/validatorsProvider_test.go @@ -953,7 +953,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "4000", TopUpPerNode: "2000", QualifiedTopUp: "4000", - AuctionList: []*common.AuctionNode{ + Nodes: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v5.PublicKey, log), Qualified: true, @@ -970,7 +970,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "7500", TopUpPerNode: "2500", QualifiedTopUp: "2500", - AuctionList: []*common.AuctionNode{ + Nodes: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v1.PublicKey, log), Qualified: true, @@ -987,7 +987,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "3000", TopUpPerNode: "1000", QualifiedTopUp: "1500", - AuctionList: []*common.AuctionNode{ + Nodes: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v3.PublicKey, log), Qualified: true, @@ -1004,7 +1004,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", - AuctionList: []*common.AuctionNode{ + Nodes: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v12.PublicKey, log), Qualified: true, @@ -1017,7 +1017,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", - AuctionList: []*common.AuctionNode{ + Nodes: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v11.PublicKey, log), Qualified: false, @@ -1030,7 +1030,7 @@ func TestValidatorsProvider_GetAuctionList(t *testing.T) { TotalTopUp: "0", TopUpPerNode: "0", QualifiedTopUp: "0", - AuctionList: []*common.AuctionNode{ + Nodes: []*common.AuctionNode{ { BlsKey: args.ValidatorPubKeyConverter.SilentEncode(v7.PublicKey, log), Qualified: false, From d0a688e4ee3a1f2b72fdfab5664a2cc87795d678 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Mon, 12 Feb 2024 16:51:39 +0200 Subject: [PATCH 774/958] MX-15154: fix merge --- integrationTests/chainSimulator/staking/delegation_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 0f7a71dff0f..62d5c29f0ab 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -260,7 +260,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) - testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorOwner, blsKeys[0], addedStakedValue, 1) + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorOwner.Bytes, blsKeys[0], addedStakedValue, 1) log.Info("Step 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and the correct topup") txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) From a2a211d1677292e4b4c0b5dbbd75a42751a6fe5a Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 12 Feb 2024 16:55:53 +0200 Subject: [PATCH 775/958] update test 12 scenario --- .../chainSimulator/staking/delegation_test.go | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 75624541854..5c28f551dbd 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -1034,8 +1034,6 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.NotNil(t, convertTx) delegationAddress := convertTx.Logs.Events[0].Topics[1] - delegationAddressBech32 := metachainNode.GetCoreComponents().AddressPubKeyConverter().SilentEncode(delegationAddress, log) - log.Info("generated delegation address", "address", delegationAddressBech32) err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() require.Nil(t, err) @@ -1062,24 +1060,22 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorB)) decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) - // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey0)) require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) - // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey1)) require.Equal(t, validatorB, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) - log.Info("Step 4. User B : whitelistForMerge@addressA") - txDataField = fmt.Sprintf("whitelistForMerge@%s", hex.EncodeToString(validatorA)) - whitelistForMerge := generateTransaction(validatorB, 1, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + log.Info("Step 4. User B : whitelistForMerge@addressB") + txDataField = fmt.Sprintf("whitelistForMerge@%s", validatorB) + whitelistForMerge := generateTransaction(validatorA, 2, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) whitelistForMergeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(whitelistForMerge, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, whitelistForMergeTx) log.Info("Step 5. User A : mergeValidatorToDelegationWithWhitelist") - txDataField = fmt.Sprintf("mergeValidatorToDelegationWithWhitelist@%s", hex.EncodeToString(validatorB)) + txDataField = fmt.Sprintf("mergeValidatorToDelegationWithWhitelist@%s", hex.EncodeToString(delegationAddress)) - txConvert = generateTransaction(validatorA, 2, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForMergeOperation) + txConvert = generateTransaction(validatorB, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForMergeOperation) convertTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, convertTx) @@ -1087,13 +1083,17 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + decodedBLSKey0, _ = hex.DecodeString(blsKeys[0]) - // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey0)) require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) decodedBLSKey1, _ = hex.DecodeString(blsKeys[1]) - // require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey1)) - require.Equal(t, validatorB, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) + require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) + + expectedTopUpValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(200)) + assert.Equal(t, expectedTopUpValue, getBLSTopUpValue(t, metachainNode, delegationAddress)) } func getBLSKeyOwner(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) []byte { From bd331b96c33459a093cd80acf2c220d098ef7634 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Mon, 12 Feb 2024 17:06:33 +0200 Subject: [PATCH 776/958] MX-15154: fix linter --- integrationTests/chainSimulator/staking/delegation_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 62d5c29f0ab..4de5e095ede 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -588,6 +588,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err := executeQuery(cs, core.MetachainShardId, vm.DelegationManagerSCAddress, "getAllContractAddresses", nil) require.Nil(t, err) returnAddress, err := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(output.ReturnData[0]) + require.Nil(t, err) require.Equal(t, delegationContractAddress, returnAddress) delegationContractAddressBytes := output.ReturnData[0] From 25e5a4762d59502f1a14cbcd01b2df40f21d9e54 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 12 Feb 2024 20:31:02 +0200 Subject: [PATCH 777/958] - removed resource leaks in chainSimulator and apiResolverFactory --- factory/api/apiResolverFactory.go | 97 ++++++++++--------- factory/api/apiResolverFactory_test.go | 18 ++-- factory/api/export_test.go | 3 +- .../components/bootstrapComponents.go | 34 +++---- .../components/cryptoComponents.go | 41 ++++---- .../components/processComponents.go | 19 +--- .../components/stateComponents.go | 8 +- .../components/statusCoreComponents.go | 45 ++++----- .../components/syncedMessenger.go | 31 ++++++ node/external/nodeApiResolver.go | 12 +++ 10 files changed, 174 insertions(+), 134 deletions(-) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 221219ac115..defca284230 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -129,7 +129,7 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { processingMode: args.ProcessingMode, } - scQueryService, err := createScQueryService(argsSCQuery) + scQueryService, storageManagers, err := createScQueryService(argsSCQuery) if err != nil { return nil, err } @@ -272,6 +272,7 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { GasScheduleNotifier: args.GasScheduleNotifier, ManagedPeersMonitor: args.StatusComponents.ManagedPeersMonitor(), NodesCoordinator: args.ProcessComponents.NodesCoordinator(), + StorageManagers: storageManagers, } return external.NewNodeApiResolver(argsApiResolver) @@ -279,10 +280,10 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { func createScQueryService( args *scQueryServiceArgs, -) (process.SCQueryService, error) { +) (process.SCQueryService, []common.StorageManager, error) { numConcurrentVms := args.generalConfig.VirtualMachine.Querying.NumConcurrentVMs if numConcurrentVms < 1 { - return nil, fmt.Errorf("VirtualMachine.Querying.NumConcurrentVms should be a positive number more than 1") + return nil, nil, fmt.Errorf("VirtualMachine.Querying.NumConcurrentVms should be a positive number more than 1") } argsQueryElem := &scQueryElementArgs{ @@ -306,42 +307,45 @@ func createScQueryService( var err error var scQueryService process.SCQueryService + var storageManager common.StorageManager + storageManagers := make([]common.StorageManager, 0, numConcurrentVms) list := make([]process.SCQueryService, 0, numConcurrentVms) for i := 0; i < numConcurrentVms; i++ { argsQueryElem.index = i - scQueryService, err = createScQueryElement(argsQueryElem) + scQueryService, storageManager, err = createScQueryElement(argsQueryElem) if err != nil { - return nil, err + return nil, nil, err } list = append(list, scQueryService) + storageManagers = append(storageManagers, storageManager) } sqQueryDispatcher, err := smartContract.NewScQueryServiceDispatcher(list) if err != nil { - return nil, err + return nil, nil, err } - return sqQueryDispatcher, nil + return sqQueryDispatcher, storageManagers, nil } func createScQueryElement( args *scQueryElementArgs, -) (process.SCQueryService, error) { +) (process.SCQueryService, common.StorageManager, error) { var err error pkConverter := args.coreComponents.AddressPubKeyConverter() automaticCrawlerAddressesStrings := args.generalConfig.BuiltInFunctions.AutomaticCrawlerAddresses convertedAddresses, errDecode := factory.DecodeAddresses(pkConverter, automaticCrawlerAddressesStrings) if errDecode != nil { - return nil, errDecode + return nil, nil, errDecode } dnsV2AddressesStrings := args.generalConfig.BuiltInFunctions.DNSV2Addresses convertedDNSV2Addresses, errDecode := factory.DecodeAddresses(pkConverter, dnsV2AddressesStrings) if errDecode != nil { - return nil, errDecode + return nil, nil, errDecode } builtInFuncFactory, err := createBuiltinFuncs( @@ -357,13 +361,13 @@ func createScQueryElement( convertedDNSV2Addresses, ) if err != nil { - return nil, err + return nil, nil, err } cacherCfg := storageFactory.GetCacherFromConfig(args.generalConfig.SmartContractDataPool) smartContractsCache, err := storageunit.NewCache(cacherCfg) if err != nil { - return nil, err + return nil, nil, err } scStorage := args.generalConfig.SmartContractsStorageForSCQuery @@ -391,32 +395,33 @@ func createScQueryElement( var apiBlockchain data.ChainHandler var vmFactory process.VirtualMachinesContainerFactory + var storageManager common.StorageManager maxGasForVmQueries := args.generalConfig.VirtualMachine.GasConfig.ShardMaxGasPerVmQuery if args.processComponents.ShardCoordinator().SelfId() == core.MetachainShardId { maxGasForVmQueries = args.generalConfig.VirtualMachine.GasConfig.MetaMaxGasPerVmQuery - apiBlockchain, vmFactory, err = createMetaVmContainerFactory(args, argsHook) + apiBlockchain, vmFactory, storageManager, err = createMetaVmContainerFactory(args, argsHook) } else { - apiBlockchain, vmFactory, err = createShardVmContainerFactory(args, argsHook) + apiBlockchain, vmFactory, storageManager, err = createShardVmContainerFactory(args, argsHook) } if err != nil { - return nil, err + return nil, nil, err } log.Debug("maximum gas per VM Query", "value", maxGasForVmQueries) vmContainer, err := vmFactory.Create() if err != nil { - return nil, err + return nil, nil, err } err = vmFactory.BlockChainHookImpl().SetVMContainer(vmContainer) if err != nil { - return nil, err + return nil, nil, err } err = builtInFuncFactory.SetPayableHandler(vmFactory.BlockChainHookImpl()) if err != nil { - return nil, err + return nil, nil, err } argsNewSCQueryService := smartContract.ArgsNewSCQueryService{ @@ -437,18 +442,20 @@ func createScQueryElement( Uint64ByteSliceConverter: args.coreComponents.Uint64ByteSliceConverter(), } - return smartContract.NewSCQueryService(argsNewSCQueryService) + scQueryService, err := smartContract.NewSCQueryService(argsNewSCQueryService) + + return scQueryService, storageManager, err } -func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, error) { +func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, common.StorageManager, error) { apiBlockchain, err := blockchain.NewMetaChain(disabled.NewAppStatusHandler()) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) + accountsAdapterApi, storageManager, err := createNewAccountsAdapterApi(args, apiBlockchain) if err != nil { - return nil, nil, err + return nil, nil, nil, err } argsHook.BlockChain = apiBlockchain @@ -456,7 +463,7 @@ func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBl blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook) if errBlockChainHook != nil { - return nil, nil, errBlockChainHook + return nil, nil, nil, errBlockChainHook } argsNewVmFactory := metachain.ArgsNewVMContainerFactory{ @@ -478,21 +485,21 @@ func createMetaVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBl } vmFactory, err := metachain.NewVMContainerFactory(argsNewVmFactory) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return apiBlockchain, vmFactory, nil + return apiBlockchain, vmFactory, storageManager, nil } -func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, error) { +func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (data.ChainHandler, process.VirtualMachinesContainerFactory, common.StorageManager, error) { apiBlockchain, err := blockchain.NewBlockChain(disabled.NewAppStatusHandler()) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) + accountsAdapterApi, storageManager, err := createNewAccountsAdapterApi(args, apiBlockchain) if err != nil { - return nil, nil, err + return nil, nil, nil, err } argsHook.BlockChain = apiBlockchain @@ -501,12 +508,12 @@ func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgB queryVirtualMachineConfig := args.generalConfig.VirtualMachine.Querying.VirtualMachineConfig esdtTransferParser, errParser := parsers.NewESDTTransferParser(args.coreComponents.InternalMarshalizer()) if errParser != nil { - return nil, nil, errParser + return nil, nil, nil, errParser } blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook) if errBlockChainHook != nil { - return nil, nil, errBlockChainHook + return nil, nil, nil, errBlockChainHook } argsNewVMFactory := shard.ArgVMContainerFactory{ @@ -528,13 +535,13 @@ func createShardVmContainerFactory(args *scQueryElementArgs, argsHook hooks.ArgB vmFactory, err := shard.NewVMContainerFactory(argsNewVMFactory) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return apiBlockchain, vmFactory, nil + return apiBlockchain, vmFactory, storageManager, nil } -func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.ChainHandler) (state.AccountsAdapterAPI, error) { +func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.ChainHandler) (state.AccountsAdapterAPI, common.StorageManager, error) { argsAccCreator := factoryState.ArgsAccountCreator{ Hasher: args.coreComponents.Hasher(), Marshaller: args.coreComponents.InternalMarshalizer(), @@ -542,17 +549,17 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha } accountFactory, err := factoryState.NewAccountCreator(argsAccCreator) if err != nil { - return nil, err + return nil, nil, err } storagePruning, err := newStoragePruningManager(args) if err != nil { - return nil, err + return nil, nil, err } storageService := args.dataComponents.StorageService() trieStorer, err := storageService.GetStorer(dataRetriever.UserAccountsUnit) if err != nil { - return nil, err + return nil, nil, err } trieFactoryArgs := trieFactory.TrieFactoryArgs{ @@ -563,7 +570,7 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha } trFactory, err := trieFactory.NewTrieFactory(trieFactoryArgs) if err != nil { - return nil, err + return nil, nil, err } trieCreatorArgs := trieFactory.TrieCreateArgs{ @@ -576,9 +583,9 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha EnableEpochsHandler: args.coreComponents.EnableEpochsHandler(), StatsCollector: args.statusCoreComponents.StateStatsHandler(), } - _, merkleTrie, err := trFactory.Create(trieCreatorArgs) + trieStorageManager, merkleTrie, err := trFactory.Create(trieCreatorArgs) if err != nil { - return nil, err + return nil, nil, err } argsAPIAccountsDB := state.ArgsAccountsDB{ @@ -593,15 +600,17 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha provider, err := blockInfoProviders.NewCurrentBlockInfo(chainHandler) if err != nil { - return nil, err + return nil, nil, err } accounts, err := state.NewAccountsDB(argsAPIAccountsDB) if err != nil { - return nil, err + return nil, nil, err } - return state.NewAccountsDBApi(accounts, provider) + accluntsDB, err := state.NewAccountsDBApi(accounts, provider) + + return accluntsDB, trieStorageManager, nil } func newStoragePruningManager(args *scQueryElementArgs) (state.StoragePruningManager, error) { diff --git a/factory/api/apiResolverFactory_test.go b/factory/api/apiResolverFactory_test.go index 57008ca340c..d62ced9447c 100644 --- a/factory/api/apiResolverFactory_test.go +++ b/factory/api/apiResolverFactory_test.go @@ -380,9 +380,10 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { args := createMockSCQueryElementArgs() args.GuardedAccountHandler = nil - scQueryService, err := api.CreateScQueryElement(args) + scQueryService, storageManager, err := api.CreateScQueryElement(args) require.Equal(t, process.ErrNilGuardedAccountHandler, err) require.Nil(t, scQueryService) + require.Nil(t, storageManager) }) t.Run("DecodeAddresses fails", func(t *testing.T) { t.Parallel() @@ -391,10 +392,11 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { args.CoreComponents = &mock.CoreComponentsMock{ AddrPubKeyConv: nil, } - scQueryService, err := api.CreateScQueryElement(args) + scQueryService, storageManager, err := api.CreateScQueryElement(args) require.NotNil(t, err) require.True(t, strings.Contains(strings.ToLower(err.Error()), "public key converter")) require.Nil(t, scQueryService) + require.Nil(t, storageManager) }) t.Run("createBuiltinFuncs fails", func(t *testing.T) { t.Parallel() @@ -402,10 +404,11 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { args := createMockSCQueryElementArgs() coreCompMock := args.CoreComponents.(*mock.CoreComponentsMock) coreCompMock.IntMarsh = nil - scQueryService, err := api.CreateScQueryElement(args) + scQueryService, storageManager, err := api.CreateScQueryElement(args) require.NotNil(t, err) require.True(t, strings.Contains(strings.ToLower(err.Error()), "marshalizer")) require.Nil(t, scQueryService) + require.Nil(t, storageManager) }) t.Run("NewCache fails", func(t *testing.T) { t.Parallel() @@ -415,10 +418,11 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { Type: "LRU", SizeInBytes: 1, } - scQueryService, err := api.CreateScQueryElement(args) + scQueryService, storageManager, err := api.CreateScQueryElement(args) require.NotNil(t, err) require.True(t, strings.Contains(strings.ToLower(err.Error()), "lru")) require.Nil(t, scQueryService) + require.Nil(t, storageManager) }) t.Run("metachain - NewVMContainerFactory fails", func(t *testing.T) { t.Parallel() @@ -433,10 +437,11 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { } coreCompMock := args.CoreComponents.(*mock.CoreComponentsMock) coreCompMock.Hash = nil - scQueryService, err := api.CreateScQueryElement(args) + scQueryService, storageManager, err := api.CreateScQueryElement(args) require.NotNil(t, err) require.True(t, strings.Contains(strings.ToLower(err.Error()), "hasher")) require.Nil(t, scQueryService) + require.Nil(t, storageManager) }) t.Run("shard - NewVMContainerFactory fails", func(t *testing.T) { t.Parallel() @@ -444,10 +449,11 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { args := createMockSCQueryElementArgs() coreCompMock := args.CoreComponents.(*mock.CoreComponentsMock) coreCompMock.Hash = nil - scQueryService, err := api.CreateScQueryElement(args) + scQueryService, storageManager, err := api.CreateScQueryElement(args) require.NotNil(t, err) require.True(t, strings.Contains(strings.ToLower(err.Error()), "hasher")) require.Nil(t, scQueryService) + require.Nil(t, storageManager) }) } diff --git a/factory/api/export_test.go b/factory/api/export_test.go index 0164c0c2b10..f8404f6cb24 100644 --- a/factory/api/export_test.go +++ b/factory/api/export_test.go @@ -2,6 +2,7 @@ package api import ( "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/process" @@ -28,7 +29,7 @@ type SCQueryElementArgs struct { } // CreateScQueryElement - -func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, error) { +func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, common.StorageManager, error) { return createScQueryElement(&scQueryElementArgs{ generalConfig: args.GeneralConfig, epochConfig: args.EpochConfig, diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index 9bc5a406c89..587f060169b 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -2,6 +2,7 @@ package components import ( "fmt" + "io" "github.com/multiversx/mx-chain-core-go/core" nodeFactory "github.com/multiversx/mx-chain-go/cmd/node/factory" @@ -28,23 +29,21 @@ type ArgsBootstrapComponentsHolder struct { } type bootstrapComponentsHolder struct { - closeHandler *closeHandler - epochStartBootstrapper factory.EpochStartBootstrapper - epochBootstrapParams factory.BootstrapParamsHolder - nodeType core.NodeType - shardCoordinator sharding.Coordinator - versionedHeaderFactory nodeFactory.VersionedHeaderFactory - headerVersionHandler nodeFactory.HeaderVersionHandler - headerIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler - guardedAccountHandler process.GuardedAccountHandler - nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory + epochStartBootstrapper factory.EpochStartBootstrapper + epochBootstrapParams factory.BootstrapParamsHolder + nodeType core.NodeType + shardCoordinator sharding.Coordinator + versionedHeaderFactory nodeFactory.VersionedHeaderFactory + headerVersionHandler nodeFactory.HeaderVersionHandler + headerIntegrityVerifier nodeFactory.HeaderIntegrityVerifierHandler + guardedAccountHandler process.GuardedAccountHandler + nodesCoordinatorRegistryFactory nodesCoordinator.NodesCoordinatorRegistryFactory + managedBootstrapComponentsCloser io.Closer } // CreateBootstrapComponents will create a new instance of bootstrap components holder func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHandler, error) { - instance := &bootstrapComponentsHolder{ - closeHandler: NewCloseHandler(), - } + instance := &bootstrapComponentsHolder{} args.PrefsConfig.Preferences.DestinationShardAsObserver = args.ShardIDStr @@ -84,8 +83,7 @@ func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (factory.Boot instance.headerIntegrityVerifier = managedBootstrapComponents.HeaderIntegrityVerifier() instance.guardedAccountHandler = managedBootstrapComponents.GuardedAccountHandler() instance.nodesCoordinatorRegistryFactory = managedBootstrapComponents.NodesCoordinatorRegistryFactory() - - instance.collectClosableComponents() + instance.managedBootstrapComponentsCloser = managedBootstrapComponents return instance, nil } @@ -135,13 +133,9 @@ func (b *bootstrapComponentsHolder) GuardedAccountHandler() process.GuardedAccou return b.guardedAccountHandler } -func (b *bootstrapComponentsHolder) collectClosableComponents() { - b.closeHandler.AddComponent(b.epochStartBootstrapper) -} - // Close will call the Close methods on all inner components func (b *bootstrapComponentsHolder) Close() error { - return b.closeHandler.Close() + return b.managedBootstrapComponentsCloser.Close() } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 42432636724..6d625a3ca29 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -2,6 +2,7 @@ package components import ( "fmt" + "io" "github.com/multiversx/mx-chain-core-go/core" crypto "github.com/multiversx/mx-chain-crypto-go" @@ -26,24 +27,25 @@ type ArgsCryptoComponentsHolder struct { } type cryptoComponentsHolder struct { - publicKey crypto.PublicKey - privateKey crypto.PrivateKey - p2pPublicKey crypto.PublicKey - p2pPrivateKey crypto.PrivateKey - p2pSingleSigner crypto.SingleSigner - txSingleSigner crypto.SingleSigner - blockSigner crypto.SingleSigner - multiSignerContainer cryptoCommon.MultiSignerContainer - peerSignatureHandler crypto.PeerSignatureHandler - blockSignKeyGen crypto.KeyGenerator - txSignKeyGen crypto.KeyGenerator - p2pKeyGen crypto.KeyGenerator - messageSignVerifier vm.MessageSignVerifier - consensusSigningHandler consensus.SigningHandler - managedPeersHolder common.ManagedPeersHolder - keysHandler consensus.KeysHandler - publicKeyBytes []byte - publicKeyString string + publicKey crypto.PublicKey + privateKey crypto.PrivateKey + p2pPublicKey crypto.PublicKey + p2pPrivateKey crypto.PrivateKey + p2pSingleSigner crypto.SingleSigner + txSingleSigner crypto.SingleSigner + blockSigner crypto.SingleSigner + multiSignerContainer cryptoCommon.MultiSignerContainer + peerSignatureHandler crypto.PeerSignatureHandler + blockSignKeyGen crypto.KeyGenerator + txSignKeyGen crypto.KeyGenerator + p2pKeyGen crypto.KeyGenerator + messageSignVerifier vm.MessageSignVerifier + consensusSigningHandler consensus.SigningHandler + managedPeersHolder common.ManagedPeersHolder + keysHandler consensus.KeysHandler + publicKeyBytes []byte + publicKeyString string + managedCryptoComponentsCloser io.Closer } // CreateCryptoComponents will create a new instance of cryptoComponentsHolder @@ -104,6 +106,7 @@ func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComp instance.consensusSigningHandler = managedCryptoComponents.ConsensusSigningHandler() instance.managedPeersHolder = managedCryptoComponents.ManagedPeersHolder() instance.keysHandler = managedCryptoComponents.KeysHandler() + instance.managedCryptoComponentsCloser = managedCryptoComponents if args.BypassTxSignatureCheck { instance.txSingleSigner = &singlesig.DisabledSingleSig{} @@ -261,5 +264,5 @@ func (c *cryptoComponentsHolder) String() string { // Close will do nothing func (c *cryptoComponentsHolder) Close() error { - return nil + return c.managedCryptoComponentsCloser.Close() } diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index ab5e6e471c2..d08061f6fb9 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -2,6 +2,7 @@ package components import ( "fmt" + "io" "math/big" "path/filepath" "time" @@ -52,7 +53,6 @@ type ArgsProcessComponentsHolder struct { } type processComponentsHolder struct { - closeHandler *closeHandler receiptsRepository factory.ReceiptsRepository nodesCoordinator nodesCoordinator.NodesCoordinator shardCoordinator sharding.Coordinator @@ -94,6 +94,7 @@ type processComponentsHolder struct { esdtDataStorageHandlerForAPI vmcommon.ESDTNFTStorageHandler accountsParser genesis.AccountsParser sendSignatureTracker process.SentSignaturesTracker + managedProcessComponentsCloser io.Closer } // CreateProcessComponents will create the process components holder @@ -221,7 +222,6 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC } instance := &processComponentsHolder{ - closeHandler: NewCloseHandler(), receiptsRepository: managedProcessComponents.ReceiptsRepository(), nodesCoordinator: managedProcessComponents.NodesCoordinator(), shardCoordinator: managedProcessComponents.ShardCoordinator(), @@ -263,10 +263,9 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC esdtDataStorageHandlerForAPI: managedProcessComponents.ESDTDataStorageHandlerForAPI(), accountsParser: managedProcessComponents.AccountsParser(), sendSignatureTracker: managedProcessComponents.SentSignaturesTracker(), + managedProcessComponentsCloser: managedProcessComponents, } - instance.collectClosableComponents() - return instance, nil } @@ -475,19 +474,9 @@ func (p *processComponentsHolder) ReceiptsRepository() factory.ReceiptsRepositor return p.receiptsRepository } -func (p *processComponentsHolder) collectClosableComponents() { - p.closeHandler.AddComponent(p.interceptorsContainer) - p.closeHandler.AddComponent(p.fullArchiveInterceptorsContainer) - p.closeHandler.AddComponent(p.resolversContainer) - p.closeHandler.AddComponent(p.epochStartTrigger) - p.closeHandler.AddComponent(p.blockProcessor) - p.closeHandler.AddComponent(p.validatorsProvider) - p.closeHandler.AddComponent(p.txsSenderHandler) -} - // Close will call the Close methods on all inner components func (p *processComponentsHolder) Close() error { - return p.closeHandler.Close() + return p.managedProcessComponentsCloser.Close() } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/components/stateComponents.go b/node/chainSimulator/components/stateComponents.go index 65a1a064fe7..70507187f57 100644 --- a/node/chainSimulator/components/stateComponents.go +++ b/node/chainSimulator/components/stateComponents.go @@ -1,6 +1,8 @@ package components import ( + "io" + chainData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" @@ -27,7 +29,7 @@ type stateComponentsHolder struct { triesContainer common.TriesHolder triesStorageManager map[string]common.StorageManager missingTrieNodesNotifier common.MissingTrieNodesNotifier - closeFunc func() error + stateComponentsCloser io.Closer } // CreateStateComponents will create the state components holder @@ -68,7 +70,7 @@ func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHan triesContainer: stateComp.TriesContainer(), triesStorageManager: stateComp.TrieStorageManagers(), missingTrieNodesNotifier: stateComp.MissingTrieNodesNotifier(), - closeFunc: stateComp.Close, + stateComponentsCloser: stateComp, }, nil } @@ -109,7 +111,7 @@ func (s *stateComponentsHolder) MissingTrieNodesNotifier() common.MissingTrieNod // Close will close the state components func (s *stateComponentsHolder) Close() error { - return s.closeFunc() + return s.stateComponentsCloser.Close() } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 47428f14a95..8be8e2f44ac 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -1,6 +1,8 @@ package components import ( + "io" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" @@ -10,14 +12,14 @@ import ( ) type statusCoreComponentsHolder struct { - closeHandler *closeHandler - resourceMonitor factory.ResourceMonitor - networkStatisticsProvider factory.NetworkStatisticsProvider - trieSyncStatisticsProvider factory.TrieSyncStatisticsProvider - statusHandler core.AppStatusHandler - statusMetrics external.StatusMetricsHandler - persistentStatusHandler factory.PersistentStatusHandler - stateStatisticsHandler common.StateStatisticsHandler + resourceMonitor factory.ResourceMonitor + networkStatisticsProvider factory.NetworkStatisticsProvider + trieSyncStatisticsProvider factory.TrieSyncStatisticsProvider + statusHandler core.AppStatusHandler + statusMetrics external.StatusMetricsHandler + persistentStatusHandler factory.PersistentStatusHandler + stateStatisticsHandler common.StateStatisticsHandler + managedStatusCoreComponentsCloser io.Closer } // CreateStatusCoreComponents will create a new instance of factory.StatusCoreComponentsHandler @@ -50,18 +52,16 @@ func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.C _ = managedStatusCoreComponents.ResourceMonitor().Close() instance := &statusCoreComponentsHolder{ - closeHandler: NewCloseHandler(), - resourceMonitor: managedStatusCoreComponents.ResourceMonitor(), - networkStatisticsProvider: managedStatusCoreComponents.NetworkStatistics(), - trieSyncStatisticsProvider: managedStatusCoreComponents.TrieSyncStatistics(), - statusHandler: managedStatusCoreComponents.AppStatusHandler(), - statusMetrics: managedStatusCoreComponents.StatusMetrics(), - persistentStatusHandler: managedStatusCoreComponents.PersistentStatusHandler(), - stateStatisticsHandler: managedStatusCoreComponents.StateStatsHandler(), + resourceMonitor: managedStatusCoreComponents.ResourceMonitor(), + networkStatisticsProvider: managedStatusCoreComponents.NetworkStatistics(), + trieSyncStatisticsProvider: managedStatusCoreComponents.TrieSyncStatistics(), + statusHandler: managedStatusCoreComponents.AppStatusHandler(), + statusMetrics: managedStatusCoreComponents.StatusMetrics(), + persistentStatusHandler: managedStatusCoreComponents.PersistentStatusHandler(), + stateStatisticsHandler: managedStatusCoreComponents.StateStatsHandler(), + managedStatusCoreComponentsCloser: managedStatusCoreComponents, } - instance.collectClosableComponents() - return instance, nil } @@ -100,16 +100,9 @@ func (s *statusCoreComponentsHolder) PersistentStatusHandler() factory.Persisten return s.persistentStatusHandler } -func (s *statusCoreComponentsHolder) collectClosableComponents() { - s.closeHandler.AddComponent(s.resourceMonitor) - s.closeHandler.AddComponent(s.networkStatisticsProvider) - s.closeHandler.AddComponent(s.statusHandler) - s.closeHandler.AddComponent(s.persistentStatusHandler) -} - // Close will call the Close methods on all inner components func (s *statusCoreComponentsHolder) Close() error { - return s.closeHandler.Close() + return s.managedStatusCoreComponentsCloser.Close() } // IsInterfaceNil returns true if there is no value under the interface diff --git a/node/chainSimulator/components/syncedMessenger.go b/node/chainSimulator/components/syncedMessenger.go index f69f572191c..d30ac85b409 100644 --- a/node/chainSimulator/components/syncedMessenger.go +++ b/node/chainSimulator/components/syncedMessenger.go @@ -27,9 +27,12 @@ var ( errTopicNotCreated = errors.New("topic not created") errTopicHasProcessor = errors.New("there is already a message processor for provided topic and identifier") errInvalidSignature = errors.New("invalid signature") + errMessengerIsClosed = errors.New("messenger is closed") ) type syncedMessenger struct { + mutIsClosed sync.RWMutex + isClosed bool mutOperation sync.RWMutex topics map[string]map[string]p2p.MessageProcessor network SyncedBroadcastNetworkHandler @@ -66,6 +69,9 @@ func (messenger *syncedMessenger) HasCompatibleProtocolID(_ string) bool { } func (messenger *syncedMessenger) receive(fromConnectedPeer core.PeerID, message p2p.MessageP2P) { + if messenger.closed() { + return + } if check.IfNil(message) { return } @@ -90,6 +96,10 @@ func (messenger *syncedMessenger) ProcessReceivedMessage(_ p2p.MessageP2P, _ cor // CreateTopic will create a topic for receiving data func (messenger *syncedMessenger) CreateTopic(name string, _ bool) error { + if messenger.closed() { + return errMessengerIsClosed + } + messenger.mutOperation.Lock() defer messenger.mutOperation.Unlock() @@ -115,6 +125,9 @@ func (messenger *syncedMessenger) HasTopic(name string) bool { // RegisterMessageProcessor will try to register a message processor on the provided topic & identifier func (messenger *syncedMessenger) RegisterMessageProcessor(topic string, identifier string, handler p2p.MessageProcessor) error { + if messenger.closed() { + return errMessengerIsClosed + } if check.IfNil(handler) { return fmt.Errorf("programming error in syncedMessenger.RegisterMessageProcessor, "+ "%w for topic %s and identifier %s", errNilMessageProcessor, topic, identifier) @@ -170,6 +183,9 @@ func (messenger *syncedMessenger) UnregisterMessageProcessor(topic string, ident // Broadcast will broadcast the provided buffer on the topic in a synchronous manner func (messenger *syncedMessenger) Broadcast(topic string, buff []byte) { + if messenger.closed() { + return + } if !messenger.HasTopic(topic) { return } @@ -194,6 +210,10 @@ func (messenger *syncedMessenger) BroadcastOnChannelUsingPrivateKey(_ string, to // SendToConnectedPeer will send the message to the peer func (messenger *syncedMessenger) SendToConnectedPeer(topic string, buff []byte, peerID core.PeerID) error { + if messenger.closed() { + return errMessengerIsClosed + } + if !messenger.HasTopic(topic) { return nil } @@ -356,9 +376,20 @@ func (messenger *syncedMessenger) SetDebugger(_ p2p.Debugger) error { // Close does nothing and returns nil func (messenger *syncedMessenger) Close() error { + messenger.mutIsClosed.Lock() + messenger.isClosed = true + messenger.mutIsClosed.Unlock() + return nil } +func (messenger *syncedMessenger) closed() bool { + messenger.mutIsClosed.RLock() + defer messenger.mutIsClosed.RUnlock() + + return messenger.isClosed +} + // IsInterfaceNil returns true if there is no value under the interface func (messenger *syncedMessenger) IsInterfaceNil() bool { return messenger == nil diff --git a/node/external/nodeApiResolver.go b/node/external/nodeApiResolver.go index d980e9ad91f..d30bb0125e8 100644 --- a/node/external/nodeApiResolver.go +++ b/node/external/nodeApiResolver.go @@ -41,6 +41,7 @@ type ArgNodeApiResolver struct { GasScheduleNotifier common.GasScheduleNotifierAPI ManagedPeersMonitor common.ManagedPeersMonitor NodesCoordinator nodesCoordinator.NodesCoordinator + StorageManagers []common.StorageManager } // nodeApiResolver can resolve API requests @@ -60,6 +61,7 @@ type nodeApiResolver struct { gasScheduleNotifier common.GasScheduleNotifierAPI managedPeersMonitor common.ManagedPeersMonitor nodesCoordinator nodesCoordinator.NodesCoordinator + storageManagers []common.StorageManager } // NewNodeApiResolver creates a new nodeApiResolver instance @@ -126,6 +128,7 @@ func NewNodeApiResolver(arg ArgNodeApiResolver) (*nodeApiResolver, error) { gasScheduleNotifier: arg.GasScheduleNotifier, managedPeersMonitor: arg.ManagedPeersMonitor, nodesCoordinator: arg.NodesCoordinator, + storageManagers: arg.StorageManagers, }, nil } @@ -151,6 +154,15 @@ func (nar *nodeApiResolver) SimulateTransactionExecution(tx *transaction.Transac // Close closes all underlying components func (nar *nodeApiResolver) Close() error { + for _, sm := range nar.storageManagers { + if check.IfNil(sm) { + continue + } + + err := sm.Close() + log.LogIfError(err) + } + return nar.scQueryService.Close() } From 419aa40f8d3b21e58006a9bbfd98750200e52632 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 13 Feb 2024 08:41:03 +0200 Subject: [PATCH 778/958] - linter & typo fixes --- factory/api/apiResolverFactory.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index defca284230..d77cc204d90 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -608,9 +608,9 @@ func createNewAccountsAdapterApi(args *scQueryElementArgs, chainHandler data.Cha return nil, nil, err } - accluntsDB, err := state.NewAccountsDBApi(accounts, provider) + accountsDB, err := state.NewAccountsDBApi(accounts, provider) - return accluntsDB, trieStorageManager, nil + return accountsDB, trieStorageManager, err } func newStoragePruningManager(args *scQueryElementArgs) (state.StoragePruningManager, error) { From 1732dcba8ababc6f82ed9779ab6d8e753fa802f5 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 13 Feb 2024 08:57:53 +0200 Subject: [PATCH 779/958] - fixed chain simulator config --- node/chainSimulator/configs/configs.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index edee6506f1e..63aa3adc48b 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -218,6 +218,7 @@ func generateValidatorsKeyAndUpdateFiles( nodes.ConsensusGroupSize = 1 nodes.MetaChainConsensusGroupSize = 1 + nodes.Hysteresis = 0 nodes.MinNodesPerShard = args.MinNodesPerShard nodes.MetaChainMinNodes = args.MetaChainMinNodes From a8b06fae1ffcc1c76bff1b730c50b38b5ae1735c Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 13 Feb 2024 10:58:32 +0200 Subject: [PATCH 780/958] configurable delay request block info --- process/block/baseProcess.go | 3 ++- process/block/metablock.go | 1 + process/block/shardblock.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index fcd77d0c75d..b12aa6b2783 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -121,6 +121,7 @@ type baseProcessor struct { mutNonceOfFirstCommittedBlock sync.RWMutex nonceOfFirstCommittedBlock core.OptionalUint64 + extraDelayRequestBlockInfo time.Duration } type bootStorerDataArgs struct { @@ -1685,7 +1686,7 @@ func (bp *baseProcessor) requestMiniBlocksIfNeeded(headerHandler data.HeaderHand return } - waitTime := common.ExtraDelayForRequestBlockInfo + waitTime := bp.extraDelayRequestBlockInfo roundDifferences := bp.roundHandler.Index() - int64(headerHandler.GetRound()) if roundDifferences > 1 { waitTime = 0 diff --git a/process/block/metablock.go b/process/block/metablock.go index a7f4919bb28..390e1cebf25 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -137,6 +137,7 @@ func NewMetaProcessor(arguments ArgMetaProcessor) (*metaProcessor, error) { blockProcessingCutoffHandler: arguments.BlockProcessingCutoffHandler, managedPeersHolder: arguments.ManagedPeersHolder, sentSignaturesTracker: arguments.SentSignaturesTracker, + extraDelayRequestBlockInfo: time.Duration(arguments.Config.EpochStartConfig.ExtraDelayForRequestBlockInfoInMilliseconds) * time.Millisecond, } mp := metaProcessor{ diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 9743abc0bb4..11e62f63ff9 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -122,6 +122,7 @@ func NewShardProcessor(arguments ArgShardProcessor) (*shardProcessor, error) { blockProcessingCutoffHandler: arguments.BlockProcessingCutoffHandler, managedPeersHolder: arguments.ManagedPeersHolder, sentSignaturesTracker: arguments.SentSignaturesTracker, + extraDelayRequestBlockInfo: time.Duration(arguments.Config.EpochStartConfig.ExtraDelayForRequestBlockInfoInMilliseconds) * time.Millisecond, } sp := shardProcessor{ From 4dcc62d5b15bf3139e31e37363353ca50ddbc03e Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 13 Feb 2024 11:04:45 +0200 Subject: [PATCH 781/958] - fixed test --- node/nodeRunner_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/node/nodeRunner_test.go b/node/nodeRunner_test.go index d10dc07a1ac..bb20b16fc47 100644 --- a/node/nodeRunner_test.go +++ b/node/nodeRunner_test.go @@ -49,9 +49,6 @@ func TestNodeRunner_StartAndCloseNodeUsingSIGINT(t *testing.T) { configs, err := testscommon.CreateTestConfigs(t.TempDir(), originalConfigsPath) require.Nil(t, err) - configs.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].MaxNumNodes = 50 - - runner, _ := NewNodeRunner(configs) From 50937b8390a9c3e68d47b2198ac215e238edffc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Feb 2024 12:00:29 +0200 Subject: [PATCH 782/958] Attempt fix for deep queries on metachain. --- factory/api/apiResolverFactory.go | 19 +++++++++++++++---- integrationTests/oneNodeNetwork.go | 13 +++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 1ceee28a6ab..2d8d5a9ffe1 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -343,6 +343,8 @@ func createScQueryElement( ) (process.SCQueryService, error) { var err error + isMetachain := args.processComponents.ShardCoordinator().SelfId() == core.MetachainShardId + pkConverter := args.coreComponents.AddressPubKeyConverter() automaticCrawlerAddressesStrings := args.generalConfig.BuiltInFunctions.AutomaticCrawlerAddresses convertedAddresses, errDecode := factory.DecodeAddresses(pkConverter, automaticCrawlerAddressesStrings) @@ -356,9 +358,18 @@ func createScQueryElement( return nil, errDecode } - apiBlockchain, err := blockchain.NewBlockChain(disabled.NewAppStatusHandler()) - if err != nil { - return nil, err + var apiBlockchain data.ChainHandler + + if isMetachain { + apiBlockchain, err = blockchain.NewMetaChain(disabled.NewAppStatusHandler()) + if err != nil { + return nil, err + } + } else { + apiBlockchain, err = blockchain.NewBlockChain(disabled.NewAppStatusHandler()) + if err != nil { + return nil, err + } } accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) @@ -415,7 +426,7 @@ func createScQueryElement( var vmFactory process.VirtualMachinesContainerFactory maxGasForVmQueries := args.generalConfig.VirtualMachine.GasConfig.ShardMaxGasPerVmQuery - if args.processComponents.ShardCoordinator().SelfId() == core.MetachainShardId { + if isMetachain { maxGasForVmQueries = args.generalConfig.VirtualMachine.GasConfig.MetaMaxGasPerVmQuery vmFactory, err = createMetaVmContainerFactory(args, argsHook) } else { diff --git a/integrationTests/oneNodeNetwork.go b/integrationTests/oneNodeNetwork.go index 184f5989f61..0f52de516a2 100644 --- a/integrationTests/oneNodeNetwork.go +++ b/integrationTests/oneNodeNetwork.go @@ -11,10 +11,13 @@ import ( // OneNodeNetwork is a one-node network, useful for some integration tests type OneNodeNetwork struct { - Round uint64 - Nonce uint64 + Round uint64 + RoundMetachain uint64 + Nonce uint64 + NonceMetachain uint64 - Node *TestProcessorNode + Node *TestProcessorNode + NodeMetachain *TestProcessorNode } // NewOneNodeNetwork creates a OneNodeNetwork @@ -24,10 +27,11 @@ func NewOneNodeNetwork() *OneNodeNetwork { nodes := CreateNodes( 1, 1, - 0, + 1, ) n.Node = nodes[0] + n.NodeMetachain = nodes[1] return n } @@ -60,6 +64,7 @@ func (n *OneNodeNetwork) GoToRoundOne() { // Continue advances processing with a number of rounds func (n *OneNodeNetwork) Continue(t *testing.T, numRounds int) { n.Nonce, n.Round = WaitOperationToBeDone(t, []*TestProcessorNode{n.Node}, numRounds, n.Nonce, n.Round, []int{0}) + n.NonceMetachain, n.RoundMetachain = WaitOperationToBeDone(t, []*TestProcessorNode{n.NodeMetachain}, numRounds, n.NonceMetachain, n.RoundMetachain, []int{0}) } // AddTxToPool adds a transaction to the pool (skips signature checks and interceptors) From 9c69d961e7d127c1766ac0a9c3a0d11f719a0fc3 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Tue, 13 Feb 2024 12:55:16 +0200 Subject: [PATCH 783/958] MX-15154: fix after review --- .../chainSimulator/staking/delegation_test.go | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 8bf2ca1e1d5..76ec2890708 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -355,8 +355,8 @@ func testBLSKeyIsInAuction( require.Equal(t, actionListSize, len(auctionList)) if actionListSize != 0 { - require.Equal(t, 1, len(auctionList[0].Nodes)) - require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) + require.Equal(t, 1, len(auctionList[0].Nodes)) + require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) } // in staking ph 4 we should find the key in the validators statics @@ -660,7 +660,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat // Step 4: Perform stakeNodes - txStakeNodes := generateTransaction(validatorOwnerBytes, 2, delegationContractAddressBytes, zeroValue, fmt.Sprintf("stakeNodes@%s", blsKeys[0]), gasLimitForDelegate) + txStakeNodes := generateTransaction(validatorOwnerBytes, 2, delegationContractAddressBytes, zeroValue, fmt.Sprintf("stakeNodes@%s", blsKeys[0]), gasLimitForStakeOperation) stakeNodesTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStakeNodes, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeNodesTx) @@ -791,21 +791,14 @@ func getSignatures(msg []byte, blsKeys [][]byte) [][]byte { func getNodesFromContract(returnData [][]byte) ([][]byte, [][]byte, [][]byte) { var stakedKeys, notStakedKeys, unStakedKeys [][]byte - // Placeholder for the current list being populated - var currentList *[][]byte - - for _, data := range returnData { - switch string(data) { + for i := 0; i < len(returnData); i += 2 { + switch string(returnData[i]) { case "staked": - currentList = &stakedKeys + stakedKeys = append(stakedKeys, returnData[i+1]) case "notStaked": - currentList = ¬StakedKeys + notStakedKeys = append(notStakedKeys, returnData[i+1]) case "unStaked": - currentList = &unStakedKeys - default: - if currentList != nil { - *currentList = append(*currentList, data) - } + unStakedKeys = append(unStakedKeys, returnData[i+1]) } } return stakedKeys, notStakedKeys, unStakedKeys From 55d7cc78d16bfc71743667fd832004f474244347 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Tue, 13 Feb 2024 12:55:52 +0200 Subject: [PATCH 784/958] MX-15154: fix sendTx --- node/chainSimulator/send_and_execute.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/send_and_execute.go b/node/chainSimulator/send_and_execute.go index 09e15a58c13..4802295aae3 100644 --- a/node/chainSimulator/send_and_execute.go +++ b/node/chainSimulator/send_and_execute.go @@ -30,9 +30,16 @@ func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { return "", err } - log.Info("############## send transaction ##############", "txHash", txHashHex) - - return txHashHex, nil + for { + txs, _ := node.GetFacadeHandler().GetTransactionsPool("") + for _, tx := range txs.RegularTransactions { + if tx.TxFields["hash"] == txHashHex { + log.Info("############## send transaction ##############", "txHash", txHashHex) + return txHashHex, nil + } + } + time.Sleep(delaySendTxs) + } } func (s *simulator) SendTxsAndGenerateBlockTilTxIsExecuted(txsToSend []*transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) ([]*transaction.ApiTransactionResult, error) { From 0a4ee7a4055c157243067af914c077e2a7dff2d8 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 13 Feb 2024 14:09:37 +0200 Subject: [PATCH 785/958] fixes after feat merge --- .../chainSimulator/staking/delegation_test.go | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 8925e757679..68ee2b92475 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -1001,20 +1001,18 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat mintValue := big.NewInt(3000) mintValue = mintValue.Mul(oneEGLD, mintValue) - validatorOwnerBech32, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + validatorA, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - validatorA, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) - validatorOwnerBech32, err = cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + validatorB, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - validatorB, _ := metachainNode.GetCoreComponents().AddressPubKeyConverter().Decode(validatorOwnerBech32) log.Info("Step 1. User A: - stake 1 node to have 100 egld more") stakeValue := big.NewInt(0).Set(minimumStakeValue) addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) stakeValue.Add(stakeValue, addedStakedValue) txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) - txStake := generateTransaction(validatorA, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + txStake := generateTransaction(validatorA.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeTx) @@ -1022,12 +1020,12 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) - testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorA, blsKeys[0], addedStakedValue, 1) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorA)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorA.Bytes, blsKeys[0], addedStakedValue, 1) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorA.Bytes)) log.Info("Step 2. Execute MakeNewContractFromValidatorData for User A") txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) - txConvert := generateTransaction(validatorA, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) + txConvert := generateTransaction(validatorA.Bytes, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) convertTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, convertTx) @@ -1047,7 +1045,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat addedStakedValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) stakeValue.Add(stakeValue, addedStakedValue) txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) - txStake = generateTransaction(validatorB, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + txStake = generateTransaction(validatorB.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeTx) @@ -1055,26 +1053,29 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) - testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorB, blsKeys[1], addedStakedValue, 2) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorB)) + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorB.Bytes, blsKeys[1], addedStakedValue, 2) + assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorB.Bytes)) decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) - require.Equal(t, validatorB, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) + require.Equal(t, validatorB.Bytes, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) log.Info("Step 4. User B : whitelistForMerge@addressB") - txDataField = fmt.Sprintf("whitelistForMerge@%s", validatorB) - whitelistForMerge := generateTransaction(validatorA, 2, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) + txDataField = fmt.Sprintf("whitelistForMerge@%s", validatorB.Bytes) + whitelistForMerge := generateTransaction(validatorA.Bytes, 2, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) whitelistForMergeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(whitelistForMerge, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, whitelistForMergeTx) + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + log.Info("Step 5. User A : mergeValidatorToDelegationWithWhitelist") txDataField = fmt.Sprintf("mergeValidatorToDelegationWithWhitelist@%s", hex.EncodeToString(delegationAddress)) - txConvert = generateTransaction(validatorB, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForMergeOperation) + txConvert = generateTransaction(validatorB.Bytes, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForMergeOperation) convertTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, convertTx) @@ -1082,9 +1083,6 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node assert.Nil(t, err) - err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() - require.Nil(t, err) - decodedBLSKey0, _ = hex.DecodeString(blsKeys[0]) require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) From 81f5149ccf3ad2b341b696b1e281d64f946d8a91 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 13 Feb 2024 14:13:45 +0200 Subject: [PATCH 786/958] scenario 4 5 6 --- .../staking/stakeAndUnStake_test.go | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index d3c3e7ff2fa..d887f335431 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -17,6 +17,7 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + "github.com/multiversx/mx-chain-go/vm" logger "github.com/multiversx/mx-chain-logger-go" "github.com/stretchr/testify/require" ) @@ -275,6 +276,122 @@ func TestChainSimulator_AddANewValidatorAfterStakingV4(t *testing.T) { checkTotalQualified(t, results, 0) } +// Internal test scenario #4 #5 #6 +// do stake +// do unStake +// do unBondNodes +// do unBondTokens +func TestChainSimulatorStakeUnStakeUnBond(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + t.Run("staking ph 4 is not active", func(t *testing.T) { + testStakeUnStakeUnBond(t, 1) + }) + + t.Run("staking ph 4 step 1 active", func(t *testing.T) { + testStakeUnStakeUnBond(t, 4) + }) + + t.Run("staking ph 4 step 2 active", func(t *testing.T) { + testStakeUnStakeUnBond(t, 5) + }) + + t.Run("staking ph 4 step 3 active", func(t *testing.T) { + testStakeUnStakeUnBond(t, 6) + }) +} + +func testStakeUnStakeUnBond(t *testing.T, targetEpoch int32) { + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + numOfShards := uint32(3) + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: numOfShards, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriod = 1 + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 1 + newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 10 + configs.SetMaxNumberOfNodesInConfigs(cfg, newNumNodes, numOfShards) + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + err = cs.AddValidatorKeys(privateKeys) + require.Nil(t, err) + + mintValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(2600)) + walletAddressShardID := uint32(0) + walletAddress, err := cs.GenerateAndMintWalletAddress(walletAddressShardID, mintValue) + require.Nil(t, err) + + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(walletAddress.Bytes, 0, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + bls0, _ := hex.DecodeString(blsKeys[0]) + blsKeyStatus := getBLSKeyStatus(t, metachainNode, bls0) + require.Equal(t, "staked", blsKeyStatus) + + // do unStake + txUnStake := generateTransaction(walletAddress.Bytes, 1, vm.ValidatorSCAddress, zeroValue, fmt.Sprintf("unStake@%s", blsKeys[0]), gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + blsKeyStatus = getBLSKeyStatus(t, metachainNode, bls0) + require.Equal(t, "unStaked", blsKeyStatus) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + // do unBond + txUnBond := generateTransaction(walletAddress.Bytes, 2, vm.ValidatorSCAddress, zeroValue, fmt.Sprintf("unBondNodes@%s", blsKeys[0]), gasLimitForStakeOperation) + unBondTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unBondTx) + + // do claim + txClaim := generateTransaction(walletAddress.Bytes, 3, vm.ValidatorSCAddress, zeroValue, fmt.Sprintf("unBondTokens"), gasLimitForStakeOperation) + claimTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txClaim, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, claimTx) + + err = cs.GenerateBlocks(5) + require.Nil(t, err) + + // check tokens are in the wallet balance + walletAccount, _, err := cs.GetNodeHandler(walletAddressShardID).GetFacadeHandler().GetAccount(walletAddress.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + walletBalanceBig, _ := big.NewInt(0).SetString(walletAccount.Balance, 10) + require.True(t, walletBalanceBig.Cmp(minimumStakeValue) > 0) +} + func checkTotalQualified(t *testing.T, auctionList []*common.AuctionListValidatorAPIResponse, expected int) { totalQualified := 0 for _, res := range auctionList { From aff9fbd46dc3584c23954cb51bf97703a492c0f2 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 13 Feb 2024 14:15:46 +0200 Subject: [PATCH 787/958] fix linter issue --- integrationTests/chainSimulator/staking/delegation_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 68ee2b92475..29146dbfcda 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -37,7 +37,6 @@ const gasLimitForDelegationContractCreationOperation = 500_000_000 const gasLimitForAddNodesOperation = 500_000_000 const gasLimitForUndelegateOperation = 500_000_000 const gasLimitForMergeOperation = 500_000_000 -const gasLimitForGetNumNodes = 100_000_000 const gasLimitForDelegate = 12_000_000 const minGasPrice = 1000000000 const txVersion = 1 From 4b9969cf0e172fdacc54837c4b8e5c563402c467 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 13 Feb 2024 14:20:22 +0200 Subject: [PATCH 788/958] fix linter --- integrationTests/chainSimulator/staking/stakeAndUnStake_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index d887f335431..72efdd1b36b 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -377,7 +377,7 @@ func testStakeUnStakeUnBond(t *testing.T, targetEpoch int32) { require.NotNil(t, unBondTx) // do claim - txClaim := generateTransaction(walletAddress.Bytes, 3, vm.ValidatorSCAddress, zeroValue, fmt.Sprintf("unBondTokens"), gasLimitForStakeOperation) + txClaim := generateTransaction(walletAddress.Bytes, 3, vm.ValidatorSCAddress, zeroValue, "unBondTokens", gasLimitForStakeOperation) claimTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txClaim, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, claimTx) From 0630e26bf73370076c9f1f1a0bc66f7fe3d3dea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Feb 2024 14:24:34 +0200 Subject: [PATCH 789/958] Fix after review. --- factory/api/apiResolverFactory.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 2d8d5a9ffe1..fb133748986 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -343,7 +343,7 @@ func createScQueryElement( ) (process.SCQueryService, error) { var err error - isMetachain := args.processComponents.ShardCoordinator().SelfId() == core.MetachainShardId + selfShardID := args.processComponents.ShardCoordinator().SelfId() pkConverter := args.coreComponents.AddressPubKeyConverter() automaticCrawlerAddressesStrings := args.generalConfig.BuiltInFunctions.AutomaticCrawlerAddresses @@ -358,18 +358,9 @@ func createScQueryElement( return nil, errDecode } - var apiBlockchain data.ChainHandler - - if isMetachain { - apiBlockchain, err = blockchain.NewMetaChain(disabled.NewAppStatusHandler()) - if err != nil { - return nil, err - } - } else { - apiBlockchain, err = blockchain.NewBlockChain(disabled.NewAppStatusHandler()) - if err != nil { - return nil, err - } + apiBlockchain, err := createBlockchainForScQuery(selfShardID) + if err != nil { + return nil, err } accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) @@ -426,7 +417,7 @@ func createScQueryElement( var vmFactory process.VirtualMachinesContainerFactory maxGasForVmQueries := args.generalConfig.VirtualMachine.GasConfig.ShardMaxGasPerVmQuery - if isMetachain { + if selfShardID == core.MetachainShardId { maxGasForVmQueries = args.generalConfig.VirtualMachine.GasConfig.MetaMaxGasPerVmQuery vmFactory, err = createMetaVmContainerFactory(args, argsHook) } else { @@ -474,6 +465,15 @@ func createScQueryElement( return smartContract.NewSCQueryService(argsNewSCQueryService) } +func createBlockchainForScQuery(selfShardID uint32) (data.ChainHandler, error) { + isMetachain := selfShardID == core.MetachainShardId + if isMetachain { + return blockchain.NewMetaChain(disabled.NewAppStatusHandler()) + } + + return blockchain.NewBlockChain(disabled.NewAppStatusHandler()) +} + func createMetaVmContainerFactory(args scQueryElementArgs, argsHook hooks.ArgBlockChainHook) (process.VirtualMachinesContainerFactory, error) { blockChainHookImpl, errBlockChainHook := hooks.NewBlockChainHookImpl(argsHook) if errBlockChainHook != nil { From 4378142348d0363a881040e4d16ffc7d60f1b6f9 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 13 Feb 2024 14:40:46 +0200 Subject: [PATCH 790/958] fix whitelist tx --- .../chainSimulator/staking/delegation_test.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 29146dbfcda..5392555c715 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -36,7 +36,7 @@ const gasLimitForConvertOperation = 510_000_000 const gasLimitForDelegationContractCreationOperation = 500_000_000 const gasLimitForAddNodesOperation = 500_000_000 const gasLimitForUndelegateOperation = 500_000_000 -const gasLimitForMergeOperation = 500_000_000 +const gasLimitForMergeOperation = 600_000_000 const gasLimitForDelegate = 12_000_000 const minGasPrice = 1000000000 const txVersion = 1 @@ -859,8 +859,7 @@ func generateTransaction(sender []byte, nonce uint64, receiver []byte, value *bi // mergeValidatorToDelegationWithWhitelist contracts still works properly // Test that their topups will merge too and will be used by auction list computing. - -// Internal test scenario #12 +// func TestChainSimulator_MergeDelegation(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -872,6 +871,13 @@ func TestChainSimulator_MergeDelegation(t *testing.T) { Value: 30, } + // Test steps: + // 1. User A: - stake 1 node to have 100 egld more ( or just pick a genesis validator on internal testnets and top it up with 100 egld) + // 2. User A : MakeNewContractFromValidatorData + // 3. User B: - stake 1 node with more than 2500 egld (or pick a genesis validator and stake 100 more egld to have a top-up) + // 4. User B : whiteListForMerge@addressA + // 5. User A : mergeValidatorToDelegationWithWhitelist + t.Run("staking ph 4 is not active", func(t *testing.T) { cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, @@ -1062,7 +1068,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.Equal(t, validatorB.Bytes, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) log.Info("Step 4. User B : whitelistForMerge@addressB") - txDataField = fmt.Sprintf("whitelistForMerge@%s", validatorB.Bytes) + txDataField = fmt.Sprintf("whitelistForMerge@%s", hex.EncodeToString(validatorB.Bytes)) whitelistForMerge := generateTransaction(validatorA.Bytes, 2, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) whitelistForMergeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(whitelistForMerge, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) From 2e255a32c700b832ed23aba52be88108060aeb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Feb 2024 16:36:51 +0200 Subject: [PATCH 791/958] Undo changed within one node network. --- integrationTests/oneNodeNetwork.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/integrationTests/oneNodeNetwork.go b/integrationTests/oneNodeNetwork.go index 0f52de516a2..184f5989f61 100644 --- a/integrationTests/oneNodeNetwork.go +++ b/integrationTests/oneNodeNetwork.go @@ -11,13 +11,10 @@ import ( // OneNodeNetwork is a one-node network, useful for some integration tests type OneNodeNetwork struct { - Round uint64 - RoundMetachain uint64 - Nonce uint64 - NonceMetachain uint64 + Round uint64 + Nonce uint64 - Node *TestProcessorNode - NodeMetachain *TestProcessorNode + Node *TestProcessorNode } // NewOneNodeNetwork creates a OneNodeNetwork @@ -27,11 +24,10 @@ func NewOneNodeNetwork() *OneNodeNetwork { nodes := CreateNodes( 1, 1, - 1, + 0, ) n.Node = nodes[0] - n.NodeMetachain = nodes[1] return n } @@ -64,7 +60,6 @@ func (n *OneNodeNetwork) GoToRoundOne() { // Continue advances processing with a number of rounds func (n *OneNodeNetwork) Continue(t *testing.T, numRounds int) { n.Nonce, n.Round = WaitOperationToBeDone(t, []*TestProcessorNode{n.Node}, numRounds, n.Nonce, n.Round, []int{0}) - n.NonceMetachain, n.RoundMetachain = WaitOperationToBeDone(t, []*TestProcessorNode{n.NodeMetachain}, numRounds, n.NonceMetachain, n.RoundMetachain, []int{0}) } // AddTxToPool adds a transaction to the pool (skips signature checks and interceptors) From e9286c968135b012dba7eefd055431263a89c61a Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 13 Feb 2024 16:58:49 +0200 Subject: [PATCH 792/958] unstake funds with deactivation scenario 1 --- .../staking/stakeAndUnStake_test.go | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 3c7dd875019..1726f886a61 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -528,3 +528,243 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) } + +// Test description +// unstake funds with deactivation of node if below 2500 -> the rest of funds are distributed as topup at epoch change +// +func TestChainSimulator_DirectStakingNodes_UnstakeFundsWithDeactivation(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test Steps + // 1. Check the stake amount and number of nodes for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance + // 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network + // 3. Check the outcome of the TX & verify new stake state with vmquery "getTotalStaked" and "getUnStakedTokensList" + // 4. Wait for change of epoch and check the outcome + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t, cs, 1) + }) + + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t, cs, 4) + }) +} + +func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + log.Info("Preconditions. Have an account with 2 staked nodes") + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(5010) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Set(minimumStakeValue) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + stakeValue = big.NewInt(0).Set(minimumStakeValue) + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) + txStake = generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + log.Info("Step 1. Check the stake amount for the owner of the staked nodes") + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked := big.NewInt(5000) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + log.Info("Step 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network") + + unStakeValue := big.NewInt(10) + unStakeValue = unStakeValue.Mul(oneEGLD, unStakeValue) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue.Bytes())) + txUnStake := generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + err = cs.GenerateBlocks(2) + assert.Nil(t, err) + + log.Info("Step 3. Check the outcome of the TX & verify new stake state with vmquery getTotalStaked and getUnStakedTokensList") + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked = big.NewInt(4990) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getUnStakedTokensList", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedUnStaked := big.NewInt(10) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) +} From eb3588169ebf26096517cf9a72aa93f36230394a Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 13 Feb 2024 17:14:23 +0200 Subject: [PATCH 793/958] fixes after review --- .../chainSimulator/staking/delegation_test.go | 45 +++++++++---------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 5392555c715..cc523b7f1c5 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -54,7 +54,7 @@ var zeroValue = big.NewInt(0) var oneEGLD = big.NewInt(1000000000000000000) var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) -// Test description +// Test description: // Test that delegation contract created with MakeNewContractFromValidatorData works properly // Also check that delegate and undelegate works properly and the top-up remain the same if every delegator undelegates. // Test that the top-up from normal stake will be transferred after creating the contract and will be used in auction list computing @@ -854,12 +854,11 @@ func generateTransaction(sender []byte, nonce uint64, receiver []byte, value *bi } } -// Test description -// Test that merging delegation with whiteListForMerge and -// mergeValidatorToDelegationWithWhitelist contracts still works properly - -// Test that their topups will merge too and will be used by auction list computing. +// Test description: +// Test that merging delegation with whiteListForMerge and mergeValidatorToDelegationWithWhitelist contracts still works properly +// Test that their topups will merge too and will be used by auction list computing. // +// Internal test scenario #12 func TestChainSimulator_MergeDelegation(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -872,11 +871,11 @@ func TestChainSimulator_MergeDelegation(t *testing.T) { } // Test steps: - // 1. User A: - stake 1 node to have 100 egld more ( or just pick a genesis validator on internal testnets and top it up with 100 egld) - // 2. User A : MakeNewContractFromValidatorData - // 3. User B: - stake 1 node with more than 2500 egld (or pick a genesis validator and stake 100 more egld to have a top-up) - // 4. User B : whiteListForMerge@addressA - // 5. User A : mergeValidatorToDelegationWithWhitelist + // 1. User A - Stake 1 node to have 100 egld more than minimum required stake value + // 2. User A - Execute `makeNewContractFromValidatorData` to create delegation contract based on User A account + // 3. User B - Stake 1 node with more than 2500 egld + // 4. User A - Execute `whiteListForMerge@addressA` in order to whitelist for merge User B + // 5. User B - Execute `mergeValidatorToDelegationWithWhitelist@delegationContract` in order to merge User B to delegation contract created at step 2. t.Run("staking ph 4 is not active", func(t *testing.T) { cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ @@ -1002,7 +1001,6 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.Nil(t, err) metachainNode := cs.GetNodeHandler(core.MetachainShardId) - log.Info("Preconditions. Pick 2 users and mint both with 3000 egld") mintValue := big.NewInt(3000) mintValue = mintValue.Mul(oneEGLD, mintValue) @@ -1012,7 +1010,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat validatorB, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - log.Info("Step 1. User A: - stake 1 node to have 100 egld more") + log.Info("Step 1. User A: - stake 1 node to have 100 egld more than minimum stake value") stakeValue := big.NewInt(0).Set(minimumStakeValue) addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) stakeValue.Add(stakeValue, addedStakedValue) @@ -1023,10 +1021,10 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorA.Bytes, blsKeys[0], addedStakedValue, 1) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorA.Bytes)) + require.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorA.Bytes)) log.Info("Step 2. Execute MakeNewContractFromValidatorData for User A") txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) @@ -1037,11 +1035,8 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat delegationAddress := convertTx.Logs.Events[0].Topics[1] - err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() - require.Nil(t, err) - err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], addedStakedValue, 1) @@ -1056,10 +1051,10 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorB.Bytes, blsKeys[1], addedStakedValue, 2) - assert.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorB.Bytes)) + require.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorB.Bytes)) decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) @@ -1067,7 +1062,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) require.Equal(t, validatorB.Bytes, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) - log.Info("Step 4. User B : whitelistForMerge@addressB") + log.Info("Step 4. User A : whitelistForMerge@addressB") txDataField = fmt.Sprintf("whitelistForMerge@%s", hex.EncodeToString(validatorB.Bytes)) whitelistForMerge := generateTransaction(validatorA.Bytes, 2, delegationAddress, zeroValue, txDataField, gasLimitForDelegate) whitelistForMergeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(whitelistForMerge, maxNumOfBlockToGenerateWhenExecutingTx) @@ -1075,7 +1070,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.NotNil(t, whitelistForMergeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) log.Info("Step 5. User A : mergeValidatorToDelegationWithWhitelist") txDataField = fmt.Sprintf("mergeValidatorToDelegationWithWhitelist@%s", hex.EncodeToString(delegationAddress)) @@ -1086,7 +1081,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.NotNil(t, convertTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) decodedBLSKey0, _ = hex.DecodeString(blsKeys[0]) require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey0)) @@ -1095,7 +1090,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.Equal(t, delegationAddress, getBLSKeyOwner(t, metachainNode, decodedBLSKey1)) expectedTopUpValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(200)) - assert.Equal(t, expectedTopUpValue, getBLSTopUpValue(t, metachainNode, delegationAddress)) + require.Equal(t, expectedTopUpValue, getBLSTopUpValue(t, metachainNode, delegationAddress)) } func getBLSKeyOwner(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) []byte { From 20eab648802d4f1028b210586166158abc71c3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Feb 2024 22:06:59 +0200 Subject: [PATCH 794/958] Add integration test. --- integrationTests/miniNetwork.go | 113 +++++++++++ integrationTests/oneNodeNetwork.go | 71 ------- integrationTests/testNetwork.go | 2 +- .../vm/wasm/queries/queries_test.go | 178 +++++++++++------- .../vm/wasm/upgrades/upgrades_test.go | 156 +++++++-------- 5 files changed, 289 insertions(+), 231 deletions(-) create mode 100644 integrationTests/miniNetwork.go delete mode 100644 integrationTests/oneNodeNetwork.go diff --git a/integrationTests/miniNetwork.go b/integrationTests/miniNetwork.go new file mode 100644 index 00000000000..e9c64f5606d --- /dev/null +++ b/integrationTests/miniNetwork.go @@ -0,0 +1,113 @@ +package integrationTests + +import ( + "encoding/hex" + "fmt" + "math/big" + "testing" + + "github.com/multiversx/mx-chain-core-go/data/transaction" +) + +// MiniNetwork is a mini network, useful for some integration tests +type MiniNetwork struct { + Round uint64 + Nonce uint64 + + Nodes []*TestProcessorNode + ShardNode *TestProcessorNode + MetachainNode *TestProcessorNode + Users map[string]*TestWalletAccount +} + +// NewMiniNetwork creates a MiniNetwork +func NewMiniNetwork() *MiniNetwork { + n := &MiniNetwork{} + + nodes := CreateNodes( + 1, + 1, + 1, + ) + + n.Nodes = nodes + n.ShardNode = nodes[0] + n.MetachainNode = nodes[1] + n.Users = make(map[string]*TestWalletAccount) + + return n +} + +// Stop stops the mini network +func (n *MiniNetwork) Stop() { + n.ShardNode.Close() + n.MetachainNode.Close() +} + +// FundAccount funds an account +func (n *MiniNetwork) FundAccount(address []byte, value *big.Int) { + shard := n.MetachainNode.ShardCoordinator.ComputeId(address) + + if shard == n.MetachainNode.ShardCoordinator.SelfId() { + MintAddress(n.MetachainNode.AccntState, address, value) + } else { + MintAddress(n.ShardNode.AccntState, address, value) + } +} + +// AddUser adds a user (account) to the mini network +func (n *MiniNetwork) AddUser(balance *big.Int) *TestWalletAccount { + user := CreateTestWalletAccount(n.ShardNode.ShardCoordinator, 0) + n.Users[string(user.Address)] = user + n.FundAccount(user.Address, balance) + return user +} + +// Start starts the mini network +func (n *MiniNetwork) Start() { + n.Round = 1 + n.Nonce = 1 +} + +// Continue advances processing with a number of rounds +func (n *MiniNetwork) Continue(t *testing.T, numRounds int) { + idxProposers := []int{0, 1} + + for i := int64(0); i < int64(numRounds); i++ { + n.Nonce, n.Round = ProposeAndSyncOneBlock(t, n.Nodes, idxProposers, n.Round, n.Nonce) + } +} + +// SendTransaction sends a transaction +func (n *MiniNetwork) SendTransaction( + senderPubkey []byte, + receiverPubkey []byte, + value *big.Int, + data string, + additionalGasLimit uint64, +) (string, error) { + sender, ok := n.Users[string(senderPubkey)] + if !ok { + return "", fmt.Errorf("unknown sender: %s", hex.EncodeToString(senderPubkey)) + } + + tx := &transaction.Transaction{ + Nonce: sender.Nonce, + Value: new(big.Int).Set(value), + SndAddr: sender.Address, + RcvAddr: receiverPubkey, + Data: []byte(data), + GasPrice: MinTxGasPrice, + GasLimit: MinTxGasLimit + uint64(len(data)) + additionalGasLimit, + ChainID: ChainID, + Version: MinTransactionVersion, + } + + txBuff, _ := tx.GetDataForSigning(TestAddressPubkeyConverter, TestTxSignMarshalizer, TestTxSignHasher) + tx.Signature, _ = sender.SingleSigner.Sign(sender.SkTxSign, txBuff) + txHash, err := n.ShardNode.SendTransaction(tx) + + sender.Nonce++ + + return txHash, err +} diff --git a/integrationTests/oneNodeNetwork.go b/integrationTests/oneNodeNetwork.go deleted file mode 100644 index 184f5989f61..00000000000 --- a/integrationTests/oneNodeNetwork.go +++ /dev/null @@ -1,71 +0,0 @@ -package integrationTests - -import ( - "math/big" - "testing" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/data/transaction" - "github.com/multiversx/mx-chain-go/process" -) - -// OneNodeNetwork is a one-node network, useful for some integration tests -type OneNodeNetwork struct { - Round uint64 - Nonce uint64 - - Node *TestProcessorNode -} - -// NewOneNodeNetwork creates a OneNodeNetwork -func NewOneNodeNetwork() *OneNodeNetwork { - n := &OneNodeNetwork{} - - nodes := CreateNodes( - 1, - 1, - 0, - ) - - n.Node = nodes[0] - return n -} - -// Stop stops the test network -func (n *OneNodeNetwork) Stop() { - n.Node.Close() -} - -// Mint mints the given address -func (n *OneNodeNetwork) Mint(address []byte, value *big.Int) { - MintAddress(n.Node.AccntState, address, value) -} - -// GetMinGasPrice returns the min gas price -func (n *OneNodeNetwork) GetMinGasPrice() uint64 { - return n.Node.EconomicsData.GetMinGasPrice() -} - -// MaxGasLimitPerBlock returns the max gas per block -func (n *OneNodeNetwork) MaxGasLimitPerBlock() uint64 { - return n.Node.EconomicsData.MaxGasLimitPerBlock(0) - 1 -} - -// GoToRoundOne advances processing to block and round 1 -func (n *OneNodeNetwork) GoToRoundOne() { - n.Round = IncrementAndPrintRound(n.Round) - n.Nonce++ -} - -// Continue advances processing with a number of rounds -func (n *OneNodeNetwork) Continue(t *testing.T, numRounds int) { - n.Nonce, n.Round = WaitOperationToBeDone(t, []*TestProcessorNode{n.Node}, numRounds, n.Nonce, n.Round, []int{0}) -} - -// AddTxToPool adds a transaction to the pool (skips signature checks and interceptors) -func (n *OneNodeNetwork) AddTxToPool(tx *transaction.Transaction) { - txHash, _ := core.CalculateHash(TestMarshalizer, TestHasher, tx) - sourceShard := n.Node.ShardCoordinator.ComputeId(tx.SndAddr) - cacheIdentifier := process.ShardCacherIdentifier(sourceShard, sourceShard) - n.Node.DataPool.Transactions().AddData(txHash, tx, tx.Size(), cacheIdentifier) -} diff --git a/integrationTests/testNetwork.go b/integrationTests/testNetwork.go index e22222d41a7..a08b3aa85c7 100644 --- a/integrationTests/testNetwork.go +++ b/integrationTests/testNetwork.go @@ -34,7 +34,7 @@ type GasScheduleMap = map[string]map[string]uint64 // TestNetwork wraps a set of TestProcessorNodes along with a set of test // Wallets, instantiates them, controls them and provides operations with them; // designed to be used in integration tests. -// TODO combine TestNetwork with the preexisting TestContext and OneNodeNetwork +// TODO combine TestNetwork with the preexisting TestContext and MiniNetwork // into a single struct containing the functionality of all three type TestNetwork struct { NumShards int diff --git a/integrationTests/vm/wasm/queries/queries_test.go b/integrationTests/vm/wasm/queries/queries_test.go index 541c88f8310..3c3af1e5283 100644 --- a/integrationTests/vm/wasm/queries/queries_test.go +++ b/integrationTests/vm/wasm/queries/queries_test.go @@ -2,22 +2,23 @@ // TODO remove build condition above to allow -race -short, after Wasm VM fix -package upgrades +package queries import ( + "context" "encoding/hex" "fmt" "math/big" "testing" "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/integrationTests" - "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/factory" + "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/require" ) @@ -36,55 +37,52 @@ func TestQueries(t *testing.T) { historyOfGetNow := make(map[uint64]now) historyOfGetState := make(map[uint64]int) - scOwner := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - scOwnerNonce := uint64(0) - - network := integrationTests.NewOneNodeNetwork() + network := integrationTests.NewMiniNetwork() defer network.Stop() - network.Mint(scOwner, big.NewInt(10000000000000)) - network.GoToRoundOne() + scOwner := network.AddUser(big.NewInt(10000000000000)) - // Block 0 + network.Start() + + // Block 1 - scAddress := deploy(network, scOwner, "../testdata/history/output/history.wasm", &scOwnerNonce) + scAddress := deploy(t, network, scOwner.Address, "../testdata/history/output/history.wasm") network.Continue(t, 1) - // Block 1 + // Block 2 - now := queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + now := queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{}) snapshotsOfGetNow[1] = now network.Continue(t, 1) - // Block 2 + // Block 3 - now = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + now = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{}) snapshotsOfGetNow[2] = now - setState(network, scAddress, scOwner, 42, &scOwnerNonce) + setState(t, network, scAddress, scOwner.Address, 42) network.Continue(t, 1) - // Block 3 + // Block 4 - state := getState(t, network.Node, scAddress, core.OptionalUint64{}) + state := getState(t, network.ShardNode, scAddress, core.OptionalUint64{}) snapshotsOfGetState[3] = state - now = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + now = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{}) snapshotsOfGetNow[3] = now - setState(network, scAddress, scOwner, 43, &scOwnerNonce) + setState(t, network, scAddress, scOwner.Address, 43) network.Continue(t, 1) // Block 4 - state = getState(t, network.Node, scAddress, core.OptionalUint64{}) + state = getState(t, network.ShardNode, scAddress, core.OptionalUint64{}) snapshotsOfGetState[4] = state - now = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{}) + now = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{}) snapshotsOfGetNow[4] = now network.Continue(t, 1) // Check snapshots - block1, _ := network.Node.GetShardHeader(1) - block2, _ := network.Node.GetShardHeader(2) - block3, _ := network.Node.GetShardHeader(3) - block4, _ := network.Node.GetShardHeader(4) + block1, _ := network.ShardNode.GetShardHeader(1) + block2, _ := network.ShardNode.GetShardHeader(2) + block3, _ := network.ShardNode.GetShardHeader(3) require.Equal(t, uint64(1), snapshotsOfGetNow[1].blockNonce) require.Equal(t, uint64(2), snapshotsOfGetNow[2].blockNonce) @@ -100,79 +98,64 @@ func TestQueries(t *testing.T) { require.Equal(t, 43, snapshotsOfGetState[4]) // Check history - historyOfGetState[1] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 1}) - historyOfGetNow[1] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 1}) + historyOfGetState[1] = getState(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 1}) + historyOfGetNow[1] = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 1}) - historyOfGetState[2] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 2}) - historyOfGetNow[2] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 2}) + historyOfGetState[2] = getState(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 2}) + historyOfGetNow[2] = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 2}) - historyOfGetState[3] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 3}) - historyOfGetNow[3] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 3}) + historyOfGetState[3] = getState(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 3}) + historyOfGetNow[3] = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 3}) - historyOfGetState[4] = getState(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 4}) - historyOfGetNow[4] = queryHistoryGetNow(t, network.Node, scAddress, core.OptionalUint64{HasValue: true, Value: 4}) + historyOfGetState[4] = getState(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 4}) + historyOfGetNow[4] = queryHistoryGetNow(t, network.ShardNode, scAddress, core.OptionalUint64{HasValue: true, Value: 4}) require.Equal(t, snapshotsOfGetState[1], historyOfGetState[1]) require.Equal(t, snapshotsOfGetNow[1].blockNonce, historyOfGetNow[1].blockNonce) - // This does not seem right! - require.Equal(t, block4.GetRootHash(), historyOfGetNow[1].stateRootHash) require.Equal(t, snapshotsOfGetState[2], historyOfGetState[2]) require.Equal(t, snapshotsOfGetNow[2].blockNonce, historyOfGetNow[2].blockNonce) - // This does not seem right! - require.Equal(t, block4.GetRootHash(), historyOfGetNow[2].stateRootHash) require.Equal(t, snapshotsOfGetState[3], historyOfGetState[3]) require.Equal(t, snapshotsOfGetNow[3].blockNonce, historyOfGetNow[3].blockNonce) - // This does not seem right! - require.Equal(t, block4.GetRootHash(), historyOfGetNow[3].stateRootHash) require.Equal(t, snapshotsOfGetState[4], historyOfGetState[4]) require.Equal(t, snapshotsOfGetNow[4].blockNonce, historyOfGetNow[4].blockNonce) - // This does not seem right! - require.Equal(t, block4.GetRootHash(), historyOfGetNow[4].stateRootHash) } -func deploy(network *integrationTests.OneNodeNetwork, sender []byte, codePath string, accountNonce *uint64) []byte { +func deploy(t *testing.T, network *integrationTests.MiniNetwork, sender []byte, codePath string) []byte { code := wasm.GetSCCode(codePath) data := fmt.Sprintf("%s@%s@0100", code, hex.EncodeToString(factory.WasmVirtualMachine)) - network.AddTxToPool(&transaction.Transaction{ - Nonce: *accountNonce, - Value: big.NewInt(0), - RcvAddr: vm.CreateEmptyAddress(), - SndAddr: sender, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(data), - }) - - *accountNonce++ - - scAddress, _ := network.Node.BlockchainHook.NewAddress(sender, 0, factory.WasmVirtualMachine) + _, err := network.SendTransaction( + sender, + make([]byte, 32), + big.NewInt(0), + data, + 1000, + ) + require.NoError(t, err) + scAddress, _ := network.ShardNode.BlockchainHook.NewAddress(sender, 0, factory.WasmVirtualMachine) return scAddress } -func setState(network *integrationTests.OneNodeNetwork, scAddress, sender []byte, value uint64, accountNonce *uint64) { +func setState(t *testing.T, network *integrationTests.MiniNetwork, scAddress []byte, sender []byte, value uint64) { data := fmt.Sprintf("setState@%x", value) - network.AddTxToPool(&transaction.Transaction{ - Nonce: *accountNonce, - Value: big.NewInt(0), - RcvAddr: scAddress, - SndAddr: sender, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(data), - }) + _, err := network.SendTransaction( + sender, + scAddress, + big.NewInt(0), + data, + 1000, + ) - *accountNonce++ + require.NoError(t, err) } func getState(t *testing.T, node *integrationTests.TestProcessorNode, scAddress []byte, blockNonce core.OptionalUint64) int { - scQuery := node.SCQueryService - vmOutput, _, err := scQuery.ExecuteQuery(&process.SCQuery{ + vmOutput, _, err := node.SCQueryService.ExecuteQuery(&process.SCQuery{ ScAddress: scAddress, FuncName: "getState", Arguments: [][]byte{}, @@ -187,8 +170,7 @@ func getState(t *testing.T, node *integrationTests.TestProcessorNode, scAddress } func queryHistoryGetNow(t *testing.T, node *integrationTests.TestProcessorNode, scAddress []byte, blockNonce core.OptionalUint64) now { - scQuery := node.SCQueryService - vmOutput, _, err := scQuery.ExecuteQuery(&process.SCQuery{ + vmOutput, _, err := node.SCQueryService.ExecuteQuery(&process.SCQuery{ ScAddress: scAddress, FuncName: "getNow", Arguments: [][]byte{}, @@ -204,3 +186,57 @@ func queryHistoryGetNow(t *testing.T, node *integrationTests.TestProcessorNode, stateRootHash: data[1], } } + +func TestQueries_Metachain(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + network := integrationTests.NewMiniNetwork() + defer network.Stop() + + network.Start() + + alice := network.AddUser(big.NewInt(10000000000000)) + issueCost := big.NewInt(1000) + tokenNameHex := hex.EncodeToString([]byte("Test")) + tokenTickerHex := hex.EncodeToString([]byte("TEST")) + txData := fmt.Sprintf("issue@%s@%s@64@00", tokenNameHex, tokenTickerHex) + + _, err := network.SendTransaction( + alice.Address, + vm.ESDTSCAddress, + issueCost, + txData, + core.MinMetaTxExtraGasCost, + ) + + require.NoError(t, err) + network.Continue(t, 5) + + tokens, err := network.MetachainNode.Node.GetAllIssuedESDTs(core.FungibleESDT, context.Background()) + require.NoError(t, err) + require.Len(t, tokens, 1) + + vmOutput, _, err := network.MetachainNode.SCQueryService.ExecuteQuery(&process.SCQuery{ + ScAddress: vm.ESDTSCAddress, + FuncName: "getTokenProperties", + Arguments: [][]byte{[]byte(tokens[0])}, + BlockNonce: core.OptionalUint64{HasValue: true, Value: 2}, + }) + + require.Nil(t, err) + require.Equal(t, vmcommon.UserError, vmOutput.ReturnCode) + require.Equal(t, "no ticker with given name", vmOutput.ReturnMessage) + + vmOutput, _, err = network.MetachainNode.SCQueryService.ExecuteQuery(&process.SCQuery{ + ScAddress: vm.ESDTSCAddress, + FuncName: "getTokenProperties", + Arguments: [][]byte{[]byte(tokens[0])}, + BlockNonce: core.OptionalUint64{HasValue: true, Value: 4}, + }) + + require.Nil(t, err) + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + require.Equal(t, "Test", string(vmOutput.ReturnData[0])) +} diff --git a/integrationTests/vm/wasm/upgrades/upgrades_test.go b/integrationTests/vm/wasm/upgrades/upgrades_test.go index c989498c955..866029191d5 100644 --- a/integrationTests/vm/wasm/upgrades/upgrades_test.go +++ b/integrationTests/vm/wasm/upgrades/upgrades_test.go @@ -10,9 +10,7 @@ import ( "math/big" "testing" - "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/integrationTests" - "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/factory" @@ -172,61 +170,53 @@ func TestUpgrades_HelloTrialAndError(t *testing.T) { t.Skip("this is not a short test") } - network := integrationTests.NewOneNodeNetwork() + network := integrationTests.NewMiniNetwork() defer network.Stop() - alice := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - bob := []byte("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") - network.Mint(alice, big.NewInt(10000000000000)) - network.Mint(bob, big.NewInt(10000000000000)) + alice := network.AddUser(big.NewInt(10000000000000)) + bob := network.AddUser(big.NewInt(10000000000000)) - network.GoToRoundOne() + network.Start() deployTxData := fmt.Sprintf("%s@%s@0100", wasm.GetSCCode("../testdata/hello-v1/output/answer.wasm"), hex.EncodeToString(factory.WasmVirtualMachine)) upgradeTxData := fmt.Sprintf("upgradeContract@%s@0100", wasm.GetSCCode("../testdata/hello-v2/output/answer.wasm")) // Deploy the smart contract. Alice is the owner - network.AddTxToPool(&transaction.Transaction{ - Nonce: 0, - Value: big.NewInt(0), - RcvAddr: vm.CreateEmptyAddress(), - SndAddr: alice, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(deployTxData), - }) - - scAddress, _ := network.Node.BlockchainHook.NewAddress(alice, 0, factory.WasmVirtualMachine) + network.SendTransaction( + alice.Address, + make([]byte, 32), + big.NewInt(0), + deployTxData, + 1000, + ) + + scAddress, _ := network.ShardNode.BlockchainHook.NewAddress(alice.Address, 0, factory.WasmVirtualMachine) network.Continue(t, 1) - require.Equal(t, []byte{24}, query(t, network.Node, scAddress, "getUltimateAnswer")) + require.Equal(t, []byte{24}, query(t, network.ShardNode, scAddress, "getUltimateAnswer")) // Upgrade as Bob - upgrade should fail, since Alice is the owner - network.AddTxToPool(&transaction.Transaction{ - Nonce: 0, - Value: big.NewInt(0), - RcvAddr: scAddress, - SndAddr: bob, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(upgradeTxData), - }) + network.SendTransaction( + bob.Address, + scAddress, + big.NewInt(0), + upgradeTxData, + 1000, + ) network.Continue(t, 1) - require.Equal(t, []byte{24}, query(t, network.Node, scAddress, "getUltimateAnswer")) + require.Equal(t, []byte{24}, query(t, network.ShardNode, scAddress, "getUltimateAnswer")) // Now upgrade as Alice, should work - network.AddTxToPool(&transaction.Transaction{ - Nonce: 1, - Value: big.NewInt(0), - RcvAddr: scAddress, - SndAddr: alice, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(upgradeTxData), - }) + network.SendTransaction( + alice.Address, + scAddress, + big.NewInt(0), + upgradeTxData, + 1000, + ) network.Continue(t, 1) - require.Equal(t, []byte{42}, query(t, network.Node, scAddress, "getUltimateAnswer")) + require.Equal(t, []byte{42}, query(t, network.ShardNode, scAddress, "getUltimateAnswer")) } func TestUpgrades_CounterTrialAndError(t *testing.T) { @@ -234,75 +224,65 @@ func TestUpgrades_CounterTrialAndError(t *testing.T) { t.Skip("this is not a short test") } - network := integrationTests.NewOneNodeNetwork() + network := integrationTests.NewMiniNetwork() defer network.Stop() - alice := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - bob := []byte("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") - network.Mint(alice, big.NewInt(10000000000000)) - network.Mint(bob, big.NewInt(10000000000000)) + alice := network.AddUser(big.NewInt(10000000000000)) + bob := network.AddUser(big.NewInt(10000000000000)) - network.GoToRoundOne() + network.Start() deployTxData := fmt.Sprintf("%s@%s@0100", wasm.GetSCCode("../testdata/counter/output/counter.wasm"), hex.EncodeToString(factory.WasmVirtualMachine)) upgradeTxData := fmt.Sprintf("upgradeContract@%s@0100", wasm.GetSCCode("../testdata/counter/output/counter.wasm")) // Deploy the smart contract. Alice is the owner - network.AddTxToPool(&transaction.Transaction{ - Nonce: 0, - Value: big.NewInt(0), - RcvAddr: vm.CreateEmptyAddress(), - SndAddr: alice, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(deployTxData), - }) - - scAddress, _ := network.Node.BlockchainHook.NewAddress(alice, 0, factory.WasmVirtualMachine) + network.SendTransaction( + alice.Address, + make([]byte, 32), + big.NewInt(0), + deployTxData, + 1000, + ) + + scAddress, _ := network.ShardNode.BlockchainHook.NewAddress(alice.Address, 0, factory.WasmVirtualMachine) network.Continue(t, 1) - require.Equal(t, []byte{1}, query(t, network.Node, scAddress, "get")) + require.Equal(t, []byte{1}, query(t, network.ShardNode, scAddress, "get")) // Increment the counter (could be either Bob or Alice) - network.AddTxToPool(&transaction.Transaction{ - Nonce: 1, - Value: big.NewInt(0), - RcvAddr: scAddress, - SndAddr: alice, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte("increment"), - }) + network.SendTransaction( + alice.Address, + scAddress, + big.NewInt(0), + "increment", + 1000, + ) network.Continue(t, 1) - require.Equal(t, []byte{2}, query(t, network.Node, scAddress, "get")) + require.Equal(t, []byte{2}, query(t, network.ShardNode, scAddress, "get")) // Upgrade as Bob - upgrade should fail, since Alice is the owner (counter.init() not executed, state not reset) - network.AddTxToPool(&transaction.Transaction{ - Nonce: 0, - Value: big.NewInt(0), - RcvAddr: scAddress, - SndAddr: bob, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(upgradeTxData), - }) + network.SendTransaction( + bob.Address, + scAddress, + big.NewInt(0), + upgradeTxData, + 1000, + ) network.Continue(t, 1) - require.Equal(t, []byte{2}, query(t, network.Node, scAddress, "get")) + require.Equal(t, []byte{2}, query(t, network.ShardNode, scAddress, "get")) // Now upgrade as Alice, should work (state is reset by counter.init()) - network.AddTxToPool(&transaction.Transaction{ - Nonce: 2, - Value: big.NewInt(0), - RcvAddr: scAddress, - SndAddr: alice, - GasPrice: network.GetMinGasPrice(), - GasLimit: network.MaxGasLimitPerBlock(), - Data: []byte(upgradeTxData), - }) + network.SendTransaction( + alice.Address, + scAddress, + big.NewInt(0), + upgradeTxData, + 1000, + ) network.Continue(t, 1) - require.Equal(t, []byte{1}, query(t, network.Node, scAddress, "get")) + require.Equal(t, []byte{1}, query(t, network.ShardNode, scAddress, "get")) } func query(t *testing.T, node *integrationTests.TestProcessorNode, scAddress []byte, function string) []byte { From 752b58af8a9cf521804a7c11cfdf8b8727a7010c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Feb 2024 22:09:56 +0200 Subject: [PATCH 795/958] Add unit test. --- factory/api/apiResolverFactory_test.go | 20 ++++++++++++++++++++ factory/api/export_test.go | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/factory/api/apiResolverFactory_test.go b/factory/api/apiResolverFactory_test.go index 591ea31b79f..ef1795d8a1a 100644 --- a/factory/api/apiResolverFactory_test.go +++ b/factory/api/apiResolverFactory_test.go @@ -1,6 +1,7 @@ package api_test import ( + "fmt" "strings" "sync" "testing" @@ -448,5 +449,24 @@ func TestCreateApiResolver_createScQueryElement(t *testing.T) { require.True(t, strings.Contains(strings.ToLower(err.Error()), "hasher")) require.Nil(t, scQueryService) }) +} + +func TestCreateApiResolver_createBlockchainForScQuery(t *testing.T) { + t.Parallel() + + t.Run("for metachain", func(t *testing.T) { + t.Parallel() + apiBlockchain, err := api.CreateBlockchainForScQuery(core.MetachainShardId) + require.NoError(t, err) + require.Equal(t, "*blockchain.metaChain", fmt.Sprintf("%T", apiBlockchain)) + }) + + t.Run("for shard", func(t *testing.T) { + t.Parallel() + + apiBlockchain, err := api.CreateBlockchainForScQuery(0) + require.NoError(t, err) + require.Equal(t, "*blockchain.blockChain", fmt.Sprintf("%T", apiBlockchain)) + }) } diff --git a/factory/api/export_test.go b/factory/api/export_test.go index 092ab83df50..13f42c575ac 100644 --- a/factory/api/export_test.go +++ b/factory/api/export_test.go @@ -2,6 +2,7 @@ package api import ( "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/process" @@ -47,3 +48,7 @@ func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, erro guardedAccountHandler: args.GuardedAccountHandler, }) } + +func CreateBlockchainForScQuery(selfShardID uint32) (data.ChainHandler, error) { + return createBlockchainForScQuery(selfShardID) +} From 7eac8b7e0ac1746a405a6ca5d3052075834e0858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Feb 2024 22:17:50 +0200 Subject: [PATCH 796/958] Add some comments. --- integrationTests/vm/wasm/queries/queries_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integrationTests/vm/wasm/queries/queries_test.go b/integrationTests/vm/wasm/queries/queries_test.go index 3c3af1e5283..7c51f04b325 100644 --- a/integrationTests/vm/wasm/queries/queries_test.go +++ b/integrationTests/vm/wasm/queries/queries_test.go @@ -198,6 +198,8 @@ func TestQueries_Metachain(t *testing.T) { network.Start() alice := network.AddUser(big.NewInt(10000000000000)) + + // Issue fungible token issueCost := big.NewInt(1000) tokenNameHex := hex.EncodeToString([]byte("Test")) tokenTickerHex := hex.EncodeToString([]byte("TEST")) @@ -218,6 +220,7 @@ func TestQueries_Metachain(t *testing.T) { require.NoError(t, err) require.Len(t, tokens, 1) + // Query token on older block (should fail) vmOutput, _, err := network.MetachainNode.SCQueryService.ExecuteQuery(&process.SCQuery{ ScAddress: vm.ESDTSCAddress, FuncName: "getTokenProperties", @@ -229,6 +232,7 @@ func TestQueries_Metachain(t *testing.T) { require.Equal(t, vmcommon.UserError, vmOutput.ReturnCode) require.Equal(t, "no ticker with given name", vmOutput.ReturnMessage) + // Query token on newer block (should succeed) vmOutput, _, err = network.MetachainNode.SCQueryService.ExecuteQuery(&process.SCQuery{ ScAddress: vm.ESDTSCAddress, FuncName: "getTokenProperties", From 6d62be014a206a277774ce85a83b13c473c3fbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 14 Feb 2024 13:39:42 +0200 Subject: [PATCH 797/958] Add test for "transferValueOnly" (async call and back transfer). --- .../transferValue/output/transferValue.wasm | Bin 0 -> 629 bytes .../testdata/transferValue/transferValue.c | 58 ++++++++++++++++++ .../transferValue/transferValue.export | 4 ++ .../vm/wasm/transfers/transfers_test.go | 36 +++++++++++ integrationTests/vm/wasm/utils.go | 41 +++++++++---- 5 files changed, 127 insertions(+), 12 deletions(-) create mode 100755 integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm create mode 100644 integrationTests/vm/wasm/testdata/transferValue/transferValue.c create mode 100644 integrationTests/vm/wasm/testdata/transferValue/transferValue.export create mode 100644 integrationTests/vm/wasm/transfers/transfers_test.go diff --git a/integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm b/integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm new file mode 100755 index 0000000000000000000000000000000000000000..a642c31d46b41a5f317955512515ba3197cb93b1 GIT binary patch literal 629 zcmchVJ5B>J5QfLz_aoV*r5Xc8kZ5SqJ2?UpCCajK-q}U_h?FK99z{wd4na#viNpms z2n9#L-c7^}7|XK$f5zj_vLVWs1OQ0K9FPj+B-OyJ_OaPWr7IyBy)iVAto*Sk zuKIj9%tW389ISq{SX@VoQUFm_5N9GP1kcw=tWrRg+bXgs$wwk)C#WKy-6m(fxfMJz)<188qFs)3)V!9GwIU=5AAj$%a53+n8PP!OHf~e`ZIZ*)&bNzC&0J1ck=fH@?Xg) RCQ&lSby{BFZCPNF!Y`XzjGq7i literal 0 HcmV?d00001 diff --git a/integrationTests/vm/wasm/testdata/transferValue/transferValue.c b/integrationTests/vm/wasm/testdata/transferValue/transferValue.c new file mode 100644 index 00000000000..bdbe9d35e0b --- /dev/null +++ b/integrationTests/vm/wasm/testdata/transferValue/transferValue.c @@ -0,0 +1,58 @@ +typedef unsigned char byte; +typedef unsigned int i32; +typedef unsigned long long i64; + +void getSCAddress(byte *address); +void getCaller(byte *callerAddress); +int transferValue(byte *destination, byte *value, byte *data, int length); +int getCallValue(byte *result); +void finish(byte *data, int length); +i32 createAsyncCall(byte *destination, byte *value, byte *data, int dataLength, byte *success, int successLength, byte *error, int errorLength, long long gas, long long extraGasForCallback); + +byte zero32_a[32] = {0}; +byte zero32_b[32] = {0}; +byte zero32_c[32] = {0}; + +byte functionNameEchoValue[] = "echoValue"; +byte strThankYouButNo[] = "thank you, but no"; + +void init() +{ +} + +void upgrade() +{ +} + +void receive() +{ + byte *selfAddress = zero32_a; + byte *callValue = zero32_b; + + getSCAddress(selfAddress); + getCallValue(callValue); + + createAsyncCall( + selfAddress, + callValue, + functionNameEchoValue, + sizeof(functionNameEchoValue) - 1, + 0, + 0, + 0, + 0, + 15000000, + 0); +} + +void echoValue() +{ + byte *selfAddress = zero32_a; + byte *callValue = zero32_b; + + getSCAddress(selfAddress); + getCallValue(callValue); + + transferValue(selfAddress, callValue, 0, 0); + finish(strThankYouButNo, sizeof(strThankYouButNo) - 1); +} diff --git a/integrationTests/vm/wasm/testdata/transferValue/transferValue.export b/integrationTests/vm/wasm/testdata/transferValue/transferValue.export new file mode 100644 index 00000000000..1609fee8812 --- /dev/null +++ b/integrationTests/vm/wasm/testdata/transferValue/transferValue.export @@ -0,0 +1,4 @@ +init +upgrade +receive +echoValue diff --git a/integrationTests/vm/wasm/transfers/transfers_test.go b/integrationTests/vm/wasm/transfers/transfers_test.go new file mode 100644 index 00000000000..4de3df27dfd --- /dev/null +++ b/integrationTests/vm/wasm/transfers/transfers_test.go @@ -0,0 +1,36 @@ +//go:build !race + +package transfers + +import ( + "math/big" + "testing" + + "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" + "github.com/stretchr/testify/require" +) + +func TestTransfers_DuplicatedTransferValueEvents(t *testing.T) { + context := wasm.SetupTestContext(t) + defer context.Close() + + err := context.DeploySC("../testdata/transferValue/output/transferValue.wasm", "") + require.Nil(t, err) + + err = context.ExecuteSCWithValue(&context.Owner, "receive", big.NewInt(1)) + require.Nil(t, err) + require.Len(t, context.LastLogs, 1) + require.Len(t, context.LastLogs[0].GetLogEvents(), 4) + + events := context.LastLogs[0].GetLogEvents() + + // There are duplicated events, to be fixed here: + // https://github.com/multiversx/mx-chain-go/pull/5936 + require.Equal(t, "transferValueOnly", string(events[0].GetIdentifier())) + require.Equal(t, "AsyncCall", string(events[0].GetData())) + require.Equal(t, []byte{0x01}, events[0].GetTopics()[0]) + + require.Equal(t, "transferValueOnly", string(events[1].GetIdentifier())) + require.Equal(t, "BackTransfer", string(events[1].GetData())) + require.Equal(t, []byte{0x01}, events[1].GetTopics()[0]) +} diff --git a/integrationTests/vm/wasm/utils.go b/integrationTests/vm/wasm/utils.go index e58d3e25c7b..2524bb86db8 100644 --- a/integrationTests/vm/wasm/utils.go +++ b/integrationTests/vm/wasm/utils.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/pubkeyConverter" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/rewardTx" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" @@ -102,6 +103,7 @@ type TestContext struct { ScAddress []byte ScCodeMetadata vmcommon.CodeMetadata Accounts *state.AccountsDB + TxLogsProcessor process.TransactionLogProcessor TxProcessor process.TransactionProcessor ScProcessor scrCommon.TestSmartContractProcessor QueryService external.SCQueryService @@ -112,6 +114,7 @@ type TestContext struct { LastTxHash []byte SCRForwarder *mock.IntermediateTransactionHandlerMock LastSCResults []*smartContractResult.SmartContractResult + LastLogs []*data.LogData } type testParticipant struct { @@ -364,8 +367,11 @@ func (context *TestContext) initTxProcessorWithOneSCExecutorWithVMs() { defaults.FillGasMapInternal(gasSchedule, 1) argsLogProcessor := transactionLog.ArgTxLogProcessor{Marshalizer: marshalizer} - logsProcessor, _ := transactionLog.NewTxLogProcessor(argsLogProcessor) + context.TxLogsProcessor, err = transactionLog.NewTxLogProcessor(argsLogProcessor) + require.Nil(context.T, err) + context.SCRForwarder = &mock.IntermediateTransactionHandlerMock{} + argsNewSCProcessor := scrCommon.ArgsNewSmartContractProcessor{ VmContainer: context.VMContainer, ArgsParser: smartContract.NewArgumentParser(), @@ -385,14 +391,14 @@ func (context *TestContext) initTxProcessorWithOneSCExecutorWithVMs() { SetGasRefundedCalled: func(gasRefunded uint64, hash []byte) {}, }, GasSchedule: mock.NewGasScheduleNotifierMock(gasSchedule), - TxLogsProcessor: logsProcessor, + TxLogsProcessor: context.TxLogsProcessor, EnableRoundsHandler: context.EnableRoundsHandler, EnableEpochsHandler: context.EnableEpochsHandler, WasmVMChangeLocker: context.WasmVMChangeLocker, VMOutputCacher: txcache.NewDisabledCache(), } - context.ScProcessor, _ = processProxy.NewTestSmartContractProcessorProxy(argsNewSCProcessor, context.EpochNotifier) + context.ScProcessor, err = processProxy.NewTestSmartContractProcessorProxy(argsNewSCProcessor, context.EpochNotifier) require.Nil(context.T, err) argsNewTxProcessor := processTransaction.ArgsNewTxProcessor{ @@ -414,7 +420,7 @@ func (context *TestContext) initTxProcessorWithOneSCExecutorWithVMs() { EnableEpochsHandler: context.EnableEpochsHandler, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, GuardianChecker: &guardianMocks.GuardedAccountHandlerStub{}, - TxLogsProcessor: logsProcessor, + TxLogsProcessor: context.TxLogsProcessor, } context.TxProcessor, err = processTransaction.NewTxProcessor(argsNewTxProcessor) @@ -550,12 +556,15 @@ func (context *TestContext) DeploySC(wasmPath string, parametersString string) e return err } - err = context.GetCompositeTestError() + err = context.acquireOutcome() if err != nil { return err } - _ = context.UpdateLastSCResults() + err = context.GetCompositeTestError() + if err != nil { + return err + } return nil } @@ -604,12 +613,15 @@ func (context *TestContext) UpgradeSC(wasmPath string, parametersString string) return err } - err = context.GetCompositeTestError() + err = context.acquireOutcome() if err != nil { return err } - _ = context.UpdateLastSCResults() + err = context.GetCompositeTestError() + if err != nil { + return err + } return nil } @@ -680,18 +692,21 @@ func (context *TestContext) ExecuteSCWithValue(sender *testParticipant, txData s return err } - err = context.GetCompositeTestError() + err = context.acquireOutcome() if err != nil { return err } - _ = context.UpdateLastSCResults() + err = context.GetCompositeTestError() + if err != nil { + return err + } return nil } -// UpdateLastSCResults -- -func (context *TestContext) UpdateLastSCResults() error { +// acquireOutcome -- +func (context *TestContext) acquireOutcome() error { transactions := context.SCRForwarder.GetIntermediateTransactions() context.LastSCResults = make([]*smartContractResult.SmartContractResult, len(transactions)) for i, tx := range transactions { @@ -703,6 +718,8 @@ func (context *TestContext) UpdateLastSCResults() error { } } + context.LastLogs = context.TxLogsProcessor.GetAllCurrentLogs() + return nil } From 828721b2d6f2e334d62f9d516860cb83828e0e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 14 Feb 2024 13:43:39 +0200 Subject: [PATCH 798/958] Fix after self review. --- .../transferValue/output/transferValue.wasm | Bin 629 -> 645 bytes .../wasm/testdata/transferValue/transferValue.c | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm b/integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm index a642c31d46b41a5f317955512515ba3197cb93b1..866fc287e8b6d32d04c476120f417c0bb4f10b6f 100755 GIT binary patch delta 101 zcmey$(#kr)m?@8KqNxK9XL@Rhb7D?TY7qmnL+Hulnj^rFO+R0ekTqSWNn%(7Gl z4$jo%jQp^~oYGVV&W*SE7#W) Date: Wed, 14 Feb 2024 14:10:00 +0200 Subject: [PATCH 799/958] Fix after review. --- .../vm/wasm/transfers/transfers_test.go | 14 +++++------ integrationTests/vm/wasm/utils.go | 23 ++++--------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/integrationTests/vm/wasm/transfers/transfers_test.go b/integrationTests/vm/wasm/transfers/transfers_test.go index 4de3df27dfd..3d94b10c95d 100644 --- a/integrationTests/vm/wasm/transfers/transfers_test.go +++ b/integrationTests/vm/wasm/transfers/transfers_test.go @@ -20,17 +20,17 @@ func TestTransfers_DuplicatedTransferValueEvents(t *testing.T) { err = context.ExecuteSCWithValue(&context.Owner, "receive", big.NewInt(1)) require.Nil(t, err) require.Len(t, context.LastLogs, 1) - require.Len(t, context.LastLogs[0].GetLogEvents(), 4) + require.Len(t, context.LastLogs[0].GetLogEvents(), 3) events := context.LastLogs[0].GetLogEvents() - // There are duplicated events, to be fixed here: - // https://github.com/multiversx/mx-chain-go/pull/5936 + // Duplicated "transferValueOnly" events are fixed in #5936. require.Equal(t, "transferValueOnly", string(events[0].GetIdentifier())) - require.Equal(t, "AsyncCall", string(events[0].GetData())) + require.Equal(t, "BackTransfer", string(events[0].GetData())) require.Equal(t, []byte{0x01}, events[0].GetTopics()[0]) - require.Equal(t, "transferValueOnly", string(events[1].GetIdentifier())) - require.Equal(t, "BackTransfer", string(events[1].GetData())) - require.Equal(t, []byte{0x01}, events[1].GetTopics()[0]) + require.Equal(t, "writeLog", string(events[1].GetIdentifier())) + require.Len(t, events[1].GetTopics(), 2) + require.Contains(t, string(events[1].GetTopics()[1]), "too much gas provided for processing") + require.Equal(t, "completedTxEvent", string(events[2].GetIdentifier())) } diff --git a/integrationTests/vm/wasm/utils.go b/integrationTests/vm/wasm/utils.go index 2524bb86db8..be94ca1993c 100644 --- a/integrationTests/vm/wasm/utils.go +++ b/integrationTests/vm/wasm/utils.go @@ -561,12 +561,7 @@ func (context *TestContext) DeploySC(wasmPath string, parametersString string) e return err } - err = context.GetCompositeTestError() - if err != nil { - return err - } - - return nil + return context.GetCompositeTestError() } // UpgradeSC - @@ -618,12 +613,7 @@ func (context *TestContext) UpgradeSC(wasmPath string, parametersString string) return err } - err = context.GetCompositeTestError() - if err != nil { - return err - } - - return nil + return context.GetCompositeTestError() } // GetSCCode - @@ -697,15 +687,10 @@ func (context *TestContext) ExecuteSCWithValue(sender *testParticipant, txData s return err } - err = context.GetCompositeTestError() - if err != nil { - return err - } - - return nil + return context.GetCompositeTestError() } -// acquireOutcome -- +// acquireOutcome - func (context *TestContext) acquireOutcome() error { transactions := context.SCRForwarder.GetIntermediateTransactions() context.LastSCResults = make([]*smartContractResult.SmartContractResult, len(transactions)) From 5a3ec4dab431c3b1a0f001a7a20a859ce9e46f0d Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 14 Feb 2024 14:28:11 +0200 Subject: [PATCH 800/958] - fixed linter issues --- factory/api/export_test.go | 1 + .../vm/wasm/upgrades/upgrades_test.go | 21 ++++++++++++------- .../consensusGroupProviderBench_test.go | 4 ---- ...dexHashedNodesCoordinatorWithRater_test.go | 4 ++-- trie/node_extension.go | 4 ++-- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/factory/api/export_test.go b/factory/api/export_test.go index 13f42c575ac..5a7948c9acb 100644 --- a/factory/api/export_test.go +++ b/factory/api/export_test.go @@ -49,6 +49,7 @@ func CreateScQueryElement(args SCQueryElementArgs) (process.SCQueryService, erro }) } +// CreateBlockchainForScQuery - func CreateBlockchainForScQuery(selfShardID uint32) (data.ChainHandler, error) { return createBlockchainForScQuery(selfShardID) } diff --git a/integrationTests/vm/wasm/upgrades/upgrades_test.go b/integrationTests/vm/wasm/upgrades/upgrades_test.go index 866029191d5..514507b0c04 100644 --- a/integrationTests/vm/wasm/upgrades/upgrades_test.go +++ b/integrationTests/vm/wasm/upgrades/upgrades_test.go @@ -182,38 +182,41 @@ func TestUpgrades_HelloTrialAndError(t *testing.T) { upgradeTxData := fmt.Sprintf("upgradeContract@%s@0100", wasm.GetSCCode("../testdata/hello-v2/output/answer.wasm")) // Deploy the smart contract. Alice is the owner - network.SendTransaction( + _, err := network.SendTransaction( alice.Address, make([]byte, 32), big.NewInt(0), deployTxData, 1000, ) + require.Nil(t, err) scAddress, _ := network.ShardNode.BlockchainHook.NewAddress(alice.Address, 0, factory.WasmVirtualMachine) network.Continue(t, 1) require.Equal(t, []byte{24}, query(t, network.ShardNode, scAddress, "getUltimateAnswer")) // Upgrade as Bob - upgrade should fail, since Alice is the owner - network.SendTransaction( + _, err = network.SendTransaction( bob.Address, scAddress, big.NewInt(0), upgradeTxData, 1000, ) + require.Nil(t, err) network.Continue(t, 1) require.Equal(t, []byte{24}, query(t, network.ShardNode, scAddress, "getUltimateAnswer")) // Now upgrade as Alice, should work - network.SendTransaction( + _, err = network.SendTransaction( alice.Address, scAddress, big.NewInt(0), upgradeTxData, 1000, ) + require.Nil(t, err) network.Continue(t, 1) require.Equal(t, []byte{42}, query(t, network.ShardNode, scAddress, "getUltimateAnswer")) @@ -236,50 +239,54 @@ func TestUpgrades_CounterTrialAndError(t *testing.T) { upgradeTxData := fmt.Sprintf("upgradeContract@%s@0100", wasm.GetSCCode("../testdata/counter/output/counter.wasm")) // Deploy the smart contract. Alice is the owner - network.SendTransaction( + _, err := network.SendTransaction( alice.Address, make([]byte, 32), big.NewInt(0), deployTxData, 1000, ) + require.Nil(t, err) scAddress, _ := network.ShardNode.BlockchainHook.NewAddress(alice.Address, 0, factory.WasmVirtualMachine) network.Continue(t, 1) require.Equal(t, []byte{1}, query(t, network.ShardNode, scAddress, "get")) // Increment the counter (could be either Bob or Alice) - network.SendTransaction( + _, err = network.SendTransaction( alice.Address, scAddress, big.NewInt(0), "increment", 1000, ) + require.Nil(t, err) network.Continue(t, 1) require.Equal(t, []byte{2}, query(t, network.ShardNode, scAddress, "get")) // Upgrade as Bob - upgrade should fail, since Alice is the owner (counter.init() not executed, state not reset) - network.SendTransaction( + _, err = network.SendTransaction( bob.Address, scAddress, big.NewInt(0), upgradeTxData, 1000, ) + require.Nil(t, err) network.Continue(t, 1) require.Equal(t, []byte{2}, query(t, network.ShardNode, scAddress, "get")) // Now upgrade as Alice, should work (state is reset by counter.init()) - network.SendTransaction( + _, err = network.SendTransaction( alice.Address, scAddress, big.NewInt(0), upgradeTxData, 1000, ) + require.Nil(t, err) network.Continue(t, 1) require.Equal(t, []byte{1}, query(t, network.ShardNode, scAddress, "get")) diff --git a/sharding/nodesCoordinator/consensusGroupProviderBench_test.go b/sharding/nodesCoordinator/consensusGroupProviderBench_test.go index c24f6f9549f..49731812213 100644 --- a/sharding/nodesCoordinator/consensusGroupProviderBench_test.go +++ b/sharding/nodesCoordinator/consensusGroupProviderBench_test.go @@ -1,11 +1,9 @@ package nodesCoordinator import ( - "math/rand" "testing" ) -const randSeed = 75 const numValidators = 63 const numValidatorsInEligibleList = 400 @@ -20,7 +18,6 @@ func getRandomness() []byte { func BenchmarkReslicingBasedProvider_Get(b *testing.B) { numVals := numValidators - rand.Seed(randSeed) expElList := getExpandedEligibleList(numValidatorsInEligibleList) randomness := getRandomness() @@ -32,7 +29,6 @@ func BenchmarkReslicingBasedProvider_Get(b *testing.B) { func BenchmarkSelectionBasedProvider_Get(b *testing.B) { numVals := numValidators - rand.Seed(randSeed) expElList := getExpandedEligibleList(numValidatorsInEligibleList) randomness := getRandomness() diff --git a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go index 5d276deaaed..d74c38e9b0b 100644 --- a/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go +++ b/sharding/nodesCoordinator/indexHashedNodesCoordinatorWithRater_test.go @@ -774,8 +774,8 @@ func BenchmarkIndexHashedGroupSelectorWithRater_TestExpandList(b *testing.B) { } //a := []int{1, 2, 3, 4, 5, 6, 7, 8} - rand.Seed(time.Now().UnixNano()) - rand.Shuffle(len(array), func(i, j int) { array[i], array[j] = array[j], array[i] }) + rnd := rand.New(rand.NewSource(time.Now().UnixNano())) + rnd.Shuffle(len(array), func(i, j int) { array[i], array[j] = array[j], array[i] }) m2 := runtime.MemStats{} runtime.ReadMemStats(&m2) diff --git a/trie/node_extension.go b/trie/node_extension.go index 4e7b38a6a7d..ffbdab699ad 100644 --- a/trie/node_extension.go +++ b/trie/node_extension.go @@ -26,8 +26,8 @@ func shouldTestNode(n node, key []byte) bool { } func snapshotGetTestPoint(key []byte, faultyChance int) error { - rand.Seed(time.Now().UnixNano()) - checkVal := rand.Intn(math.MaxInt) + rnd := rand.New(rand.NewSource(time.Now().UnixNano())) + checkVal := rnd.Intn(math.MaxInt) if checkVal%faultyChance == 0 { log.Debug("deliberately not returning hash", "hash", key) return fmt.Errorf("snapshot get error") From dd0eae18e887399f308ef75b221a20fc38c721e8 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 14 Feb 2024 16:31:04 +0200 Subject: [PATCH 801/958] added tests for chainSimulator processor --- node/chainSimulator/process/errors.go | 6 + node/chainSimulator/process/processor.go | 7 +- node/chainSimulator/process/processor_test.go | 631 ++++++++++++++++++ testscommon/headerHandlerStub.go | 80 ++- testscommon/roundHandlerMock.go | 20 +- .../shardingMocks/nodesCoordinatorStub.go | 4 +- 6 files changed, 720 insertions(+), 28 deletions(-) create mode 100644 node/chainSimulator/process/errors.go create mode 100644 node/chainSimulator/process/processor_test.go diff --git a/node/chainSimulator/process/errors.go b/node/chainSimulator/process/errors.go new file mode 100644 index 00000000000..eb1a69656e7 --- /dev/null +++ b/node/chainSimulator/process/errors.go @@ -0,0 +1,6 @@ +package process + +import "errors" + +// ErrNilNodeHandler signals that a nil node handler has been provided +var ErrNilNodeHandler = errors.New("nil node handler") diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index e47ccb92b50..bca5b6ac2a1 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -1,6 +1,7 @@ package process import ( + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus/spos" @@ -20,6 +21,10 @@ type blocksCreator struct { // NewBlocksCreator will create a new instance of blocksCreator func NewBlocksCreator(nodeHandler NodeHandler) (*blocksCreator, error) { + if check.IfNil(nodeHandler) { + return nil, ErrNilNodeHandler + } + return &blocksCreator{ nodeHandler: nodeHandler, }, nil @@ -70,7 +75,7 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } - headerCreationTime := creator.nodeHandler.GetProcessComponents().RoundHandler().TimeStamp() + headerCreationTime := creator.nodeHandler.GetCoreComponents().RoundHandler().TimeStamp() err = newHeader.SetTimeStamp(uint64(headerCreationTime.Unix())) if err != nil { return err diff --git a/node/chainSimulator/process/processor_test.go b/node/chainSimulator/process/processor_test.go new file mode 100644 index 00000000000..80ffd568134 --- /dev/null +++ b/node/chainSimulator/process/processor_test.go @@ -0,0 +1,631 @@ +package process_test + +import ( + "errors" + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-core-go/hashing" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/consensus" + mockConsensus "github.com/multiversx/mx-chain-go/consensus/mock" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/integrationTests/mock" + chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/chainSimulator" + testsConsensus "github.com/multiversx/mx-chain-go/testscommon/consensus" + testsFactory "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/stretchr/testify/require" +) + +var expectedErr = errors.New("expected error") + +func TestNewBlocksCreator(t *testing.T) { + t.Parallel() + + t.Run("nil node handler should error", func(t *testing.T) { + t.Parallel() + + creator, err := chainSimulatorProcess.NewBlocksCreator(nil) + require.Equal(t, chainSimulatorProcess.ErrNilNodeHandler, err) + require.Nil(t, creator) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + creator, err := chainSimulatorProcess.NewBlocksCreator(&chainSimulator.NodeHandlerMock{}) + require.NoError(t, err) + require.NotNil(t, creator) + }) +} + +func TestBlocksCreator_IsInterfaceNil(t *testing.T) { + t.Parallel() + + creator, _ := chainSimulatorProcess.NewBlocksCreator(nil) + require.True(t, creator.IsInterfaceNil()) + + creator, _ = chainSimulatorProcess.NewBlocksCreator(&chainSimulator.NodeHandlerMock{}) + require.False(t, creator.IsInterfaceNil()) +} + +func TestBlocksCreator_IncrementRound(t *testing.T) { + t.Parallel() + + wasIncrementIndexCalled := false + wasSetUInt64ValueCalled := false + nodeHandler := &chainSimulator.NodeHandlerMock{ + GetCoreComponentsCalled: func() factory.CoreComponentsHolder { + return &testsFactory.CoreComponentsHolderStub{ + RoundHandlerCalled: func() consensus.RoundHandler { + return &testscommon.RoundHandlerMock{ + IncrementIndexCalled: func() { + wasIncrementIndexCalled = true + }, + } + }, + } + }, + GetStatusCoreComponentsCalled: func() factory.StatusCoreComponentsHolder { + return &testsFactory.StatusCoreComponentsStub{ + AppStatusHandlerField: &statusHandler.AppStatusHandlerStub{ + SetUInt64ValueHandler: func(key string, value uint64) { + wasSetUInt64ValueCalled = true + require.Equal(t, common.MetricCurrentRound, key) + }, + }, + } + }, + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + creator.IncrementRound() + require.True(t, wasIncrementIndexCalled) + require.True(t, wasSetUInt64ValueCalled) +} + +func TestBlocksCreator_CreateNewBlock(t *testing.T) { + t.Parallel() + + t.Run("CreateNewHeader failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return nil, expectedErr + }, + } + nodeHandler := getNodeHandler() + nodeHandler.GetProcessComponentsCalled = func() factory.ProcessComponentsHolder { + return &mock.ProcessComponentsStub{ + BlockProcess: blockProcess, + } + } + nodeHandler.GetChainHandlerCalled = func() data.ChainHandler { + return &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.HeaderV2{} // coverage for getPreviousHeaderData + }, + } + } + + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("SetShardID failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetShardIDCalled: func(shardId uint32) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("SetPrevHash failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetPrevHashCalled: func(hash []byte) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("SetPrevRandSeed failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetPrevRandSeedCalled: func(seed []byte) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("SetPubKeysBitmap failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetPubKeysBitmapCalled: func(bitmap []byte) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("SetChainID failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetChainIDCalled: func(chainID []byte) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("SetTimeStamp failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetTimeStampCalled: func(timestamp uint64) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("ComputeConsensusGroup failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + nodeHandler.GetProcessComponentsCalled = func() factory.ProcessComponentsHolder { + return &mock.ProcessComponentsStub{ + BlockProcess: &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + }, + NodesCoord: &shardingMocks.NodesCoordinatorStub{ + ComputeConsensusGroupCalled: func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + return nil, expectedErr + }, + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("key not managed by the current node should return nil", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + nodeHandler.GetCryptoComponentsCalled = func() factory.CryptoComponentsHolder { + return &mock.CryptoComponentsStub{ + KeysHandlerField: &testscommon.KeysHandlerStub{ + IsKeyManagedByCurrentNodeCalled: func(pkBytes []byte) bool { + return false + }, + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.NoError(t, err) + }) + t.Run("CreateSignatureForPublicKey failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + kh := nodeHandler.GetCryptoComponents().KeysHandler() + nodeHandler.GetCryptoComponentsCalled = func() factory.CryptoComponentsHolder { + return &mock.CryptoComponentsStub{ + KeysHandlerField: kh, + SigHandler: &testsConsensus.SigningHandlerStub{ + CreateSignatureForPublicKeyCalled: func(message []byte, publicKeyBytes []byte) ([]byte, error) { + return nil, expectedErr + }, + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("SetRandSeed failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + SetRandSeedCalled: func(seed []byte) error { + return expectedErr + }, + }, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("CreateBlock failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return nil, nil, expectedErr + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("setHeaderSignatures.Marshal failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + rh := nodeHandler.GetCoreComponents().RoundHandler() + nodeHandler.GetCoreComponentsCalled = func() factory.CoreComponentsHolder { + return &testsFactory.CoreComponentsHolderStub{ + RoundHandlerCalled: func() consensus.RoundHandler { + return rh + }, + InternalMarshalizerCalled: func() marshal.Marshalizer { + return &testscommon.MarshallerStub{ + MarshalCalled: func(obj interface{}) ([]byte, error) { + return nil, expectedErr + }, + } + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("setHeaderSignatures.Reset failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + kh := nodeHandler.GetCryptoComponents().KeysHandler() + nodeHandler.GetCryptoComponentsCalled = func() factory.CryptoComponentsHolder { + return &mock.CryptoComponentsStub{ + KeysHandlerField: kh, + SigHandler: &testsConsensus.SigningHandlerStub{ + ResetCalled: func(pubKeys []string) error { + return expectedErr + }, + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("setHeaderSignatures.CreateSignatureShareForPublicKey failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + kh := nodeHandler.GetCryptoComponents().KeysHandler() + nodeHandler.GetCryptoComponentsCalled = func() factory.CryptoComponentsHolder { + return &mock.CryptoComponentsStub{ + KeysHandlerField: kh, + SigHandler: &testsConsensus.SigningHandlerStub{ + CreateSignatureShareForPublicKeyCalled: func(message []byte, index uint16, epoch uint32, publicKeyBytes []byte) ([]byte, error) { + return nil, expectedErr + }, + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("setHeaderSignatures.AggregateSigs failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + kh := nodeHandler.GetCryptoComponents().KeysHandler() + nodeHandler.GetCryptoComponentsCalled = func() factory.CryptoComponentsHolder { + return &mock.CryptoComponentsStub{ + KeysHandlerField: kh, + SigHandler: &testsConsensus.SigningHandlerStub{ + AggregateSigsCalled: func(bitmap []byte, epoch uint32) ([]byte, error) { + return nil, expectedErr + }, + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("setHeaderSignatures.SetSignature failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{} + }, + SetSignatureCalled: func(signature []byte) error { + return expectedErr + }, + }, &block.Body{}, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("createLeaderSignature.SetLeaderSignature failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{ + SetLeaderSignatureCalled: func(signature []byte) error { + return expectedErr + }, + } + }, + }, &block.Body{}, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("createLeaderSignature.SetLeaderSignature failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{ + SetLeaderSignatureCalled: func(signature []byte) error { + return expectedErr + }, + } + }, + }, &block.Body{}, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("setHeaderSignatures.SetLeaderSignature failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{} + }, + SetLeaderSignatureCalled: func(signature []byte) error { + return expectedErr + }, + }, &block.Body{}, nil + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("CommitBlock failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{} + }, + }, &block.Body{}, nil + }, + CommitBlockCalled: func(header data.HeaderHandler, body data.BodyHandler) error { + return expectedErr + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("MarshalizedDataToBroadcast failure should error", func(t *testing.T) { + t.Parallel() + + blockProcess := &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{} + }, + }, &block.Body{}, nil + }, + MarshalizedDataToBroadcastCalled: func(header data.HeaderHandler, body data.BodyHandler) (map[uint32][]byte, map[string][][]byte, error) { + return nil, nil, expectedErr + }, + } + testCreateNewBlock(t, blockProcess, expectedErr) + }) + t.Run("BroadcastHeader failure should error", func(t *testing.T) { + t.Parallel() + + nodeHandler := getNodeHandler() + nodeHandler.GetBroadcastMessengerCalled = func() consensus.BroadcastMessenger { + return &mockConsensus.BroadcastMessengerMock{ + BroadcastHeaderCalled: func(handler data.HeaderHandler, bytes []byte) error { + return expectedErr + }, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + creator, err := chainSimulatorProcess.NewBlocksCreator(getNodeHandler()) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.NoError(t, err) + }) +} + +func testCreateNewBlock(t *testing.T, blockProcess process.BlockProcessor, expectedErr error) { + nodeHandler := getNodeHandler() + nc := nodeHandler.GetProcessComponents().NodesCoordinator() + nodeHandler.GetProcessComponentsCalled = func() factory.ProcessComponentsHolder { + return &mock.ProcessComponentsStub{ + BlockProcess: blockProcess, + NodesCoord: nc, + } + } + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + require.NoError(t, err) + + err = creator.CreateNewBlock() + require.Equal(t, expectedErr, err) +} + +func getNodeHandler() *chainSimulator.NodeHandlerMock { + return &chainSimulator.NodeHandlerMock{ + GetCoreComponentsCalled: func() factory.CoreComponentsHolder { + return &testsFactory.CoreComponentsHolderStub{ + RoundHandlerCalled: func() consensus.RoundHandler { + return &testscommon.RoundHandlerMock{ + TimeStampCalled: func() time.Time { + return time.Now() + }, + } + }, + InternalMarshalizerCalled: func() marshal.Marshalizer { + return &testscommon.MarshallerStub{} + }, + HasherCalled: func() hashing.Hasher { + return &testscommon.HasherStub{ + ComputeCalled: func(s string) []byte { + return []byte("hash") + }, + } + }, + } + }, + GetProcessComponentsCalled: func() factory.ProcessComponentsHolder { + return &mock.ProcessComponentsStub{ + BlockProcess: &testscommon.BlockProcessorStub{ + CreateNewHeaderCalled: func(round uint64, nonce uint64) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{}, nil + }, + CreateBlockCalled: func(initialHdrData data.HeaderHandler, haveTime func() bool) (data.HeaderHandler, data.BodyHandler, error) { + haveTime() // coverage only + return &testscommon.HeaderHandlerStub{ + CloneCalled: func() data.HeaderHandler { + return &testscommon.HeaderHandlerStub{} + }, + }, &block.Body{}, nil + }, + MarshalizedDataToBroadcastCalled: func(header data.HeaderHandler, body data.BodyHandler) (map[uint32][]byte, map[string][][]byte, error) { + return make(map[uint32][]byte), make(map[string][][]byte), nil + }, + }, + NodesCoord: &shardingMocks.NodesCoordinatorStub{ + ComputeConsensusGroupCalled: func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validatorsGroup []nodesCoordinator.Validator, err error) { + return []nodesCoordinator.Validator{ + shardingMocks.NewValidatorMock([]byte("A"), 1, 1), + }, nil + }, + }, + } + }, + GetChainHandlerCalled: func() data.ChainHandler { + return &testscommon.ChainHandlerStub{ + GetGenesisHeaderCalled: func() data.HeaderHandler { + return &block.HeaderV2{} + }, + } + }, + GetShardCoordinatorCalled: func() sharding.Coordinator { + return &testscommon.ShardsCoordinatorMock{} + }, + GetCryptoComponentsCalled: func() factory.CryptoComponentsHolder { + return &mock.CryptoComponentsStub{ + KeysHandlerField: &testscommon.KeysHandlerStub{ + IsKeyManagedByCurrentNodeCalled: func(pkBytes []byte) bool { + return true + }, + }, + SigHandler: &testsConsensus.SigningHandlerStub{}, + } + }, + GetBroadcastMessengerCalled: func() consensus.BroadcastMessenger { + return &mockConsensus.BroadcastMessengerMock{} + }, + } +} diff --git a/testscommon/headerHandlerStub.go b/testscommon/headerHandlerStub.go index 7bbd8d2883e..773a1f7413d 100644 --- a/testscommon/headerHandlerStub.go +++ b/testscommon/headerHandlerStub.go @@ -28,6 +28,15 @@ type HeaderHandlerStub struct { HasScheduledMiniBlocksCalled func() bool GetNonceCalled func() uint64 CheckFieldsForNilCalled func() error + SetShardIDCalled func(shardID uint32) error + SetPrevHashCalled func(hash []byte) error + SetPrevRandSeedCalled func(seed []byte) error + SetPubKeysBitmapCalled func(bitmap []byte) error + SetChainIDCalled func(chainID []byte) error + SetTimeStampCalled func(timestamp uint64) error + SetRandSeedCalled func(seed []byte) error + SetSignatureCalled func(signature []byte) error + SetLeaderSignatureCalled func(signature []byte) error } // GetAccumulatedFees - @@ -56,7 +65,10 @@ func (hhs *HeaderHandlerStub) GetReceiptsHash() []byte { } // SetShardID - -func (hhs *HeaderHandlerStub) SetShardID(_ uint32) error { +func (hhs *HeaderHandlerStub) SetShardID(shardID uint32) error { + if hhs.SetShardIDCalled != nil { + return hhs.SetShardIDCalled(shardID) + } return nil } @@ -114,7 +126,10 @@ func (hhs *HeaderHandlerStub) GetPrevHash() []byte { // GetPrevRandSeed - func (hhs *HeaderHandlerStub) GetPrevRandSeed() []byte { - return hhs.GetPrevRandSeedCalled() + if hhs.GetPrevRandSeedCalled != nil { + return hhs.GetPrevRandSeedCalled() + } + return make([]byte, 0) } // GetRandSeed - @@ -124,7 +139,10 @@ func (hhs *HeaderHandlerStub) GetRandSeed() []byte { // GetPubKeysBitmap - func (hhs *HeaderHandlerStub) GetPubKeysBitmap() []byte { - return hhs.GetPubKeysBitmapCalled() + if hhs.GetPubKeysBitmapCalled != nil { + return hhs.GetPubKeysBitmapCalled() + } + return make([]byte, 0) } // GetSignature - @@ -172,8 +190,11 @@ func (hhs *HeaderHandlerStub) SetRound(_ uint64) error { } // SetTimeStamp - -func (hhs *HeaderHandlerStub) SetTimeStamp(_ uint64) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetTimeStamp(timestamp uint64) error { + if hhs.SetTimeStampCalled != nil { + return hhs.SetTimeStampCalled(timestamp) + } + return nil } // SetRootHash - @@ -182,38 +203,59 @@ func (hhs *HeaderHandlerStub) SetRootHash(_ []byte) error { } // SetPrevHash - -func (hhs *HeaderHandlerStub) SetPrevHash(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetPrevHash(hash []byte) error { + if hhs.SetPrevHashCalled != nil { + return hhs.SetPrevHashCalled(hash) + } + return nil } // SetPrevRandSeed - -func (hhs *HeaderHandlerStub) SetPrevRandSeed(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetPrevRandSeed(seed []byte) error { + if hhs.SetPrevRandSeedCalled != nil { + return hhs.SetPrevRandSeedCalled(seed) + } + return nil } // SetRandSeed - -func (hhs *HeaderHandlerStub) SetRandSeed(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetRandSeed(seed []byte) error { + if hhs.SetRandSeedCalled != nil { + return hhs.SetRandSeedCalled(seed) + } + return nil } // SetPubKeysBitmap - -func (hhs *HeaderHandlerStub) SetPubKeysBitmap(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetPubKeysBitmap(bitmap []byte) error { + if hhs.SetPubKeysBitmapCalled != nil { + return hhs.SetPubKeysBitmapCalled(bitmap) + } + return nil } // SetSignature - -func (hhs *HeaderHandlerStub) SetSignature(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetSignature(signature []byte) error { + if hhs.SetSignatureCalled != nil { + return hhs.SetSignatureCalled(signature) + } + return nil } // SetLeaderSignature - -func (hhs *HeaderHandlerStub) SetLeaderSignature(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetLeaderSignature(signature []byte) error { + if hhs.SetLeaderSignatureCalled != nil { + return hhs.SetLeaderSignatureCalled(signature) + } + return nil } // SetChainID - -func (hhs *HeaderHandlerStub) SetChainID(_ []byte) error { - panic("implement me") +func (hhs *HeaderHandlerStub) SetChainID(chainID []byte) error { + if hhs.SetChainIDCalled != nil { + return hhs.SetChainIDCalled(chainID) + } + return nil } // SetTxCount - diff --git a/testscommon/roundHandlerMock.go b/testscommon/roundHandlerMock.go index 976e8a55181..6c5d45cc7bc 100644 --- a/testscommon/roundHandlerMock.go +++ b/testscommon/roundHandlerMock.go @@ -10,12 +10,13 @@ type RoundHandlerMock struct { indexMut sync.RWMutex index int64 - IndexCalled func() int64 - TimeDurationCalled func() time.Duration - TimeStampCalled func() time.Time - UpdateRoundCalled func(time.Time, time.Time) - RemainingTimeCalled func(startTime time.Time, maxTime time.Duration) time.Duration - BeforeGenesisCalled func() bool + IndexCalled func() int64 + TimeDurationCalled func() time.Duration + TimeStampCalled func() time.Time + UpdateRoundCalled func(time.Time, time.Time) + RemainingTimeCalled func(startTime time.Time, maxTime time.Duration) time.Duration + BeforeGenesisCalled func() bool + IncrementIndexCalled func() } // BeforeGenesis - @@ -77,6 +78,13 @@ func (rndm *RoundHandlerMock) RemainingTime(startTime time.Time, maxTime time.Du return 4000 * time.Millisecond } +// IncrementIndex - +func (rndm *RoundHandlerMock) IncrementIndex() { + if rndm.IncrementIndexCalled != nil { + rndm.IncrementIndexCalled() + } +} + // IsInterfaceNil returns true if there is no value under the interface func (rndm *RoundHandlerMock) IsInterfaceNil() bool { return rndm == nil diff --git a/testscommon/shardingMocks/nodesCoordinatorStub.go b/testscommon/shardingMocks/nodesCoordinatorStub.go index a9d3aecf380..0666b8f15df 100644 --- a/testscommon/shardingMocks/nodesCoordinatorStub.go +++ b/testscommon/shardingMocks/nodesCoordinatorStub.go @@ -103,8 +103,8 @@ func (ncm *NodesCoordinatorStub) ComputeConsensusGroup( shardId uint32, epoch uint32, ) (validatorsGroup []nodesCoordinator.Validator, err error) { - if ncm.ComputeValidatorsGroupCalled != nil { - return ncm.ComputeValidatorsGroupCalled(randomness, round, shardId, epoch) + if ncm.ComputeConsensusGroupCalled != nil { + return ncm.ComputeConsensusGroupCalled(randomness, round, shardId, epoch) } var list []nodesCoordinator.Validator From bb5d6370a0634cdeb4c42b2f1d728080e76503f5 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 14 Feb 2024 17:18:24 +0200 Subject: [PATCH 802/958] added missing file --- testscommon/chainSimulator/nodeHandlerMock.go | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 testscommon/chainSimulator/nodeHandlerMock.go diff --git a/testscommon/chainSimulator/nodeHandlerMock.go b/testscommon/chainSimulator/nodeHandlerMock.go new file mode 100644 index 00000000000..23941f914eb --- /dev/null +++ b/testscommon/chainSimulator/nodeHandlerMock.go @@ -0,0 +1,127 @@ +package chainSimulator + +import ( + chainData "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/api/shared" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + "github.com/multiversx/mx-chain-go/sharding" +) + +// NodeHandlerMock - +type NodeHandlerMock struct { + GetProcessComponentsCalled func() factory.ProcessComponentsHolder + GetChainHandlerCalled func() chainData.ChainHandler + GetBroadcastMessengerCalled func() consensus.BroadcastMessenger + GetShardCoordinatorCalled func() sharding.Coordinator + GetCryptoComponentsCalled func() factory.CryptoComponentsHolder + GetCoreComponentsCalled func() factory.CoreComponentsHolder + GetStateComponentsCalled func() factory.StateComponentsHolder + GetFacadeHandlerCalled func() shared.FacadeHandler + GetStatusCoreComponentsCalled func() factory.StatusCoreComponentsHolder + SetKeyValueForAddressCalled func(addressBytes []byte, state map[string]string) error + SetStateForAddressCalled func(address []byte, state *dtos.AddressState) error + CloseCalled func() error +} + +// GetProcessComponents - +func (mock *NodeHandlerMock) GetProcessComponents() factory.ProcessComponentsHolder { + if mock.GetProcessComponentsCalled != nil { + return mock.GetProcessComponentsCalled() + } + return nil +} + +// GetChainHandler - +func (mock *NodeHandlerMock) GetChainHandler() chainData.ChainHandler { + if mock.GetChainHandlerCalled != nil { + return mock.GetChainHandlerCalled() + } + return nil +} + +// GetBroadcastMessenger - +func (mock *NodeHandlerMock) GetBroadcastMessenger() consensus.BroadcastMessenger { + if mock.GetBroadcastMessengerCalled != nil { + return mock.GetBroadcastMessengerCalled() + } + return nil +} + +// GetShardCoordinator - +func (mock *NodeHandlerMock) GetShardCoordinator() sharding.Coordinator { + if mock.GetShardCoordinatorCalled != nil { + return mock.GetShardCoordinatorCalled() + } + return nil +} + +// GetCryptoComponents - +func (mock *NodeHandlerMock) GetCryptoComponents() factory.CryptoComponentsHolder { + if mock.GetCryptoComponentsCalled != nil { + return mock.GetCryptoComponentsCalled() + } + return nil +} + +// GetCoreComponents - +func (mock *NodeHandlerMock) GetCoreComponents() factory.CoreComponentsHolder { + if mock.GetCoreComponentsCalled != nil { + return mock.GetCoreComponentsCalled() + } + return nil +} + +// GetStateComponents - +func (mock *NodeHandlerMock) GetStateComponents() factory.StateComponentsHolder { + if mock.GetStateComponentsCalled != nil { + return mock.GetStateComponentsCalled() + } + return nil +} + +// GetFacadeHandler - +func (mock *NodeHandlerMock) GetFacadeHandler() shared.FacadeHandler { + if mock.GetFacadeHandlerCalled != nil { + return mock.GetFacadeHandlerCalled() + } + return nil +} + +// GetStatusCoreComponents - +func (mock *NodeHandlerMock) GetStatusCoreComponents() factory.StatusCoreComponentsHolder { + if mock.GetStatusCoreComponentsCalled != nil { + return mock.GetStatusCoreComponentsCalled() + } + return nil +} + +// SetKeyValueForAddress - +func (mock *NodeHandlerMock) SetKeyValueForAddress(addressBytes []byte, state map[string]string) error { + if mock.SetKeyValueForAddressCalled != nil { + return mock.SetKeyValueForAddressCalled(addressBytes, state) + } + return nil +} + +// SetStateForAddress - +func (mock *NodeHandlerMock) SetStateForAddress(address []byte, state *dtos.AddressState) error { + if mock.SetStateForAddressCalled != nil { + return mock.SetStateForAddressCalled(address, state) + } + return nil +} + +// Close - +func (mock *NodeHandlerMock) Close() error { + if mock.CloseCalled != nil { + return mock.CloseCalled() + } + return nil +} + +// IsInterfaceNil - +func (mock *NodeHandlerMock) IsInterfaceNil() bool { + return mock == nil +} From 98d49f4624fb441d90690c58967519163f3c92a4 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 15 Feb 2024 10:39:01 +0200 Subject: [PATCH 803/958] fixes after review --- .../transactionEvaluator.go | 14 ++++++++++--- .../transactionEvaluator_test.go | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/process/transactionEvaluator/transactionEvaluator.go b/process/transactionEvaluator/transactionEvaluator.go index 56077c0a498..9e61d138419 100644 --- a/process/transactionEvaluator/transactionEvaluator.go +++ b/process/transactionEvaluator/transactionEvaluator.go @@ -98,7 +98,7 @@ func (ate *apiTransactionEvaluator) SimulateTransactionExecution(tx *transaction ate.mutExecution.Unlock() }() - currentHeader := ate.blockChain.GetCurrentBlockHeader() + currentHeader := ate.getCurrentBlockHeader() return ate.txSimulator.ProcessTx(tx, currentHeader) } @@ -149,8 +149,7 @@ func (ate *apiTransactionEvaluator) simulateTransactionCost(tx *transaction.Tran } costResponse := &transaction.CostResponse{} - currentHeader := ate.blockChain.GetCurrentBlockHeader() - + currentHeader := ate.getCurrentBlockHeader() res, err := ate.txSimulator.ProcessTx(tx, currentHeader) if err != nil { costResponse.ReturnMessage = err.Error() @@ -238,6 +237,15 @@ func (ate *apiTransactionEvaluator) addMissingFieldsIfNeeded(tx *transaction.Tra return nil } +func (ate *apiTransactionEvaluator) getCurrentBlockHeader() data.HeaderHandler { + currentHeader := ate.blockChain.GetCurrentBlockHeader() + if check.IfNil(currentHeader) { + return ate.blockChain.GetGenesisHeader() + } + + return currentHeader +} + func (ate *apiTransactionEvaluator) getTxGasLimit(tx *transaction.Transaction) (uint64, error) { selfShardID := ate.shardCoordinator.SelfId() maxGasLimitPerBlock := ate.feeHandler.MaxGasLimitPerBlock(selfShardID) - 1 diff --git a/process/transactionEvaluator/transactionEvaluator_test.go b/process/transactionEvaluator/transactionEvaluator_test.go index ea8f01049b7..f36a5388777 100644 --- a/process/transactionEvaluator/transactionEvaluator_test.go +++ b/process/transactionEvaluator/transactionEvaluator_test.go @@ -407,3 +407,23 @@ func TestApiTransactionEvaluator_ComputeTransactionGasLimit(t *testing.T) { require.Nil(t, err) require.True(t, called) } + +func TestApiTransactionEvaluator_GetCurrentHeader(t *testing.T) { + t.Parallel() + + args := createArgs() + args.BlockChain = &testscommon.ChainHandlerMock{} + _ = args.BlockChain.SetGenesisHeader(&block.Header{Nonce: 0}) + + tce, err := NewAPITransactionEvaluator(args) + require.Nil(t, err) + + currentHeader := tce.getCurrentBlockHeader() + require.Equal(t, uint64(0), currentHeader.GetNonce()) + + expectedNonce := uint64(100) + _ = args.BlockChain.SetCurrentBlockHeaderAndRootHash(&block.Header{Nonce: expectedNonce}, []byte("root")) + + currentHeader = tce.getCurrentBlockHeader() + require.Equal(t, expectedNonce, currentHeader.GetNonce()) +} From acef8ffc11393a40d99fe83852dd5d67156ba849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 11:36:15 +0200 Subject: [PATCH 804/958] Fix contract to test for duplicated events. --- .../transferValue/output/transferValue.wasm | Bin 645 -> 619 bytes .../testdata/transferValue/transferValue.c | 46 +++++++++--------- .../transferValue/transferValue.export | 6 ++- .../vm/wasm/transfers/transfers_test.go | 44 +++++++++++++---- integrationTests/vm/wasm/utils.go | 4 +- 5 files changed, 65 insertions(+), 35 deletions(-) diff --git a/integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm b/integrationTests/vm/wasm/testdata/transferValue/output/transferValue.wasm index 866fc287e8b6d32d04c476120f417c0bb4f10b6f..cea133a3b2ffcfa799e926da9233c1f70628aeb7 100755 GIT binary patch literal 619 zcmb7?zfL1D5XQ&$?%MkYHpNv`V?n_Kplhx&=sK=L)G>(@L9!d<>;h@lIcVtb1!yRE z2qdI?k$aT0H{^5`5}##h=JUw&^T?o=6#)Qp7!Rp)#0@j|uCDVLaWE9lb-m|v0D2ZN zQ{UuM(k=ULZjYBtbwjlN9MeZ>qP)aKw-z z`$`L>hqRE90vThB(V(x{+qj8$xq9mBg%UDVFMXV;OyNGvSfO&>z=s~64ZSJAu_K$I24nTQI(^Hmb76j0?lvR5gQHI1zzi;{dOvZhm0HRf=V zO!6`4nxPviGy>GLB_IFZ>YjCOmoYg!#|WB>ymGJ=3)#wgO0+T^cWmC}%+)}=oGtfelc-laCu4)vLV zMpzdsX)_be@Ky~xY|>U^+k8{^I^1C{2j*S8e>_{vzW~-k3vG1JMQ``{*b49J8Iq|j zcWX~sfI-6)crS#s|AYEoZSe;+FlUG7gbxkUQ+*JZA23fbhmXpZpuPn4r}8+hJ*am| cfNyN?==TcbJCjk2qhyAwv^>M>vcM#TANjkHp#T5? diff --git a/integrationTests/vm/wasm/testdata/transferValue/transferValue.c b/integrationTests/vm/wasm/testdata/transferValue/transferValue.c index cb9fe07c70f..e82fc4054d8 100644 --- a/integrationTests/vm/wasm/testdata/transferValue/transferValue.c +++ b/integrationTests/vm/wasm/testdata/transferValue/transferValue.c @@ -2,19 +2,18 @@ typedef unsigned char byte; typedef unsigned int i32; typedef unsigned long long i64; -void getSCAddress(byte *address); -int transferValue(byte *destination, byte *value, byte *data, int length); +int getArgument(int argumentIndex, byte *argument); +int transferValueExecute(byte *destination, byte *value, long long gas, byte *function, int functionLength, int numArguments, byte *argumentsLengths, byte *arguments); void getCaller(byte *callerAddress); -int getCallValue(byte *result); i32 createAsyncCall(byte *destination, byte *value, byte *data, int dataLength, byte *success, int successLength, byte *error, int errorLength, long long gas, long long extraGasForCallback); -void finish(byte *data, int length); byte zero32_a[32] = {0}; byte zero32_b[32] = {0}; byte zero32_c[32] = {0}; -byte functionNameEchoValue[] = "echoValue"; -byte strThankYouButNo[] = "thank you, but no"; +byte oneAtomOfEGLD[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; +byte functionNameAskMoney[] = "askMoney"; +byte functionNameMyCallback[] = "myCallback"; void init() { @@ -24,35 +23,36 @@ void upgrade() { } -void receive() +void fund() { - byte *selfAddress = zero32_a; - byte *callValue = zero32_b; +} - getSCAddress(selfAddress); - getCallValue(callValue); +void forwardAskMoney() +{ + byte *otherContract = zero32_a; + getArgument(0, otherContract); createAsyncCall( - selfAddress, - callValue, - functionNameEchoValue, - sizeof(functionNameEchoValue) - 1, - 0, - 0, - 0, + otherContract, 0, + functionNameAskMoney, + sizeof(functionNameAskMoney) - 1, + functionNameMyCallback, + sizeof(functionNameMyCallback) - 1, + functionNameMyCallback, + sizeof(functionNameMyCallback) - 1, 15000000, 0); } -void echoValue() +void askMoney() { byte *caller = zero32_a; - byte *callValue = zero32_b; getCaller(caller); - getCallValue(callValue); + transferValueExecute(caller, oneAtomOfEGLD, 0, 0, 0, 0, 0, 0); +} - transferValue(caller, callValue, 0, 0); - finish(strThankYouButNo, sizeof(strThankYouButNo) - 1); +void myCallback() +{ } diff --git a/integrationTests/vm/wasm/testdata/transferValue/transferValue.export b/integrationTests/vm/wasm/testdata/transferValue/transferValue.export index 1609fee8812..c9613a09af3 100644 --- a/integrationTests/vm/wasm/testdata/transferValue/transferValue.export +++ b/integrationTests/vm/wasm/testdata/transferValue/transferValue.export @@ -1,4 +1,6 @@ init upgrade -receive -echoValue +fund +forwardAskMoney +askMoney +myCallback diff --git a/integrationTests/vm/wasm/transfers/transfers_test.go b/integrationTests/vm/wasm/transfers/transfers_test.go index 3d94b10c95d..1a40caa67f0 100644 --- a/integrationTests/vm/wasm/transfers/transfers_test.go +++ b/integrationTests/vm/wasm/transfers/transfers_test.go @@ -3,6 +3,8 @@ package transfers import ( + "encoding/hex" + "fmt" "math/big" "testing" @@ -16,21 +18,45 @@ func TestTransfers_DuplicatedTransferValueEvents(t *testing.T) { err := context.DeploySC("../testdata/transferValue/output/transferValue.wasm", "") require.Nil(t, err) + vault := context.ScAddress - err = context.ExecuteSCWithValue(&context.Owner, "receive", big.NewInt(1)) + err = context.DeploySC("../testdata/transferValue/output/transferValue.wasm", "") + require.Nil(t, err) + forwarder := context.ScAddress + + // Add money to the vault + context.ScAddress = vault + err = context.ExecuteSCWithValue(&context.Owner, "fund", big.NewInt(42)) + require.Nil(t, err) + + // Ask money from the vault, via the forwarder + context.ScAddress = forwarder + err = context.ExecuteSC(&context.Owner, fmt.Sprintf("forwardAskMoney@%s", hex.EncodeToString(vault))) require.Nil(t, err) require.Len(t, context.LastLogs, 1) - require.Len(t, context.LastLogs[0].GetLogEvents(), 3) + require.Len(t, context.LastLogs[0].GetLogEvents(), 5) events := context.LastLogs[0].GetLogEvents() - // Duplicated "transferValueOnly" events are fixed in #5936. require.Equal(t, "transferValueOnly", string(events[0].GetIdentifier())) - require.Equal(t, "BackTransfer", string(events[0].GetData())) - require.Equal(t, []byte{0x01}, events[0].GetTopics()[0]) + require.Equal(t, "AsyncCall", string(events[0].GetData())) + require.Equal(t, []byte{}, events[0].GetTopics()[0]) + require.Equal(t, forwarder, events[0].GetAddress()) + require.Equal(t, vault, events[0].GetTopics()[1]) + + require.Equal(t, "transferValueOnly", string(events[1].GetIdentifier())) + require.Equal(t, "BackTransfer", string(events[1].GetData())) + require.Equal(t, []byte{0x01}, events[1].GetTopics()[0]) + require.Equal(t, vault, events[1].GetAddress()) + require.Equal(t, forwarder, events[1].GetTopics()[1]) - require.Equal(t, "writeLog", string(events[1].GetIdentifier())) - require.Len(t, events[1].GetTopics(), 2) - require.Contains(t, string(events[1].GetTopics()[1]), "too much gas provided for processing") - require.Equal(t, "completedTxEvent", string(events[2].GetIdentifier())) + // Duplicated "transferValueOnly" events are fixed in #5936. + require.Equal(t, "transferValueOnly", string(events[2].GetIdentifier())) + require.Equal(t, "AsyncCallback", string(events[2].GetData())) + require.Equal(t, []byte{0x01}, events[2].GetTopics()[0]) + require.Equal(t, vault, events[2].GetAddress()) + require.Equal(t, forwarder, events[2].GetTopics()[1]) + + require.Equal(t, "writeLog", string(events[3].GetIdentifier())) + require.Equal(t, "completedTxEvent", string(events[4].GetIdentifier())) } diff --git a/integrationTests/vm/wasm/utils.go b/integrationTests/vm/wasm/utils.go index be94ca1993c..e8987f24bd2 100644 --- a/integrationTests/vm/wasm/utils.go +++ b/integrationTests/vm/wasm/utils.go @@ -167,7 +167,7 @@ func SetupTestContextWithGasSchedule(t *testing.T, gasSchedule map[string]map[st context.initFeeHandlers() context.initVMAndBlockchainHook() context.initTxProcessorWithOneSCExecutorWithVMs() - context.ScAddress, _ = context.BlockchainHook.NewAddress(context.Owner.Address, context.Owner.Nonce, factory.WasmVirtualMachine) + argsNewSCQueryService := smartContract.ArgsNewSCQueryService{ VmContainer: context.VMContainer, EconomicsFee: context.EconomicsFee, @@ -550,6 +550,8 @@ func (context *TestContext) DeploySC(wasmPath string, parametersString string) e return err } + context.ScAddress, _ = context.BlockchainHook.NewAddress(context.Owner.Address, context.Owner.Nonce, factory.WasmVirtualMachine) + owner.Nonce++ _, err = context.Accounts.Commit() if err != nil { From fa959a691db002034b49f154d86afb196d593a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 11:39:02 +0200 Subject: [PATCH 805/958] Make test fail (should work after merging #5936). --- integrationTests/vm/wasm/transfers/transfers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/vm/wasm/transfers/transfers_test.go b/integrationTests/vm/wasm/transfers/transfers_test.go index 1a40caa67f0..98e0a416a89 100644 --- a/integrationTests/vm/wasm/transfers/transfers_test.go +++ b/integrationTests/vm/wasm/transfers/transfers_test.go @@ -53,7 +53,7 @@ func TestTransfers_DuplicatedTransferValueEvents(t *testing.T) { // Duplicated "transferValueOnly" events are fixed in #5936. require.Equal(t, "transferValueOnly", string(events[2].GetIdentifier())) require.Equal(t, "AsyncCallback", string(events[2].GetData())) - require.Equal(t, []byte{0x01}, events[2].GetTopics()[0]) + require.Equal(t, []byte{}, events[2].GetTopics()[0]) require.Equal(t, vault, events[2].GetAddress()) require.Equal(t, forwarder, events[2].GetTopics()[1]) From 5e708b5e0efe54113e8b07c1489b307e6f67393e Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 15 Feb 2024 13:33:26 +0200 Subject: [PATCH 806/958] added tests for testOnlyProcessingNode --- .../components/testOnlyProcessingNode.go | 4 +- .../components/testOnlyProcessingNode_test.go | 422 +++++++++++++++++- testscommon/state/userAccountStub.go | 6 +- 3 files changed, 407 insertions(+), 25 deletions(-) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 14ec26cba86..8fe8fdaf6b6 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -220,7 +220,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - err = instance.createBroadcastMessanger() + err = instance.createBroadcastMessenger() if err != nil { return nil, err } @@ -308,7 +308,7 @@ func (node *testOnlyProcessingNode) createNodesCoordinator(pref config.Preferenc return nil } -func (node *testOnlyProcessingNode) createBroadcastMessanger() error { +func (node *testOnlyProcessingNode) createBroadcastMessenger() error { broadcastMessenger, err := sposFactory.GetBroadcastMessenger( node.CoreComponentsHolder.InternalMarshalizer(), node.CoreComponentsHolder.Hasher(), diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 64dbf32b8e3..bb44ec5a9be 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -1,17 +1,26 @@ package components import ( + "errors" + "math/big" "strings" "testing" "time" "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/state" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var expectedErr = errors.New("expected error") + func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNode { outputConfigs, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ NumOfShards: 3, @@ -40,20 +49,15 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { t.Parallel() t.Run("should work", func(t *testing.T) { - if testing.Short() { - t.Skip("cannot run with -race -short; requires Wasm VM fix") - } + t.Parallel() args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) assert.Nil(t, err) assert.NotNil(t, node) }) - t.Run("try commit a block", func(t *testing.T) { - if testing.Short() { - t.Skip("cannot run with -race -short; requires Wasm VM fix") - } + t.Parallel() args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) @@ -81,27 +85,401 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { err = node.ProcessComponentsHolder.BlockProcessor().CommitBlock(header, block) assert.Nil(t, err) }) + t.Run("CreateCoreComponents failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.Configs.GeneralConfig.Marshalizer.Type = "invalid type" + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) + t.Run("CreateCryptoComponents failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.Configs.GeneralConfig.PublicKeyPIDSignature.Type = "invalid type" + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) + t.Run("CreateNetworkComponents failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.SyncedBroadcastNetwork = nil + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) + t.Run("CreateBootstrapComponents failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.Configs.FlagsConfig.WorkingDir = "" + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) + t.Run("CreateStateComponents failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.ShardIDStr = common.MetachainShardName // coverage only + args.Configs.GeneralConfig.StateTriesConfig.MaxStateTrieLevelInMemory = 0 + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) + t.Run("CreateProcessComponents failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.Configs.FlagsConfig.Version = "" + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) + t.Run("createFacade failure should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgsTestOnlyProcessingNode(t) + args.Configs.EpochConfig.GasSchedule.GasScheduleByEpochs = nil + node, err := NewTestOnlyProcessingNode(args) + require.Error(t, err) + require.Nil(t, node) + }) } -func TestOnlyProcessingNodeSetStateShouldError(t *testing.T) { - args := createMockArgsTestOnlyProcessingNode(t) - node, err := NewTestOnlyProcessingNode(args) - require.Nil(t, err) +func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { + t.Parallel() + + goodKeyValueMap := map[string]string{ + "01": "02", + } + node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.NoError(t, err) address := "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj" addressBytes, _ := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(address) - keyValueMap := map[string]string{ - "nonHex": "01", - } - err = node.SetKeyValueForAddress(addressBytes, keyValueMap) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), "cannot decode key")) + t.Run("should work", func(t *testing.T) { + _, err = node.StateComponentsHolder.AccountsAdapter().GetExistingAccount(addressBytes) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), "account was not found")) + + err = node.SetKeyValueForAddress(addressBytes, goodKeyValueMap) + require.NoError(t, err) + + _, err = node.StateComponentsHolder.AccountsAdapter().GetExistingAccount(addressBytes) + require.NoError(t, err) + }) + t.Run("decode key failure should error", func(t *testing.T) { + keyValueMap := map[string]string{ + "nonHex": "01", + } + err = node.SetKeyValueForAddress(addressBytes, keyValueMap) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), "cannot decode key")) + }) + t.Run("decode value failure should error", func(t *testing.T) { + keyValueMap := map[string]string{ + "01": "nonHex", + } + err = node.SetKeyValueForAddress(addressBytes, keyValueMap) + require.NotNil(t, err) + require.True(t, strings.Contains(err.Error(), "cannot decode value")) + }) + t.Run("LoadAccount failure should error", func(t *testing.T) { + t.Parallel() + + argsLocal := createMockArgsTestOnlyProcessingNode(t) + nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + LoadAccountCalled: func(container []byte) (vmcommon.AccountHandler, error) { + return nil, expectedErr + }, + }, + } + + err = nodeLocal.SetKeyValueForAddress(addressBytes, nil) + require.Equal(t, expectedErr, err) + }) + t.Run("account un-castable to UserAccountHandler should error", func(t *testing.T) { + t.Parallel() + + argsLocal := createMockArgsTestOnlyProcessingNode(t) + nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + LoadAccountCalled: func(container []byte) (vmcommon.AccountHandler, error) { + return &state.PeerAccountHandlerMock{}, nil + }, + }, + } + + err = nodeLocal.SetKeyValueForAddress(addressBytes, nil) + require.Error(t, err) + require.Equal(t, "cannot cast AccountHandler to UserAccountHandler", err.Error()) + }) + t.Run("SaveKeyValue failure should error", func(t *testing.T) { + t.Parallel() + + argsLocal := createMockArgsTestOnlyProcessingNode(t) + nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + LoadAccountCalled: func(container []byte) (vmcommon.AccountHandler, error) { + return &state.UserAccountStub{ + SaveKeyValueCalled: func(key []byte, value []byte) error { + return expectedErr + }, + }, nil + }, + }, + } + + err = nodeLocal.SetKeyValueForAddress(addressBytes, goodKeyValueMap) + require.Equal(t, expectedErr, err) + }) + t.Run("SaveAccount failure should error", func(t *testing.T) { + t.Parallel() + + argsLocal := createMockArgsTestOnlyProcessingNode(t) + nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + SaveAccountCalled: func(account vmcommon.AccountHandler) error { + return expectedErr + }, + }, + } - keyValueMap = map[string]string{ - "01": "nonHex", + err = nodeLocal.SetKeyValueForAddress(addressBytes, goodKeyValueMap) + require.Equal(t, expectedErr, err) + }) +} + +func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { + t.Parallel() + + node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.NoError(t, err) + + address := "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj" + scAddress := "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" + addressBytes, _ := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(address) + scAddressBytes, _ := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(scAddress) + addressState := &dtos.AddressState{ + Address: "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj", + Nonce: 100, + Balance: "1000000000000000000", + Keys: map[string]string{ + "01": "02", + }, } - err = node.SetKeyValueForAddress(addressBytes, keyValueMap) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), "cannot decode value")) + + t.Run("should work", func(t *testing.T) { + _, err = node.StateComponentsHolder.AccountsAdapter().GetExistingAccount(addressBytes) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), "account was not found")) + + err = node.SetStateForAddress(addressBytes, addressState) + require.NoError(t, err) + + account, err := node.StateComponentsHolder.AccountsAdapter().GetExistingAccount(addressBytes) + require.NoError(t, err) + require.Equal(t, addressState.Nonce, account.GetNonce()) + }) + t.Run("LoadAccount failure should error", func(t *testing.T) { + t.Parallel() + + nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + LoadAccountCalled: func(container []byte) (vmcommon.AccountHandler, error) { + return nil, expectedErr + }, + }, + } + + errLocal = nodeLocal.SetStateForAddress([]byte("address"), nil) + require.Equal(t, expectedErr, errLocal) + }) + t.Run("state balance invalid should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Balance = "invalid balance" + err = node.SetStateForAddress(addressBytes, &addressStateCopy) + require.Error(t, err) + require.Equal(t, "cannot convert string balance to *big.Int", err.Error()) + }) + t.Run("AddToBalance failure should error", func(t *testing.T) { + t.Parallel() + + nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + LoadAccountCalled: func(container []byte) (vmcommon.AccountHandler, error) { + return &state.UserAccountStub{ + AddToBalanceCalled: func(value *big.Int) error { + return expectedErr + }, + }, nil + }, + }, + } + + errLocal = nodeLocal.SetStateForAddress([]byte("address"), addressState) + require.Equal(t, expectedErr, errLocal) + }) + t.Run("SaveKeyValue failure should error", func(t *testing.T) { + t.Parallel() + + argsLocal := createMockArgsTestOnlyProcessingNode(t) + nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + LoadAccountCalled: func(container []byte) (vmcommon.AccountHandler, error) { + return &state.UserAccountStub{ + SaveKeyValueCalled: func(key []byte, value []byte) error { + return expectedErr + }, + }, nil + }, + }, + } + + errLocal = nodeLocal.SetStateForAddress(addressBytes, addressState) + require.Equal(t, expectedErr, errLocal) + }) + t.Run("invalid sc code should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Address = scAddress + addressStateCopy.Code = "invalid code" + + err = node.SetStateForAddress(scAddressBytes, &addressStateCopy) + require.Error(t, err) + }) + t.Run("invalid sc code hash should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Address = scAddress + addressStateCopy.CodeHash = "invalid code hash" + + err = node.SetStateForAddress(scAddressBytes, &addressStateCopy) + require.Error(t, err) + }) + t.Run("invalid sc code metadata should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Address = scAddress + addressStateCopy.CodeMetadata = "invalid code metadata" + + err = node.SetStateForAddress(scAddressBytes, &addressStateCopy) + require.Error(t, err) + }) + t.Run("invalid sc owner should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Address = scAddress + addressStateCopy.Owner = "invalid owner" + + err = node.SetStateForAddress(scAddressBytes, &addressStateCopy) + require.Error(t, err) + }) + t.Run("invalid sc dev rewards should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Owner = address + addressStateCopy.Address = scAddress + addressStateCopy.DeveloperRewards = "invalid dev rewards" + + err = node.SetStateForAddress(scAddressBytes, &addressStateCopy) + require.Error(t, err) + }) + t.Run("invalid root hash should error", func(t *testing.T) { + addressStateCopy := *addressState + addressStateCopy.Owner = address + addressStateCopy.Address = scAddress // coverage + addressStateCopy.DeveloperRewards = "1000000" + addressStateCopy.RootHash = "invalid root hash" + + err = node.SetStateForAddress(scAddressBytes, &addressStateCopy) + require.Error(t, err) + }) + t.Run("SaveAccount failure should error", func(t *testing.T) { + t.Parallel() + + argsLocal := createMockArgsTestOnlyProcessingNode(t) + nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + require.NoError(t, errLocal) + + nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ + Accounts: &state.AccountsStub{ + SaveAccountCalled: func(account vmcommon.AccountHandler) error { + return expectedErr + }, + }, + } + + err = nodeLocal.SetStateForAddress(addressBytes, addressState) + require.Equal(t, expectedErr, err) + }) +} + +func TestTestOnlyProcessingNode_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var node *testOnlyProcessingNode + require.True(t, node.IsInterfaceNil()) + + node, _ = NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.False(t, node.IsInterfaceNil()) +} + +func TestTestOnlyProcessingNode_Close(t *testing.T) { + t.Parallel() + + node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.NoError(t, err) + + require.NoError(t, node.Close()) +} + +func TestTestOnlyProcessingNode_Getters(t *testing.T) { + t.Parallel() + + node := &testOnlyProcessingNode{} + require.Nil(t, node.GetProcessComponents()) + require.Nil(t, node.GetChainHandler()) + require.Nil(t, node.GetBroadcastMessenger()) + require.Nil(t, node.GetCryptoComponents()) + require.Nil(t, node.GetCoreComponents()) + require.Nil(t, node.GetStateComponents()) + require.Nil(t, node.GetFacadeHandler()) + require.Nil(t, node.GetStatusCoreComponents()) + + node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) + require.Nil(t, err) + + require.NotNil(t, node.GetProcessComponents()) + require.NotNil(t, node.GetChainHandler()) + require.NotNil(t, node.GetBroadcastMessenger()) + require.NotNil(t, node.GetShardCoordinator()) + require.NotNil(t, node.GetCryptoComponents()) + require.NotNil(t, node.GetCoreComponents()) + require.NotNil(t, node.GetStateComponents()) + require.NotNil(t, node.GetFacadeHandler()) + require.NotNil(t, node.GetStatusCoreComponents()) } diff --git a/testscommon/state/userAccountStub.go b/testscommon/state/userAccountStub.go index 3e4278b2d38..ce54f059252 100644 --- a/testscommon/state/userAccountStub.go +++ b/testscommon/state/userAccountStub.go @@ -30,6 +30,7 @@ type UserAccountStub struct { RetrieveValueCalled func(_ []byte) ([]byte, uint32, error) SetDataTrieCalled func(dataTrie common.Trie) GetRootHashCalled func() []byte + SaveKeyValueCalled func(key []byte, value []byte) error } // HasNewCode - @@ -172,7 +173,10 @@ func (u *UserAccountStub) RetrieveValue(key []byte) ([]byte, uint32, error) { } // SaveKeyValue - -func (u *UserAccountStub) SaveKeyValue(_ []byte, _ []byte) error { +func (u *UserAccountStub) SaveKeyValue(key []byte, value []byte) error { + if u.SaveKeyValueCalled != nil { + return u.SaveKeyValueCalled(key, value) + } return nil } From b4145645237ea5bf9084cc3c52b77dc06aa04c7d Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 15 Feb 2024 14:13:09 +0200 Subject: [PATCH 807/958] fixed races --- .../components/testOnlyProcessingNode_test.go | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index bb44ec5a9be..9a9714cd28c 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -205,8 +205,8 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { }, } - err = nodeLocal.SetKeyValueForAddress(addressBytes, nil) - require.Equal(t, expectedErr, err) + errLocal = nodeLocal.SetKeyValueForAddress(addressBytes, nil) + require.Equal(t, expectedErr, errLocal) }) t.Run("account un-castable to UserAccountHandler should error", func(t *testing.T) { t.Parallel() @@ -223,15 +223,14 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { }, } - err = nodeLocal.SetKeyValueForAddress(addressBytes, nil) - require.Error(t, err) - require.Equal(t, "cannot cast AccountHandler to UserAccountHandler", err.Error()) + errLocal = nodeLocal.SetKeyValueForAddress(addressBytes, nil) + require.Error(t, errLocal) + require.Equal(t, "cannot cast AccountHandler to UserAccountHandler", errLocal.Error()) }) t.Run("SaveKeyValue failure should error", func(t *testing.T) { t.Parallel() - argsLocal := createMockArgsTestOnlyProcessingNode(t) - nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) + nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, errLocal) nodeLocal.StateComponentsHolder = &factory.StateComponentsMock{ @@ -246,8 +245,8 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { }, } - err = nodeLocal.SetKeyValueForAddress(addressBytes, goodKeyValueMap) - require.Equal(t, expectedErr, err) + errLocal = nodeLocal.SetKeyValueForAddress(addressBytes, goodKeyValueMap) + require.Equal(t, expectedErr, errLocal) }) t.Run("SaveAccount failure should error", func(t *testing.T) { t.Parallel() @@ -264,8 +263,8 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { }, } - err = nodeLocal.SetKeyValueForAddress(addressBytes, goodKeyValueMap) - require.Equal(t, expectedErr, err) + errLocal = nodeLocal.SetKeyValueForAddress(addressBytes, goodKeyValueMap) + require.Equal(t, expectedErr, errLocal) }) } @@ -433,8 +432,8 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { }, } - err = nodeLocal.SetStateForAddress(addressBytes, addressState) - require.Equal(t, expectedErr, err) + errLocal = nodeLocal.SetStateForAddress(addressBytes, addressState) + require.Equal(t, expectedErr, errLocal) }) } From 866fa2a9a27599e1cd6a9c989647f36caa2a13e1 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Thu, 15 Feb 2024 15:06:43 +0200 Subject: [PATCH 808/958] vm1.5.27 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index fc99478d2d5..07f88e915e5 100644 --- a/go.mod +++ b/go.mod @@ -19,10 +19,10 @@ require ( github.com/multiversx/mx-chain-crypto-go v1.2.9 github.com/multiversx/mx-chain-es-indexer-go v1.4.18 github.com/multiversx/mx-chain-logger-go v1.0.13 - github.com/multiversx/mx-chain-scenario-go v1.3.0 + github.com/multiversx/mx-chain-scenario-go v1.4.1 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.11 - github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240206121310-ce5f10e5fe16 + github.com/multiversx/mx-chain-vm-go v1.5.27 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 diff --git a/go.sum b/go.sum index 0e5e120d68b..2a706a5054f 100644 --- a/go.sum +++ b/go.sum @@ -395,14 +395,14 @@ github.com/multiversx/mx-chain-es-indexer-go v1.4.18 h1:rCA+/mn/77MyB7c8FjtabdQe github.com/multiversx/mx-chain-es-indexer-go v1.4.18/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= github.com/multiversx/mx-chain-logger-go v1.0.13 h1:eru/TETo0MkO4ZTnXsQDKf4PBRpAXmqjT02klNT/JnY= github.com/multiversx/mx-chain-logger-go v1.0.13/go.mod h1:MZJhTAtZTJxT+yK2EHc4ZW3YOHUc1UdjCD0iahRNBZk= -github.com/multiversx/mx-chain-scenario-go v1.3.0 h1:Vm6jYipJuIcJt8kamgXkePtKkwXaF5Lv5DglZjE5o8I= -github.com/multiversx/mx-chain-scenario-go v1.3.0/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= +github.com/multiversx/mx-chain-scenario-go v1.4.1 h1:CrVXb1aNBRiFfSfpoMAUoGUy2aNXke5WnoesLdFxC2g= +github.com/multiversx/mx-chain-scenario-go v1.4.1/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.11 h1:rAQR00ALKOmWAuNA8XW8hR02M9gmrAE4WZwyJH4dMMU= github.com/multiversx/mx-chain-vm-common-go v1.5.11/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= -github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240206121310-ce5f10e5fe16 h1:mSUJjgaSLmspQRNbqU0Aw3v9cuXtPnlUDTchFiipuZQ= -github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240206121310-ce5f10e5fe16/go.mod h1:gNZ/s4Z6OHg6ZeBsW6aDxWQduXsRS0Bsv4pfkmHeRzs= +github.com/multiversx/mx-chain-vm-go v1.5.27 h1:80AdXyjAnN5w4hucPMtpsXnoWtcV47ZLcjECsTTccsA= +github.com/multiversx/mx-chain-vm-go v1.5.27/go.mod h1:Y1O50Z7+suo4D1hnSBA7n34KvgKs5W9jzoEGwpfAjks= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 h1:TxFjQH0dXC/ACQxlIgJbO7pVoh00rcqeKSnIjWTDMxg= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 h1:xgrXfHKa0Za4xjFj5W0FcYEivjrQIhLvGEFXXa1uQZU= From 19ea2fe3a180559e680f96f056327f279e4c3e99 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 15 Feb 2024 15:08:22 +0200 Subject: [PATCH 809/958] skip new tests --- .../components/testOnlyProcessingNode_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 9a9714cd28c..10ab4ecec70 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -152,6 +152,11 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { } func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() goodKeyValueMap := map[string]string{ @@ -269,6 +274,11 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { } func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) From 0f58adea6ef2d815b5f8a9b31b2a4fa64da06ce7 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Thu, 15 Feb 2024 15:08:42 +0200 Subject: [PATCH 810/958] vm1.5.27 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 07f88e915e5..2dd2a79c66d 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/multiversx/mx-chain-crypto-go v1.2.9 github.com/multiversx/mx-chain-es-indexer-go v1.4.18 github.com/multiversx/mx-chain-logger-go v1.0.13 - github.com/multiversx/mx-chain-scenario-go v1.4.1 + github.com/multiversx/mx-chain-scenario-go v1.4.2 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.11 github.com/multiversx/mx-chain-vm-go v1.5.27 diff --git a/go.sum b/go.sum index 2a706a5054f..af5baee69a5 100644 --- a/go.sum +++ b/go.sum @@ -395,8 +395,8 @@ github.com/multiversx/mx-chain-es-indexer-go v1.4.18 h1:rCA+/mn/77MyB7c8FjtabdQe github.com/multiversx/mx-chain-es-indexer-go v1.4.18/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= github.com/multiversx/mx-chain-logger-go v1.0.13 h1:eru/TETo0MkO4ZTnXsQDKf4PBRpAXmqjT02klNT/JnY= github.com/multiversx/mx-chain-logger-go v1.0.13/go.mod h1:MZJhTAtZTJxT+yK2EHc4ZW3YOHUc1UdjCD0iahRNBZk= -github.com/multiversx/mx-chain-scenario-go v1.4.1 h1:CrVXb1aNBRiFfSfpoMAUoGUy2aNXke5WnoesLdFxC2g= -github.com/multiversx/mx-chain-scenario-go v1.4.1/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= +github.com/multiversx/mx-chain-scenario-go v1.4.2 h1:iGgqMHup7DfMYFEynGjn2CX9ZNBfgPQLqzZx1AWHJzc= +github.com/multiversx/mx-chain-scenario-go v1.4.2/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.11 h1:rAQR00ALKOmWAuNA8XW8hR02M9gmrAE4WZwyJH4dMMU= From 3daf0f9aff173d7ccdcb53d63bba01d84aca5cb9 Mon Sep 17 00:00:00 2001 From: robertsasu Date: Thu, 15 Feb 2024 15:11:36 +0200 Subject: [PATCH 811/958] vm1.5.27 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2dd2a79c66d..84138c3ebc3 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/multiversx/mx-chain-vm-go v1.5.27 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil v3.21.11+incompatible From f79b2d43aca2c471178ab828ce06032799d3327c Mon Sep 17 00:00:00 2001 From: robertsasu Date: Thu, 15 Feb 2024 15:18:21 +0200 Subject: [PATCH 812/958] vm1.5.27 --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index af5baee69a5..b7cd3036bc2 100644 --- a/go.sum +++ b/go.sum @@ -407,8 +407,8 @@ github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 h1:TxFjQH0dXC/ACQxlIgJbO7pVoh0 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 h1:xgrXfHKa0Za4xjFj5W0FcYEivjrQIhLvGEFXXa1uQZU= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66/go.mod h1:mx6IOAqo7zjSinYd8D2YqlpMWsuqFoYXJ6bntnTOeQg= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 h1:MZFEBjDmfwLGB0cZb/pvlLx+qRv/9tO83bEgHUk34is= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94/go.mod h1:uuSbZGe0UwOWQyHA4EeJWhs8UeDdhtmMwlhNaX9ppx0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95 h1:zswK06SKd8VYjFTeC/4Jat5PhU9PT4pO5hw01U9ZjtE= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95/go.mod h1:t4YcFK6VJkG1wGKx1JK4jyowo9zfGFpi8Jl3ycfqAxw= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From b02ed4622ecc74454bc45ed129a5169c5ed9b9b7 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 15 Feb 2024 20:06:00 +0200 Subject: [PATCH 813/958] update scenario 26 --- .../staking/stakeAndUnStake_test.go | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 0c4753a004b..104127b65ea 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -18,10 +18,10 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" + chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/vm" logger "github.com/multiversx/mx-chain-logger-go" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -588,7 +588,7 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) stakeValue = big.NewInt(0).Set(minimumStakeValue) txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) @@ -598,7 +598,7 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) log.Info("Step 1. Check the stake amount for the owner of the staked nodes") scQuery := &process.SCQuery{ @@ -626,7 +626,7 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) log.Info("Step 3. Check the stake amount for the owner of the staked nodes") scQuery = &process.SCQuery{ @@ -645,9 +645,10 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) } -// Test description -// unstake funds with deactivation of node if below 2500 -> the rest of funds are distributed as topup at epoch change +// Test description: +// Unstake funds with deactivation of node if below 2500 -> the rest of funds are distributed as topup at epoch change // +// Internal test scenario #26 func TestChainSimulator_DirectStakingNodes_UnstakeFundsWithDeactivation(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -790,7 +791,6 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) - log.Info("Preconditions. Have an account with 2 staked nodes") privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) require.Nil(t, err) @@ -812,7 +812,9 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) stakeValue = big.NewInt(0).Set(minimumStakeValue) txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) @@ -822,7 +824,9 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs require.NotNil(t, stakeTx) err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node - assert.Nil(t, err) + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[1], targetEpoch) log.Info("Step 1. Check the stake amount for the owner of the staked nodes") scQuery := &process.SCQuery{ @@ -851,7 +855,7 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs require.NotNil(t, unStakeTx) err = cs.GenerateBlocks(2) - assert.Nil(t, err) + require.Nil(t, err) log.Info("Step 3. Check the outcome of the TX & verify new stake state with vmquery getTotalStaked and getUnStakedTokensList") scQuery = &process.SCQuery{ @@ -883,4 +887,42 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs expectedUnStaked := big.NewInt(10) expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + + log.Info("Step 4. Wait for change of epoch and check the outcome") + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) + require.NotEqual(t, stakedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey0)) + decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) + require.NotEqual(t, stakedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey1)) +} + +func testBLSKeyStaked(t *testing.T, + cs chainSimulatorIntegrationTests.ChainSimulator, + metachainNode chainSimulatorProcess.NodeHandler, + blsKey string, targetEpoch int32, +) { + decodedBLSKey, _ := hex.DecodeString(blsKey) + err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + + validatorStatistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + + activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) + if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { + require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey)) + + validatorInfo, found := validatorStatistics[blsKey] + require.True(t, found) + require.Equal(t, auctionStatus, validatorInfo.ValidatorStatus) + + return + } + + // in staking ph 2/3.5 we do not find the bls key on the validator statistics + _, found := validatorStatistics[blsKey] + require.False(t, found) + require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey)) } From a850211b3398a6a171747d2cd62a4c284f7d5a84 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 15 Feb 2024 20:38:45 +0200 Subject: [PATCH 814/958] added scenario: direct staked nodes, deactivation with reactivation --- .../staking/stakeAndUnStake_test.go | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 104127b65ea..7c9a808d3db 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -926,3 +926,278 @@ func testBLSKeyStaked(t *testing.T, require.False(t, found) require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey)) } + +// Test description: +// Unstake funds with deactivation of node, followed by stake with sufficient ammount does not unstake node at end of epoch +// +// Internal test scenario #27 +func TestChainSimulator_DirectStakingNodes_UnstakeFundsWithDeactivation_WithReactivation(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test Steps + // 1. Check the stake amount and number of nodes for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance + // 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network + // 3. Check the outcome of the TX & verify new stake state with vmquery + // 4. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network + // 5. Check the outcome of the TX & verify new stake state with vmquery + // 6. Wait for change of epoch and check the outcome + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t, cs, 1) + }) + + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t, cs, 4) + }) +} + +func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(6000) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Set(minimumStakeValue) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + stakeValue = big.NewInt(0).Set(minimumStakeValue) + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[1], mockBLSSignature) + txStake = generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[1], targetEpoch) + + log.Info("Step 1. Check the stake amount for the owner of the staked nodes") + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked := big.NewInt(5000) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + log.Info("Step 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network") + + unStakeValue := big.NewInt(10) + unStakeValue = unStakeValue.Mul(oneEGLD, unStakeValue) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue.Bytes())) + txUnStake := generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + log.Info("Step 3. Check the outcome of the TX & verify new stake state with vmquery getTotalStaked and getUnStakedTokensList") + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked = big.NewInt(4990) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getUnStakedTokensList", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedUnStaked := big.NewInt(10) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + + log.Info("Step 4. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network") + + newStakeValue := big.NewInt(10) + newStakeValue = newStakeValue.Mul(oneEGLD, newStakeValue) + txDataField = fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake = generateTransaction(validatorOwner.Bytes, 3, vm.ValidatorSCAddress, newStakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + log.Info("5. Check the outcome of the TX & verify new stake state with vmquery") + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked = big.NewInt(5000) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) +} From 8e2f483b0729a0df5248993b54936655cd391a7b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 16 Feb 2024 09:19:55 +0200 Subject: [PATCH 815/958] - fixes after merge --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 8c0a458138f..092a7006c38 100644 --- a/go.mod +++ b/go.mod @@ -19,13 +19,13 @@ require ( github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c - github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1 + github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 - github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129150215-43996b664ada + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index 11cb5b9a820..fcbb3672f50 100644 --- a/go.sum +++ b/go.sum @@ -395,20 +395,20 @@ github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d3 github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a/go.mod h1:3aSGRJNvfUuPQkZUGHWuF11rPPxphsKGuAuIB+eD3is= github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c h1:QIUOn8FgNRa5cir4BCWHZi/Qcr6Gg0eGNhns4+jy6+k= github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c/go.mod h1:fH/fR/GEBsDjPkBoZDVJMoYo2HhlA7++DP6QfITJ1N8= -github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1 h1:hkeHftnhRuJoT5FrfF97gEtb5aY351SWEjZPaTb6D+Y= -github.com/multiversx/mx-chain-scenario-go v1.3.1-0.20240129145446-ca4fba98f6d1/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= +github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 h1:ydzN3f+Y7H0InXuxAcNUSyVc+omNYL8uYtLqVzqaaX4= +github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 h1:/EYv/HGX0OKbeNFt667J0yZRtuJiZH0lEK8YtobuH/c= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 h1:zImJa/r6B5L2OLWbKTn5io53U11PPGDla12H2OaJ9y0= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83 h1:G/d9aplnwP/9MrLE3gcANEpGfn5e8ZZufijPv2XVUfw= -github.com/multiversx/mx-chain-vm-go v1.5.27-0.20240129150501-7c828af05c83/go.mod h1:64dTd60QUGWx5W3eU28IOfpqAWApWqB/Z7mJHmuQfXo= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 h1:NMHNT4NcqOdnHttYsT3ydZHVapwOctp6t+WDGDy0UEQ= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 h1:1uMlT5TjiHUlx81fEH/WQANWlY0PjF3opMlW+E3L3GI= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129150215-43996b664ada h1:NZLV2QmNPW+QTefuAhC24sOuGbOsAQEXzfv2CWoRJKc= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.95-0.20240129150215-43996b664ada/go.mod h1:tCjtWeBEZCfjEjlBcgLIRDGJbVmdV8dsmG6ydtiUtSo= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 h1:0y1k2+FjFfWgoPCMi0nkYkCYQJtPYJvph6bre4Elqxk= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From e865ea91d947b508847fd1adcfd7b178092e4dc4 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 16 Feb 2024 09:58:24 +0200 Subject: [PATCH 816/958] rename incr to increment --- common/interface.go | 10 +++--- common/statistics/disabled/stateStatistics.go | 20 +++++------ .../disabled/stateStatistics_test.go | 12 +++---- common/statistics/stateStatistics.go | 20 +++++------ common/statistics/stateStatistics_test.go | 36 +++++++++---------- storage/interface.go | 8 ++--- storage/pruning/pruningStorer.go | 4 +-- storage/pruning/triePruningStorer.go | 4 +-- trie/node.go | 2 +- 9 files changed, 58 insertions(+), 58 deletions(-) diff --git a/common/interface.go b/common/interface.go index 38efb0a082b..84e4be9f055 100644 --- a/common/interface.go +++ b/common/interface.go @@ -223,17 +223,17 @@ type StateStatisticsHandler interface { Reset() ResetSnapshot() - IncrCache() + IncrementCache() Cache() uint64 - IncrSnapshotCache() + IncrementSnapshotCache() SnapshotCache() uint64 - IncrPersister(epoch uint32) + IncrementPersister(epoch uint32) Persister(epoch uint32) uint64 - IncrSnapshotPersister(epoch uint32) + IncrementSnapshotPersister(epoch uint32) SnapshotPersister(epoch uint32) uint64 - IncrTrie() + IncrementTrie() Trie() uint64 ProcessingStats() []string diff --git a/common/statistics/disabled/stateStatistics.go b/common/statistics/disabled/stateStatistics.go index d10d310129a..c3bdf12420d 100644 --- a/common/statistics/disabled/stateStatistics.go +++ b/common/statistics/disabled/stateStatistics.go @@ -19,8 +19,8 @@ func (s *stateStatistics) Reset() { func (s *stateStatistics) ResetSnapshot() { } -// IncrCache does nothing -func (s *stateStatistics) IncrCache() { +// IncrementCache does nothing +func (s *stateStatistics) IncrementCache() { } // Cache returns zero @@ -28,8 +28,8 @@ func (s *stateStatistics) Cache() uint64 { return 0 } -// IncrSnapshotCache does nothing -func (ss *stateStatistics) IncrSnapshotCache() { +// IncrementSnapshotCache does nothing +func (ss *stateStatistics) IncrementSnapshotCache() { } // SnapshotCache returns the number of cached operations @@ -37,8 +37,8 @@ func (ss *stateStatistics) SnapshotCache() uint64 { return 0 } -// IncrPersister does nothing -func (s *stateStatistics) IncrPersister(epoch uint32) { +// IncrementPersister does nothing +func (s *stateStatistics) IncrementPersister(epoch uint32) { } // Persister returns zero @@ -46,8 +46,8 @@ func (s *stateStatistics) Persister(epoch uint32) uint64 { return 0 } -// IncrSnapshotPersister does nothing -func (ss *stateStatistics) IncrSnapshotPersister(epoch uint32) { +// IncrementSnapshotPersister does nothing +func (ss *stateStatistics) IncrementSnapshotPersister(epoch uint32) { } // SnapshotPersister returns the number of persister operations @@ -55,8 +55,8 @@ func (ss *stateStatistics) SnapshotPersister(epoch uint32) uint64 { return 0 } -// IncrTrie does nothing -func (s *stateStatistics) IncrTrie() { +// IncrementTrie does nothing +func (s *stateStatistics) IncrementTrie() { } // Trie returns zero diff --git a/common/statistics/disabled/stateStatistics_test.go b/common/statistics/disabled/stateStatistics_test.go index 7d17aa689d1..725ec3ee6a1 100644 --- a/common/statistics/disabled/stateStatistics_test.go +++ b/common/statistics/disabled/stateStatistics_test.go @@ -31,12 +31,12 @@ func TestStateStatistics_MethodsShouldNotPanic(t *testing.T) { stats.ResetSnapshot() stats.ResetAll() - stats.IncrCache() - stats.IncrSnapshotCache() - stats.IncrSnapshotCache() - stats.IncrPersister(1) - stats.IncrSnapshotPersister(1) - stats.IncrTrie() + stats.IncrementCache() + stats.IncrementSnapshotCache() + stats.IncrementSnapshotCache() + stats.IncrementPersister(1) + stats.IncrementSnapshotPersister(1) + stats.IncrementTrie() require.Equal(t, uint64(0), stats.Cache()) require.Equal(t, uint64(0), stats.SnapshotCache()) diff --git a/common/statistics/stateStatistics.go b/common/statistics/stateStatistics.go index c41040ab933..474dc6d47d1 100644 --- a/common/statistics/stateStatistics.go +++ b/common/statistics/stateStatistics.go @@ -51,8 +51,8 @@ func (ss *stateStatistics) ResetSnapshot() { ss.mutPersisters.Unlock() } -// IncrCache will increment cache counter -func (ss *stateStatistics) IncrCache() { +// IncrementCache will increment cache counter +func (ss *stateStatistics) IncrementCache() { atomic.AddUint64(&ss.numCache, 1) } @@ -61,8 +61,8 @@ func (ss *stateStatistics) Cache() uint64 { return atomic.LoadUint64(&ss.numCache) } -// IncrSnapshotCache will increment snapshot cache counter -func (ss *stateStatistics) IncrSnapshotCache() { +// IncrementSnapshotCache will increment snapshot cache counter +func (ss *stateStatistics) IncrementSnapshotCache() { atomic.AddUint64(&ss.numSnapshotCache, 1) } @@ -71,8 +71,8 @@ func (ss *stateStatistics) SnapshotCache() uint64 { return atomic.LoadUint64(&ss.numSnapshotCache) } -// IncrPersister will increment persister counter -func (ss *stateStatistics) IncrPersister(epoch uint32) { +// IncrementPersister will increment persister counter +func (ss *stateStatistics) IncrementPersister(epoch uint32) { ss.mutPersisters.Lock() defer ss.mutPersisters.Unlock() @@ -87,8 +87,8 @@ func (ss *stateStatistics) Persister(epoch uint32) uint64 { return ss.numPersister[epoch] } -// IncrSnapshotPersister will increment snapshot persister counter -func (ss *stateStatistics) IncrSnapshotPersister(epoch uint32) { +// IncrementSnapshotPersister will increment snapshot persister counter +func (ss *stateStatistics) IncrementSnapshotPersister(epoch uint32) { ss.mutPersisters.Lock() defer ss.mutPersisters.Unlock() @@ -103,8 +103,8 @@ func (ss *stateStatistics) SnapshotPersister(epoch uint32) uint64 { return ss.numSnapshotPersister[epoch] } -// IncrTrie will increment trie counter -func (ss *stateStatistics) IncrTrie() { +// IncrementTrie will increment trie counter +func (ss *stateStatistics) IncrementTrie() { atomic.AddUint64(&ss.numTrie, 1) } diff --git a/common/statistics/stateStatistics_test.go b/common/statistics/stateStatistics_test.go index e1beaf9d35b..674b3d8ea6b 100644 --- a/common/statistics/stateStatistics_test.go +++ b/common/statistics/stateStatistics_test.go @@ -27,11 +27,11 @@ func TestStateStatistics_Processing(t *testing.T) { assert.Equal(t, uint64(0), ss.Trie()) - ss.IncrTrie() - ss.IncrTrie() + ss.IncrementTrie() + ss.IncrementTrie() assert.Equal(t, uint64(2), ss.Trie()) - ss.IncrTrie() + ss.IncrementTrie() assert.Equal(t, uint64(3), ss.Trie()) ss.Reset() @@ -47,11 +47,11 @@ func TestStateStatistics_Processing(t *testing.T) { assert.Equal(t, uint64(0), ss.Persister(epoch)) - ss.IncrPersister(epoch) - ss.IncrPersister(epoch) + ss.IncrementPersister(epoch) + ss.IncrementPersister(epoch) assert.Equal(t, uint64(2), ss.Persister(epoch)) - ss.IncrPersister(epoch) + ss.IncrementPersister(epoch) assert.Equal(t, uint64(3), ss.Persister(epoch)) ss.Reset() @@ -65,11 +65,11 @@ func TestStateStatistics_Processing(t *testing.T) { assert.Equal(t, uint64(0), ss.Cache()) - ss.IncrCache() - ss.IncrCache() + ss.IncrementCache() + ss.IncrementCache() assert.Equal(t, uint64(2), ss.Cache()) - ss.IncrCache() + ss.IncrementCache() assert.Equal(t, uint64(3), ss.Cache()) ss.Reset() @@ -89,11 +89,11 @@ func TestStateStatistics_Snapshot(t *testing.T) { assert.Equal(t, uint64(0), ss.SnapshotPersister(epoch)) - ss.IncrSnapshotPersister(epoch) - ss.IncrSnapshotPersister(epoch) + ss.IncrementSnapshotPersister(epoch) + ss.IncrementSnapshotPersister(epoch) assert.Equal(t, uint64(2), ss.SnapshotPersister(epoch)) - ss.IncrSnapshotPersister(epoch) + ss.IncrementSnapshotPersister(epoch) assert.Equal(t, uint64(3), ss.SnapshotPersister(epoch)) ss.ResetSnapshot() @@ -107,11 +107,11 @@ func TestStateStatistics_Snapshot(t *testing.T) { assert.Equal(t, uint64(0), ss.Cache()) - ss.IncrSnapshotCache() - ss.IncrSnapshotCache() + ss.IncrementSnapshotCache() + ss.IncrementSnapshotCache() assert.Equal(t, uint64(2), ss.SnapshotCache()) - ss.IncrSnapshotCache() + ss.IncrementSnapshotCache() assert.Equal(t, uint64(3), ss.SnapshotCache()) ss.ResetSnapshot() @@ -144,11 +144,11 @@ func TestStateStatistics_ConcurrenyOperations(t *testing.T) { case 0: ss.Reset() case 1: - ss.IncrCache() + ss.IncrementCache() case 2: - ss.IncrPersister(epoch) + ss.IncrementPersister(epoch) case 3: - ss.IncrTrie() + ss.IncrementTrie() case 7: _ = ss.Cache() case 8: diff --git a/storage/interface.go b/storage/interface.go index 328eb86c4ed..c3e5aa3826d 100644 --- a/storage/interface.go +++ b/storage/interface.go @@ -216,8 +216,8 @@ type PersisterFactoryHandler interface { // StateStatsHandler defines the behaviour needed to handler storage statistics type StateStatsHandler interface { - IncrCache() - IncrSnapshotCache() - IncrPersister(epoch uint32) - IncrSnapshotPersister(epoch uint32) + IncrementCache() + IncrementSnapshotCache() + IncrementPersister(epoch uint32) + IncrementSnapshotPersister(epoch uint32) } diff --git a/storage/pruning/pruningStorer.go b/storage/pruning/pruningStorer.go index f90f1c75aaa..2007454a7c8 100644 --- a/storage/pruning/pruningStorer.go +++ b/storage/pruning/pruningStorer.go @@ -434,7 +434,7 @@ func (ps *PruningStorer) createAndInitPersister(pd *persisterData) (storage.Pers func (ps *PruningStorer) Get(key []byte) ([]byte, error) { v, ok := ps.cacher.Get(key) if ok { - ps.stateStatsHandler.IncrCache() + ps.stateStatsHandler.IncrementCache() return v.([]byte), nil } @@ -457,7 +457,7 @@ func (ps *PruningStorer) Get(key []byte) ([]byte, error) { // if found in persistence unit, add it to cache and return _ = ps.cacher.Put(key, val, len(val)) - ps.stateStatsHandler.IncrPersister(ps.activePersisters[idx].epoch) + ps.stateStatsHandler.IncrementPersister(ps.activePersisters[idx].epoch) return val, nil } diff --git a/storage/pruning/triePruningStorer.go b/storage/pruning/triePruningStorer.go index 1eb290023c6..e013820db65 100644 --- a/storage/pruning/triePruningStorer.go +++ b/storage/pruning/triePruningStorer.go @@ -95,7 +95,7 @@ func (ps *triePruningStorer) PutInEpochWithoutCache(key []byte, data []byte, epo func (ps *triePruningStorer) GetFromOldEpochsWithoutAddingToCache(key []byte) ([]byte, core.OptionalUint32, error) { v, ok := ps.cacher.Get(key) if ok && !bytes.Equal([]byte(common.ActiveDBKey), key) { - ps.stateStatsHandler.IncrSnapshotCache() + ps.stateStatsHandler.IncrementSnapshotCache() return v.([]byte), core.OptionalUint32{}, nil } @@ -118,7 +118,7 @@ func (ps *triePruningStorer) GetFromOldEpochsWithoutAddingToCache(key []byte) ([ HasValue: true, } - ps.stateStatsHandler.IncrSnapshotPersister(epoch.Value) + ps.stateStatsHandler.IncrementSnapshotPersister(epoch.Value) return val, epoch, nil } diff --git a/trie/node.go b/trie/node.go index 6d82a238e95..754b3b3548d 100644 --- a/trie/node.go +++ b/trie/node.go @@ -152,7 +152,7 @@ func resolveIfCollapsed(n node, pos byte, db common.TrieStorageInteractor) error func handleStorageInteractorStats(db common.TrieStorageInteractor) { if db != nil { - db.GetStateStatsHandler().IncrTrie() + db.GetStateStatsHandler().IncrementTrie() } } From 923149b44d6bb78f5154d738804fdc7b9d13952e Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 16 Feb 2024 09:58:47 +0200 Subject: [PATCH 817/958] - fixed unit tests & added new stub --- facade/nodeFacade_test.go | 62 +++------- factory/api/apiResolverFactory_test.go | 1 + testscommon/stateStatisticsHandlerStub.go | 137 ++++++++++++++++++++++ 3 files changed, 154 insertions(+), 46 deletions(-) create mode 100644 testscommon/stateStatisticsHandlerStub.go diff --git a/facade/nodeFacade_test.go b/facade/nodeFacade_test.go index 116339589ec..21823b60b6e 100644 --- a/facade/nodeFacade_test.go +++ b/facade/nodeFacade_test.go @@ -1317,6 +1317,22 @@ func TestNodeFacade_GetEligibleManagedKeys(t *testing.T) { assert.Equal(t, expectedResult, result) } +func TestNodeFacade_GetLoadedKeys(t *testing.T) { + t.Parallel() + + providedLoadedKeys := []string{"pk1", "pk2"} + arg := createMockArguments() + arg.ApiResolver = &mock.ApiResolverStub{ + GetLoadedKeysCalled: func() []string { + return providedLoadedKeys + }, + } + nf, _ := NewNodeFacade(arg) + + keys := nf.GetLoadedKeys() + require.Equal(t, providedLoadedKeys, keys) +} + func TestNodeFacade_GetWaitingEpochsLeftForPublicKey(t *testing.T) { t.Parallel() @@ -2331,52 +2347,6 @@ func TestNodeFacade_GetInternalStartOfEpochMetaBlock(t *testing.T) { require.Equal(t, providedResponse, response) } -func TestNodeFacade_GetManagedKeys(t *testing.T) { - t.Parallel() - - providedCount := 100 - providedManagedKeys := []string{"pk1", "pk2"} - providedLoadedKeys := []string{"pk3", "pk4"} - providedEligibleKeys := []string{"pk5", "pk6"} - providedWaitingKeys := []string{"pk7", "pk8"} - arg := createMockArguments() - arg.ApiResolver = &mock.ApiResolverStub{ - GetManagedKeysCountCalled: func() int { - return providedCount - }, - GetManagedKeysCalled: func() []string { - return providedManagedKeys - }, - GetLoadedKeysCalled: func() []string { - return providedLoadedKeys - }, - GetEligibleManagedKeysCalled: func() ([]string, error) { - return providedEligibleKeys, nil - }, - GetWaitingManagedKeysCalled: func() ([]string, error) { - return providedWaitingKeys, nil - }, - } - nf, _ := NewNodeFacade(arg) - - count := nf.GetManagedKeysCount() - require.Equal(t, providedCount, count) - - keys := nf.GetManagedKeys() - require.Equal(t, providedManagedKeys, keys) - - keys = nf.GetLoadedKeys() - require.Equal(t, providedLoadedKeys, keys) - - keys, err := nf.GetEligibleManagedKeys() - require.Equal(t, providedEligibleKeys, keys) - require.Nil(t, err) - - keys, err = nf.GetWaitingManagedKeys() - require.Equal(t, providedWaitingKeys, keys) - require.Nil(t, err) -} - func TestNodeFacade_Close(t *testing.T) { t.Parallel() diff --git a/factory/api/apiResolverFactory_test.go b/factory/api/apiResolverFactory_test.go index ef1795d8a1a..e43ac2962d8 100644 --- a/factory/api/apiResolverFactory_test.go +++ b/factory/api/apiResolverFactory_test.go @@ -347,6 +347,7 @@ func createMockSCQueryElementArgs() api.SCQueryElementArgs { AppStatusHandlerCalled: func() core.AppStatusHandler { return &statusHandler.AppStatusHandlerStub{} }, + StateStatsHandlerField: &testscommon.StateStatisticsHandlerStub{}, }, DataComponents: &mock.DataComponentsMock{ Storage: genericMocks.NewChainStorerMock(0), diff --git a/testscommon/stateStatisticsHandlerStub.go b/testscommon/stateStatisticsHandlerStub.go new file mode 100644 index 00000000000..970aceedfda --- /dev/null +++ b/testscommon/stateStatisticsHandlerStub.go @@ -0,0 +1,137 @@ +package testscommon + +// StateStatisticsHandlerStub - +type StateStatisticsHandlerStub struct { + ResetCalled func() + ResetSnapshotCalled func() + IncrCacheCalled func() + CacheCalled func() uint64 + IncrSnapshotCacheCalled func() + SnapshotCacheCalled func() uint64 + IncrPersisterCalled func(epoch uint32) + PersisterCalled func(epoch uint32) uint64 + IncrSnapshotPersisterCalled func(epoch uint32) + SnapshotPersisterCalled func(epoch uint32) uint64 + IncrTrieCalled func() + TrieCalled func() uint64 + ProcessingStatsCalled func() []string + SnapshotStatsCalled func() []string +} + +// Reset - +func (stub *StateStatisticsHandlerStub) Reset() { + if stub.ResetCalled != nil { + stub.ResetCalled() + } +} + +// ResetSnapshot - +func (stub *StateStatisticsHandlerStub) ResetSnapshot() { + if stub.ResetSnapshotCalled != nil { + stub.ResetSnapshotCalled() + } +} + +// IncrCache - +// TODO: replace Incr with Increment on all usages in this file + rename the interface and the other 2 implementations +func (stub *StateStatisticsHandlerStub) IncrCache() { + if stub.IncrCacheCalled != nil { + stub.IncrCacheCalled() + } +} + +// Cache - +func (stub *StateStatisticsHandlerStub) Cache() uint64 { + if stub.CacheCalled != nil { + return stub.CacheCalled() + } + + return 0 +} + +// IncrSnapshotCache - +func (stub *StateStatisticsHandlerStub) IncrSnapshotCache() { + if stub.IncrSnapshotCacheCalled != nil { + stub.IncrSnapshotCacheCalled() + } +} + +// SnapshotCache - +func (stub *StateStatisticsHandlerStub) SnapshotCache() uint64 { + if stub.SnapshotCacheCalled != nil { + return stub.SnapshotCacheCalled() + } + + return 0 +} + +// IncrPersister - +func (stub *StateStatisticsHandlerStub) IncrPersister(epoch uint32) { + if stub.IncrPersisterCalled != nil { + stub.IncrPersisterCalled(epoch) + } +} + +// Persister - +func (stub *StateStatisticsHandlerStub) Persister(epoch uint32) uint64 { + if stub.PersisterCalled != nil { + return stub.PersisterCalled(epoch) + } + + return 0 +} + +// IncrSnapshotPersister - +func (stub *StateStatisticsHandlerStub) IncrSnapshotPersister(epoch uint32) { + if stub.IncrSnapshotPersisterCalled != nil { + stub.IncrSnapshotPersisterCalled(epoch) + } +} + +// SnapshotPersister - +func (stub *StateStatisticsHandlerStub) SnapshotPersister(epoch uint32) uint64 { + if stub.SnapshotPersisterCalled != nil { + return stub.SnapshotPersisterCalled(epoch) + } + + return 0 +} + +// IncrTrie - +func (stub *StateStatisticsHandlerStub) IncrTrie() { + if stub.IncrTrieCalled != nil { + stub.IncrTrieCalled() + } +} + +// Trie - +func (stub *StateStatisticsHandlerStub) Trie() uint64 { + if stub.TrieCalled != nil { + return stub.TrieCalled() + } + + return 0 +} + +// ProcessingStats - +func (stub *StateStatisticsHandlerStub) ProcessingStats() []string { + if stub.ProcessingStatsCalled != nil { + return stub.ProcessingStatsCalled() + } + + return make([]string, 0) +} + +// SnapshotStats - +func (stub *StateStatisticsHandlerStub) SnapshotStats() []string { + if stub.SnapshotStatsCalled != nil { + return stub.SnapshotStatsCalled() + } + + return make([]string, 0) +} + +// IsInterfaceNil - +func (stub *StateStatisticsHandlerStub) IsInterfaceNil() bool { + return stub == nil +} From c1d06c9a3fbb7416ac486c622899c00445e56207 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 16 Feb 2024 11:03:48 +0200 Subject: [PATCH 818/958] fix scenario with deactivation --- .../chainSimulator/staking/delegation_test.go | 1 + .../staking/stakeAndUnStake_test.go | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index cc523b7f1c5..8c6d621718c 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -43,6 +43,7 @@ const txVersion = 1 const mockTxSignature = "sig" const queuedStatus = "queued" const stakedStatus = "staked" +const unStakedStatus = "unStaked" const auctionStatus = "auction" const okReturnCode = "ok" const maxCap = "00" // no cap diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 7c9a808d3db..ef5e4d8af81 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -892,10 +892,27 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) require.Nil(t, err) + checkOneOfTheNodesIsUnstaked(t, metachainNode, blsKeys[:2]) +} + +func checkOneOfTheNodesIsUnstaked(t *testing.T, + metachainNode chainSimulatorProcess.NodeHandler, + blsKeys []string, +) { decodedBLSKey0, _ := hex.DecodeString(blsKeys[0]) - require.NotEqual(t, stakedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey0)) + keyStatus0 := getBLSKeyStatus(t, metachainNode, decodedBLSKey0) + log.Info("Key info", "key", blsKeys[0], "status", keyStatus0) + + isNotStaked0 := keyStatus0 == unStakedStatus + + require.NotEqual(t, stakedStatus, keyStatus0) decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) - require.NotEqual(t, stakedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey1)) + keyStatus1 := getBLSKeyStatus(t, metachainNode, decodedBLSKey1) + log.Info("Key info", "key", blsKeys[1], "status", keyStatus1) + + isNotStaked1 := keyStatus1 == unStakedStatus + + require.True(t, isNotStaked0 != isNotStaked1) } func testBLSKeyStaked(t *testing.T, From 7757ae9ce8d70449958fe973088c02caf3f17958 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 16 Feb 2024 11:05:46 +0200 Subject: [PATCH 819/958] removed t.Parallel --- node/chainSimulator/components/testOnlyProcessingNode_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 10ab4ecec70..fba412b937e 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -157,8 +157,6 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { t.Skip("cannot run with -race -short; requires Wasm VM fix") } - t.Parallel() - goodKeyValueMap := map[string]string{ "01": "02", } @@ -279,8 +277,6 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { t.Skip("cannot run with -race -short; requires Wasm VM fix") } - t.Parallel() - node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, err) From 7f00d6185b5e8883e43cfb131d64fe2055d0bd07 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 16 Feb 2024 11:12:49 +0200 Subject: [PATCH 820/958] update scenario with deactivation and reactivation --- .../chainSimulator/staking/stakeAndUnStake_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index ef5e4d8af81..19e5a3835ab 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -905,7 +905,6 @@ func checkOneOfTheNodesIsUnstaked(t *testing.T, isNotStaked0 := keyStatus0 == unStakedStatus - require.NotEqual(t, stakedStatus, keyStatus0) decodedBLSKey1, _ := hex.DecodeString(blsKeys[1]) keyStatus1 := getBLSKeyStatus(t, metachainNode, decodedBLSKey1) log.Info("Key info", "key", blsKeys[1], "status", keyStatus1) @@ -930,11 +929,6 @@ func testBLSKeyStaked(t *testing.T, activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey)) - - validatorInfo, found := validatorStatistics[blsKey] - require.True(t, found) - require.Equal(t, auctionStatus, validatorInfo.ValidatorStatus) - return } @@ -1217,4 +1211,11 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t expectedStaked = big.NewInt(5000) expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + log.Info("Step 6. Wait for change of epoch and check the outcome") + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + testBLSKeyStaked(t, cs, metachainNode, blsKeys[1], targetEpoch) } From 3635617e0d9efe8ec9fd97a4209442ec180ef89b Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 16 Feb 2024 11:16:58 +0200 Subject: [PATCH 821/958] merge delegation scenario: close cs --- .../chainSimulator/staking/delegation_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 8c6d621718c..bf16816ce25 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -903,6 +903,8 @@ func TestChainSimulator_MergeDelegation(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMergingDelegation(t, cs, 1) }) @@ -931,6 +933,8 @@ func TestChainSimulator_MergeDelegation(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMergingDelegation(t, cs, 2) }) @@ -959,6 +963,8 @@ func TestChainSimulator_MergeDelegation(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMergingDelegation(t, cs, 3) }) @@ -987,6 +993,8 @@ func TestChainSimulator_MergeDelegation(t *testing.T) { require.Nil(t, err) require.NotNil(t, cs) + defer cs.Close() + testChainSimulatorMergingDelegation(t, cs, 4) }) } From 8e483e0609317d22bf61e56cd23ef36b159e2cef Mon Sep 17 00:00:00 2001 From: ssd04 Date: Fri, 16 Feb 2024 12:57:50 +0200 Subject: [PATCH 822/958] improve test coverage --- storage/pruning/triePruningStorer_test.go | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/storage/pruning/triePruningStorer_test.go b/storage/pruning/triePruningStorer_test.go index 4d9a7c83227..28dc5c93f8e 100644 --- a/storage/pruning/triePruningStorer_test.go +++ b/storage/pruning/triePruningStorer_test.go @@ -76,6 +76,31 @@ func TestTriePruningStorer_GetFromOldEpochsWithoutCacheSearchesOnlyOldEpochsAndR assert.True(t, strings.Contains(err.Error(), "not found")) } +func TestTriePruningStorer_GetFromOldEpochsWithCache(t *testing.T) { + t.Parallel() + + args := getDefaultArgs() + ps, _ := pruning.NewTriePruningStorer(args) + cacher := testscommon.NewCacherMock() + ps.SetCacher(cacher) + + testKey1 := []byte("key1") + testVal1 := []byte("value1") + + err := ps.PutInEpoch(testKey1, testVal1, 0) + assert.Nil(t, err) + + err = ps.ChangeEpochSimple(1) + assert.Nil(t, err) + ps.SetEpochForPutOperation(1) + + res, epoch, err := ps.GetFromOldEpochsWithoutAddingToCache(testKey1) + assert.Equal(t, testVal1, res) + assert.Nil(t, err) + assert.False(t, epoch.HasValue) + assert.Equal(t, uint32(0), epoch.Value) +} + func TestTriePruningStorer_GetFromOldEpochsWithoutCacheLessActivePersisters(t *testing.T) { t.Parallel() From 4c23c9f8bc78a76bbea3896365cd939d39c13f24 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 16 Feb 2024 13:29:24 +0200 Subject: [PATCH 823/958] fix long tests --- integrationTests/testProcessorNode.go | 2 +- testscommon/shardingMocks/nodesCoordinatorStub.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 7704b9c1029..b4bdfe92657 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -3492,7 +3492,7 @@ func getDefaultNodesSetup(maxShards, numNodes uint32, address []byte, pksBytes m func getDefaultNodesCoordinator(maxShards uint32, pksBytes map[uint32][]byte) nodesCoordinator.NodesCoordinator { return &shardingMocks.NodesCoordinatorStub{ - ComputeValidatorsGroupCalled: func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validators []nodesCoordinator.Validator, err error) { + ComputeConsensusGroupCalled: func(randomness []byte, round uint64, shardId uint32, epoch uint32) (validators []nodesCoordinator.Validator, err error) { v, _ := nodesCoordinator.NewValidator(pksBytes[shardId], 1, defaultChancesSelection) return []nodesCoordinator.Validator{v}, nil }, diff --git a/testscommon/shardingMocks/nodesCoordinatorStub.go b/testscommon/shardingMocks/nodesCoordinatorStub.go index 0666b8f15df..b2f50d52eb6 100644 --- a/testscommon/shardingMocks/nodesCoordinatorStub.go +++ b/testscommon/shardingMocks/nodesCoordinatorStub.go @@ -8,7 +8,6 @@ import ( // NodesCoordinatorStub - type NodesCoordinatorStub struct { - ComputeValidatorsGroupCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]nodesCoordinator.Validator, error) GetValidatorsPublicKeysCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) GetValidatorsRewardsAddressesCalled func(randomness []byte, round uint64, shardId uint32, epoch uint32) ([]string, error) GetValidatorWithPublicKeyCalled func(publicKey []byte) (validator nodesCoordinator.Validator, shardId uint32, err error) From e41fe7e713fa1e5f03d67e14a51067181a47291f Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 16 Feb 2024 14:23:41 +0200 Subject: [PATCH 824/958] FEAT: Nodes config provider for api calls --- epochStart/notifier/errors.go | 5 ++ epochStart/notifier/nodesConfigProviderAPI.go | 69 +++++++++++++++++++ factory/processing/blockProcessorCreator.go | 6 +- 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 epochStart/notifier/errors.go create mode 100644 epochStart/notifier/nodesConfigProviderAPI.go diff --git a/epochStart/notifier/errors.go b/epochStart/notifier/errors.go new file mode 100644 index 00000000000..eba24016fa1 --- /dev/null +++ b/epochStart/notifier/errors.go @@ -0,0 +1,5 @@ +package notifier + +import "errors" + +var errNoMaxNodesConfigChangeForStakingV4 = errors.New("no MaxNodesChangeEnableEpoch config found for EpochEnable = StakingV4Step3EnableEpoch") diff --git a/epochStart/notifier/nodesConfigProviderAPI.go b/epochStart/notifier/nodesConfigProviderAPI.go new file mode 100644 index 00000000000..272c56a4a38 --- /dev/null +++ b/epochStart/notifier/nodesConfigProviderAPI.go @@ -0,0 +1,69 @@ +package notifier + +import ( + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/process" +) + +type nodesConfigProviderAPI struct { + *nodesConfigProvider + stakingV4Step2Epoch uint32 + stakingV4Step3MaxNodesConfig config.MaxNodesChangeConfig +} + +// NewNodesConfigProviderAPI returns a new instance of nodes config provider for API calls only, which provides the current +// max nodes change config based on the current epoch +func NewNodesConfigProviderAPI( + epochNotifier process.EpochNotifier, + cfg config.EnableEpochs, +) (*nodesConfigProviderAPI, error) { + nodesCfgProvider, err := NewNodesConfigProvider(epochNotifier, cfg.MaxNodesChangeEnableEpoch) + if err != nil { + return nil, err + } + + stakingV4Step3MaxNodesConfig, err := getStakingV4Step3MaxNodesConfig(nodesCfgProvider.allNodesConfigs, cfg.StakingV4Step3EnableEpoch) + if err != nil { + return nil, err + } + + return &nodesConfigProviderAPI{ + nodesConfigProvider: nodesCfgProvider, + stakingV4Step2Epoch: cfg.StakingV4Step2EnableEpoch, + stakingV4Step3MaxNodesConfig: stakingV4Step3MaxNodesConfig, + }, nil +} + +func getStakingV4Step3MaxNodesConfig( + allNodesConfigs []config.MaxNodesChangeConfig, + stakingV4Step3EnableEpoch uint32, +) (config.MaxNodesChangeConfig, error) { + for _, cfg := range allNodesConfigs { + if cfg.EpochEnable == stakingV4Step3EnableEpoch { + return cfg, nil + } + } + + return config.MaxNodesChangeConfig{}, errNoMaxNodesConfigChangeForStakingV4 +} + +// GetCurrentNodesConfig retrieves the current configuration of nodes. However, when invoked during epoch stakingV4 step 2 +// through API calls, it will provide the nodes configuration as it will appear in epoch stakingV4 step 3. This adjustment +// is made because, with the transition to step 3 at the epoch change, the maximum number of nodes will be reduced. +// Therefore, calling this API during step 2 aims to offer a preview of the upcoming epoch, accurately reflecting the +// adjusted number of nodes that will qualify from the auction. +func (ncp *nodesConfigProviderAPI) GetCurrentNodesConfig() config.MaxNodesChangeConfig { + ncp.mutex.RLock() + defer ncp.mutex.RUnlock() + + if ncp.currentNodesConfig.EpochEnable == ncp.stakingV4Step2Epoch { + return ncp.stakingV4Step3MaxNodesConfig + } + + return ncp.currentNodesConfig +} + +// IsInterfaceNil checks if the underlying pointer is nil +func (ncp *nodesConfigProviderAPI) IsInterfaceNil() bool { + return ncp == nil +} diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 33201b74772..7db9e20cf7d 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -912,10 +912,14 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } + maxNodesChangeConfigProviderAPI, err := notifier.NewNodesConfigProviderAPI(pcf.epochNotifier, pcf.epochConfig.EnableEpochs) + if err != nil { + return nil, err + } argsAuctionListSelectorAPI := metachainEpochStart.AuctionListSelectorArgs{ ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), StakingDataProvider: stakingDataProviderAPI, - MaxNodesChangeConfigProvider: maxNodesChangeConfigProvider, + MaxNodesChangeConfigProvider: maxNodesChangeConfigProviderAPI, SoftAuctionConfig: pcf.systemSCConfig.SoftAuctionConfig, Denomination: pcf.economicsConfig.GlobalSettings.Denomination, AuctionListDisplayHandler: factoryDisabled.NewDisabledAuctionListDisplayer(), From 2e2d064324456f02cf59a73ff4bedda06ac3da72 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 16 Feb 2024 14:58:00 +0200 Subject: [PATCH 825/958] FIX: Broken unit tests --- factory/processing/processComponents_test.go | 14 ++++++++++++-- testscommon/components/components.go | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index 9e4b8dc8e95..573e8675603 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -80,8 +80,18 @@ var ( func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFactoryArgs { args := processComp.ProcessComponentsFactoryArgs{ - Config: testscommon.GetGeneralConfig(), - EpochConfig: config.EpochConfig{}, + Config: testscommon.GetGeneralConfig(), + EpochConfig: config.EpochConfig{ + EnableEpochs: config.EnableEpochs{ + MaxNodesChangeEnableEpoch: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 100, + NodesToShufflePerShard: 2, + }, + }, + }, + }, PrefConfigs: config.Preferences{}, ImportDBConfig: config.ImportDbConfig{}, FlagsConfig: config.ContextFlagsConfig{ diff --git a/testscommon/components/components.go b/testscommon/components/components.go index 055c4ba37e2..64ea4f75c33 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -199,6 +199,13 @@ func GetCryptoArgs(coreComponents factory.CoreComponentsHolder) cryptoComp.Crypt }, EnableEpochs: config.EnableEpochs{ BLSMultiSignerEnableEpoch: []config.MultiSignerConfig{{EnableEpoch: 0, Type: "no-KOSK"}}, + MaxNodesChangeEnableEpoch: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 100, + NodesToShufflePerShard: 2, + }, + }, }, } @@ -572,6 +579,17 @@ func GetProcessArgs( Version: "v1.0.0", }, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, + EpochConfig: config.EpochConfig{ + EnableEpochs: config.EnableEpochs{ + MaxNodesChangeEnableEpoch: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 100, + NodesToShufflePerShard: 2, + }, + }, + }, + }, } } From b8ee2ed6e6d3484211157a3116e002172935398d Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 16 Feb 2024 15:20:32 +0200 Subject: [PATCH 826/958] FEAT: Unit tests nodes config provider api --- epochStart/notifier/nodesConfigProvider.go | 3 + epochStart/notifier/nodesConfigProviderAPI.go | 6 +- .../notifier/nodesConfigProviderAPI_test.go | 95 +++++++++++++++++++ 3 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 epochStart/notifier/nodesConfigProviderAPI_test.go diff --git a/epochStart/notifier/nodesConfigProvider.go b/epochStart/notifier/nodesConfigProvider.go index bdae9af17a3..273f750ae44 100644 --- a/epochStart/notifier/nodesConfigProvider.go +++ b/epochStart/notifier/nodesConfigProvider.go @@ -12,6 +12,7 @@ import ( type nodesConfigProvider struct { mutex sync.RWMutex + currentEpoch uint32 currentNodesConfig config.MaxNodesChangeConfig allNodesConfigs []config.MaxNodesChangeConfig } @@ -71,6 +72,8 @@ func (ncp *nodesConfigProvider) EpochConfirmed(epoch uint32, _ uint64) { ncp.currentNodesConfig = maxNodesConfig } } + + ncp.currentEpoch = epoch } // IsInterfaceNil checks if the underlying pointer is nil diff --git a/epochStart/notifier/nodesConfigProviderAPI.go b/epochStart/notifier/nodesConfigProviderAPI.go index 272c56a4a38..3db0d028ece 100644 --- a/epochStart/notifier/nodesConfigProviderAPI.go +++ b/epochStart/notifier/nodesConfigProviderAPI.go @@ -1,6 +1,8 @@ package notifier import ( + "fmt" + "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/process" ) @@ -44,7 +46,7 @@ func getStakingV4Step3MaxNodesConfig( } } - return config.MaxNodesChangeConfig{}, errNoMaxNodesConfigChangeForStakingV4 + return config.MaxNodesChangeConfig{}, fmt.Errorf("%w when creating api nodes config provider", errNoMaxNodesConfigChangeForStakingV4) } // GetCurrentNodesConfig retrieves the current configuration of nodes. However, when invoked during epoch stakingV4 step 2 @@ -56,7 +58,7 @@ func (ncp *nodesConfigProviderAPI) GetCurrentNodesConfig() config.MaxNodesChange ncp.mutex.RLock() defer ncp.mutex.RUnlock() - if ncp.currentNodesConfig.EpochEnable == ncp.stakingV4Step2Epoch { + if ncp.currentEpoch == ncp.stakingV4Step2Epoch { return ncp.stakingV4Step3MaxNodesConfig } diff --git a/epochStart/notifier/nodesConfigProviderAPI_test.go b/epochStart/notifier/nodesConfigProviderAPI_test.go new file mode 100644 index 00000000000..5438d533741 --- /dev/null +++ b/epochStart/notifier/nodesConfigProviderAPI_test.go @@ -0,0 +1,95 @@ +package notifier + +import ( + "testing" + + "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/common/forking" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/process" + epochNotifierMock "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" + "github.com/stretchr/testify/require" +) + +func getEnableEpochCfg() config.EnableEpochs { + return config.EnableEpochs{ + StakingV4Step1EnableEpoch: 2, + StakingV4Step2EnableEpoch: 3, + StakingV4Step3EnableEpoch: 4, + MaxNodesChangeEnableEpoch: []config.MaxNodesChangeConfig{ + { + EpochEnable: 0, + MaxNumNodes: 36, + NodesToShufflePerShard: 4, + }, + { + EpochEnable: 1, + MaxNumNodes: 64, + NodesToShufflePerShard: 2, + }, + { + EpochEnable: 4, + MaxNumNodes: 56, + NodesToShufflePerShard: 2, + }, + }, + } +} + +func TestNewNodesConfigProviderAPI(t *testing.T) { + t.Parallel() + + t.Run("nil epoch notifier, should return error", func(t *testing.T) { + ncp, err := NewNodesConfigProviderAPI(nil, config.EnableEpochs{}) + require.Equal(t, process.ErrNilEpochNotifier, err) + require.Nil(t, ncp) + }) + + t.Run("no nodes config for staking v4 step 3, should return error", func(t *testing.T) { + ncp, err := NewNodesConfigProviderAPI(&epochNotifierMock.EpochNotifierStub{}, config.EnableEpochs{}) + require.ErrorIs(t, err, errNoMaxNodesConfigChangeForStakingV4) + require.Nil(t, ncp) + }) + + t.Run("should work", func(t *testing.T) { + ncp, err := NewNodesConfigProviderAPI(&epochNotifierMock.EpochNotifierStub{}, getEnableEpochCfg()) + require.Nil(t, err) + require.False(t, ncp.IsInterfaceNil()) + }) +} + +func TestNodesConfigProviderAPI_GetCurrentNodesConfig(t *testing.T) { + t.Parallel() + + epochNotifier := forking.NewGenericEpochNotifier() + enableEpochCfg := getEnableEpochCfg() + ncp, _ := NewNodesConfigProviderAPI(epochNotifier, enableEpochCfg) + + maxNodesConfig1 := enableEpochCfg.MaxNodesChangeEnableEpoch[0] + maxNodesConfig2 := enableEpochCfg.MaxNodesChangeEnableEpoch[1] + maxNodesConfigStakingV4Step3 := enableEpochCfg.MaxNodesChangeEnableEpoch[2] + + require.Equal(t, maxNodesConfig1, ncp.GetCurrentNodesConfig()) + + epochNotifier.CheckEpoch(&block.Header{Epoch: enableEpochCfg.StakingV4Step1EnableEpoch}) + require.Equal(t, maxNodesConfig2, ncp.GetCurrentNodesConfig()) + + epochNotifier.CheckEpoch(&block.Header{Epoch: enableEpochCfg.StakingV4Step2EnableEpoch}) + require.Equal(t, maxNodesConfigStakingV4Step3, ncp.GetCurrentNodesConfig()) + + epochNotifier.CheckEpoch(&block.Header{Epoch: enableEpochCfg.StakingV4Step3EnableEpoch}) + require.Equal(t, maxNodesConfigStakingV4Step3, ncp.GetCurrentNodesConfig()) + + epochNotifier.CheckEpoch(&block.Header{Epoch: enableEpochCfg.StakingV4Step3EnableEpoch + 1}) + require.Equal(t, maxNodesConfigStakingV4Step3, ncp.GetCurrentNodesConfig()) + + // simulate restart + epochNotifier.CheckEpoch(&block.Header{Epoch: 0}) + epochNotifier.CheckEpoch(&block.Header{Epoch: enableEpochCfg.StakingV4Step2EnableEpoch}) + require.Equal(t, maxNodesConfigStakingV4Step3, ncp.GetCurrentNodesConfig()) + + // simulate restart + epochNotifier.CheckEpoch(&block.Header{Epoch: 0}) + epochNotifier.CheckEpoch(&block.Header{Epoch: enableEpochCfg.StakingV4Step3EnableEpoch}) + require.Equal(t, maxNodesConfigStakingV4Step3, ncp.GetCurrentNodesConfig()) +} From bd8c482757fdcb354b306caeb123c09b22ff33d4 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 16 Feb 2024 15:48:35 +0200 Subject: [PATCH 827/958] remove t.Parallel from testOnlyProcessingNode tests --- .../components/testOnlyProcessingNode_test.go | 52 ------------------- 1 file changed, 52 deletions(-) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index fba412b937e..c2603c62441 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -46,19 +46,13 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo } func TestNewTestOnlyProcessingNode(t *testing.T) { - t.Parallel() - t.Run("should work", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) assert.Nil(t, err) assert.NotNil(t, node) }) t.Run("try commit a block", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) assert.Nil(t, err) @@ -86,8 +80,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { assert.Nil(t, err) }) t.Run("CreateCoreComponents failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.Configs.GeneralConfig.Marshalizer.Type = "invalid type" node, err := NewTestOnlyProcessingNode(args) @@ -95,8 +87,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { require.Nil(t, node) }) t.Run("CreateCryptoComponents failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.Configs.GeneralConfig.PublicKeyPIDSignature.Type = "invalid type" node, err := NewTestOnlyProcessingNode(args) @@ -104,8 +94,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { require.Nil(t, node) }) t.Run("CreateNetworkComponents failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.SyncedBroadcastNetwork = nil node, err := NewTestOnlyProcessingNode(args) @@ -113,8 +101,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { require.Nil(t, node) }) t.Run("CreateBootstrapComponents failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.Configs.FlagsConfig.WorkingDir = "" node, err := NewTestOnlyProcessingNode(args) @@ -122,8 +108,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { require.Nil(t, node) }) t.Run("CreateStateComponents failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.ShardIDStr = common.MetachainShardName // coverage only args.Configs.GeneralConfig.StateTriesConfig.MaxStateTrieLevelInMemory = 0 @@ -132,8 +116,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { require.Nil(t, node) }) t.Run("CreateProcessComponents failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.Configs.FlagsConfig.Version = "" node, err := NewTestOnlyProcessingNode(args) @@ -141,8 +123,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { require.Nil(t, node) }) t.Run("createFacade failure should error", func(t *testing.T) { - t.Parallel() - args := createMockArgsTestOnlyProcessingNode(t) args.Configs.EpochConfig.GasSchedule.GasScheduleByEpochs = nil node, err := NewTestOnlyProcessingNode(args) @@ -152,11 +132,6 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { } func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { - // TODO reinstate test after Wasm VM pointer fix - if testing.Short() { - t.Skip("cannot run with -race -short; requires Wasm VM fix") - } - goodKeyValueMap := map[string]string{ "01": "02", } @@ -194,8 +169,6 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { require.True(t, strings.Contains(err.Error(), "cannot decode value")) }) t.Run("LoadAccount failure should error", func(t *testing.T) { - t.Parallel() - argsLocal := createMockArgsTestOnlyProcessingNode(t) nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) require.NoError(t, errLocal) @@ -212,8 +185,6 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { require.Equal(t, expectedErr, errLocal) }) t.Run("account un-castable to UserAccountHandler should error", func(t *testing.T) { - t.Parallel() - argsLocal := createMockArgsTestOnlyProcessingNode(t) nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) require.NoError(t, errLocal) @@ -231,8 +202,6 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { require.Equal(t, "cannot cast AccountHandler to UserAccountHandler", errLocal.Error()) }) t.Run("SaveKeyValue failure should error", func(t *testing.T) { - t.Parallel() - nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, errLocal) @@ -252,8 +221,6 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { require.Equal(t, expectedErr, errLocal) }) t.Run("SaveAccount failure should error", func(t *testing.T) { - t.Parallel() - argsLocal := createMockArgsTestOnlyProcessingNode(t) nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) require.NoError(t, errLocal) @@ -272,11 +239,6 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { } func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { - // TODO reinstate test after Wasm VM pointer fix - if testing.Short() { - t.Skip("cannot run with -race -short; requires Wasm VM fix") - } - node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, err) @@ -306,8 +268,6 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { require.Equal(t, addressState.Nonce, account.GetNonce()) }) t.Run("LoadAccount failure should error", func(t *testing.T) { - t.Parallel() - nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, errLocal) @@ -330,8 +290,6 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { require.Equal(t, "cannot convert string balance to *big.Int", err.Error()) }) t.Run("AddToBalance failure should error", func(t *testing.T) { - t.Parallel() - nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, errLocal) @@ -351,8 +309,6 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { require.Equal(t, expectedErr, errLocal) }) t.Run("SaveKeyValue failure should error", func(t *testing.T) { - t.Parallel() - argsLocal := createMockArgsTestOnlyProcessingNode(t) nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) require.NoError(t, errLocal) @@ -424,8 +380,6 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { require.Error(t, err) }) t.Run("SaveAccount failure should error", func(t *testing.T) { - t.Parallel() - argsLocal := createMockArgsTestOnlyProcessingNode(t) nodeLocal, errLocal := NewTestOnlyProcessingNode(argsLocal) require.NoError(t, errLocal) @@ -444,8 +398,6 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { } func TestTestOnlyProcessingNode_IsInterfaceNil(t *testing.T) { - t.Parallel() - var node *testOnlyProcessingNode require.True(t, node.IsInterfaceNil()) @@ -454,8 +406,6 @@ func TestTestOnlyProcessingNode_IsInterfaceNil(t *testing.T) { } func TestTestOnlyProcessingNode_Close(t *testing.T) { - t.Parallel() - node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, err) @@ -463,8 +413,6 @@ func TestTestOnlyProcessingNode_Close(t *testing.T) { } func TestTestOnlyProcessingNode_Getters(t *testing.T) { - t.Parallel() - node := &testOnlyProcessingNode{} require.Nil(t, node.GetProcessComponents()) require.Nil(t, node.GetChainHandler()) From 3a90de9d8579a98b1eb32ae8e59b59125638414c Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 16 Feb 2024 16:48:45 +0200 Subject: [PATCH 828/958] fix after review --- .../components/testOnlyProcessingNode_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index c2603c62441..6ee1620f888 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -132,6 +132,11 @@ func TestNewTestOnlyProcessingNode(t *testing.T) { } func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + goodKeyValueMap := map[string]string{ "01": "02", } @@ -239,6 +244,11 @@ func TestTestOnlyProcessingNode_SetKeyValueForAddress(t *testing.T) { } func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, err) From f4bc0df1b44650c7aa170590508f4357f599fc58 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 16 Feb 2024 17:07:26 +0200 Subject: [PATCH 829/958] FEAT: Chain simulator test for staking v4 step 2 api calls --- .../staking/simpleStake_test.go | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/integrationTests/chainSimulator/staking/simpleStake_test.go b/integrationTests/chainSimulator/staking/simpleStake_test.go index 424b7d30e08..6b00cceb967 100644 --- a/integrationTests/chainSimulator/staking/simpleStake_test.go +++ b/integrationTests/chainSimulator/staking/simpleStake_test.go @@ -9,10 +9,12 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/vm" "github.com/stretchr/testify/require" ) @@ -129,3 +131,133 @@ func testChainSimulatorSimpleStake(t *testing.T, targetEpoch int32, nodesStatus checkValidatorStatus(t, cs, blsKeys[2], nodesStatus) } } + +// Test auction list api calls during stakingV4 step 2 and onwards. +// Nodes configuration at genesis consisting of a total of 32 nodes, distributed on 3 shards + meta: +// - 4 eligible nodes/shard +// - 4 waiting nodes/shard +// - 2 nodes to shuffle per shard +// - max num nodes config for stakingV4 step3 = 24 (being downsized from previously 32 nodes) +// Steps: +// 1. Stake 1 node and check that in stakingV4 step1 it is found in auction +// 2. From stakingV4 step2 onwards, check that api returns 8 qualified + 1 unqualified nodes +func TestChainSimulator_StakingV4Step2APICalls(t *testing.T) { + stakingV4Step1Epoch := uint32(2) + stakingV4Step2Epoch := uint32(3) + stakingV4Step3Epoch := uint32(4) + + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: uint64(6000), + RoundsPerEpoch: core.OptionalUint64{ + HasValue: true, + Value: 30, + }, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 4, + MetaChainMinNodes: 4, + NumNodesWaitingListMeta: 4, + NumNodesWaitingListShard: 4, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = stakingV4Step1Epoch + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = stakingV4Step2Epoch + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = stakingV4Step3Epoch + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[1].MaxNumNodes = 32 + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[1].NodesToShufflePerShard = 2 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = stakingV4Step3Epoch + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].MaxNumNodes = 24 + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].NodesToShufflePerShard = 2 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + + mintValue := big.NewInt(0).Add(minimumStakeValue, oneEGLD) + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + // Stake a new validator that should end up in auction in step 1 + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, minimumStakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + err = cs.GenerateBlocksUntilEpochIsReached(int32(stakingV4Step1Epoch)) + require.Nil(t, err) + require.Nil(t, err) + err = cs.GenerateBlocks(2) + + // In step 1, only the previously staked node should be in auction list + err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + auctionList, err := metachainNode.GetProcessComponents().ValidatorsProvider().GetAuctionList() + require.Nil(t, err) + require.Equal(t, []*common.AuctionListValidatorAPIResponse{ + { + Owner: validatorOwner.Bech32, + NumStakedNodes: 1, + TotalTopUp: "0", + TopUpPerNode: "0", + QualifiedTopUp: "0", + Nodes: []*common.AuctionNode{ + { + BlsKey: blsKeys[0], + Qualified: true, + }, + }, + }, + }, auctionList) + + // For steps 2,3 and onwards, when making API calls, we'll be using the api nodes config provider to mimic the max number of + // nodes as it will be in step 3. This means we'll see the 8 nodes that were shuffled out from the eligible list, + // plus the additional node that was staked manually. + // Since those 8 shuffled out nodes will be replaced only with another 8 nodes, and the auction list size = 9, + // the outcome should show 8 nodes qualifying and 1 node not qualifying + for epochToSimulate := int32(stakingV4Step2Epoch); epochToSimulate < int32(stakingV4Step3Epoch)+3; epochToSimulate++ { + err = cs.GenerateBlocksUntilEpochIsReached(epochToSimulate) + require.Nil(t, err) + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + numQualified, numUnQualified := getNumQualifiedAndUnqualified(t, metachainNode) + require.Equal(t, 8, numQualified) + require.Equal(t, 1, numUnQualified) + } +} + +func getNumQualifiedAndUnqualified(t *testing.T, metachainNode process.NodeHandler) (int, int) { + err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + auctionList, err := metachainNode.GetProcessComponents().ValidatorsProvider().GetAuctionList() + require.Nil(t, err) + + numQualified := 0 + numUnQualified := 0 + + for _, auctionOwnerData := range auctionList { + for _, auctionNode := range auctionOwnerData.Nodes { + if auctionNode.Qualified { + numQualified++ + } else { + numUnQualified++ + } + } + } + + return numQualified, numUnQualified +} From 162c4a77ce1bc4c4492aa3c0dd964be3ea03f5f4 Mon Sep 17 00:00:00 2001 From: MariusC Date: Fri, 16 Feb 2024 17:13:09 +0200 Subject: [PATCH 830/958] FIX: Linter --- integrationTests/chainSimulator/staking/simpleStake_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/simpleStake_test.go b/integrationTests/chainSimulator/staking/simpleStake_test.go index 6b00cceb967..79e606c0fa3 100644 --- a/integrationTests/chainSimulator/staking/simpleStake_test.go +++ b/integrationTests/chainSimulator/staking/simpleStake_test.go @@ -199,8 +199,8 @@ func TestChainSimulator_StakingV4Step2APICalls(t *testing.T) { metachainNode := cs.GetNodeHandler(core.MetachainShardId) err = cs.GenerateBlocksUntilEpochIsReached(int32(stakingV4Step1Epoch)) require.Nil(t, err) - require.Nil(t, err) err = cs.GenerateBlocks(2) + require.Nil(t, err) // In step 1, only the previously staked node should be in auction list err = metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() From e92dd3e0332af3aa470805d558df21cc3635bf2d Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 16 Feb 2024 17:41:41 +0200 Subject: [PATCH 831/958] bootstrapComponentsHolder tests --- .../components/bootstrapComponents.go | 2 +- .../components/bootstrapComponents_test.go | 191 ++++++++++++++++++ 2 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 node/chainSimulator/components/bootstrapComponents_test.go diff --git a/node/chainSimulator/components/bootstrapComponents.go b/node/chainSimulator/components/bootstrapComponents.go index b40eeb0810d..410cbf7f477 100644 --- a/node/chainSimulator/components/bootstrapComponents.go +++ b/node/chainSimulator/components/bootstrapComponents.go @@ -39,7 +39,7 @@ type bootstrapComponentsHolder struct { } // CreateBootstrapComponents will create a new instance of bootstrap components holder -func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (factory.BootstrapComponentsHandler, error) { +func CreateBootstrapComponents(args ArgsBootstrapComponentsHolder) (*bootstrapComponentsHolder, error) { instance := &bootstrapComponentsHolder{ closeHandler: NewCloseHandler(), } diff --git a/node/chainSimulator/components/bootstrapComponents_test.go b/node/chainSimulator/components/bootstrapComponents_test.go new file mode 100644 index 00000000000..29304e03498 --- /dev/null +++ b/node/chainSimulator/components/bootstrapComponents_test.go @@ -0,0 +1,191 @@ +package components + +import ( + "testing" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data/typeConverters" + "github.com/multiversx/mx-chain-core-go/hashing" + "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" + "github.com/multiversx/mx-chain-go/storage" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" + "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" + "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/stretchr/testify/require" +) + +func createArgsBootstrapComponentsHolder() ArgsBootstrapComponentsHolder { + return ArgsBootstrapComponentsHolder{ + CoreComponents: &factory.CoreComponentsHolderStub{ + ChainIDCalled: func() string { + return "T" + }, + GenesisNodesSetupCalled: func() sharding.GenesisNodesSetupHandler { + return &testscommon.NodesSetupStub{} + }, + InternalMarshalizerCalled: func() marshal.Marshalizer { + return &testscommon.MarshallerStub{} + }, + EpochNotifierCalled: func() process.EpochNotifier { + return &epochNotifier.EpochNotifierStub{} + }, + EconomicsDataCalled: func() process.EconomicsDataHandler { + return &economicsmocks.EconomicsHandlerMock{} + }, + RaterCalled: func() sharding.PeerAccountListAndRatingHandler { + return &testscommon.RaterMock{} + }, + NodesShufflerCalled: func() nodesCoordinator.NodesShuffler { + return &shardingMocks.NodeShufflerMock{} + }, + RoundHandlerCalled: func() consensus.RoundHandler { + return &testscommon.RoundHandlerMock{} + }, + HasherCalled: func() hashing.Hasher { + return &testscommon.HasherStub{} + }, + PathHandlerCalled: func() storage.PathManagerHandler { + return &testscommon.PathManagerStub{} + }, + TxMarshalizerCalled: func() marshal.Marshalizer { + return &testscommon.MarshallerStub{} + }, + AddressPubKeyConverterCalled: func() core.PubkeyConverter { + return &testscommon.PubkeyConverterStub{} + }, + Uint64ByteSliceConverterCalled: func() typeConverters.Uint64ByteSliceConverter { + return &mock.Uint64ByteSliceConverterMock{} + }, + TxSignHasherCalled: func() hashing.Hasher { + return &testscommon.HasherStub{} + }, + }, + CryptoComponents: &mock.CryptoComponentsStub{ + PubKey: &mock.PublicKeyMock{}, + BlockSig: &cryptoMocks.SingleSignerStub{}, + BlKeyGen: &cryptoMocks.KeyGenStub{}, + TxSig: &cryptoMocks.SingleSignerStub{}, + TxKeyGen: &cryptoMocks.KeyGenStub{}, + ManagedPeersHolderField: &testscommon.ManagedPeersHolderStub{}, + }, + NetworkComponents: &mock.NetworkComponentsStub{ + Messenger: &p2pmocks.MessengerStub{}, + FullArchiveNetworkMessengerField: &p2pmocks.MessengerStub{}, + }, + StatusCoreComponents: &factory.StatusCoreComponentsStub{ + TrieSyncStatisticsField: &testscommon.SizeSyncStatisticsHandlerStub{}, + AppStatusHandlerField: &statusHandler.AppStatusHandlerStub{}, + StateStatsHandlerField: &testscommon.StateStatisticsHandlerStub{}, + }, + WorkingDir: ".", + FlagsConfig: config.ContextFlagsConfig{}, + ImportDBConfig: config.ImportDbConfig{}, + PrefsConfig: config.Preferences{}, + Config: config.Config{ + EpochStartConfig: config.EpochStartConfig{ + MinNumConnectedPeersToStart: 1, + MinNumOfPeersToConsiderBlockValid: 1, + }, + TrieSync: config.TrieSyncConfig{ + MaxHardCapForMissingNodes: 1, + NumConcurrentTrieSyncers: 1, + }, + GeneralSettings: config.GeneralSettingsConfig{ + SetGuardianEpochsDelay: 1, + }, + Versions: config.VersionsConfig{ + Cache: config.CacheConfig{ + Type: "LRU", + Capacity: 123, + }, + DefaultVersion: "1", + VersionsByEpochs: []config.VersionByEpochs{ + { + StartEpoch: 0, + Version: "1", + }, + }, + }, + WhiteListPool: config.CacheConfig{ + Type: "LRU", + Capacity: 123, + }, + }, + ShardIDStr: "0", + } +} + +func TestCreateBootstrapComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateBootstrapComponents(createArgsBootstrapComponentsHolder()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("NewBootstrapComponentsFactory failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsBootstrapComponentsHolder() + args.StatusCoreComponents = &factory.StatusCoreComponentsStub{} + comp, err := CreateBootstrapComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("managedBootstrapCreate failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsBootstrapComponentsHolder() + args.StatusCoreComponents = &factory.StatusCoreComponentsStub{ + TrieSyncStatisticsField: &testscommon.SizeSyncStatisticsHandlerStub{}, + AppStatusHandlerField: &statusHandler.AppStatusHandlerStub{}, + } + comp, err := CreateBootstrapComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestBootstrapComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *bootstrapComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateBootstrapComponents(createArgsBootstrapComponentsHolder()) + require.False(t, comp.IsInterfaceNil()) +} + +func TestBootstrapComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + comp, err := CreateBootstrapComponents(createArgsBootstrapComponentsHolder()) + require.NoError(t, err) + + require.NotNil(t, comp.EpochStartBootstrapper()) + require.NotNil(t, comp.EpochBootstrapParams()) + require.NotEmpty(t, comp.NodeType()) + require.NotNil(t, comp.ShardCoordinator()) + require.NotNil(t, comp.VersionedHeaderFactory()) + require.NotNil(t, comp.HeaderVersionHandler()) + require.NotNil(t, comp.HeaderIntegrityVerifier()) + require.NotNil(t, comp.GuardedAccountHandler()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) +} From a868baa717d9a8b1904b739b88c0c4ebba2a135a Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 16 Feb 2024 18:42:31 +0200 Subject: [PATCH 832/958] - fixes after merge --- factory/api/apiResolverFactory.go | 6 +++--- go.mod | 4 ++-- go.sum | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 515daf033d8..13373a0c50b 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -353,12 +353,12 @@ func createScQueryElement( apiBlockchain, err := createBlockchainForScQuery(selfShardID) if err != nil { - return nil, err + return nil, nil, err } - accountsAdapterApi, err := createNewAccountsAdapterApi(args, apiBlockchain) + accountsAdapterApi, storageManager, err := createNewAccountsAdapterApi(args, apiBlockchain) if err != nil { - return nil, err + return nil, nil, err } builtInFuncFactory, err := createBuiltinFuncs( diff --git a/go.mod b/go.mod index 092a7006c38..9626fb8530d 100644 --- a/go.mod +++ b/go.mod @@ -21,8 +21,8 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 - github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 + github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130132341-93fdd39a4ebb + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216161541-26d85a6428e1 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 diff --git a/go.sum b/go.sum index fcbb3672f50..9bb73d6b6a8 100644 --- a/go.sum +++ b/go.sum @@ -399,10 +399,10 @@ github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 h1:/EYv/HGX0OKbeNFt667J0yZRtuJiZH0lEK8YtobuH/c= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 h1:zImJa/r6B5L2OLWbKTn5io53U11PPGDla12H2OaJ9y0= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 h1:NMHNT4NcqOdnHttYsT3ydZHVapwOctp6t+WDGDy0UEQ= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130132341-93fdd39a4ebb h1:wIyvWXmCkEwN8sh1qzwAvU5Zix71tAR7wPOfOsacRE0= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130132341-93fdd39a4ebb/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216161541-26d85a6428e1 h1:h/ehvb/5YPYY34Kr9ftICH8/sLwU3wmAsssg/vkR6Is= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216161541-26d85a6428e1/go.mod h1:Xs0xFsPv+c1p8pwurLV7VBS7bEpIN/0jZrCwXVU26zw= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 h1:1uMlT5TjiHUlx81fEH/WQANWlY0PjF3opMlW+E3L3GI= From c8e3b6d496c3b292ccf32ef3937f05c5f8f10cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 16 Feb 2024 21:52:50 +0200 Subject: [PATCH 833/958] Integrate VM branches with shim for wasmer 1. --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index fbd61b07d8d..d9001fd8c47 100644 --- a/go.mod +++ b/go.mod @@ -19,13 +19,13 @@ require ( github.com/multiversx/mx-chain-crypto-go v1.2.9 github.com/multiversx/mx-chain-es-indexer-go v1.4.18 github.com/multiversx/mx-chain-logger-go v1.0.13 - github.com/multiversx/mx-chain-scenario-go v1.3.0 + github.com/multiversx/mx-chain-scenario-go v1.4.1 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.11 - github.com/multiversx/mx-chain-vm-go v1.5.26 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216193401-b4cb46e6e87b + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240216194327-581d1a5e62d9 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240216194415-8ed1f3b92aac + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216194026-53c42d212ddd github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil v3.21.11+incompatible diff --git a/go.sum b/go.sum index b7cb342ed43..c7693c9c761 100644 --- a/go.sum +++ b/go.sum @@ -395,20 +395,20 @@ github.com/multiversx/mx-chain-es-indexer-go v1.4.18 h1:rCA+/mn/77MyB7c8FjtabdQe github.com/multiversx/mx-chain-es-indexer-go v1.4.18/go.mod h1:maraR9xXcfi0lLifhGMc+DVHpw1IOPX/c89HVckF1Js= github.com/multiversx/mx-chain-logger-go v1.0.13 h1:eru/TETo0MkO4ZTnXsQDKf4PBRpAXmqjT02klNT/JnY= github.com/multiversx/mx-chain-logger-go v1.0.13/go.mod h1:MZJhTAtZTJxT+yK2EHc4ZW3YOHUc1UdjCD0iahRNBZk= -github.com/multiversx/mx-chain-scenario-go v1.3.0 h1:Vm6jYipJuIcJt8kamgXkePtKkwXaF5Lv5DglZjE5o8I= -github.com/multiversx/mx-chain-scenario-go v1.3.0/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= +github.com/multiversx/mx-chain-scenario-go v1.4.1 h1:CrVXb1aNBRiFfSfpoMAUoGUy2aNXke5WnoesLdFxC2g= +github.com/multiversx/mx-chain-scenario-go v1.4.1/go.mod h1:Sdgz8nzA9Ki/pdY/e2a4k90LALBKQB1Eo8HeCV3Bkzo= github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0OabSQnpxai5WKhi1YCs= github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.11 h1:rAQR00ALKOmWAuNA8XW8hR02M9gmrAE4WZwyJH4dMMU= github.com/multiversx/mx-chain-vm-common-go v1.5.11/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= -github.com/multiversx/mx-chain-vm-go v1.5.26 h1:ZjUJTG9cO2h5WNRIZ50ZSZNsTEPqXXPGS9Y/SAGyC2A= -github.com/multiversx/mx-chain-vm-go v1.5.26/go.mod h1:gNZ/s4Z6OHg6ZeBsW6aDxWQduXsRS0Bsv4pfkmHeRzs= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65 h1:TxFjQH0dXC/ACQxlIgJbO7pVoh00rcqeKSnIjWTDMxg= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.65/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66 h1:xgrXfHKa0Za4xjFj5W0FcYEivjrQIhLvGEFXXa1uQZU= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.66/go.mod h1:mx6IOAqo7zjSinYd8D2YqlpMWsuqFoYXJ6bntnTOeQg= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94 h1:MZFEBjDmfwLGB0cZb/pvlLx+qRv/9tO83bEgHUk34is= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.94/go.mod h1:uuSbZGe0UwOWQyHA4EeJWhs8UeDdhtmMwlhNaX9ppx0= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216193401-b4cb46e6e87b h1:xZiHpFFei/tC8hPRaKMl13BDFXLM7GVBzbXUA1oe8n0= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216193401-b4cb46e6e87b/go.mod h1:Y1O50Z7+suo4D1hnSBA7n34KvgKs5W9jzoEGwpfAjks= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240216194327-581d1a5e62d9 h1:txF01BBn2rpSi6W91r1z0wPa8jdr0srs1v+dju0TSl0= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240216194327-581d1a5e62d9/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240216194415-8ed1f3b92aac h1:RQn1xU7tIXmOEIUp38UjKzzwWPhsxa8Kmu7URg8EZ2A= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240216194415-8ed1f3b92aac/go.mod h1:mx6IOAqo7zjSinYd8D2YqlpMWsuqFoYXJ6bntnTOeQg= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216194026-53c42d212ddd h1:aEv/+/nd8HZt7WaKmrM4rt+aB2OTysDP0viMJp2+WQU= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216194026-53c42d212ddd/go.mod h1:t4YcFK6VJkG1wGKx1JK4jyowo9zfGFpi8Jl3ycfqAxw= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From d553a937ee08c7b743f8371dcfb98d22c22ae74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 16 Feb 2024 22:06:41 +0200 Subject: [PATCH 834/958] Fix reference. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d9001fd8c47..b80e90eade5 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.4.1 github.com/multiversx/mx-chain-storage-go v1.0.14 github.com/multiversx/mx-chain-vm-common-go v1.5.11 - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216193401-b4cb46e6e87b + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216200544-4034119a7e4f github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240216194327-581d1a5e62d9 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240216194415-8ed1f3b92aac github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216194026-53c42d212ddd diff --git a/go.sum b/go.sum index c7693c9c761..af8a32eea2f 100644 --- a/go.sum +++ b/go.sum @@ -401,8 +401,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.14 h1:h0acoqPS3FKJ4S3cKBEriTU0Oab github.com/multiversx/mx-chain-storage-go v1.0.14/go.mod h1:sJ2q49tgjxNpMpsHysjABqCAB0FLBmDblbjBkQ8XfmA= github.com/multiversx/mx-chain-vm-common-go v1.5.11 h1:rAQR00ALKOmWAuNA8XW8hR02M9gmrAE4WZwyJH4dMMU= github.com/multiversx/mx-chain-vm-common-go v1.5.11/go.mod h1:T04rZt/VdwjPXcXVxltMmDmrhxNXsqlByYbWNWcNLYA= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216193401-b4cb46e6e87b h1:xZiHpFFei/tC8hPRaKMl13BDFXLM7GVBzbXUA1oe8n0= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216193401-b4cb46e6e87b/go.mod h1:Y1O50Z7+suo4D1hnSBA7n34KvgKs5W9jzoEGwpfAjks= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216200544-4034119a7e4f h1:Jh2jT7vS2Z7A21DVA0ahua0nAAFb2PrJC4fI4Y08xZE= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216200544-4034119a7e4f/go.mod h1:Y1O50Z7+suo4D1hnSBA7n34KvgKs5W9jzoEGwpfAjks= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240216194327-581d1a5e62d9 h1:txF01BBn2rpSi6W91r1z0wPa8jdr0srs1v+dju0TSl0= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240216194327-581d1a5e62d9/go.mod h1:UUUxIU7mlRkz+Jz4GWV2GkgJt2mKd+j1kky++RNYc9s= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240216194415-8ed1f3b92aac h1:RQn1xU7tIXmOEIUp38UjKzzwWPhsxa8Kmu7URg8EZ2A= From 7c2fc6fc436271fb7cda86929c119ccfd8cdc3cb Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Sat, 17 Feb 2024 12:13:25 +0200 Subject: [PATCH 835/958] use proper DelegationSmartContractFlag flag --- epochStart/metachain/legacySystemSCs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/legacySystemSCs.go b/epochStart/metachain/legacySystemSCs.go index 5cc0ac96d84..327a5ab88e5 100644 --- a/epochStart/metachain/legacySystemSCs.go +++ b/epochStart/metachain/legacySystemSCs.go @@ -164,7 +164,7 @@ func (s *legacySystemSCProcessor) processLegacy( } } - if s.enableEpochsHandler.IsFlagEnabled(common.DelegationSmartContractFlag) { + if s.enableEpochsHandler.IsFlagEnabled(common.DelegationSmartContractFlagInSpecificEpochOnly) { err := s.initDelegationSystemSC() if err != nil { return err From a6aa80b8c7141975a5d0eee03bca7acb5f175200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Sat, 17 Feb 2024 14:29:30 +0200 Subject: [PATCH 836/958] Do not create older VMs. --- process/factory/shard/vmContainerFactory.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/process/factory/shard/vmContainerFactory.go b/process/factory/shard/vmContainerFactory.go index 92eb6292008..39b7d91183b 100644 --- a/process/factory/shard/vmContainerFactory.go +++ b/process/factory/shard/vmContainerFactory.go @@ -282,12 +282,12 @@ func (vmf *vmContainerFactory) getMatchingVersion(epoch uint32) config.WasmVMVer func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { logVMContainerFactory.Debug("createInProcessWasmVMByVersion", "version", version) switch version.Version { - case "v1.2": - return vmf.createInProcessWasmVMV12() - case "v1.3": - return vmf.createInProcessWasmVMV13() - case "v1.4": - return vmf.createInProcessWasmVMV14() + // case "v1.2": + // return vmf.createInProcessWasmVMV12() + // case "v1.3": + // return vmf.createInProcessWasmVMV13() + // case "v1.4": + // return vmf.createInProcessWasmVMV14() default: return vmf.createInProcessWasmVMV15() } From 2ba4f5bf65aa7b705155179ba6a6736011038582 Mon Sep 17 00:00:00 2001 From: radu chis Date: Sat, 17 Feb 2024 14:34:42 +0200 Subject: [PATCH 837/958] proper flag for GovernanceFlagInSpecificEpochOnly --- epochStart/metachain/systemSCs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index cfbefbd8bcd..4b608300b3c 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -127,7 +127,7 @@ func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlag) { + if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlagInSpecificEpochOnly) { err := s.updateToGovernanceV2() if err != nil { return err From 22e0cd2a39aa351d50df84fbdec86716855be729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Sat, 17 Feb 2024 21:26:09 +0200 Subject: [PATCH 838/958] Remove legacy checks. Add extra logs. --- process/smartContract/scQueryService.go | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index eb3d9b95e4e..0848fb77882 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -39,7 +39,6 @@ type SCQueryService struct { blockChainHook process.BlockChainHookWithAccountsAdapter mainBlockChain data.ChainHandler apiBlockChain data.ChainHandler - numQueries int gasForQuery uint64 wasmVMChangeLocker common.Locker bootstrapper process.Bootstrapper @@ -179,8 +178,7 @@ func (service *SCQueryService) shouldAllowQueriesExecution() bool { } func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice uint64) (*vmcommon.VMOutput, common.BlockInfo, error) { - log.Trace("executeScCall", "function", query.FuncName, "numQueries", service.numQueries) - service.numQueries++ + log.Trace("executeScCall", "address", query.ScAddress, "function", query.FuncName, "blockNonce", query.BlockNonce.Value, "blockHash", query.BlockHash) shouldEarlyExitBecauseOfSyncState := query.ShouldBeSynced && service.bootstrapper.GetNodeState() == common.NsNotSynchronized if shouldEarlyExitBecauseOfSyncState { @@ -193,6 +191,8 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } if len(blockRootHash) > 0 { + log.Trace("preparing execution for block and root hash", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + err = service.apiBlockChain.SetCurrentBlockHeaderAndRootHash(blockHeader, blockRootHash) if err != nil { return nil, nil, err @@ -229,15 +229,6 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui return nil, nil, err } - if service.hasRetriableExecutionError(vmOutput) { - log.Error("Retriable execution error detected. Will retry (once) executeScCall()", "returnCode", vmOutput.ReturnCode, "returnMessage", vmOutput.ReturnMessage) - - vmOutput, err = vm.RunSmartContractCall(vmInput) - if err != nil { - return nil, nil, err - } - } - if query.SameScState { err = service.checkForRootHashChanges(rootHashBeforeExecution) if err != nil { @@ -417,10 +408,6 @@ func (service *SCQueryService) createVMCallInput(query *process.SCQuery, gasPric return vmContractCallInput } -func (service *SCQueryService) hasRetriableExecutionError(vmOutput *vmcommon.VMOutput) bool { - return vmOutput.ReturnMessage == "allocation error" -} - // ComputeScCallGasLimit will estimate how many gas a transaction will consume func (service *SCQueryService) ComputeScCallGasLimit(tx *transaction.Transaction) (uint64, error) { argParser := parsers.NewCallArgsParser() From 3e3aed07dc8fcb691a40fb001ddd32751b037559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Sat, 17 Feb 2024 21:31:27 +0200 Subject: [PATCH 839/958] Separate logs. --- process/smartContract/scQueryService.go | 7 +++++-- process/smartContract/scQueryServiceDispatcher.go | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 0848fb77882..2e7a974ff99 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -22,12 +22,15 @@ import ( "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/smartContract/scrCommon" "github.com/multiversx/mx-chain-go/sharding" + logger "github.com/multiversx/mx-chain-logger-go" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/multiversx/mx-chain-vm-common-go/parsers" ) var _ process.SCQueryService = (*SCQueryService)(nil) +var logQueryService = logger.GetOrCreate("process/smartcontract.queryService") + // MaxGasLimitPerQuery - each unit is the equivalent of 1 nanosecond processing time const MaxGasLimitPerQuery = 300_000_000_000 @@ -178,7 +181,7 @@ func (service *SCQueryService) shouldAllowQueriesExecution() bool { } func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice uint64) (*vmcommon.VMOutput, common.BlockInfo, error) { - log.Trace("executeScCall", "address", query.ScAddress, "function", query.FuncName, "blockNonce", query.BlockNonce.Value, "blockHash", query.BlockHash) + logQueryService.Trace("executeScCall", "address", query.ScAddress, "function", query.FuncName, "blockNonce", query.BlockNonce.Value, "blockHash", query.BlockHash) shouldEarlyExitBecauseOfSyncState := query.ShouldBeSynced && service.bootstrapper.GetNodeState() == common.NsNotSynchronized if shouldEarlyExitBecauseOfSyncState { @@ -191,7 +194,7 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } if len(blockRootHash) > 0 { - log.Trace("preparing execution for block and root hash", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + logQueryService.Trace("preparing execution for block and root hash", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) err = service.apiBlockChain.SetCurrentBlockHeaderAndRootHash(blockHeader, blockRootHash) if err != nil { diff --git a/process/smartContract/scQueryServiceDispatcher.go b/process/smartContract/scQueryServiceDispatcher.go index 2c51b47d55d..981f71f3dd9 100644 --- a/process/smartContract/scQueryServiceDispatcher.go +++ b/process/smartContract/scQueryServiceDispatcher.go @@ -78,7 +78,7 @@ func (sqsd *scQueryServiceDispatcher) Close() error { for _, scQueryService := range sqsd.list { err := scQueryService.Close() if err != nil { - log.Error("error while closing inner SC query service in scQueryServiceDispatcher.Close", "error", err) + logQueryService.Error("error while closing inner SC query service in scQueryServiceDispatcher.Close", "error", err) errFound = err } } From abfecd3de93ae8b926d36c21d2998c8bc2b83471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Sat, 17 Feb 2024 22:03:54 +0200 Subject: [PATCH 840/958] Undo changes. --- process/factory/shard/vmContainerFactory.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/process/factory/shard/vmContainerFactory.go b/process/factory/shard/vmContainerFactory.go index 39b7d91183b..92eb6292008 100644 --- a/process/factory/shard/vmContainerFactory.go +++ b/process/factory/shard/vmContainerFactory.go @@ -282,12 +282,12 @@ func (vmf *vmContainerFactory) getMatchingVersion(epoch uint32) config.WasmVMVer func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { logVMContainerFactory.Debug("createInProcessWasmVMByVersion", "version", version) switch version.Version { - // case "v1.2": - // return vmf.createInProcessWasmVMV12() - // case "v1.3": - // return vmf.createInProcessWasmVMV13() - // case "v1.4": - // return vmf.createInProcessWasmVMV14() + case "v1.2": + return vmf.createInProcessWasmVMV12() + case "v1.3": + return vmf.createInProcessWasmVMV13() + case "v1.4": + return vmf.createInProcessWasmVMV14() default: return vmf.createInProcessWasmVMV15() } From 86c3bb666a2bdcf229041ba60a4e790982151710 Mon Sep 17 00:00:00 2001 From: radu chis Date: Sun, 18 Feb 2024 10:24:35 +0200 Subject: [PATCH 841/958] added more flags on checkHandlerCompatibility --- epochStart/metachain/systemSCs.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 4b608300b3c..97ea4021366 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -79,6 +79,10 @@ func NewSystemSCProcessor(args ArgsNewEpochStartSystemSCProcessing) (*systemSCPr common.SaveJailedAlwaysFlag, common.StakingV4Step1Flag, common.StakingV4Step2Flag, + common.StakingQueueFlag, + common.StakingV4StartedFlag, + common.DelegationSmartContractFlagInSpecificEpochOnly, + common.GovernanceFlagInSpecificEpochOnly, }) if err != nil { return nil, err @@ -127,7 +131,7 @@ func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlagInSpecificEpochOnly) { + if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlag) { err := s.updateToGovernanceV2() if err != nil { return err From 3eadc9b153cfe85cae9bf58d0e86aef17d2a746f Mon Sep 17 00:00:00 2001 From: radu chis Date: Mon, 19 Feb 2024 10:54:37 +0200 Subject: [PATCH 842/958] refixed GovernanceSpecific Epoch Flag --- epochStart/metachain/systemSCs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epochStart/metachain/systemSCs.go b/epochStart/metachain/systemSCs.go index 97ea4021366..a0bd2a3402d 100644 --- a/epochStart/metachain/systemSCs.go +++ b/epochStart/metachain/systemSCs.go @@ -131,7 +131,7 @@ func (s *systemSCProcessor) processWithNewFlags( validatorsInfoMap state.ShardValidatorsInfoMapHandler, header data.HeaderHandler, ) error { - if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlag) { + if s.enableEpochsHandler.IsFlagEnabled(common.GovernanceFlagInSpecificEpochOnly) { err := s.updateToGovernanceV2() if err != nil { return err From cbc42e8024a125735e49988945ae85ac5187d705 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 19 Feb 2024 12:43:27 +0200 Subject: [PATCH 843/958] - added unit tests --- epochStart/metachain/systemSCs_test.go | 129 ++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 13 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 6fbffd7b598..5e849866b57 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -99,6 +99,11 @@ func createPhysicalUnit(t *testing.T) (storage.Storer, string) { return unit, dir } +type enableEpochHandlerWithEpochConfirm interface { + common.EnableEpochsHandler + core.EpochSubscriberHandler +} + func TestNewSystemSCProcessor(t *testing.T) { t.Parallel() @@ -956,21 +961,119 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testing.T) { t.Parallel() - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - - validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + t.Run("flag not active - activation epoch is in the future", func(t *testing.T) { + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + DelegationManagerEnableEpoch: 39, + StakingV2EnableEpoch: 1000, + }, testscommon.CreateMemUnit()) + s, _ := NewSystemSCProcessor(args) + handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) + handler.EpochConfirmed(37, 0) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + assert.Nil(t, err) + + acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) + assert.NotNil(t, err) + assert.True(t, check.IfNil(acc)) + }) + t.Run("flag active in that specific epoch", func(t *testing.T) { + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + DelegationManagerEnableEpoch: 37, + StakingV2EnableEpoch: 1000, + }, testscommon.CreateMemUnit()) + s, _ := NewSystemSCProcessor(args) + handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) + handler.EpochConfirmed(37, 0) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + assert.Nil(t, err) + + acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) + assert.Nil(t, err) + + userAcc, _ := acc.(state.UserAccountHandler) + assert.Equal(t, userAcc.GetOwnerAddress(), vm.DelegationManagerSCAddress) + assert.NotNil(t, userAcc.GetCodeMetadata()) + }) + t.Run("flag not active - activation epoch is in the past", func(t *testing.T) { + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + DelegationManagerEnableEpoch: 35, + StakingV2EnableEpoch: 1000, + }, testscommon.CreateMemUnit()) + s, _ := NewSystemSCProcessor(args) + handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) + handler.EpochConfirmed(37, 0) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + assert.Nil(t, err) + + acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) + assert.NotNil(t, err) + assert.True(t, check.IfNil(acc)) + }) +} - acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) - assert.Nil(t, err) +func TestSystemSCProcessor_ProcessSystemSmartContractInitGovernance(t *testing.T) { + t.Parallel() - userAcc, _ := acc.(state.UserAccountHandler) - assert.Equal(t, userAcc.GetOwnerAddress(), vm.DelegationManagerSCAddress) - assert.NotNil(t, userAcc.GetCodeMetadata()) + t.Run("flag not active - activation epoch is in the future", func(t *testing.T) { + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + GovernanceEnableEpoch: 39, + StakingV2EnableEpoch: 1000, + }, testscommon.CreateMemUnit()) + s, _ := NewSystemSCProcessor(args) + handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) + handler.EpochConfirmed(37, 0) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + assert.Nil(t, err) + + acc, err := s.userAccountsDB.GetExistingAccount(vm.GovernanceSCAddress) + assert.NotNil(t, err) + assert.True(t, check.IfNil(acc)) + }) + t.Run("flag active in that specific epoch", func(t *testing.T) { + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + GovernanceEnableEpoch: 37, + StakingV2EnableEpoch: 1000, + }, testscommon.CreateMemUnit()) + s, _ := NewSystemSCProcessor(args) + handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) + handler.EpochConfirmed(37, 0) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + assert.Nil(t, err) + + acc, err := s.userAccountsDB.GetExistingAccount(vm.GovernanceSCAddress) + assert.Nil(t, err) + + userAcc, _ := acc.(state.UserAccountHandler) + assert.Empty(t, userAcc.GetOwnerAddress()) + assert.Empty(t, userAcc.GetCodeMetadata()) + }) + t.Run("flag not active - activation epoch is in the past", func(t *testing.T) { + args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ + GovernanceEnableEpoch: 35, + StakingV2EnableEpoch: 1000, + }, testscommon.CreateMemUnit()) + s, _ := NewSystemSCProcessor(args) + handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) + handler.EpochConfirmed(37, 0) // epoch 37 + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + assert.Nil(t, err) + + acc, err := s.userAccountsDB.GetExistingAccount(vm.GovernanceSCAddress) + assert.NotNil(t, err) + assert.True(t, check.IfNil(acc)) + }) } func TestSystemSCProcessor_ProcessDelegationRewardsNothingToExecute(t *testing.T) { From 73076ce99597a9015b70ae705774bcf76db8936a Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 19 Feb 2024 13:07:55 +0200 Subject: [PATCH 844/958] replaced IsFlagEnabled with IsFlagEnabledInEpoch on processProxy in order to avoid possible edge case --- process/smartContract/processProxy/processProxy.go | 4 ++-- process/smartContract/processProxy/processProxy_test.go | 6 +++++- process/smartContract/processProxy/testProcessProxy.go | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/process/smartContract/processProxy/processProxy.go b/process/smartContract/processProxy/processProxy.go index d2408c36dfa..c64db4791a4 100644 --- a/process/smartContract/processProxy/processProxy.go +++ b/process/smartContract/processProxy/processProxy.go @@ -169,11 +169,11 @@ func (proxy *scProcessorProxy) IsInterfaceNil() bool { } // EpochConfirmed is called whenever a new epoch is confirmed -func (proxy *scProcessorProxy) EpochConfirmed(_ uint32, _ uint64) { +func (proxy *scProcessorProxy) EpochConfirmed(epoch uint32, _ uint64) { proxy.mutRc.Lock() defer proxy.mutRc.Unlock() - if proxy.args.EnableEpochsHandler.IsFlagEnabled(common.SCProcessorV2Flag) { + if proxy.args.EnableEpochsHandler.IsFlagEnabledInEpoch(common.SCProcessorV2Flag, epoch) { proxy.setActiveProcessorV2() return } diff --git a/process/smartContract/processProxy/processProxy_test.go b/process/smartContract/processProxy/processProxy_test.go index ba0a9c1c0b8..0b5695386a8 100644 --- a/process/smartContract/processProxy/processProxy_test.go +++ b/process/smartContract/processProxy/processProxy_test.go @@ -129,7 +129,11 @@ func TestNewSmartContractProcessorProxy(t *testing.T) { t.Parallel() args := createMockSmartContractProcessorArguments() - args.EnableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.SCProcessorV2Flag) + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledInEpochCalled: func(flag core.EnableEpochFlag, epoch uint32) bool { + return flag == common.SCProcessorV2Flag + }, + } proxy, err := NewSmartContractProcessorProxy(args, &epochNotifierMock.EpochNotifierStub{}) assert.False(t, check.IfNil(proxy)) diff --git a/process/smartContract/processProxy/testProcessProxy.go b/process/smartContract/processProxy/testProcessProxy.go index 31c6514814b..5d5d96ee0d2 100644 --- a/process/smartContract/processProxy/testProcessProxy.go +++ b/process/smartContract/processProxy/testProcessProxy.go @@ -145,11 +145,11 @@ func (proxy *scProcessorTestProxy) IsInterfaceNil() bool { } // EpochConfirmed is called whenever a new epoch is confirmed -func (proxy *scProcessorTestProxy) EpochConfirmed(_ uint32, _ uint64) { +func (proxy *scProcessorTestProxy) EpochConfirmed(epoch uint32, _ uint64) { proxy.mutRc.Lock() defer proxy.mutRc.Unlock() - if proxy.args.EnableEpochsHandler.IsFlagEnabled(common.SCProcessorV2Flag) { + if proxy.args.EnableEpochsHandler.IsFlagEnabledInEpoch(common.SCProcessorV2Flag, epoch) { proxy.setActiveProcessorV2() return } From ca4384ce9b64bbb8d16b7c34ff7d5feebb989d48 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 19 Feb 2024 15:12:46 +0200 Subject: [PATCH 845/958] - fixed unit tests --- epochStart/metachain/systemSCs_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 5e849866b57..97ea4c7497f 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -963,8 +963,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin t.Run("flag not active - activation epoch is in the future", func(t *testing.T) { args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - DelegationManagerEnableEpoch: 39, - StakingV2EnableEpoch: 1000, + DelegationSmartContractEnableEpoch: 39, + StakingV2EnableEpoch: 1000, }, testscommon.CreateMemUnit()) s, _ := NewSystemSCProcessor(args) handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) @@ -980,8 +980,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin }) t.Run("flag active in that specific epoch", func(t *testing.T) { args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - DelegationManagerEnableEpoch: 37, - StakingV2EnableEpoch: 1000, + DelegationSmartContractEnableEpoch: 37, + StakingV2EnableEpoch: 1000, }, testscommon.CreateMemUnit()) s, _ := NewSystemSCProcessor(args) handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) @@ -1000,8 +1000,8 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin }) t.Run("flag not active - activation epoch is in the past", func(t *testing.T) { args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - DelegationManagerEnableEpoch: 35, - StakingV2EnableEpoch: 1000, + DelegationSmartContractEnableEpoch: 35, + StakingV2EnableEpoch: 1000, }, testscommon.CreateMemUnit()) s, _ := NewSystemSCProcessor(args) handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) From 2ed3018e160cbdefd534d783b72cfe848d6aca25 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 19 Feb 2024 16:14:26 +0200 Subject: [PATCH 846/958] coreComponentsHolder tests --- .../components/coreComponents.go | 2 +- .../components/coreComponents_test.go | 269 ++++++++++++++++++ 2 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 node/chainSimulator/components/coreComponents_test.go diff --git a/node/chainSimulator/components/coreComponents.go b/node/chainSimulator/components/coreComponents.go index 373e34de033..80f50f6b016 100644 --- a/node/chainSimulator/components/coreComponents.go +++ b/node/chainSimulator/components/coreComponents.go @@ -93,7 +93,7 @@ type ArgsCoreComponentsHolder struct { } // CreateCoreComponents will create a new instance of factory.CoreComponentsHolder -func CreateCoreComponents(args ArgsCoreComponentsHolder) (factory.CoreComponentsHandler, error) { +func CreateCoreComponents(args ArgsCoreComponentsHolder) (*coreComponentsHolder, error) { var err error instance := &coreComponentsHolder{ closeHandler: NewCloseHandler(), diff --git a/node/chainSimulator/components/coreComponents_test.go b/node/chainSimulator/components/coreComponents_test.go new file mode 100644 index 00000000000..5e287e4748c --- /dev/null +++ b/node/chainSimulator/components/coreComponents_test.go @@ -0,0 +1,269 @@ +package components + +import ( + "encoding/hex" + "testing" + + "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-go/config" + "github.com/stretchr/testify/require" +) + +func createArgsCoreComponentsHolder() ArgsCoreComponentsHolder { + return ArgsCoreComponentsHolder{ + Config: config.Config{ + Marshalizer: config.MarshalizerConfig{ + Type: "json", + }, + TxSignMarshalizer: config.TypeConfig{ + Type: "json", + }, + VmMarshalizer: config.TypeConfig{ + Type: "json", + }, + Hasher: config.TypeConfig{ + Type: "blake2b", + }, + TxSignHasher: config.TypeConfig{ + Type: "blake2b", + }, + AddressPubkeyConverter: config.PubkeyConfig{ + Length: 32, + Type: "hex", + }, + ValidatorPubkeyConverter: config.PubkeyConfig{ + Length: 128, + Type: "hex", + }, + GeneralSettings: config.GeneralSettingsConfig{ + ChainID: "T", + MinTransactionVersion: 1, + }, + Hardfork: config.HardforkConfig{ + PublicKeyToListenFrom: "41378f754e2c7b2745208c3ed21b151d297acdc84c3aca00b9e292cf28ec2d444771070157ea7760ed83c26f4fed387d0077e00b563a95825dac2cbc349fc0025ccf774e37b0a98ad9724d30e90f8c29b4091ccb738ed9ffc0573df776ee9ea30b3c038b55e532760ea4a8f152f2a52848020e5cee1cc537f2c2323399723081", + }, + }, + EnableEpochsConfig: config.EnableEpochs{}, + RoundsConfig: config.RoundConfig{ + RoundActivations: map[string]config.ActivationRoundByName{ + "DisableAsyncCallV1": { + Round: "18446744073709551615", + }, + }, + }, + EconomicsConfig: config.EconomicsConfig{ + GlobalSettings: config.GlobalSettings{ + GenesisTotalSupply: "2000000000000000000000", + MinimumInflation: 0, + YearSettings: []*config.YearSetting{ + { + Year: 0, + MaximumInflation: 0.01, + }, + }, + }, + FeeSettings: config.FeeSettings{ + GasLimitSettings: []config.GasLimitSetting{ + { + MaxGasLimitPerBlock: "10000000000", + MaxGasLimitPerMiniBlock: "10000000000", + MaxGasLimitPerMetaBlock: "10000000000", + MaxGasLimitPerMetaMiniBlock: "10000000000", + MaxGasLimitPerTx: "10000000000", + MinGasLimit: "10", + ExtraGasLimitGuardedTx: "50000", + }, + }, + GasPriceModifier: 0.01, + MinGasPrice: "100", + GasPerDataByte: "1", + MaxGasPriceSetGuardian: "100", + }, + RewardsSettings: config.RewardsSettings{ + RewardsConfigByEpoch: []config.EpochRewardSettings{ + { + LeaderPercentage: 0.1, + DeveloperPercentage: 0.1, + ProtocolSustainabilityPercentage: 0.1, + ProtocolSustainabilityAddress: "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp", + TopUpGradientPoint: "300000000000000000000", + TopUpFactor: 0.25, + EpochEnable: 0, + }, + }, + }, + }, + ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), + InitialRound: 0, + NodesSetupPath: "../../../sharding/mock/testdata/nodesSetupMock.json", + GasScheduleFilename: "../../../cmd/node/config/gasSchedules/gasScheduleV7.toml", + NumShards: 3, + WorkingDir: ".", + MinNodesPerShard: 1, + MinNodesMeta: 1, + } +} + +func TestCreateCoreComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateCoreComponents(createArgsCoreComponentsHolder()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("internal NewMarshalizer failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.Marshalizer.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("tx NewMarshalizer failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.TxSignMarshalizer.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("vm NewMarshalizer failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.VmMarshalizer.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("main NewHasher failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.Hasher.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("tx NewHasher failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.TxSignHasher.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("address NewPubkeyConverter failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.AddressPubkeyConverter.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("validator NewPubkeyConverter failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.ValidatorPubkeyConverter.Type = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewNodesSetup failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.NumShards = 0 + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewEconomicsData failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.EconomicsConfig.GlobalSettings.MinimumInflation = -1.0 + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("validatorPubKeyConverter.Decode failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCoreComponentsHolder() + args.Config.Hardfork.PublicKeyToListenFrom = "invalid" + comp, err := CreateCoreComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestCoreComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *coreComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateCoreComponents(createArgsCoreComponentsHolder()) + require.False(t, comp.IsInterfaceNil()) +} + +func TestCoreComponents_GettersSetters(t *testing.T) { + t.Parallel() + + comp, err := CreateCoreComponents(createArgsCoreComponentsHolder()) + require.NoError(t, err) + + require.NotNil(t, comp.InternalMarshalizer()) + require.Nil(t, comp.SetInternalMarshalizer(nil)) + require.Nil(t, comp.InternalMarshalizer()) + + require.NotNil(t, comp.TxMarshalizer()) + require.NotNil(t, comp.VmMarshalizer()) + require.NotNil(t, comp.Hasher()) + require.NotNil(t, comp.TxSignHasher()) + require.NotNil(t, comp.Uint64ByteSliceConverter()) + require.NotNil(t, comp.AddressPubKeyConverter()) + require.NotNil(t, comp.ValidatorPubKeyConverter()) + require.NotNil(t, comp.PathHandler()) + require.NotNil(t, comp.Watchdog()) + require.NotNil(t, comp.AlarmScheduler()) + require.NotNil(t, comp.SyncTimer()) + require.NotNil(t, comp.RoundHandler()) + require.NotNil(t, comp.EconomicsData()) + require.NotNil(t, comp.APIEconomicsData()) + require.NotNil(t, comp.RatingsData()) + require.NotNil(t, comp.Rater()) + require.NotNil(t, comp.GenesisNodesSetup()) + require.NotNil(t, comp.NodesShuffler()) + require.NotNil(t, comp.EpochNotifier()) + require.NotNil(t, comp.EnableRoundsHandler()) + require.NotNil(t, comp.RoundNotifier()) + require.NotNil(t, comp.EpochStartNotifierWithConfirm()) + require.NotNil(t, comp.ChanStopNodeProcess()) + require.NotNil(t, comp.GenesisTime()) + require.Equal(t, "T", comp.ChainID()) + require.Equal(t, uint32(1), comp.MinTransactionVersion()) + require.NotNil(t, comp.TxVersionChecker()) + require.Equal(t, uint32(64), comp.EncodedAddressLen()) + hfPk, _ := hex.DecodeString("41378f754e2c7b2745208c3ed21b151d297acdc84c3aca00b9e292cf28ec2d444771070157ea7760ed83c26f4fed387d0077e00b563a95825dac2cbc349fc0025ccf774e37b0a98ad9724d30e90f8c29b4091ccb738ed9ffc0573df776ee9ea30b3c038b55e532760ea4a8f152f2a52848020e5cee1cc537f2c2323399723081") + require.Equal(t, hfPk, comp.HardforkTriggerPubKey()) + require.NotNil(t, comp.NodeTypeProvider()) + require.NotNil(t, comp.WasmVMChangeLocker()) + require.NotNil(t, comp.ProcessStatusHandler()) + require.NotNil(t, comp.ProcessStatusHandler()) + require.NotNil(t, comp.EnableEpochsHandler()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) +} From c6508c2131677e46350693740dc86a91c02b91cb Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 19 Feb 2024 16:32:52 +0200 Subject: [PATCH 847/958] - refactor --- .../staking/stakeAndUnStake_test.go | 9 +- node/chainSimulator/chainSimulator.go | 2 + node/chainSimulator/chainSimulator_test.go | 2 +- node/chainSimulator/configs/configs.go | 106 ++++++++++-------- node/chainSimulator/dtos/keys.go | 25 +++++ node/chainSimulator/dtos/wallet.go | 19 ---- ...{send_and_execute.go => sendAndExecute.go} | 5 +- 7 files changed, 97 insertions(+), 71 deletions(-) create mode 100644 node/chainSimulator/dtos/keys.go delete mode 100644 node/chainSimulator/dtos/wallet.go rename node/chainSimulator/{send_and_execute.go => sendAndExecute.go} (90%) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 72efdd1b36b..83ea532aaac 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -125,15 +125,14 @@ func TestChainSimulator_AddValidatorKey(t *testing.T) { firstValidatorKey, err := cs.GetValidatorPrivateKeys()[0].GeneratePublic().ToByteArray() require.Nil(t, err) - initialAddressWithValidators := cs.GetInitialWalletKeys().InitialWalletWithStake.Address - senderBytes, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(initialAddressWithValidators) - shardID := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(senderBytes) - initialAccount, _, err := cs.GetNodeHandler(shardID).GetFacadeHandler().GetAccount(initialAddressWithValidators, coreAPI.AccountQueryOptions{}) + initialAddressWithValidators := cs.GetInitialWalletKeys().StakeWallets[0].Address + shardID := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(initialAddressWithValidators.Bytes) + initialAccount, _, err := cs.GetNodeHandler(shardID).GetFacadeHandler().GetAccount(initialAddressWithValidators.Bech32, coreAPI.AccountQueryOptions{}) require.Nil(t, err) tx = &transaction.Transaction{ Nonce: initialAccount.Nonce, Value: big.NewInt(0), - SndAddr: senderBytes, + SndAddr: initialAddressWithValidators.Bytes, RcvAddr: rcvAddrBytes, Data: []byte(fmt.Sprintf("unStake@%s", hex.EncodeToString(firstValidatorKey))), GasLimit: 50_000_000, diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 66b43fcec21..656e7e11d20 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -52,6 +52,7 @@ type simulator struct { syncedBroadcastNetwork components.SyncedBroadcastNetworkHandler handlers []ChainHandler initialWalletKeys *dtos.InitialWalletKeys + initialStakedKeys map[string]*dtos.BLSKey validatorsPrivateKeys []crypto.PrivateKey nodes map[uint32]process.NodeHandler numOfShards uint32 @@ -69,6 +70,7 @@ func NewChainSimulator(args ArgsChainSimulator) (*simulator, error) { numOfShards: args.NumOfShards, chanStopNodeProcess: make(chan endProcess.ArgEndProcess), mutex: sync.RWMutex{}, + initialStakedKeys: make(map[string]*dtos.BLSKey), } err := instance.createChainHandlers(args) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index b0758044fa4..f2bd354bb53 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -109,7 +109,7 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { facade, err := NewChainSimulatorFacade(chainSimulator) require.Nil(t, err) - genesisAddressWithStake := chainSimulator.initialWalletKeys.InitialWalletWithStake.Address + genesisAddressWithStake := chainSimulator.initialWalletKeys.StakeWallets[0].Address.Bech32 initialAccount, err := facade.GetExistingAccountFromBech32AddressString(genesisAddressWithStake) require.Nil(t, err) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 2ca7e3343cc..6c51bdc3922 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -34,7 +34,6 @@ const ( // ChainID contains the chain id ChainID = "chain" - shardIDWalletWithStake = 0 allValidatorsPemFileName = "allValidatorsKeys.pem" ) @@ -85,7 +84,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi // generate validators key and nodesSetup.json privateKeys, publicKeys, err := generateValidatorsKeyAndUpdateFiles( configs, - initialWallets.InitialWalletWithStake.Address, + initialWallets.StakeWallets, args, ) if err != nil { @@ -179,29 +178,33 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs } initialWalletKeys := &dtos.InitialWalletKeys{ - ShardWallets: make(map[uint32]*dtos.WalletKey), + BalanceWallets: make(map[uint32]*dtos.WalletKey), + StakeWallets: make([]*dtos.WalletKey, 0), } - initialAddressWithStake, err := generateWalletKeyForShard(shardIDWalletWithStake, args.NumOfShards, addressConverter) - if err != nil { - return nil, err - } + addresses := make([]data.InitialAccount, 0) + numOfNodes := int((args.NumNodesWaitingListShard+args.MinNodesPerShard)*args.NumOfShards + args.NumNodesWaitingListMeta + args.MetaChainMinNodes) + for i := 0; i < numOfNodes; i++ { + wallet, errGenerate := generateWalletKey(addressConverter) + if errGenerate != nil { + return nil, errGenerate + } - initialWalletKeys.InitialWalletWithStake = initialAddressWithStake + stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) + addresses = append(addresses, data.InitialAccount{ + Address: wallet.Address.Bech32, + StakingValue: stakedValue, + Supply: stakedValue, + }) - addresses := make([]data.InitialAccount, 0) - stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) - numOfNodes := (args.NumNodesWaitingListShard+args.MinNodesPerShard)*args.NumOfShards + args.NumNodesWaitingListMeta + args.MetaChainMinNodes - stakedValue = stakedValue.Mul(stakedValue, big.NewInt(int64(numOfNodes))) // 2500 EGLD * number of nodes - addresses = append(addresses, data.InitialAccount{ - Address: initialAddressWithStake.Address, - StakingValue: stakedValue, - Supply: stakedValue, - }) + initialWalletKeys.StakeWallets = append(initialWalletKeys.StakeWallets, wallet) + } // generate an address for every shard initialBalance := big.NewInt(0).Set(initialSupply) - initialBalance = initialBalance.Sub(initialBalance, stakedValue) + totalStakedValue := big.NewInt(int64(numOfNodes)) + totalStakedValue = totalStakedValue.Mul(totalStakedValue, big.NewInt(0).Set(initialStakedEgldPerNode)) + initialBalance = initialBalance.Sub(initialBalance, totalStakedValue) walletBalance := big.NewInt(0).Set(initialBalance) walletBalance.Div(walletBalance, big.NewInt(int64(args.NumOfShards))) @@ -217,16 +220,16 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs } addresses = append(addresses, data.InitialAccount{ - Address: walletKey.Address, + Address: walletKey.Address.Bech32, Balance: big.NewInt(0).Set(walletBalance), Supply: big.NewInt(0).Set(walletBalance), }) - initialWalletKeys.ShardWallets[shardID] = walletKey + initialWalletKeys.BalanceWallets[shardID] = walletKey } - addresses[1].Balance.Add(walletBalance, remainder) - addresses[1].Supply.Add(walletBalance, remainder) + addresses[len(addresses)-1].Balance.Add(walletBalance, remainder) + addresses[len(addresses)-1].Supply.Add(walletBalance, remainder) addressesBytes, errM := json.Marshal(addresses) if errM != nil { @@ -243,7 +246,7 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs func generateValidatorsKeyAndUpdateFiles( configs *config.Configs, - address string, + stakeWallets []*dtos.WalletKey, args ArgsChainSimulatorConfigs, ) ([]crypto.PrivateKey, []crypto.PublicKey, error) { blockSigningGenerator := signing.NewKeyGenerator(mcl.NewSuiteBLS12()) @@ -269,6 +272,7 @@ func generateValidatorsKeyAndUpdateFiles( nodes.InitialNodes = make([]*sharding.InitialNode, 0) privateKeys := make([]crypto.PrivateKey, 0) publicKeys := make([]crypto.PublicKey, 0) + walletIndex := 0 // generate meta keys for idx := uint32(0); idx < args.NumNodesWaitingListMeta+args.MetaChainMinNodes; idx++ { sk, pk := blockSigningGenerator.GeneratePair() @@ -282,8 +286,10 @@ func generateValidatorsKeyAndUpdateFiles( nodes.InitialNodes = append(nodes.InitialNodes, &sharding.InitialNode{ PubKey: hex.EncodeToString(pkBytes), - Address: address, + Address: stakeWallets[walletIndex].Address.Bech32, }) + + walletIndex++ } // generate shard keys @@ -300,8 +306,9 @@ func generateValidatorsKeyAndUpdateFiles( nodes.InitialNodes = append(nodes.InitialNodes, &sharding.InitialNode{ PubKey: hex.EncodeToString(pkBytes), - Address: address, + Address: stakeWallets[walletIndex].Address.Bech32, }) + walletIndex++ } } @@ -394,35 +401,46 @@ func GetLatestGasScheduleFilename(directory string) (string, error) { } func generateWalletKeyForShard(shardID, numOfShards uint32, converter core.PubkeyConverter) (*dtos.WalletKey, error) { - walletSuite := ed25519.NewEd25519() - walletKeyGenerator := signing.NewKeyGenerator(walletSuite) - for { - sk, pk := walletKeyGenerator.GeneratePair() - - pubKeyBytes, err := pk.ToByteArray() + walletKey, err := generateWalletKey(converter) if err != nil { return nil, err } - addressShardID := shardingCore.ComputeShardID(pubKeyBytes, numOfShards) + addressShardID := shardingCore.ComputeShardID(walletKey.Address.Bytes, numOfShards) if addressShardID != shardID { continue } - privateKeyBytes, err := sk.ToByteArray() - if err != nil { - return nil, err - } + return walletKey, nil + } +} - address, err := converter.Encode(pubKeyBytes) - if err != nil { - return nil, err - } +func generateWalletKey(converter core.PubkeyConverter) (*dtos.WalletKey, error) { + walletSuite := ed25519.NewEd25519() + walletKeyGenerator := signing.NewKeyGenerator(walletSuite) + + sk, pk := walletKeyGenerator.GeneratePair() + pubKeyBytes, err := pk.ToByteArray() + if err != nil { + return nil, err + } - return &dtos.WalletKey{ - Address: address, - PrivateKeyHex: hex.EncodeToString(privateKeyBytes), - }, nil + privateKeyBytes, err := sk.ToByteArray() + if err != nil { + return nil, err } + + bech32Address, err := converter.Encode(pubKeyBytes) + if err != nil { + return nil, err + } + + return &dtos.WalletKey{ + Address: dtos.WalletAddress{ + Bech32: bech32Address, + Bytes: pubKeyBytes, + }, + PrivateKeyHex: hex.EncodeToString(privateKeyBytes), + }, nil } diff --git a/node/chainSimulator/dtos/keys.go b/node/chainSimulator/dtos/keys.go new file mode 100644 index 00000000000..1c185c9f94d --- /dev/null +++ b/node/chainSimulator/dtos/keys.go @@ -0,0 +1,25 @@ +package dtos + +// WalletKey holds the public and the private key of a wallet bey +type WalletKey struct { + Address WalletAddress `json:"address"` + PrivateKeyHex string `json:"privateKeyHex"` +} + +// InitialWalletKeys holds the initial wallet keys +type InitialWalletKeys struct { + StakeWallets []*WalletKey `json:"stakeWallets"` + BalanceWallets map[uint32]*WalletKey `json:"balanceWallets"` +} + +// WalletAddress holds the address in multiple formats +type WalletAddress struct { + Bech32 string `json:"bech32"` + Bytes []byte `json:"bytes"` +} + +// BLSKey holds the BLS key in multiple formats +type BLSKey struct { + Hex string + Bytes []byte +} diff --git a/node/chainSimulator/dtos/wallet.go b/node/chainSimulator/dtos/wallet.go deleted file mode 100644 index 27e5740f08d..00000000000 --- a/node/chainSimulator/dtos/wallet.go +++ /dev/null @@ -1,19 +0,0 @@ -package dtos - -// WalletKey holds the public and the private key of a wallet bey -type WalletKey struct { - Address string `json:"address"` - PrivateKeyHex string `json:"privateKeyHex"` -} - -// InitialWalletKeys holds the initial wallet keys -type InitialWalletKeys struct { - InitialWalletWithStake *WalletKey `json:"initialWalletWithStake"` - ShardWallets map[uint32]*WalletKey `json:"shardWallets"` -} - -// WalletAddress holds the address in multiple formats -type WalletAddress struct { - Bech32 string - Bytes []byte -} diff --git a/node/chainSimulator/send_and_execute.go b/node/chainSimulator/sendAndExecute.go similarity index 90% rename from node/chainSimulator/send_and_execute.go rename to node/chainSimulator/sendAndExecute.go index 4802295aae3..a53174d2832 100644 --- a/node/chainSimulator/send_and_execute.go +++ b/node/chainSimulator/sendAndExecute.go @@ -32,8 +32,8 @@ func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { for { txs, _ := node.GetFacadeHandler().GetTransactionsPool("") - for _, tx := range txs.RegularTransactions { - if tx.TxFields["hash"] == txHashHex { + for _, sentTx := range txs.RegularTransactions { + if sentTx.TxFields["hash"] == txHashHex { log.Info("############## send transaction ##############", "txHash", txHashHex) return txHashHex, nil } @@ -42,6 +42,7 @@ func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { } } +// SendTxsAndGenerateBlockTilTxIsExecuted will send the transactions provided and generate the blocks until the transactions are finished func (s *simulator) SendTxsAndGenerateBlockTilTxIsExecuted(txsToSend []*transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) ([]*transaction.ApiTransactionResult, error) { hashTxIndex := make(map[string]int) for idx, txToSend := range txsToSend { From a9f0b4891d974ff42c8c6ed1a4000fefc2030070 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 19 Feb 2024 17:08:13 +0200 Subject: [PATCH 848/958] - fixed tests --- .../chainSimulator/staking/delegation_test.go | 58 ++++++++++--------- node/chainSimulator/chainSimulator_test.go | 25 +++++--- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index cc523b7f1c5..6ea872ef646 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -45,11 +45,12 @@ const queuedStatus = "queued" const stakedStatus = "staked" const auctionStatus = "auction" const okReturnCode = "ok" -const maxCap = "00" // no cap -const serviceFee = "0ea1" // 37.45% +const maxCap = "00" // no cap +const hexServiceFee = "0ea1" // 37.45% const walletAddressBytesLen = 32 -var stakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) // 1250 EGLD +var initialDelegationValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) // 1250 EGLD +// var stakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) // 1250 EGLD var zeroValue = big.NewInt(0) var oneEGLD = big.NewInt(1000000000000000000) var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) @@ -264,7 +265,7 @@ func testChainSimulatorMakeNewContractFromValidatorData(t *testing.T, cs chainSi testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorOwner.Bytes, blsKeys[0], addedStakedValue, 1) log.Info("Step 4. Execute the MakeNewContractFromValidatorData transaction and test that the key is on queue / auction list and the correct topup") - txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) + txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, hexServiceFee) txConvert := generateTransaction(validatorOwner.Bytes, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) convertTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -349,9 +350,13 @@ func testBLSKeyIsInAuction( require.Nil(t, err) currentEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() - if metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step2Flag) <= currentEpoch { + if metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step2Flag) == currentEpoch { // starting from phase 2, we have the shuffled out nodes from the previous epoch in the action list - actionListSize += 1 + actionListSize += 8 + } + if metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step3Flag) <= currentEpoch { + // starting from phase 3, we have the shuffled out nodes from the previous epoch in the action list + actionListSize += 4 } require.Equal(t, actionListSize, len(auctionList)) @@ -569,9 +574,8 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat // Step 3: Create a new delegation contract maxDelegationCap := big.NewInt(0).Mul(oneEGLD, big.NewInt(51000)) // 51000 EGLD cap - serviceFee := big.NewInt(100) // 100 as service fee - txCreateDelegationContract := generateTransaction(validatorOwnerBytes, 0, vm.DelegationManagerSCAddress, stakeValue, - fmt.Sprintf("createNewDelegationContract@%s@%s", hex.EncodeToString(maxDelegationCap.Bytes()), hex.EncodeToString(serviceFee.Bytes())), + txCreateDelegationContract := generateTransaction(validatorOwnerBytes, 0, vm.DelegationManagerSCAddress, initialDelegationValue, + fmt.Sprintf("createNewDelegationContract@%s@%s", hex.EncodeToString(maxDelegationCap.Bytes()), hexServiceFee), gasLimitForDelegationContractCreationOperation) createDelegationContractTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txCreateDelegationContract, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -615,8 +619,8 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat require.Equal(t, blsKeys[0], hex.EncodeToString(notStakedKeys[0])) require.Equal(t, 0, len(unStakedKeys)) - expectedTopUp := big.NewInt(0).Set(stakeValue) - expectedTotalStaked := big.NewInt(0).Set(stakeValue) + expectedTopUp := big.NewInt(0).Set(initialDelegationValue) + expectedTotalStaked := big.NewInt(0).Set(initialDelegationValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -624,16 +628,16 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{validatorOwnerBytes}) require.Nil(t, err) - require.Equal(t, stakeValue, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, initialDelegationValue, big.NewInt(0).SetBytes(output.ReturnData[0])) // Step 3: Perform delegation operations - txDelegate1 := generateTransaction(delegator1Bytes, 0, delegationContractAddressBytes, stakeValue, "delegate", gasLimitForDelegate) + txDelegate1 := generateTransaction(delegator1Bytes, 0, delegationContractAddressBytes, initialDelegationValue, "delegate", gasLimitForDelegate) delegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, delegate1Tx) - expectedTopUp = expectedTopUp.Add(expectedTopUp, stakeValue) - expectedTotalStaked = expectedTotalStaked.Add(expectedTotalStaked, stakeValue) + expectedTopUp = expectedTopUp.Add(expectedTopUp, initialDelegationValue) + expectedTotalStaked = expectedTotalStaked.Add(expectedTotalStaked, initialDelegationValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -641,15 +645,15 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator1Bytes}) require.Nil(t, err) - require.Equal(t, stakeValue, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, initialDelegationValue, big.NewInt(0).SetBytes(output.ReturnData[0])) - txDelegate2 := generateTransaction(delegator2Bytes, 0, delegationContractAddressBytes, stakeValue, "delegate", gasLimitForDelegate) + txDelegate2 := generateTransaction(delegator2Bytes, 0, delegationContractAddressBytes, initialDelegationValue, "delegate", gasLimitForDelegate) delegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate2, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, delegate2Tx) - expectedTopUp = expectedTopUp.Add(expectedTopUp, stakeValue) - expectedTotalStaked = expectedTotalStaked.Add(expectedTotalStaked, stakeValue) + expectedTopUp = expectedTopUp.Add(expectedTopUp, initialDelegationValue) + expectedTotalStaked = expectedTotalStaked.Add(expectedTotalStaked, initialDelegationValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -657,7 +661,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getUserActiveStake", [][]byte{delegator2Bytes}) require.Nil(t, err) - require.Equal(t, stakeValue, big.NewInt(0).SetBytes(output.ReturnData[0])) + require.Equal(t, initialDelegationValue, big.NewInt(0).SetBytes(output.ReturnData[0])) // Step 4: Perform stakeNodes @@ -666,8 +670,8 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat require.Nil(t, err) require.NotNil(t, stakeNodesTx) - expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) - expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) + expectedTopUp = expectedTopUp.Sub(expectedTopUp, initialDelegationValue) + expectedTopUp = expectedTopUp.Sub(expectedTopUp, initialDelegationValue) require.Equal(t, expectedTopUp, getBLSTopUpValue(t, metachainNode, delegationContractAddressBytes)) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getAllNodeStates", nil) @@ -688,13 +692,13 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat // The nodes should remain in the staked state // The total active stake should be reduced by the amount undelegated - txUndelegate1 := generateTransaction(delegator1Bytes, 1, delegationContractAddressBytes, zeroValue, fmt.Sprintf("unDelegate@%s", hex.EncodeToString(stakeValue.Bytes())), gasLimitForUndelegateOperation) + txUndelegate1 := generateTransaction(delegator1Bytes, 1, delegationContractAddressBytes, zeroValue, fmt.Sprintf("unDelegate@%s", hex.EncodeToString(initialDelegationValue.Bytes())), gasLimitForUndelegateOperation) undelegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUndelegate1, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, undelegate1Tx) - expectedTopUp = expectedTopUp.Sub(expectedTopUp, stakeValue) - expectedTotalStaked = expectedTotalStaked.Sub(expectedTotalStaked, stakeValue) + expectedTopUp = expectedTopUp.Sub(expectedTopUp, initialDelegationValue) + expectedTotalStaked = expectedTotalStaked.Sub(expectedTotalStaked, initialDelegationValue) output, err = executeQuery(cs, core.MetachainShardId, delegationContractAddressBytes, "getTotalActiveStake", nil) require.Nil(t, err) require.Equal(t, expectedTotalStaked, big.NewInt(0).SetBytes(output.ReturnData[0])) @@ -716,7 +720,7 @@ func testChainSimulatorCreateNewDelegationContract(t *testing.T, cs chainSimulat // The nodes should remain in the unStaked state // The total active stake should be reduced by the amount undelegated - txUndelegate2 := generateTransaction(delegator2Bytes, 1, delegationContractAddressBytes, zeroValue, fmt.Sprintf("unDelegate@%s", hex.EncodeToString(stakeValue.Bytes())), gasLimitForUndelegateOperation) + txUndelegate2 := generateTransaction(delegator2Bytes, 1, delegationContractAddressBytes, zeroValue, fmt.Sprintf("unDelegate@%s", hex.EncodeToString(initialDelegationValue.Bytes())), gasLimitForUndelegateOperation) undelegate2Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUndelegate2, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, undelegate2Tx) @@ -1027,7 +1031,7 @@ func testChainSimulatorMergingDelegation(t *testing.T, cs chainSimulatorIntegrat require.Equal(t, addedStakedValue, getBLSTopUpValue(t, metachainNode, validatorA.Bytes)) log.Info("Step 2. Execute MakeNewContractFromValidatorData for User A") - txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, serviceFee) + txDataField = fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, hexServiceFee) txConvert := generateTransaction(validatorA.Bytes, 1, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) convertTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txConvert, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index f2bd354bb53..4fcd1c482b0 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -2,7 +2,6 @@ package chainSimulator import ( "encoding/base64" - "fmt" "math/big" "testing" "time" @@ -109,22 +108,30 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { facade, err := NewChainSimulatorFacade(chainSimulator) require.Nil(t, err) - genesisAddressWithStake := chainSimulator.initialWalletKeys.StakeWallets[0].Address.Bech32 - initialAccount, err := facade.GetExistingAccountFromBech32AddressString(genesisAddressWithStake) - require.Nil(t, err) + genesisBalances := make(map[string]*big.Int) + for _, stakeWallet := range chainSimulator.initialWalletKeys.StakeWallets { + initialAccount, errGet := facade.GetExistingAccountFromBech32AddressString(stakeWallet.Address.Bech32) + require.Nil(t, errGet) + + genesisBalances[stakeWallet.Address.Bech32] = initialAccount.GetBalance() + } time.Sleep(time.Second) err = chainSimulator.GenerateBlocks(80) require.Nil(t, err) - accountAfterRewards, err := facade.GetExistingAccountFromBech32AddressString(genesisAddressWithStake) - require.Nil(t, err) + numAccountsWithIncreasedBalances := 0 + for _, stakeWallet := range chainSimulator.initialWalletKeys.StakeWallets { + account, errGet := facade.GetExistingAccountFromBech32AddressString(stakeWallet.Address.Bech32) + require.Nil(t, errGet) - assert.True(t, accountAfterRewards.GetBalance().Cmp(initialAccount.GetBalance()) > 0, - fmt.Sprintf("initial balance %s, balance after rewards %s", initialAccount.GetBalance().String(), accountAfterRewards.GetBalance().String())) + if account.GetBalance().Cmp(genesisBalances[stakeWallet.Address.Bech32]) > 0 { + numAccountsWithIncreasedBalances++ + } + } - fmt.Println(chainSimulator.GetRestAPIInterfaces()) + assert.True(t, numAccountsWithIncreasedBalances > 0) } func TestChainSimulator_SetState(t *testing.T) { From 13bc2e4865fcded4d24cfbb6edd0580767c43583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 20 Feb 2024 13:09:41 +0200 Subject: [PATCH 849/958] Omit re-create if possible. --- state/accountsDBApi.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/state/accountsDBApi.go b/state/accountsDBApi.go index d9bd467d7d2..ae3ca439984 100644 --- a/state/accountsDBApi.go +++ b/state/accountsDBApi.go @@ -175,13 +175,18 @@ func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(options common.RootHashHo accountsDB.mutRecreatedTrieBlockInfo.Lock() defer accountsDB.mutRecreatedTrieBlockInfo.Unlock() + newBlockInfo := holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) + if newBlockInfo.Equal(accountsDB.blockInfo) { + return nil + } + err := accountsDB.innerAccountsAdapter.RecreateTrieFromEpoch(options) if err != nil { accountsDB.blockInfo = nil return err } - accountsDB.blockInfo = holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) + accountsDB.blockInfo = newBlockInfo return nil } From 6be2c90afe33a2d8c8dcda5a8909bf749281e7f4 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 20 Feb 2024 15:52:12 +0200 Subject: [PATCH 850/958] - fixed recreate trie in sc query service --- process/smartContract/scQueryService.go | 27 +- process/smartContract/scQueryService_test.go | 360 ++++++++++++++++++- 2 files changed, 381 insertions(+), 6 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 0c1501bac45..0090c9d16b4 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -33,6 +33,7 @@ var logQueryService = logger.GetOrCreate("process/smartcontract.queryService") // MaxGasLimitPerQuery - each unit is the equivalent of 1 nanosecond processing time const MaxGasLimitPerQuery = 300_000_000_000 +const epochDifferenceToConsiderHistory = 2 // SCQueryService can execute Get functions over SC to fetch stored values type SCQueryService struct { @@ -201,10 +202,7 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui return nil, nil, err } - accountsAdapter := service.blockChainHook.GetAccountsAdapter() - - holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) - err = accountsAdapter.RecreateTrieFromEpoch(holder) + err = service.recreateTrie(blockRootHash, blockHeader) if err != nil { return nil, nil, err } @@ -253,6 +251,27 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui return vmOutput, blockInfo, nil } +func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader data.HeaderHandler) error { + accountsAdapter := service.blockChainHook.GetAccountsAdapter() + if blockHeader.GetEpoch()+epochDifferenceToConsiderHistory >= service.getCurrentEpoch() { + // recent history + return accountsAdapter.RecreateTrie(blockRootHash) + } + + // old history, this will take a little longer + holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) + return accountsAdapter.RecreateTrieFromEpoch(holder) +} + +func (service *SCQueryService) getCurrentEpoch() uint32 { + header := service.mainBlockChain.GetCurrentBlockHeader() + if check.IfNil(header) { + return 0 + } + + return header.GetEpoch() +} + // TODO: extract duplicated code with nodeBlocks.go func (service *SCQueryService) extractBlockHeaderAndRootHash(query *process.SCQuery) (data.HeaderHandler, []byte, error) { if len(query.BlockHash) > 0 { diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 69672531752..ed57b9f1689 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -367,7 +367,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) }) - t.Run("block hash should work", func(t *testing.T) { + t.Run("block hash should work - old epoch", func(t *testing.T) { t.Parallel() runWasCalled := false @@ -396,6 +396,13 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return uint64(math.MaxUint64) }, } + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: 37, + } + }, + } providedHash := []byte("provided hash") providedRootHash := []byte("provided root hash") argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} @@ -457,7 +464,97 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { assert.True(t, wasRecreateTrieCalled) assert.Nil(t, err) }) - t.Run("block nonce should work", func(t *testing.T) { + t.Run("block hash should work - current epoch", func(t *testing.T) { + t.Parallel() + + runWasCalled := false + + mockVM := &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { + runWasCalled = true + assert.Equal(t, int64(42), big.NewInt(0).SetBytes(input.Arguments[0]).Int64()) + assert.Equal(t, int64(43), big.NewInt(0).SetBytes(input.Arguments[1]).Int64()) + assert.Equal(t, scAddress, input.CallerAddr) + assert.Equal(t, funcName, input.Function) + + return &vmcommon.VMOutput{ + ReturnCode: vmcommon.Ok, + }, nil + }, + } + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.VmContainer = &mock.VMContainerMock{ + GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { + return mockVM, nil + }, + } + argsNewSCQuery.EconomicsFee = &economicsmocks.EconomicsHandlerStub{ + MaxGasLimitPerBlockCalled: func(_ uint32) uint64 { + return uint64(math.MaxUint64) + }, + } + providedHash := []byte("provided hash") + providedRootHash := []byte("provided root hash") + argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} + counter := 0 + argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ + GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { + return &storageStubs.StorerStub{ + GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { + counter++ + if counter > 2 { + return nil, fmt.Errorf("no scheduled") + } + hdr := &block.Header{ + RootHash: providedRootHash, + } + buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) + return buff, nil + }, + }, nil + }, + } + argsNewSCQuery.HistoryRepository = &dblookupext.HistoryRepositoryStub{ + IsEnabledCalled: func() bool { + return true + }, + GetEpochByHashCalled: func(hash []byte) (uint32, error) { + return 12, nil + }, + } + wasRecreateTrieCalled := false + providedAccountsAdapter := &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + wasRecreateTrieCalled = true + assert.Equal(t, providedRootHash, rootHash) + return nil + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return providedAccountsAdapter + }, + } + + target, _ := NewSCQueryService(argsNewSCQuery) + + dataArgs := make([][]byte, len(args)) + for i, arg := range args { + dataArgs[i] = append(dataArgs[i], arg.Bytes()...) + } + query := process.SCQuery{ + ScAddress: scAddress, + FuncName: funcName, + Arguments: dataArgs, + BlockHash: providedHash, + } + + _, _, err := target.ExecuteQuery(&query) + assert.True(t, runWasCalled) + assert.True(t, wasRecreateTrieCalled) + assert.Nil(t, err) + }) + t.Run("block nonce should work - old epoch", func(t *testing.T) { t.Parallel() runWasCalled := false @@ -476,6 +573,13 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { }, } argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: 37, + } + }, + } argsNewSCQuery.VmContainer = &mock.VMContainerMock{ GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { return mockVM, nil @@ -554,6 +658,258 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { assert.True(t, runWasCalled) assert.True(t, wasRecreateTrieCalled) }) + t.Run("block nonce should work - current epoch", func(t *testing.T) { + t.Parallel() + + runWasCalled := false + + mockVM := &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { + runWasCalled = true + assert.Equal(t, int64(42), big.NewInt(0).SetBytes(input.Arguments[0]).Int64()) + assert.Equal(t, int64(43), big.NewInt(0).SetBytes(input.Arguments[1]).Int64()) + assert.Equal(t, scAddress, input.CallerAddr) + assert.Equal(t, funcName, input.Function) + + return &vmcommon.VMOutput{ + ReturnCode: vmcommon.Ok, + }, nil + }, + } + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.VmContainer = &mock.VMContainerMock{ + GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { + return mockVM, nil + }, + } + argsNewSCQuery.EconomicsFee = &economicsmocks.EconomicsHandlerStub{ + MaxGasLimitPerBlockCalled: func(_ uint32) uint64 { + return uint64(math.MaxUint64) + }, + } + providedHash := []byte("provided hash") + providedRootHash := []byte("provided root hash") + providedNonce := uint64(123) + argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} + counter := 0 + argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ + GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { + return &storageStubs.StorerStub{ + GetCalled: func(key []byte) ([]byte, error) { + return providedHash, nil + }, + GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { + counter++ + if counter > 2 { + return nil, fmt.Errorf("no scheduled") + } + hdr := &block.Header{ + RootHash: providedRootHash, + } + buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) + return buff, nil + }, + }, nil + }, + } + argsNewSCQuery.HistoryRepository = &dblookupext.HistoryRepositoryStub{ + IsEnabledCalled: func() bool { + return true + }, + GetEpochByHashCalled: func(hash []byte) (uint32, error) { + require.Equal(t, providedHash, hash) + return 12, nil + }, + } + wasRecreateTrieCalled := false + providedAccountsAdapter := &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + wasRecreateTrieCalled = true + assert.Equal(t, providedRootHash, rootHash) + return nil + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return providedAccountsAdapter + }, + } + + target, _ := NewSCQueryService(argsNewSCQuery) + + dataArgs := make([][]byte, len(args)) + for i, arg := range args { + dataArgs[i] = append(dataArgs[i], arg.Bytes()...) + } + query := process.SCQuery{ + ScAddress: scAddress, + FuncName: funcName, + Arguments: dataArgs, + BlockNonce: core.OptionalUint64{ + Value: providedNonce, + HasValue: true, + }, + } + + _, _, _ = target.ExecuteQuery(&query) + assert.True(t, runWasCalled) + assert.True(t, wasRecreateTrieCalled) + }) +} + +func TestSCQueryService_RecreateTrie(t *testing.T) { + t.Parallel() + + testRootHash := []byte("test root hash") + t.Run("should call RecreateTrie for genesis block", func(t *testing.T) { + t.Parallel() + + recreateTrieCalled := false + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return nil // after the genesis we do not have a header as current block + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + recreateTrieCalled = true + assert.Equal(t, testRootHash, rootHash) + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + err := service.recreateTrie(testRootHash, &block.Header{}) + assert.Nil(t, err) + assert.True(t, recreateTrieCalled) + }) + t.Run("should call RecreateTrie for block on epoch 0", func(t *testing.T) { + t.Parallel() + + recreateTrieCalled := false + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: 0, + } + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + recreateTrieCalled = true + assert.Equal(t, testRootHash, rootHash) + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + err := service.recreateTrie(testRootHash, &block.Header{}) + assert.Nil(t, err) + assert.True(t, recreateTrieCalled) + }) + t.Run("should call RecreateTrie for block on epoch 1", func(t *testing.T) { + t.Parallel() + + recreateTrieCalled := false + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: 1, + } + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + recreateTrieCalled = true + assert.Equal(t, testRootHash, rootHash) + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + err := service.recreateTrie(testRootHash, &block.Header{ + Epoch: 0, + }) + assert.Nil(t, err) + assert.True(t, recreateTrieCalled) + }) + t.Run("should call RecreateTrie for block on epoch 2", func(t *testing.T) { + t.Parallel() + + recreateTrieCalled := false + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: 3, + } + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + recreateTrieCalled = true + assert.Equal(t, testRootHash, rootHash) + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + err := service.recreateTrie(testRootHash, &block.Header{ + Epoch: 2, + }) + assert.Nil(t, err) + assert.True(t, recreateTrieCalled) + }) + t.Run("should call RecreateTrieFromEpoch for block on epoch 3", func(t *testing.T) { + t.Parallel() + + recreateTrieCalled := false + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: 3, + } + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieCalled = true + assert.Equal(t, testRootHash, options.GetRootHash()) + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + err := service.recreateTrie(testRootHash, &block.Header{ + Epoch: 0, + }) + assert.Nil(t, err) + assert.True(t, recreateTrieCalled) + }) } func TestExecuteQuery_ReturnsCorrectly(t *testing.T) { From b9ecacf7c4fa449d7876b41912473e0172c560af Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 20 Feb 2024 16:28:04 +0200 Subject: [PATCH 851/958] - fixes --- state/accountsDBApi.go | 3 +++ state/accountsDBApi_test.go | 7 +++---- state/errors.go | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/state/accountsDBApi.go b/state/accountsDBApi.go index ae3ca439984..e94610f0fcb 100644 --- a/state/accountsDBApi.go +++ b/state/accountsDBApi.go @@ -175,6 +175,9 @@ func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(options common.RootHashHo accountsDB.mutRecreatedTrieBlockInfo.Lock() defer accountsDB.mutRecreatedTrieBlockInfo.Unlock() + if options == nil { + return ErrNilRootHashHolder + } newBlockInfo := holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) if newBlockInfo.Equal(accountsDB.blockInfo) { return nil diff --git a/state/accountsDBApi_test.go b/state/accountsDBApi_test.go index 1544e5691b1..1a22366ab06 100644 --- a/state/accountsDBApi_test.go +++ b/state/accountsDBApi_test.go @@ -230,17 +230,16 @@ func TestAccountsDBApi_RecreateTrieFromEpoch(t *testing.T) { t.Parallel() t.Run("should error if the roothash holder is nil", func(t *testing.T) { - wasCalled := false accountsApi, _ := state.NewAccountsDBApi(&mockState.AccountsStub{ RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - wasCalled = true - return trie.ErrNilRootHashHolder + assert.Fail(t, "should have not called accountsApi.RecreateTrieFromEpochCalled") + + return nil }, }, createBlockInfoProviderStub(dummyRootHash)) err := accountsApi.RecreateTrieFromEpoch(nil) assert.Equal(t, trie.ErrNilRootHashHolder, err) - assert.True(t, wasCalled) }) t.Run("should work", func(t *testing.T) { wasCalled := false diff --git a/state/errors.go b/state/errors.go index 5a56aff40ff..893d65d7ec0 100644 --- a/state/errors.go +++ b/state/errors.go @@ -144,3 +144,6 @@ var ErrNilStateMetrics = errors.New("nil sstate metrics") // ErrNilChannelsProvider signals that a nil channels provider has been given var ErrNilChannelsProvider = errors.New("nil channels provider") + +// ErrNilRootHashHolder signals that a nil root hash holder was provided +var ErrNilRootHashHolder = errors.New("nil root hash holder provided") From 9f3d0108d24508598ab45ae2eb29522f665e50bb Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 20 Feb 2024 16:44:52 +0200 Subject: [PATCH 852/958] - fixes after review --- process/smartContract/scQueryService_test.go | 64 +++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index ed57b9f1689..818fa9c2f73 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -432,10 +432,10 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return 12, nil }, } - wasRecreateTrieCalled := false + recreateTrieWasCalled := false providedAccountsAdapter := &stateMocks.AccountsStub{ RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - wasRecreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, providedRootHash, options.GetRootHash()) return nil }, @@ -461,7 +461,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, err := target.ExecuteQuery(&query) assert.True(t, runWasCalled) - assert.True(t, wasRecreateTrieCalled) + assert.True(t, recreateTrieWasCalled) assert.Nil(t, err) }) t.Run("block hash should work - current epoch", func(t *testing.T) { @@ -496,15 +496,10 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { providedHash := []byte("provided hash") providedRootHash := []byte("provided root hash") argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} - counter := 0 argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { return &storageStubs.StorerStub{ GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { - counter++ - if counter > 2 { - return nil, fmt.Errorf("no scheduled") - } hdr := &block.Header{ RootHash: providedRootHash, } @@ -522,10 +517,10 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return 12, nil }, } - wasRecreateTrieCalled := false + recreateTrieWasCalled := false providedAccountsAdapter := &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { - wasRecreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, providedRootHash, rootHash) return nil }, @@ -551,7 +546,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, err := target.ExecuteQuery(&query) assert.True(t, runWasCalled) - assert.True(t, wasRecreateTrieCalled) + assert.True(t, recreateTrieWasCalled) assert.Nil(t, err) }) t.Run("block nonce should work - old epoch", func(t *testing.T) { @@ -624,10 +619,10 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return 12, nil }, } - wasRecreateTrieCalled := false + recreateTrieWasCalled := false providedAccountsAdapter := &stateMocks.AccountsStub{ RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - wasRecreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, providedRootHash, options.GetRootHash()) return nil }, @@ -656,7 +651,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) - assert.True(t, wasRecreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) t.Run("block nonce should work - current epoch", func(t *testing.T) { t.Parallel() @@ -691,7 +686,6 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { providedRootHash := []byte("provided root hash") providedNonce := uint64(123) argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} - counter := 0 argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { return &storageStubs.StorerStub{ @@ -699,10 +693,6 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return providedHash, nil }, GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { - counter++ - if counter > 2 { - return nil, fmt.Errorf("no scheduled") - } hdr := &block.Header{ RootHash: providedRootHash, } @@ -721,10 +711,10 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return 12, nil }, } - wasRecreateTrieCalled := false + recreateTrieWasCalled := false providedAccountsAdapter := &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { - wasRecreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, providedRootHash, rootHash) return nil }, @@ -753,7 +743,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) - assert.True(t, wasRecreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) } @@ -764,7 +754,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { t.Run("should call RecreateTrie for genesis block", func(t *testing.T) { t.Parallel() - recreateTrieCalled := false + recreateTrieWasCalled := false argsNewSCQuery := createMockArgumentsForSCQuery() argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { @@ -775,7 +765,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { GetAccountsAdapterCalled: func() state.AccountsAdapter { return &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, testRootHash, rootHash) return nil }, @@ -786,12 +776,12 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { service, _ := NewSCQueryService(argsNewSCQuery) err := service.recreateTrie(testRootHash, &block.Header{}) assert.Nil(t, err) - assert.True(t, recreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) t.Run("should call RecreateTrie for block on epoch 0", func(t *testing.T) { t.Parallel() - recreateTrieCalled := false + recreateTrieWasCalled := false argsNewSCQuery := createMockArgumentsForSCQuery() argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { @@ -804,7 +794,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { GetAccountsAdapterCalled: func() state.AccountsAdapter { return &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, testRootHash, rootHash) return nil }, @@ -815,12 +805,12 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { service, _ := NewSCQueryService(argsNewSCQuery) err := service.recreateTrie(testRootHash, &block.Header{}) assert.Nil(t, err) - assert.True(t, recreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) t.Run("should call RecreateTrie for block on epoch 1", func(t *testing.T) { t.Parallel() - recreateTrieCalled := false + recreateTrieWasCalled := false argsNewSCQuery := createMockArgumentsForSCQuery() argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { @@ -833,7 +823,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { GetAccountsAdapterCalled: func() state.AccountsAdapter { return &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, testRootHash, rootHash) return nil }, @@ -846,12 +836,12 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { Epoch: 0, }) assert.Nil(t, err) - assert.True(t, recreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) t.Run("should call RecreateTrie for block on epoch 2", func(t *testing.T) { t.Parallel() - recreateTrieCalled := false + recreateTrieWasCalled := false argsNewSCQuery := createMockArgumentsForSCQuery() argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { @@ -864,7 +854,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { GetAccountsAdapterCalled: func() state.AccountsAdapter { return &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, testRootHash, rootHash) return nil }, @@ -877,12 +867,12 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { Epoch: 2, }) assert.Nil(t, err) - assert.True(t, recreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) t.Run("should call RecreateTrieFromEpoch for block on epoch 3", func(t *testing.T) { t.Parallel() - recreateTrieCalled := false + recreateTrieWasCalled := false argsNewSCQuery := createMockArgumentsForSCQuery() argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { @@ -895,7 +885,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { GetAccountsAdapterCalled: func() state.AccountsAdapter { return &stateMocks.AccountsStub{ RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - recreateTrieCalled = true + recreateTrieWasCalled = true assert.Equal(t, testRootHash, options.GetRootHash()) return nil }, @@ -908,7 +898,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { Epoch: 0, }) assert.Nil(t, err) - assert.True(t, recreateTrieCalled) + assert.True(t, recreateTrieWasCalled) }) } From 3fef6379795483e93c4cdc3d6dec7083a6f38ad1 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 20 Feb 2024 17:29:12 +0200 Subject: [PATCH 853/958] first impl --- .../staking/stakeAndUnStake_test.go | 219 ++++++++++++++++++ 1 file changed, 219 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 19e5a3835ab..43ddef304d5 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" "math/big" + "strings" "testing" "time" @@ -1219,3 +1220,221 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) testBLSKeyStaked(t, cs, metachainNode, blsKeys[1], targetEpoch) } + +// Test description: +// Withdraw unstaked funds before unbonding period should return error +// +// Internal test scenario #28 +func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test Steps + // 1. Check the stake amount and number of nodes for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance + // 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network + // 3. Check the outcome of the TX & verify new stake state with vmquery + // 4. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network + // 5. Check the outcome of the TX & verify new stake state with vmquery + // 6. Wait for change of epoch and check the outcome + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 1) + }) + + // t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + + // defer cs.Close() + + // testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 2) + // }) + + // t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + + // defer cs.Close() + + // testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 3) + // }) + + // t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + + // defer cs.Close() + + // testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 4) + // }) +} + +func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + validatorOwnerBytes := generateWalletAddressBytes() + validatorOwner2, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(validatorOwnerBytes) + + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(10000) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + addresses := []*dtos.AddressState{ + {Address: validatorOwner2, Balance: mintValue.String()}, + } + err = cs.SetStateMultiple(addresses) + require.Nil(t, err) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Set(minimumStakeValue) + addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) + stakeValue.Add(stakeValue, addedStakedValue) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwnerBytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + // Step 3: Create a new delegation contract + maxDelegationCap := big.NewInt(0).Mul(oneEGLD, big.NewInt(51000)) // 51000 EGLD cap + serviceFee := big.NewInt(100) // 100 as service fee + txCreateDelegationContract := generateTransaction(validatorOwnerBytes, 1, vm.DelegationManagerSCAddress, stakeValue, + fmt.Sprintf("createNewDelegationContract@%s@%s", hex.EncodeToString(maxDelegationCap.Bytes()), hex.EncodeToString(serviceFee.Bytes())), + gasLimitForDelegationContractCreationOperation) + createDelegationContractTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txCreateDelegationContract, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, createDelegationContractTx) + + // check delegation contract creation was successful + data := createDelegationContractTx.SmartContractResults[0].Data + parts := strings.Split(data, "@") + require.Equal(t, 3, len(parts)) + + require.Equal(t, hex.EncodeToString([]byte("ok")), parts[1]) + delegationContractAddressHex, _ := hex.DecodeString(parts[2]) + delegationContractAddress, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(delegationContractAddressHex) + + output, err := executeQuery(cs, core.MetachainShardId, vm.DelegationManagerSCAddress, "getAllContractAddresses", nil) + require.Nil(t, err) + returnAddress, err := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(output.ReturnData[0]) + require.Nil(t, err) + require.Equal(t, delegationContractAddress, returnAddress) + delegationContractAddressBytes := output.ReturnData[0] + + // delegate funds + delegationValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(150)) + txDelegate1 := generateTransaction(validatorOwner.Bytes, 0, delegationContractAddressBytes, delegationValue, "delegate", gasLimitForDelegate) + delegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, delegate1Tx) +} From 1ad1e264071134cc55bebefce5d75ef17e195b56 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 20 Feb 2024 18:10:37 +0200 Subject: [PATCH 854/958] added withdraw unstaked funds before unbonding period scenario --- .../chainSimulator/staking/delegation_test.go | 1 + .../staking/stakeAndUnStake_test.go | 281 +++++++++--------- 2 files changed, 149 insertions(+), 133 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index bf16816ce25..39302a28b68 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -38,6 +38,7 @@ const gasLimitForAddNodesOperation = 500_000_000 const gasLimitForUndelegateOperation = 500_000_000 const gasLimitForMergeOperation = 600_000_000 const gasLimitForDelegate = 12_000_000 +const gasLimitForUnBond = 2_000_000 const minGasPrice = 1000000000 const txVersion = 1 const mockTxSignature = "sig" diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 43ddef304d5..6bf8efcbb0c 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "fmt" "math/big" - "strings" "testing" "time" @@ -1237,12 +1236,8 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding( } // Test Steps - // 1. Check the stake amount and number of nodes for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance - // 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network - // 3. Check the outcome of the TX & verify new stake state with vmquery - // 4. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network - // 5. Check the outcome of the TX & verify new stake state with vmquery - // 6. Wait for change of epoch and check the outcome + // 1. Create from the owner of staked nodes a transaction to withdraw the unstaked funds + // 2. Check the outcome of the TX & verify new stake state with vmquery ("getUnStakedTokensList") t.Run("staking ph 4 is not active", func(t *testing.T) { cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ @@ -1274,104 +1269,101 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding( testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 1) }) - // t.Run("staking ph 4 step 1 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - - // defer cs.Close() - - // testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 2) - // }) - - // t.Run("staking ph 4 step 2 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - - // defer cs.Close() - - // testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 3) - // }) - - // t.Run("staking ph 4 step 3 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - - // defer cs.Close() - - // testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 4) - // }) + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 4) + }) } func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) - validatorOwnerBytes := generateWalletAddressBytes() - validatorOwner2, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(validatorOwnerBytes) - privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) require.Nil(t, err) @@ -1382,20 +1374,12 @@ func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testi mintValue := big.NewInt(10000) mintValue = mintValue.Mul(oneEGLD, mintValue) - addresses := []*dtos.AddressState{ - {Address: validatorOwner2, Balance: mintValue.String()}, - } - err = cs.SetStateMultiple(addresses) - require.Nil(t, err) - validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) require.Nil(t, err) - stakeValue := big.NewInt(0).Set(minimumStakeValue) - addedStakedValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) - stakeValue.Add(stakeValue, addedStakedValue) + stakeValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(2600)) txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) - txStake := generateTransaction(validatorOwnerBytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.NotNil(t, stakeTx) @@ -1405,36 +1389,67 @@ func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testi testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) - // Step 3: Create a new delegation contract - maxDelegationCap := big.NewInt(0).Mul(oneEGLD, big.NewInt(51000)) // 51000 EGLD cap - serviceFee := big.NewInt(100) // 100 as service fee - txCreateDelegationContract := generateTransaction(validatorOwnerBytes, 1, vm.DelegationManagerSCAddress, stakeValue, - fmt.Sprintf("createNewDelegationContract@%s@%s", hex.EncodeToString(maxDelegationCap.Bytes()), hex.EncodeToString(serviceFee.Bytes())), - gasLimitForDelegationContractCreationOperation) - createDelegationContractTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txCreateDelegationContract, maxNumOfBlockToGenerateWhenExecutingTx) + shardIDValidatorOwner := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(validatorOwner.Bytes) + accountValidatorOwner, _, err := cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) require.Nil(t, err) - require.NotNil(t, createDelegationContractTx) + balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - // check delegation contract creation was successful - data := createDelegationContractTx.SmartContractResults[0].Data - parts := strings.Split(data, "@") - require.Equal(t, 3, len(parts)) + log.Info("Step 1. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") - require.Equal(t, hex.EncodeToString([]byte("ok")), parts[1]) - delegationContractAddressHex, _ := hex.DecodeString(parts[2]) - delegationContractAddress, _ := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(delegationContractAddressHex) + unStakeValue := big.NewInt(10) + unStakeValue = unStakeValue.Mul(oneEGLD, unStakeValue) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue.Bytes())) + txUnStake := generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) - output, err := executeQuery(cs, core.MetachainShardId, vm.DelegationManagerSCAddress, "getAllContractAddresses", nil) + err = cs.GenerateBlocks(2) require.Nil(t, err) - returnAddress, err := cs.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Encode(output.ReturnData[0]) + + // check bls key is still staked + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + txDataField = fmt.Sprintf("unBond@%s", blsKeys[0]) + txUnBond := generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) + unBondTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) - require.Equal(t, delegationContractAddress, returnAddress) - delegationContractAddressBytes := output.ReturnData[0] + require.NotNil(t, unBondTx) - // delegate funds - delegationValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(150)) - txDelegate1 := generateTransaction(validatorOwner.Bytes, 0, delegationContractAddressBytes, delegationValue, "delegate", gasLimitForDelegate) - delegate1Tx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txDelegate1, maxNumOfBlockToGenerateWhenExecutingTx) + err = cs.GenerateBlocks(2) require.Nil(t, err) - require.NotNil(t, delegate1Tx) + + log.Info("Step 2. Check the outcome of the TX & verify new stake state with vmquery (`getUnStakedTokensList`)") + + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getUnStakedTokensList", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedUnStaked := big.NewInt(10) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + + // the owner balance should decrease only with the txs fee + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + txsFee, _ := big.NewInt(0).SetString(unBondTx.Fee, 10) + balanceAfterUnbondingWithFee := big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + + txsFee, _ = big.NewInt(0).SetString(unStakeTx.Fee, 10) + balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + + txsFee, _ = big.NewInt(0).SetString(stakeTx.Fee, 10) + balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + + require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) + } From 9150abc369d8a5cd3b5035844d1cb00a5c27bb87 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Tue, 20 Feb 2024 19:35:17 +0200 Subject: [PATCH 855/958] scenario: withdraw unstaked funds in first available epoch --- .../chainSimulator/staking/delegation_test.go | 2 +- .../staking/stakeAndUnStake_test.go | 268 +++++++++++++++++- 2 files changed, 263 insertions(+), 7 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 39302a28b68..93652aa0f56 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -38,7 +38,7 @@ const gasLimitForAddNodesOperation = 500_000_000 const gasLimitForUndelegateOperation = 500_000_000 const gasLimitForMergeOperation = 600_000_000 const gasLimitForDelegate = 12_000_000 -const gasLimitForUnBond = 2_000_000 +const gasLimitForUnBond = 12_000_000 const minGasPrice = 1000000000 const txVersion = 1 const mockTxSignature = "sig" diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 6bf8efcbb0c..04f3a544fcd 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -1266,7 +1266,7 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding( defer cs.Close() - testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 1) + testChainSimulatorDirectStakedWithdrawUnstakedFundsBeforeUnbonding(t, cs, 1) }) t.Run("staking ph 4 step 1 is active", func(t *testing.T) { @@ -1296,7 +1296,7 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding( defer cs.Close() - testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 2) + testChainSimulatorDirectStakedWithdrawUnstakedFundsBeforeUnbonding(t, cs, 2) }) t.Run("staking ph 4 step 2 is active", func(t *testing.T) { @@ -1326,7 +1326,7 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding( defer cs.Close() - testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 3) + testChainSimulatorDirectStakedWithdrawUnstakedFundsBeforeUnbonding(t, cs, 3) }) t.Run("staking ph 4 step 3 is active", func(t *testing.T) { @@ -1356,11 +1356,11 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedFundsBeforeUnbonding( defer cs.Close() - testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t, cs, 4) + testChainSimulatorDirectStakedWithdrawUnstakedFundsBeforeUnbonding(t, cs, 4) }) } -func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { +func testChainSimulatorDirectStakedWithdrawUnstakedFundsBeforeUnbonding(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) @@ -1410,7 +1410,7 @@ func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testi // check bls key is still staked testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) - txDataField = fmt.Sprintf("unBond@%s", blsKeys[0]) + txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) txUnBond := generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) unBondTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -1451,5 +1451,261 @@ func testChainSimulatorDirectStakedWithdrayUnstakedFundsBeforeUnbonding(t *testi balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) +} + +// Test description: +// Withdraw unstaked funds in first available withdraw epoch +// +// Internal test scenario #29 +func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInWithdrawEpoch(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test Steps + // 1. Wait for the unbonding epoch to start + // 2. Create from the owner of staked nodes a transaction to withdraw the unstaked funds + // 3. Check the outcome of the TX & verify new stake state with vmquery ("getUnStakedTokensList") + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInFirstEpoch(t, cs, 1) + }) + + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInFirstEpoch(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInFirstEpoch(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInFirstEpoch(t, cs, 4) + }) +} + +func testChainSimulatorDirectStakedWithdrawUnstakedFundsInFirstEpoch(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(10000) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(2600)) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + shardIDValidatorOwner := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(validatorOwner.Bytes) + accountValidatorOwner, _, err := cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + unStakeValue := big.NewInt(10) + unStakeValue = unStakeValue.Mul(oneEGLD, unStakeValue) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue.Bytes())) + txUnStake := generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + // check bls key is still staked + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getUnStakedTokensList", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedUnStaked := big.NewInt(10) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + + log.Info("Step 1. Wait for the unbonding epoch to start") + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + log.Info("Step 2. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") + + txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) + txUnBond := generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) + unBondTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unBondTx) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + log.Info("Step 3. Check the outcome of the TX & verify new stake state with vmquery (`getUnStakedTokensList`)") + + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked := big.NewInt(2590) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + // the owner balance should increase with the (10 EGLD - tx fee) + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + // substract unbonding value + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue) + + txsFee, _ := big.NewInt(0).SetString(unBondTx.Fee, 10) + balanceAfterUnbondingWithFee := big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + + txsFee, _ = big.NewInt(0).SetString(unStakeTx.Fee, 10) + balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + + txsFee, _ = big.NewInt(0).SetString(stakeTx.Fee, 10) + balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + + require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) } From 8e7be72af369323e5995e08345ebebb89896d7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 20 Feb 2024 21:12:34 +0200 Subject: [PATCH 856/958] Fix after review. --- process/smartContract/scQueryService.go | 8 ++++++-- process/smartContract/scQueryService_test.go | 19 +++++++++++++++++++ state/accountsDBApi.go | 3 ++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 0090c9d16b4..af522e88d83 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -195,8 +195,6 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } if len(blockRootHash) > 0 { - logQueryService.Trace("preparing execution for block and root hash", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) - err = service.apiBlockChain.SetCurrentBlockHeaderAndRootHash(blockHeader, blockRootHash) if err != nil { return nil, nil, err @@ -252,6 +250,12 @@ func (service *SCQueryService) executeScCall(query *process.SCQuery, gasPrice ui } func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader data.HeaderHandler) error { + if check.IfNil(blockHeader) { + return process.ErrNilBlockHeader + } + + logQueryService.Trace("preparing execution for block and root hash", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + accountsAdapter := service.blockChainHook.GetAccountsAdapter() if blockHeader.GetEpoch()+epochDifferenceToConsiderHistory >= service.getCurrentEpoch() { // recent history diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 818fa9c2f73..cd31bc165ec 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -751,6 +751,25 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { t.Parallel() testRootHash := []byte("test root hash") + t.Run("should not call RecreateTrie if block header is nil", func(t *testing.T) { + t.Parallel() + + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + require.Fail(t, "should not be called") + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + err := service.recreateTrie(testRootHash, nil) + assert.ErrorIs(t, err, process.ErrNilBlockHeader) + }) t.Run("should call RecreateTrie for genesis block", func(t *testing.T) { t.Parallel() diff --git a/state/accountsDBApi.go b/state/accountsDBApi.go index e94610f0fcb..791bfc658df 100644 --- a/state/accountsDBApi.go +++ b/state/accountsDBApi.go @@ -175,9 +175,10 @@ func (accountsDB *accountsDBApi) RecreateTrieFromEpoch(options common.RootHashHo accountsDB.mutRecreatedTrieBlockInfo.Lock() defer accountsDB.mutRecreatedTrieBlockInfo.Unlock() - if options == nil { + if check.IfNil(options) { return ErrNilRootHashHolder } + newBlockInfo := holders.NewBlockInfo([]byte{}, 0, options.GetRootHash()) if newBlockInfo.Equal(accountsDB.blockInfo) { return nil From f9bcc00f9385127e0cfb2c94dce2a4ae38f69d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 20 Feb 2024 21:16:54 +0200 Subject: [PATCH 857/958] Fix logs. --- process/smartContract/scQueryService.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index af522e88d83..b243a8db2b0 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -254,15 +254,13 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da return process.ErrNilBlockHeader } - logQueryService.Trace("preparing execution for block and root hash", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) - accountsAdapter := service.blockChainHook.GetAccountsAdapter() if blockHeader.GetEpoch()+epochDifferenceToConsiderHistory >= service.getCurrentEpoch() { - // recent history + logQueryService.Trace("calling RecreateTrie, for recent history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) return accountsAdapter.RecreateTrie(blockRootHash) } - // old history, this will take a little longer + logQueryService.Trace("calling RecreateTrieFromEpoch, for older history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) return accountsAdapter.RecreateTrieFromEpoch(holder) } From e8dd458f39467635779fc4bae5ec821ebefdf524 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 21 Feb 2024 10:08:53 +0200 Subject: [PATCH 858/958] - refactored unit tests --- epochStart/metachain/systemSCs_test.go | 214 ++++++++++-------- .../maxNodesChangeConfigProviderStub.go | 40 ++++ 2 files changed, 162 insertions(+), 92 deletions(-) create mode 100644 testscommon/maxNodesChangeConfigProviderStub.go diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index 97ea4c7497f..d48ffaa5071 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -47,9 +47,12 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" dataRetrieverMock "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" + "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/multiversx/mx-chain-go/testscommon/stakingcommon" + stateMock "github.com/multiversx/mx-chain-go/testscommon/state" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" storageMock "github.com/multiversx/mx-chain-go/testscommon/storage" "github.com/multiversx/mx-chain-go/trie" @@ -99,9 +102,27 @@ func createPhysicalUnit(t *testing.T) (storage.Storer, string) { return unit, dir } -type enableEpochHandlerWithEpochConfirm interface { - common.EnableEpochsHandler - core.EpochSubscriberHandler +func createMockArgsForSystemSCProcessor() ArgsNewEpochStartSystemSCProcessing { + return ArgsNewEpochStartSystemSCProcessing{ + SystemVM: &mock.VMExecutionHandlerStub{}, + UserAccountsDB: &stateMock.AccountsStub{}, + PeerAccountsDB: &stateMock.AccountsStub{}, + Marshalizer: &marshallerMock.MarshalizerStub{}, + StartRating: 0, + ValidatorInfoCreator: &testscommon.ValidatorStatisticsProcessorStub{}, + ChanceComputer: &mock.ChanceComputerStub{}, + ShardCoordinator: &testscommon.ShardsCoordinatorMock{}, + EndOfEpochCallerAddress: vm.EndOfEpochAddress, + StakingSCAddress: vm.StakingSCAddress, + ESDTOwnerAddressBytes: vm.ESDTSCAddress, + GenesisNodesConfig: &genesisMocks.NodesSetupStub{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + NodesConfigProvider: &shardingMocks.NodesCoordinatorStub{}, + StakingDataProvider: &stakingcommon.StakingDataProviderStub{}, + AuctionListSelector: &stakingcommon.AuctionListSelectorStub{}, + MaxNodesChangeConfigProvider: &testscommon.MaxNodesChangeConfigProviderStub{}, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + } } func TestNewSystemSCProcessor(t *testing.T) { @@ -961,118 +982,127 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testing.T) { t.Parallel() - t.Run("flag not active - activation epoch is in the future", func(t *testing.T) { - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - DelegationSmartContractEnableEpoch: 39, - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) - handler.EpochConfirmed(37, 0) + t.Run("flag not active", func(t *testing.T) { + args := createMockArgsForSystemSCProcessor() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + if flag == common.GovernanceFlagInSpecificEpochOnly || + flag == common.StakingV4Step1Flag || + flag == common.StakingV4Step2Flag || + flag == common.SwitchHysteresisForMinNodesFlagInSpecificEpochOnly || + flag == common.StakingV2OwnerFlagInSpecificEpochOnly || + flag == common.CorrectLastUnJailedFlagInSpecificEpochOnly || + flag == common.DelegationSmartContractFlagInSpecificEpochOnly || + flag == common.CorrectLastUnJailedFlag || + flag == common.SwitchJailWaitingFlag || + flag == common.StakingV2Flag || + flag == common.ESDTFlagInSpecificEpochOnly { + + return false + } - validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + return true + }, + } + args.SystemVM = &mock.VMExecutionHandlerStub{ + RunSmartContractCreateCalled: func(input *vmcommon.ContractCreateInput) (*vmcommon.VMOutput, error) { + assert.Fail(t, "should have not called") - acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) - assert.NotNil(t, err) - assert.True(t, check.IfNil(acc)) - }) - t.Run("flag active in that specific epoch", func(t *testing.T) { - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - DelegationSmartContractEnableEpoch: 37, - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) - handler.EpochConfirmed(37, 0) + return nil, fmt.Errorf("should have not called") + }, + } + processor, _ := NewSystemSCProcessor(args) + require.NotNil(t, processor) validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - - acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) - assert.Nil(t, err) - - userAcc, _ := acc.(state.UserAccountHandler) - assert.Equal(t, userAcc.GetOwnerAddress(), vm.DelegationManagerSCAddress) - assert.NotNil(t, userAcc.GetCodeMetadata()) }) - t.Run("flag not active - activation epoch is in the past", func(t *testing.T) { - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - DelegationSmartContractEnableEpoch: 35, - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) - handler.EpochConfirmed(37, 0) + t.Run("flag active", func(t *testing.T) { + args := createMockArgsForSystemSCProcessor() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + return flag == common.DelegationSmartContractFlagInSpecificEpochOnly + }, + } + runSmartContractCreateCalled := false + args.SystemVM = &mock.VMExecutionHandlerStub{ + RunSmartContractCreateCalled: func(input *vmcommon.ContractCreateInput) (*vmcommon.VMOutput, error) { + runSmartContractCreateCalled = true + + return &vmcommon.VMOutput{}, nil + }, + } + processor, _ := NewSystemSCProcessor(args) + require.NotNil(t, processor) validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - - acc, err := s.userAccountsDB.GetExistingAccount(vm.DelegationManagerSCAddress) - assert.NotNil(t, err) - assert.True(t, check.IfNil(acc)) + assert.True(t, runSmartContractCreateCalled) }) } func TestSystemSCProcessor_ProcessSystemSmartContractInitGovernance(t *testing.T) { t.Parallel() + t.Run("flag not active", func(t *testing.T) { + args := createMockArgsForSystemSCProcessor() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + if flag == common.GovernanceFlagInSpecificEpochOnly || + flag == common.StakingV4Step1Flag || + flag == common.StakingV4Step2Flag || + flag == common.SwitchHysteresisForMinNodesFlagInSpecificEpochOnly || + flag == common.StakingV2OwnerFlagInSpecificEpochOnly || + flag == common.CorrectLastUnJailedFlagInSpecificEpochOnly || + flag == common.DelegationSmartContractFlagInSpecificEpochOnly || + flag == common.CorrectLastUnJailedFlag || + flag == common.SwitchJailWaitingFlag || + flag == common.StakingV2Flag || + flag == common.ESDTFlagInSpecificEpochOnly { + + return false + } - t.Run("flag not active - activation epoch is in the future", func(t *testing.T) { - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - GovernanceEnableEpoch: 39, - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) - handler.EpochConfirmed(37, 0) - - validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + return true + }, + } + args.SystemVM = &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + assert.Fail(t, "should have not called") - acc, err := s.userAccountsDB.GetExistingAccount(vm.GovernanceSCAddress) - assert.NotNil(t, err) - assert.True(t, check.IfNil(acc)) - }) - t.Run("flag active in that specific epoch", func(t *testing.T) { - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - GovernanceEnableEpoch: 37, - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) - handler.EpochConfirmed(37, 0) + return nil, fmt.Errorf("should have not called") + }, + } + processor, _ := NewSystemSCProcessor(args) + require.NotNil(t, processor) validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - - acc, err := s.userAccountsDB.GetExistingAccount(vm.GovernanceSCAddress) - assert.Nil(t, err) - - userAcc, _ := acc.(state.UserAccountHandler) - assert.Empty(t, userAcc.GetOwnerAddress()) - assert.Empty(t, userAcc.GetCodeMetadata()) }) - t.Run("flag not active - activation epoch is in the past", func(t *testing.T) { - args, _ := createFullArgumentsForSystemSCProcessing(config.EnableEpochs{ - GovernanceEnableEpoch: 35, - StakingV2EnableEpoch: 1000, - }, testscommon.CreateMemUnit()) - s, _ := NewSystemSCProcessor(args) - handler := s.enableEpochsHandler.(enableEpochHandlerWithEpochConfirm) - handler.EpochConfirmed(37, 0) // epoch 37 + t.Run("flag active", func(t *testing.T) { + args := createMockArgsForSystemSCProcessor() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + return flag == common.GovernanceFlagInSpecificEpochOnly + }, + } + runSmartContractCreateCalled := false + args.SystemVM = &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + runSmartContractCreateCalled = true + + return &vmcommon.VMOutput{}, nil + }, + } + processor, _ := NewSystemSCProcessor(args) + require.NotNil(t, processor) validatorsInfo := state.NewShardValidatorsInfoMap() - err := s.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) assert.Nil(t, err) - - acc, err := s.userAccountsDB.GetExistingAccount(vm.GovernanceSCAddress) - assert.NotNil(t, err) - assert.True(t, check.IfNil(acc)) + assert.True(t, runSmartContractCreateCalled) }) } diff --git a/testscommon/maxNodesChangeConfigProviderStub.go b/testscommon/maxNodesChangeConfigProviderStub.go new file mode 100644 index 00000000000..1d7195e84f7 --- /dev/null +++ b/testscommon/maxNodesChangeConfigProviderStub.go @@ -0,0 +1,40 @@ +package testscommon + +import "github.com/multiversx/mx-chain-go/config" + +// MaxNodesChangeConfigProviderStub - +type MaxNodesChangeConfigProviderStub struct { + GetAllNodesConfigCalled func() []config.MaxNodesChangeConfig + GetCurrentNodesConfigCalled func() config.MaxNodesChangeConfig + EpochConfirmedCalled func(epoch uint32, round uint64) +} + +// GetAllNodesConfig - +func (stub *MaxNodesChangeConfigProviderStub) GetAllNodesConfig() []config.MaxNodesChangeConfig { + if stub.GetAllNodesConfigCalled != nil { + return stub.GetAllNodesConfigCalled() + } + + return nil +} + +// GetCurrentNodesConfig - +func (stub *MaxNodesChangeConfigProviderStub) GetCurrentNodesConfig() config.MaxNodesChangeConfig { + if stub.GetCurrentNodesConfigCalled != nil { + return stub.GetCurrentNodesConfigCalled() + } + + return config.MaxNodesChangeConfig{} +} + +// EpochConfirmed - +func (stub *MaxNodesChangeConfigProviderStub) EpochConfirmed(epoch uint32, round uint64) { + if stub.EpochConfirmedCalled != nil { + stub.EpochConfirmedCalled(epoch, round) + } +} + +// IsInterfaceNil - +func (stub *MaxNodesChangeConfigProviderStub) IsInterfaceNil() bool { + return stub == nil +} From aa8c3f18b74ace755f25a69e6ddb7029233e9230 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 21 Feb 2024 10:20:35 +0200 Subject: [PATCH 859/958] - added more unit tests --- epochStart/metachain/systemSCs_test.go | 62 +++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/epochStart/metachain/systemSCs_test.go b/epochStart/metachain/systemSCs_test.go index d48ffaa5071..d9426d2d34b 100644 --- a/epochStart/metachain/systemSCs_test.go +++ b/epochStart/metachain/systemSCs_test.go @@ -982,6 +982,7 @@ func createFullArgumentsForSystemSCProcessing(enableEpochsConfig config.EnableEp func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testing.T) { t.Parallel() + expectedErr := errors.New("expected error") t.Run("flag not active", func(t *testing.T) { args := createMockArgsForSystemSCProcessor() args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ @@ -1016,7 +1017,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin validatorsInfo := state.NewShardValidatorsInfoMap() err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + require.Nil(t, err) }) t.Run("flag active", func(t *testing.T) { args := createMockArgsForSystemSCProcessor() @@ -1038,13 +1039,38 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitDelegationMgr(t *testin validatorsInfo := state.NewShardValidatorsInfoMap() err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) - assert.True(t, runSmartContractCreateCalled) + require.Nil(t, err) + require.True(t, runSmartContractCreateCalled) + }) + t.Run("flag active but contract create call errors, should error", func(t *testing.T) { + args := createMockArgsForSystemSCProcessor() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + return flag == common.DelegationSmartContractFlagInSpecificEpochOnly + }, + } + runSmartContractCreateCalled := false + args.SystemVM = &mock.VMExecutionHandlerStub{ + RunSmartContractCreateCalled: func(input *vmcommon.ContractCreateInput) (*vmcommon.VMOutput, error) { + runSmartContractCreateCalled = true + + return nil, expectedErr + }, + } + processor, _ := NewSystemSCProcessor(args) + require.NotNil(t, processor) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + require.ErrorIs(t, err, expectedErr) + require.True(t, runSmartContractCreateCalled) }) } func TestSystemSCProcessor_ProcessSystemSmartContractInitGovernance(t *testing.T) { t.Parallel() + + expectedErr := errors.New("expected error") t.Run("flag not active", func(t *testing.T) { args := createMockArgsForSystemSCProcessor() args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ @@ -1079,7 +1105,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitGovernance(t *testing.T validatorsInfo := state.NewShardValidatorsInfoMap() err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) + require.Nil(t, err) }) t.Run("flag active", func(t *testing.T) { args := createMockArgsForSystemSCProcessor() @@ -1101,8 +1127,32 @@ func TestSystemSCProcessor_ProcessSystemSmartContractInitGovernance(t *testing.T validatorsInfo := state.NewShardValidatorsInfoMap() err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) - assert.Nil(t, err) - assert.True(t, runSmartContractCreateCalled) + require.Nil(t, err) + require.True(t, runSmartContractCreateCalled) + }) + t.Run("flag active but contract call errors, should error", func(t *testing.T) { + args := createMockArgsForSystemSCProcessor() + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledCalled: func(flag core.EnableEpochFlag) bool { + return flag == common.GovernanceFlagInSpecificEpochOnly + }, + } + runSmartContractCreateCalled := false + args.SystemVM = &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (*vmcommon.VMOutput, error) { + runSmartContractCreateCalled = true + + return nil, expectedErr + }, + } + processor, _ := NewSystemSCProcessor(args) + require.NotNil(t, processor) + + validatorsInfo := state.NewShardValidatorsInfoMap() + err := processor.ProcessSystemSmartContract(validatorsInfo, &block.Header{}) + require.ErrorIs(t, err, expectedErr) + require.Contains(t, err.Error(), "governanceV2") + require.True(t, runSmartContractCreateCalled) }) } From ca7aba4b6068efded0c92b2d3cefafa8a2b1263a Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 21 Feb 2024 11:13:12 +0200 Subject: [PATCH 860/958] cryptoComponentsHolder tests --- .../components/cryptoComponents.go | 2 +- .../components/cryptoComponents_test.go | 165 ++++++++++++++++++ 2 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 node/chainSimulator/components/cryptoComponents_test.go diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 42432636724..8ac5b4db751 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -47,7 +47,7 @@ type cryptoComponentsHolder struct { } // CreateCryptoComponents will create a new instance of cryptoComponentsHolder -func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (factory.CryptoComponentsHandler, error) { +func CreateCryptoComponents(args ArgsCryptoComponentsHolder) (*cryptoComponentsHolder, error) { instance := &cryptoComponentsHolder{} cryptoComponentsHandlerArgs := cryptoComp.CryptoComponentsFactoryArgs{ diff --git a/node/chainSimulator/components/cryptoComponents_test.go b/node/chainSimulator/components/cryptoComponents_test.go new file mode 100644 index 00000000000..8a7d42c4496 --- /dev/null +++ b/node/chainSimulator/components/cryptoComponents_test.go @@ -0,0 +1,165 @@ +package components + +import ( + "testing" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/stretchr/testify/require" +) + +func createArgsCryptoComponentsHolder() ArgsCryptoComponentsHolder { + return ArgsCryptoComponentsHolder{ + Config: config.Config{ + Consensus: config.ConsensusConfig{ + Type: "bls", + }, + MultisigHasher: config.TypeConfig{ + Type: "blake2b", + }, + PublicKeyPIDSignature: config.CacheConfig{ + Capacity: 1000, + Type: "LRU", + }, + }, + EnableEpochsConfig: config.EnableEpochs{ + BLSMultiSignerEnableEpoch: []config.MultiSignerConfig{ + { + EnableEpoch: 0, + Type: "no-KOSK", + }, + { + EnableEpoch: 10, + Type: "KOSK", + }, + }, + }, + Preferences: config.Preferences{}, + CoreComponentsHolder: &factory.CoreComponentsHolderStub{ + ValidatorPubKeyConverterCalled: func() core.PubkeyConverter { + return &testscommon.PubkeyConverterStub{ + EncodeCalled: func(pkBytes []byte) (string, error) { + return "public key", nil + }, + } + }, + }, + AllValidatorKeysPemFileName: "allValidatorKeys.pem", + BypassTxSignatureCheck: false, + } +} + +func TestCreateCryptoComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateCryptoComponents(createArgsCryptoComponentsHolder()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("should work with bypass tx sig check", func(t *testing.T) { + t.Parallel() + + args := createArgsCryptoComponentsHolder() + args.BypassTxSignatureCheck = true + comp, err := CreateCryptoComponents(args) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("NewCryptoComponentsFactory failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCryptoComponentsHolder() + args.CoreComponentsHolder = &factory.CoreComponentsHolderStub{ + ValidatorPubKeyConverterCalled: func() core.PubkeyConverter { + return nil + }, + } + comp, err := CreateCryptoComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("managedCryptoComponents.Create failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsCryptoComponentsHolder() + args.CoreComponentsHolder = &factory.CoreComponentsHolderStub{ + ValidatorPubKeyConverterCalled: func() core.PubkeyConverter { + return &testscommon.PubkeyConverterStub{ + EncodeCalled: func(pkBytes []byte) (string, error) { + return "", expectedErr + }, + } + }, + } + comp, err := CreateCryptoComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestCryptoComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *cryptoComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateCryptoComponents(createArgsCryptoComponentsHolder()) + require.False(t, comp.IsInterfaceNil()) +} + +func TestCryptoComponentsHolder_GettersSetters(t *testing.T) { + t.Parallel() + + comp, err := CreateCryptoComponents(createArgsCryptoComponentsHolder()) + require.NoError(t, err) + + require.NotNil(t, comp.PublicKey()) + require.NotNil(t, comp.PrivateKey()) + require.NotEmpty(t, comp.PublicKeyString()) + require.NotEmpty(t, comp.PublicKeyBytes()) + require.NotNil(t, comp.P2pPublicKey()) + require.NotNil(t, comp.P2pPrivateKey()) + require.NotNil(t, comp.P2pSingleSigner()) + require.NotNil(t, comp.TxSingleSigner()) + require.NotNil(t, comp.BlockSigner()) + container := comp.MultiSignerContainer() + require.NotNil(t, container) + require.Nil(t, comp.SetMultiSignerContainer(nil)) + require.Nil(t, comp.MultiSignerContainer()) + require.Nil(t, comp.SetMultiSignerContainer(container)) + signer, err := comp.GetMultiSigner(0) + require.NoError(t, err) + require.NotNil(t, signer) + require.NotNil(t, comp.PeerSignatureHandler()) + require.NotNil(t, comp.BlockSignKeyGen()) + require.NotNil(t, comp.TxSignKeyGen()) + require.NotNil(t, comp.P2pKeyGen()) + require.NotNil(t, comp.MessageSignVerifier()) + require.NotNil(t, comp.ConsensusSigningHandler()) + require.NotNil(t, comp.ManagedPeersHolder()) + require.NotNil(t, comp.KeysHandler()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) +} + +func TestCryptoComponentsHolder_Clone(t *testing.T) { + t.Parallel() + + comp, err := CreateCryptoComponents(createArgsCryptoComponentsHolder()) + require.NoError(t, err) + + compClone := comp.Clone() + require.Equal(t, comp, compClone) + require.False(t, comp == compClone) // pointer testing +} From be242d24229fc7cd357e648e936e2ab8b80c0025 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 21 Feb 2024 11:25:10 +0200 Subject: [PATCH 861/958] close components on successful tests --- node/chainSimulator/components/bootstrapComponents_test.go | 2 ++ node/chainSimulator/components/coreComponents_test.go | 2 ++ node/chainSimulator/components/cryptoComponents_test.go | 3 +++ 3 files changed, 7 insertions(+) diff --git a/node/chainSimulator/components/bootstrapComponents_test.go b/node/chainSimulator/components/bootstrapComponents_test.go index 29304e03498..0bfcc7146af 100644 --- a/node/chainSimulator/components/bootstrapComponents_test.go +++ b/node/chainSimulator/components/bootstrapComponents_test.go @@ -170,6 +170,7 @@ func TestBootstrapComponentsHolder_IsInterfaceNil(t *testing.T) { comp, _ = CreateBootstrapComponents(createArgsBootstrapComponentsHolder()) require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) } func TestBootstrapComponentsHolder_Getters(t *testing.T) { @@ -188,4 +189,5 @@ func TestBootstrapComponentsHolder_Getters(t *testing.T) { require.NotNil(t, comp.GuardedAccountHandler()) require.Nil(t, comp.CheckSubcomponents()) require.Empty(t, comp.String()) + require.Nil(t, comp.Close()) } diff --git a/node/chainSimulator/components/coreComponents_test.go b/node/chainSimulator/components/coreComponents_test.go index 5e287e4748c..1f6552aa421 100644 --- a/node/chainSimulator/components/coreComponents_test.go +++ b/node/chainSimulator/components/coreComponents_test.go @@ -217,6 +217,7 @@ func TestCoreComponentsHolder_IsInterfaceNil(t *testing.T) { comp, _ = CreateCoreComponents(createArgsCoreComponentsHolder()) require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) } func TestCoreComponents_GettersSetters(t *testing.T) { @@ -266,4 +267,5 @@ func TestCoreComponents_GettersSetters(t *testing.T) { require.NotNil(t, comp.EnableEpochsHandler()) require.Nil(t, comp.CheckSubcomponents()) require.Empty(t, comp.String()) + require.Nil(t, comp.Close()) } diff --git a/node/chainSimulator/components/cryptoComponents_test.go b/node/chainSimulator/components/cryptoComponents_test.go index 8a7d42c4496..fc8087f5cd4 100644 --- a/node/chainSimulator/components/cryptoComponents_test.go +++ b/node/chainSimulator/components/cryptoComponents_test.go @@ -116,6 +116,7 @@ func TestCryptoComponentsHolder_IsInterfaceNil(t *testing.T) { comp, _ = CreateCryptoComponents(createArgsCryptoComponentsHolder()) require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) } func TestCryptoComponentsHolder_GettersSetters(t *testing.T) { @@ -151,6 +152,7 @@ func TestCryptoComponentsHolder_GettersSetters(t *testing.T) { require.NotNil(t, comp.KeysHandler()) require.Nil(t, comp.CheckSubcomponents()) require.Empty(t, comp.String()) + require.Nil(t, comp.Close()) } func TestCryptoComponentsHolder_Clone(t *testing.T) { @@ -162,4 +164,5 @@ func TestCryptoComponentsHolder_Clone(t *testing.T) { compClone := comp.Clone() require.Equal(t, comp, compClone) require.False(t, comp == compClone) // pointer testing + require.Nil(t, comp.Close()) } From cb25f66ec31d2dc7216671fe5ddf61188cd6a963 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 21 Feb 2024 11:44:02 +0200 Subject: [PATCH 862/958] fix after merge - update stub --- testscommon/stateStatisticsHandlerStub.go | 69 +++++++++++------------ 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/testscommon/stateStatisticsHandlerStub.go b/testscommon/stateStatisticsHandlerStub.go index 970aceedfda..bc13bea90d4 100644 --- a/testscommon/stateStatisticsHandlerStub.go +++ b/testscommon/stateStatisticsHandlerStub.go @@ -2,20 +2,20 @@ package testscommon // StateStatisticsHandlerStub - type StateStatisticsHandlerStub struct { - ResetCalled func() - ResetSnapshotCalled func() - IncrCacheCalled func() - CacheCalled func() uint64 - IncrSnapshotCacheCalled func() - SnapshotCacheCalled func() uint64 - IncrPersisterCalled func(epoch uint32) - PersisterCalled func(epoch uint32) uint64 - IncrSnapshotPersisterCalled func(epoch uint32) - SnapshotPersisterCalled func(epoch uint32) uint64 - IncrTrieCalled func() - TrieCalled func() uint64 - ProcessingStatsCalled func() []string - SnapshotStatsCalled func() []string + ResetCalled func() + ResetSnapshotCalled func() + IncrementCacheCalled func() + CacheCalled func() uint64 + IncrementSnapshotCacheCalled func() + SnapshotCacheCalled func() uint64 + IncrementPersisterCalled func(epoch uint32) + PersisterCalled func(epoch uint32) uint64 + IncrementSnapshotPersisterCalled func(epoch uint32) + SnapshotPersisterCalled func(epoch uint32) uint64 + IncrementTrieCalled func() + TrieCalled func() uint64 + ProcessingStatsCalled func() []string + SnapshotStatsCalled func() []string } // Reset - @@ -32,11 +32,10 @@ func (stub *StateStatisticsHandlerStub) ResetSnapshot() { } } -// IncrCache - -// TODO: replace Incr with Increment on all usages in this file + rename the interface and the other 2 implementations -func (stub *StateStatisticsHandlerStub) IncrCache() { - if stub.IncrCacheCalled != nil { - stub.IncrCacheCalled() +// IncrementCache - +func (stub *StateStatisticsHandlerStub) IncrementCache() { + if stub.IncrementCacheCalled != nil { + stub.IncrementCacheCalled() } } @@ -49,10 +48,10 @@ func (stub *StateStatisticsHandlerStub) Cache() uint64 { return 0 } -// IncrSnapshotCache - -func (stub *StateStatisticsHandlerStub) IncrSnapshotCache() { - if stub.IncrSnapshotCacheCalled != nil { - stub.IncrSnapshotCacheCalled() +// IncrementSnapshotCache - +func (stub *StateStatisticsHandlerStub) IncrementSnapshotCache() { + if stub.IncrementSnapshotCacheCalled != nil { + stub.IncrementSnapshotCacheCalled() } } @@ -65,10 +64,10 @@ func (stub *StateStatisticsHandlerStub) SnapshotCache() uint64 { return 0 } -// IncrPersister - -func (stub *StateStatisticsHandlerStub) IncrPersister(epoch uint32) { - if stub.IncrPersisterCalled != nil { - stub.IncrPersisterCalled(epoch) +// IncrementPersister - +func (stub *StateStatisticsHandlerStub) IncrementPersister(epoch uint32) { + if stub.IncrementPersisterCalled != nil { + stub.IncrementPersisterCalled(epoch) } } @@ -81,10 +80,10 @@ func (stub *StateStatisticsHandlerStub) Persister(epoch uint32) uint64 { return 0 } -// IncrSnapshotPersister - -func (stub *StateStatisticsHandlerStub) IncrSnapshotPersister(epoch uint32) { - if stub.IncrSnapshotPersisterCalled != nil { - stub.IncrSnapshotPersisterCalled(epoch) +// IncrementSnapshotPersister - +func (stub *StateStatisticsHandlerStub) IncrementSnapshotPersister(epoch uint32) { + if stub.IncrementSnapshotPersisterCalled != nil { + stub.IncrementSnapshotPersisterCalled(epoch) } } @@ -97,10 +96,10 @@ func (stub *StateStatisticsHandlerStub) SnapshotPersister(epoch uint32) uint64 { return 0 } -// IncrTrie - -func (stub *StateStatisticsHandlerStub) IncrTrie() { - if stub.IncrTrieCalled != nil { - stub.IncrTrieCalled() +// IncrementTrie - +func (stub *StateStatisticsHandlerStub) IncrementTrie() { + if stub.IncrementTrieCalled != nil { + stub.IncrementTrieCalled() } } From 190de2b5883446b48b1a508b93d492c21653cd6c Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 21 Feb 2024 12:58:04 +0200 Subject: [PATCH 863/958] more tests for chain simulator --- .../components/dataComponents.go | 3 +- .../components/dataComponents_test.go | 113 +++++++++++++++ .../instantBroadcastMessenger_test.go | 134 ++++++++++++++++++ .../components/manualRoundHandler_test.go | 44 ++++++ .../components/memoryComponents.go | 14 +- .../components/memoryComponents_test.go | 55 +++++++ .../components/networkComponents.go | 2 +- .../components/networkComponents_test.go | 62 ++++++++ 8 files changed, 418 insertions(+), 9 deletions(-) create mode 100644 node/chainSimulator/components/dataComponents_test.go create mode 100644 node/chainSimulator/components/instantBroadcastMessenger_test.go create mode 100644 node/chainSimulator/components/manualRoundHandler_test.go create mode 100644 node/chainSimulator/components/memoryComponents_test.go create mode 100644 node/chainSimulator/components/networkComponents_test.go diff --git a/node/chainSimulator/components/dataComponents.go b/node/chainSimulator/components/dataComponents.go index 9eb8605af12..8f04c351509 100644 --- a/node/chainSimulator/components/dataComponents.go +++ b/node/chainSimulator/components/dataComponents.go @@ -25,7 +25,7 @@ type dataComponentsHolder struct { } // CreateDataComponents will create the data components holder -func CreateDataComponents(args ArgsDataComponentsHolder) (factory.DataComponentsHandler, error) { +func CreateDataComponents(args ArgsDataComponentsHolder) (*dataComponentsHolder, error) { miniBlockStorer, err := args.StorageService.GetStorer(dataRetriever.MiniBlockUnit) if err != nil { return nil, err @@ -89,6 +89,7 @@ func (d *dataComponentsHolder) Clone() interface{} { storageService: d.storageService, dataPool: d.dataPool, miniBlockProvider: d.miniBlockProvider, + closeHandler: d.closeHandler, } } diff --git a/node/chainSimulator/components/dataComponents_test.go b/node/chainSimulator/components/dataComponents_test.go new file mode 100644 index 00000000000..24c1ca532ce --- /dev/null +++ b/node/chainSimulator/components/dataComponents_test.go @@ -0,0 +1,113 @@ +package components + +import ( + "errors" + "testing" + + retriever "github.com/multiversx/mx-chain-go/dataRetriever" + chainStorage "github.com/multiversx/mx-chain-go/storage" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/storage" + "github.com/stretchr/testify/require" +) + +var expectedErr = errors.New("expected error") + +func createArgsDataComponentsHolder() ArgsDataComponentsHolder { + return ArgsDataComponentsHolder{ + Chain: &testscommon.ChainHandlerStub{}, + StorageService: &storage.ChainStorerStub{ + GetStorerCalled: func(unitType retriever.UnitType) (chainStorage.Storer, error) { + return &storage.StorerStub{}, nil + }, + }, + DataPool: &dataRetriever.PoolsHolderStub{ + MiniBlocksCalled: func() chainStorage.Cacher { + return &testscommon.CacherStub{} + }, + }, + InternalMarshaller: &testscommon.MarshallerStub{}, + } +} + +func TestCreateDataComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateDataComponents(createArgsDataComponentsHolder()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("", func(t *testing.T) { + t.Parallel() + + args := createArgsDataComponentsHolder() + args.DataPool = &dataRetriever.PoolsHolderStub{ + MiniBlocksCalled: func() chainStorage.Cacher { + return nil + }, + } + comp, err := CreateDataComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("", func(t *testing.T) { + t.Parallel() + + args := createArgsDataComponentsHolder() + args.StorageService = &storage.ChainStorerStub{ + GetStorerCalled: func(unitType retriever.UnitType) (chainStorage.Storer, error) { + return nil, expectedErr + }, + } + comp, err := CreateDataComponents(args) + require.Equal(t, expectedErr, err) + require.Nil(t, comp) + }) +} + +func TestDataComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *dataComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateDataComponents(createArgsDataComponentsHolder()) + require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) +} + +func TestDataComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + comp, err := CreateDataComponents(createArgsDataComponentsHolder()) + require.NoError(t, err) + + require.NotNil(t, comp.Blockchain()) + require.Nil(t, comp.SetBlockchain(nil)) + require.Nil(t, comp.Blockchain()) + require.NotNil(t, comp.StorageService()) + require.NotNil(t, comp.Datapool()) + require.NotNil(t, comp.MiniBlocksProvider()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) + require.Nil(t, comp.Close()) +} + +func TestDataComponentsHolder_Clone(t *testing.T) { + t.Parallel() + + comp, err := CreateDataComponents(createArgsDataComponentsHolder()) + require.NoError(t, err) + + compClone := comp.Clone() + require.Equal(t, comp, compClone) + require.False(t, comp == compClone) // pointer testing + require.Nil(t, comp.Close()) +} diff --git a/node/chainSimulator/components/instantBroadcastMessenger_test.go b/node/chainSimulator/components/instantBroadcastMessenger_test.go new file mode 100644 index 00000000000..361caa03bbc --- /dev/null +++ b/node/chainSimulator/components/instantBroadcastMessenger_test.go @@ -0,0 +1,134 @@ +package components + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/consensus/mock" + errorsMx "github.com/multiversx/mx-chain-go/errors" + "github.com/stretchr/testify/require" +) + +func TestNewInstantBroadcastMessenger(t *testing.T) { + t.Parallel() + + t.Run("nil broadcastMessenger should error", func(t *testing.T) { + t.Parallel() + + mes, err := NewInstantBroadcastMessenger(nil, nil) + require.Equal(t, errorsMx.ErrNilBroadcastMessenger, err) + require.Nil(t, mes) + }) + t.Run("nil shardCoordinator should error", func(t *testing.T) { + t.Parallel() + + mes, err := NewInstantBroadcastMessenger(&mock.BroadcastMessengerMock{}, nil) + require.Equal(t, errorsMx.ErrNilShardCoordinator, err) + require.Nil(t, mes) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + mes, err := NewInstantBroadcastMessenger(&mock.BroadcastMessengerMock{}, &mock.ShardCoordinatorMock{}) + require.NoError(t, err) + require.NotNil(t, mes) + }) +} + +func TestInstantBroadcastMessenger_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var mes *instantBroadcastMessenger + require.True(t, mes.IsInterfaceNil()) + + mes, _ = NewInstantBroadcastMessenger(&mock.BroadcastMessengerMock{}, &mock.ShardCoordinatorMock{}) + require.False(t, mes.IsInterfaceNil()) +} + +func TestInstantBroadcastMessenger_BroadcastBlockDataLeader(t *testing.T) { + t.Parallel() + + t.Run("meta should work", func(t *testing.T) { + t.Parallel() + + providedMBs := map[uint32][]byte{ + 0: []byte("mb shard 0"), + 1: []byte("mb shard 1"), + common.MetachainShardId: []byte("mb shard meta"), + } + providedTxs := map[string][][]byte{ + "topic_0": {[]byte("txs topic 0")}, + "topic_1": {[]byte("txs topic 1")}, + } + mes, err := NewInstantBroadcastMessenger(&mock.BroadcastMessengerMock{ + BroadcastMiniBlocksCalled: func(mbs map[uint32][]byte, bytes []byte) error { + require.Equal(t, providedMBs, mbs) + return expectedErr // for coverage only + }, + BroadcastTransactionsCalled: func(txs map[string][][]byte, bytes []byte) error { + require.Equal(t, providedTxs, txs) + return expectedErr // for coverage only + }, + }, &mock.ShardCoordinatorMock{ + ShardID: common.MetachainShardId, + }) + require.NoError(t, err) + + err = mes.BroadcastBlockDataLeader(nil, providedMBs, providedTxs, []byte("pk")) + require.NoError(t, err) + }) + t.Run("shard should work", func(t *testing.T) { + t.Parallel() + + providedMBs := map[uint32][]byte{ + 0: []byte("mb shard 0"), // for coverage only + common.MetachainShardId: []byte("mb shard meta"), + } + expectedMBs := map[uint32][]byte{ + common.MetachainShardId: []byte("mb shard meta"), + } + providedTxs := map[string][][]byte{ + "topic_0": {[]byte("txs topic 1")}, // for coverage only + "topic_0_META": {[]byte("txs topic meta")}, + } + expectedTxs := map[string][][]byte{ + "topic_0_META": {[]byte("txs topic meta")}, + } + mes, err := NewInstantBroadcastMessenger(&mock.BroadcastMessengerMock{ + BroadcastMiniBlocksCalled: func(mbs map[uint32][]byte, bytes []byte) error { + require.Equal(t, expectedMBs, mbs) + return nil + }, + BroadcastTransactionsCalled: func(txs map[string][][]byte, bytes []byte) error { + require.Equal(t, expectedTxs, txs) + return nil + }, + }, &mock.ShardCoordinatorMock{ + ShardID: 0, + }) + require.NoError(t, err) + + err = mes.BroadcastBlockDataLeader(nil, providedMBs, providedTxs, []byte("pk")) + require.NoError(t, err) + }) + t.Run("shard, empty miniblocks should early exit", func(t *testing.T) { + t.Parallel() + + mes, err := NewInstantBroadcastMessenger(&mock.BroadcastMessengerMock{ + BroadcastMiniBlocksCalled: func(mbs map[uint32][]byte, bytes []byte) error { + require.Fail(t, "should have not been called") + return nil + }, + BroadcastTransactionsCalled: func(txs map[string][][]byte, bytes []byte) error { + require.Fail(t, "should have not been called") + return nil + }, + }, &mock.ShardCoordinatorMock{ + ShardID: 0, + }) + require.NoError(t, err) + + err = mes.BroadcastBlockDataLeader(nil, nil, nil, []byte("pk")) + require.NoError(t, err) + }) +} diff --git a/node/chainSimulator/components/manualRoundHandler_test.go b/node/chainSimulator/components/manualRoundHandler_test.go new file mode 100644 index 00000000000..8a866d6ccec --- /dev/null +++ b/node/chainSimulator/components/manualRoundHandler_test.go @@ -0,0 +1,44 @@ +package components + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestNewManualRoundHandler(t *testing.T) { + t.Parallel() + + handler := NewManualRoundHandler(100, time.Second, 0) + require.NotNil(t, handler) +} + +func TestManualRoundHandler_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var handler *manualRoundHandler + require.True(t, handler.IsInterfaceNil()) + + handler = NewManualRoundHandler(100, time.Second, 0) + require.False(t, handler.IsInterfaceNil()) +} + +func TestManualRoundHandler_Operations(t *testing.T) { + t.Parallel() + + genesisTime := time.Now() + providedIndex := int64(0) + providedRoundDuration := time.Second + handler := NewManualRoundHandler(genesisTime.Unix(), providedRoundDuration, providedIndex) + require.Equal(t, providedIndex, handler.Index()) + handler.IncrementIndex() + require.Equal(t, providedIndex+1, handler.Index()) + expectedTimestamp := time.Unix(handler.genesisTimeStamp, 0).Add(providedRoundDuration) + require.Equal(t, expectedTimestamp, handler.TimeStamp()) + require.Equal(t, providedRoundDuration, handler.TimeDuration()) + providedMaxTime := time.Minute + require.Equal(t, providedMaxTime, handler.RemainingTime(time.Now(), providedMaxTime)) + require.False(t, handler.BeforeGenesis()) + handler.UpdateRound(time.Now(), time.Now()) // for coverage only +} diff --git a/node/chainSimulator/components/memoryComponents.go b/node/chainSimulator/components/memoryComponents.go index 92b562beb6f..3b12e720756 100644 --- a/node/chainSimulator/components/memoryComponents.go +++ b/node/chainSimulator/components/memoryComponents.go @@ -23,6 +23,13 @@ type trieStorage struct { storage.Storer } +// CreateMemUnitForTries returns a special type of storer used on tries instances +func CreateMemUnitForTries() storage.Storer { + return &trieStorage{ + Storer: CreateMemUnit(), + } +} + // SetEpochForPutOperation does nothing func (store *trieStorage) SetEpochForPutOperation(_ uint32) { } @@ -73,10 +80,3 @@ func (store *trieStorage) RemoveFromCurrentEpoch(key []byte) error { func (store *trieStorage) RemoveFromAllActiveEpochs(key []byte) error { return store.Remove(key) } - -// CreateMemUnitForTries returns a special type of storer used on tries instances -func CreateMemUnitForTries() storage.Storer { - return &trieStorage{ - Storer: CreateMemUnit(), - } -} diff --git a/node/chainSimulator/components/memoryComponents_test.go b/node/chainSimulator/components/memoryComponents_test.go new file mode 100644 index 00000000000..b393bca7d47 --- /dev/null +++ b/node/chainSimulator/components/memoryComponents_test.go @@ -0,0 +1,55 @@ +package components + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCreateMemUnitForTries(t *testing.T) { + t.Parallel() + + memUnitStorer := CreateMemUnitForTries() + require.NotNil(t, memUnitStorer) + + memUnit, ok := memUnitStorer.(*trieStorage) + require.True(t, ok) + memUnit.SetEpochForPutOperation(0) // for coverage only + key := []byte("key") + data := []byte("data") + require.NoError(t, memUnit.Put(key, data)) + + require.NoError(t, memUnit.PutInEpoch(key, data, 0)) + require.NoError(t, memUnit.PutInEpochWithoutCache(key, data, 0)) + + value, _, err := memUnit.GetFromOldEpochsWithoutAddingToCache(key) + require.NoError(t, err) + require.Equal(t, data, value) + + latest, err := memUnit.GetLatestStorageEpoch() + require.NoError(t, err) + require.Zero(t, latest) + + value, err = memUnit.GetFromCurrentEpoch(key) + require.NoError(t, err) + require.Equal(t, data, value) + + value, err = memUnit.GetFromEpoch(key, 0) + require.NoError(t, err) + require.Equal(t, data, value) + + value, err = memUnit.GetFromLastEpoch(key) + require.NoError(t, err) + require.Equal(t, data, value) + + require.NoError(t, memUnit.RemoveFromCurrentEpoch(key)) + value, err = memUnit.GetFromCurrentEpoch(key) + require.Error(t, err) + require.Empty(t, value) + + require.NoError(t, memUnit.PutInEpoch(key, data, 0)) + require.NoError(t, memUnit.RemoveFromAllActiveEpochs(key)) + value, err = memUnit.GetFromCurrentEpoch(key) + require.Error(t, err) + require.Empty(t, value) +} diff --git a/node/chainSimulator/components/networkComponents.go b/node/chainSimulator/components/networkComponents.go index 6a6bf8d346b..6b791f6927b 100644 --- a/node/chainSimulator/components/networkComponents.go +++ b/node/chainSimulator/components/networkComponents.go @@ -27,7 +27,7 @@ type networkComponentsHolder struct { } // CreateNetworkComponents creates a new networkComponentsHolder instance -func CreateNetworkComponents(network SyncedBroadcastNetworkHandler) (factory.NetworkComponentsHandler, error) { +func CreateNetworkComponents(network SyncedBroadcastNetworkHandler) (*networkComponentsHolder, error) { messenger, err := NewSyncedMessenger(network) if err != nil { return nil, err diff --git a/node/chainSimulator/components/networkComponents_test.go b/node/chainSimulator/components/networkComponents_test.go new file mode 100644 index 00000000000..9c184d4d608 --- /dev/null +++ b/node/chainSimulator/components/networkComponents_test.go @@ -0,0 +1,62 @@ +package components + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCreateNetworkComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateNetworkComponents(NewSyncedBroadcastNetwork()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("nil network should error", func(t *testing.T) { + t.Parallel() + + comp, err := CreateNetworkComponents(nil) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestNetworkComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *networkComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateNetworkComponents(NewSyncedBroadcastNetwork()) + require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) +} + +func TestNetworkComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + comp, err := CreateNetworkComponents(NewSyncedBroadcastNetwork()) + require.NoError(t, err) + + require.NotNil(t, comp.NetworkMessenger()) + require.NotNil(t, comp.InputAntiFloodHandler()) + require.NotNil(t, comp.OutputAntiFloodHandler()) + require.NotNil(t, comp.PubKeyCacher()) + require.NotNil(t, comp.PeerBlackListHandler()) + require.NotNil(t, comp.PeerHonestyHandler()) + require.NotNil(t, comp.PreferredPeersHolderHandler()) + require.NotNil(t, comp.PeersRatingHandler()) + require.NotNil(t, comp.PeersRatingMonitor()) + require.NotNil(t, comp.FullArchiveNetworkMessenger()) + require.NotNil(t, comp.FullArchivePreferredPeersHolderHandler()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) + require.Nil(t, comp.Close()) +} From 98392f1037055042d12ce281e4f67b5889ae42c9 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 21 Feb 2024 13:47:46 +0200 Subject: [PATCH 864/958] genesis epoch --- cmd/node/config/config.toml | 1 + config/config.go | 1 + epochStart/bootstrap/process.go | 1 + epochStart/metachain/epochStartData.go | 2 +- factory/processing/processComponents.go | 1 + genesis/process/argGenesisBlockCreator.go | 1 + genesis/process/genesisBlockCreator.go | 4 ++-- node/chainSimulator/chainSimulator.go | 2 ++ node/chainSimulator/chainSimulator_test.go | 14 +++++++++----- node/chainSimulator/configs/configs.go | 3 +++ node/chainSimulator/process/processor.go | 1 + 11 files changed, 23 insertions(+), 8 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 08ed541ed82..f0a1dc708fc 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -621,6 +621,7 @@ Type = "json" [EpochStartConfig] + GenesisEpoch = 0 MinRoundsBetweenEpochs = 20 RoundsPerEpoch = 200 # Min and Max ShuffledOutRestartThreshold represents the minimum and maximum duration of an epoch (in percentage) after a node which diff --git a/config/config.go b/config/config.go index f2454a6e52f..472378d49fd 100644 --- a/config/config.go +++ b/config/config.go @@ -95,6 +95,7 @@ type EpochStartConfig struct { MinNumConnectedPeersToStart int MinNumOfPeersToConsiderBlockValid int ExtraDelayForRequestBlockInfoInMilliseconds int + GenesisEpoch uint32 } // BlockSizeThrottleConfig will hold the configuration for adaptive block size throttle diff --git a/epochStart/bootstrap/process.go b/epochStart/bootstrap/process.go index d2c0aa199ae..0055fa8995a 100644 --- a/epochStart/bootstrap/process.go +++ b/epochStart/bootstrap/process.go @@ -237,6 +237,7 @@ func NewEpochStartBootstrap(args ArgsEpochStartBootstrap) (*epochStartBootstrap, nodeProcessingMode: args.NodeProcessingMode, nodeOperationMode: common.NormalOperation, stateStatsHandler: args.StateStatsHandler, + startEpoch: args.GeneralConfig.EpochStartConfig.GenesisEpoch, } if epochStartProvider.prefsConfig.FullArchive { diff --git a/epochStart/metachain/epochStartData.go b/epochStart/metachain/epochStartData.go index 1c6bd30516e..1a67b3a3692 100644 --- a/epochStart/metachain/epochStartData.go +++ b/epochStart/metachain/epochStartData.go @@ -289,7 +289,7 @@ func (e *epochStartData) getShardDataFromEpochStartData( } epochStartIdentifier := core.EpochStartIdentifier(prevEpoch) - if prevEpoch == 0 { + if prevEpoch == e.genesisEpoch { return lastMetaHash, []byte(epochStartIdentifier), nil } diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 9b0dcf43ee8..9fad572d80a 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -888,6 +888,7 @@ func (pcf *processComponentsFactory) generateGenesisHeadersAndApplyInitialBalanc GenesisNodePrice: genesisNodePrice, GenesisString: pcf.config.GeneralSettings.GenesisString, TxExecutionOrderHandler: pcf.txExecutionOrderHandler, + GenesisEpoch: pcf.config.EpochStartConfig.GenesisEpoch, } gbc, err := processGenesis.NewGenesisBlockCreator(arg) diff --git a/genesis/process/argGenesisBlockCreator.go b/genesis/process/argGenesisBlockCreator.go index e4374b7f6f0..db18b8df61b 100644 --- a/genesis/process/argGenesisBlockCreator.go +++ b/genesis/process/argGenesisBlockCreator.go @@ -45,6 +45,7 @@ type dataComponentsHandler interface { type ArgsGenesisBlockCreator struct { GenesisTime uint64 StartEpochNum uint32 + GenesisEpoch uint32 Data dataComponentsHandler Core coreComponentsHandler Accounts state.AccountsAdapter diff --git a/genesis/process/genesisBlockCreator.go b/genesis/process/genesisBlockCreator.go index 2e9b14d7db3..ba01b319301 100644 --- a/genesis/process/genesisBlockCreator.go +++ b/genesis/process/genesisBlockCreator.go @@ -82,7 +82,7 @@ func getGenesisBlocksRoundNonceEpoch(arg ArgsGenesisBlockCreator) (uint64, uint6 if arg.HardForkConfig.AfterHardFork { return arg.HardForkConfig.StartRound, arg.HardForkConfig.StartNonce, arg.HardForkConfig.StartEpoch } - return 0, 0, 0 + return 0, 0, arg.GenesisEpoch } func (gbc *genesisBlockCreator) createHardForkImportHandler() error { @@ -212,7 +212,7 @@ func checkArgumentsForBlockCreator(arg ArgsGenesisBlockCreator) error { } func mustDoGenesisProcess(arg ArgsGenesisBlockCreator) bool { - genesisEpoch := uint32(0) + genesisEpoch := arg.GenesisEpoch if arg.HardForkConfig.AfterHardFork { genesisEpoch = arg.HardForkConfig.StartEpoch } diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index dcd09ce4b65..42d6299085d 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -29,6 +29,7 @@ type ArgsChainSimulator struct { MetaChainMinNodes uint32 GenesisTimestamp int64 InitialRound int64 + InitialEpoch uint32 RoundDurationInMillis uint64 RoundsPerEpoch core.OptionalUint64 ApiInterface components.APIConfigurator @@ -76,6 +77,7 @@ func (s *simulator) createChainHandlers(args ArgsChainSimulator) error { MinNodesPerShard: args.MinNodesPerShard, MetaChainMinNodes: args.MetaChainMinNodes, RoundsPerEpoch: args.RoundsPerEpoch, + InitialEpoch: args.InitialEpoch, }) if err != nil { return err diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 17eebfc81d7..23edab3f9c4 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -57,11 +57,15 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { NumOfShards: 3, GenesisTimestamp: startTime, RoundDurationInMillis: roundDurationInMillis, - RoundsPerEpoch: core.OptionalUint64{}, - ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 1, - MetaChainMinNodes: 1, - InitialRound: 200000000, + RoundsPerEpoch: core.OptionalUint64{ + HasValue: true, + Value: 20, + }, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, + InitialRound: 200000000, + InitialEpoch: 100, }) require.Nil(t, err) require.NotNil(t, chainSimulator) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 63aa3adc48b..6c94475af36 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -47,6 +47,7 @@ type ArgsChainSimulatorConfigs struct { TempDir string MinNodesPerShard uint32 MetaChainMinNodes uint32 + InitialEpoch uint32 RoundsPerEpoch core.OptionalUint64 } @@ -117,6 +118,8 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.DbLookupExtensions.Enabled = true configs.GeneralConfig.EpochStartConfig.ExtraDelayForRequestBlockInfoInMilliseconds = 1 + configs.GeneralConfig.EpochStartConfig.GenesisEpoch = args.InitialEpoch + configs.EpochConfig.EnableEpochs.StakingV2EnableEpoch = args.InitialEpoch + 1 if args.RoundsPerEpoch.HasValue { configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index bca5b6ac2a1..ccbedcee2cb 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -149,6 +149,7 @@ func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prev prevHash = creator.nodeHandler.GetChainHandler().GetGenesisHeaderHash() prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() round = uint64(creator.nodeHandler.GetCoreComponents().RoundHandler().Index()) - 1 + epoch = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetEpoch() return } From 0f3a9caac7049c3c93c980a74b65363cb7150020 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 21 Feb 2024 17:25:53 +0200 Subject: [PATCH 865/958] genesis nonce --- genesis/process/genesisBlockCreator.go | 15 ++++++++++++++- node/chainSimulator/chainSimulator.go | 5 +++++ node/chainSimulator/chainSimulator_test.go | 3 ++- .../components/manualRoundHandler.go | 4 +++- node/chainSimulator/process/processor.go | 1 + 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/genesis/process/genesisBlockCreator.go b/genesis/process/genesisBlockCreator.go index ba01b319301..143dd39ef15 100644 --- a/genesis/process/genesisBlockCreator.go +++ b/genesis/process/genesisBlockCreator.go @@ -38,6 +38,9 @@ import ( const accountStartNonce = uint64(0) +var genesisNonce uint64 +var genesisRound uint64 + type genesisBlockCreator struct { arg ArgsGenesisBlockCreator initialIndexingData map[uint32]*genesis.IndexingData @@ -82,7 +85,17 @@ func getGenesisBlocksRoundNonceEpoch(arg ArgsGenesisBlockCreator) (uint64, uint6 if arg.HardForkConfig.AfterHardFork { return arg.HardForkConfig.StartRound, arg.HardForkConfig.StartNonce, arg.HardForkConfig.StartEpoch } - return 0, 0, arg.GenesisEpoch + return genesisRound, genesisNonce, arg.GenesisEpoch +} + +// SetGenesisRound will set the genesis round +func SetGenesisRound(round uint64) { + genesisRound = round +} + +// SetGenesisNonce will set the genesis nonce +func SetGenesisNonce(nonce uint64) { + genesisNonce = nonce } func (gbc *genesisBlockCreator) createHardForkImportHandler() error { diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 42d6299085d..2da45d6c8e0 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" crypto "github.com/multiversx/mx-chain-crypto-go" + processGenesis "github.com/multiversx/mx-chain-go/genesis/process" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" @@ -30,6 +31,7 @@ type ArgsChainSimulator struct { GenesisTimestamp int64 InitialRound int64 InitialEpoch uint32 + InitialNonce uint64 RoundDurationInMillis uint64 RoundsPerEpoch core.OptionalUint64 ApiInterface components.APIConfigurator @@ -59,6 +61,9 @@ func NewChainSimulator(args ArgsChainSimulator) (*simulator, error) { mutex: sync.RWMutex{}, } + processGenesis.SetGenesisNonce(args.InitialNonce) + processGenesis.SetGenesisRound(uint64(args.InitialRound)) + err := instance.createChainHandlers(args) if err != nil { return nil, err diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 23edab3f9c4..a986221c17c 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -66,13 +66,14 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { MetaChainMinNodes: 1, InitialRound: 200000000, InitialEpoch: 100, + InitialNonce: 100, }) require.Nil(t, err) require.NotNil(t, chainSimulator) time.Sleep(time.Second) - err = chainSimulator.GenerateBlocks(30) + err = chainSimulator.GenerateBlocks(50) require.Nil(t, err) err = chainSimulator.Close() diff --git a/node/chainSimulator/components/manualRoundHandler.go b/node/chainSimulator/components/manualRoundHandler.go index 3639bf23752..479cf63a1f5 100644 --- a/node/chainSimulator/components/manualRoundHandler.go +++ b/node/chainSimulator/components/manualRoundHandler.go @@ -9,6 +9,7 @@ type manualRoundHandler struct { index int64 genesisTimeStamp int64 roundDuration time.Duration + initialRound int64 } // NewManualRoundHandler returns a manual round handler instance @@ -17,6 +18,7 @@ func NewManualRoundHandler(genesisTimeStamp int64, roundDuration time.Duration, genesisTimeStamp: genesisTimeStamp, roundDuration: roundDuration, index: initialRound, + initialRound: initialRound, } } @@ -44,7 +46,7 @@ func (handler *manualRoundHandler) TimeStamp() time.Time { rounds := atomic.LoadInt64(&handler.index) timeFromGenesis := handler.roundDuration * time.Duration(rounds) timestamp := time.Unix(handler.genesisTimeStamp, 0).Add(timeFromGenesis) - + timestamp = time.Unix(timestamp.Unix()-int64(handler.roundDuration.Seconds())*handler.initialRound, 0) return timestamp } diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index ccbedcee2cb..49029c63083 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -150,6 +150,7 @@ func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prev prevRandSeed = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetRandSeed() round = uint64(creator.nodeHandler.GetCoreComponents().RoundHandler().Index()) - 1 epoch = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetEpoch() + nonce = creator.nodeHandler.GetChainHandler().GetGenesisHeader().GetNonce() return } From 22a790925a272ed09e47fd457adaa326a9beb488 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 21 Feb 2024 17:32:50 +0200 Subject: [PATCH 866/958] - fixes after review --- integrationTests/chainSimulator/staking/delegation_test.go | 3 +-- node/chainSimulator/dtos/keys.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 6ea872ef646..73462ff46f8 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -49,8 +49,7 @@ const maxCap = "00" // no cap const hexServiceFee = "0ea1" // 37.45% const walletAddressBytesLen = 32 -var initialDelegationValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) // 1250 EGLD -// var stakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) // 1250 EGLD +var initialDelegationValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(1250)) var zeroValue = big.NewInt(0) var oneEGLD = big.NewInt(1000000000000000000) var minimumStakeValue = big.NewInt(0).Mul(oneEGLD, big.NewInt(2500)) diff --git a/node/chainSimulator/dtos/keys.go b/node/chainSimulator/dtos/keys.go index 1c185c9f94d..7f4c0e613e9 100644 --- a/node/chainSimulator/dtos/keys.go +++ b/node/chainSimulator/dtos/keys.go @@ -1,6 +1,6 @@ package dtos -// WalletKey holds the public and the private key of a wallet bey +// WalletKey holds the public and the private key of a wallet type WalletKey struct { Address WalletAddress `json:"address"` PrivateKeyHex string `json:"privateKeyHex"` From aa16de3cd5e53f54a0de618581941376ace38570 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 21 Feb 2024 17:41:37 +0200 Subject: [PATCH 867/958] fixes after review --- factory/processing/processComponents.go | 10 ++++++++++ genesis/process/argGenesisBlockCreator.go | 2 ++ genesis/process/genesisBlockCreator.go | 15 +-------------- node/chainSimulator/chainSimulator.go | 5 +---- .../components/processComponents.go | 5 +++++ .../components/testOnlyProcessingNode.go | 3 +++ 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 9fad572d80a..8f116c4b9b6 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -162,6 +162,9 @@ type ProcessComponentsFactoryArgs struct { StatusComponents factory.StatusComponentsHolder StatusCoreComponents factory.StatusCoreComponentsHolder TxExecutionOrderHandler common.TxExecutionOrderHandler + + GenesisNonce uint64 + GenesisRound uint64 } type processComponentsFactory struct { @@ -196,6 +199,9 @@ type processComponentsFactory struct { statusComponents factory.StatusComponentsHolder statusCoreComponents factory.StatusCoreComponentsHolder txExecutionOrderHandler common.TxExecutionOrderHandler + + genesisNonce uint64 + genesisRound uint64 } // NewProcessComponentsFactory will return a new instance of processComponentsFactory @@ -232,6 +238,8 @@ func NewProcessComponentsFactory(args ProcessComponentsFactoryArgs) (*processCom statusCoreComponents: args.StatusCoreComponents, flagsConfig: args.FlagsConfig, txExecutionOrderHandler: args.TxExecutionOrderHandler, + genesisNonce: args.GenesisNonce, + genesisRound: args.GenesisRound, }, nil } @@ -889,6 +897,8 @@ func (pcf *processComponentsFactory) generateGenesisHeadersAndApplyInitialBalanc GenesisString: pcf.config.GeneralSettings.GenesisString, TxExecutionOrderHandler: pcf.txExecutionOrderHandler, GenesisEpoch: pcf.config.EpochStartConfig.GenesisEpoch, + GenesisNonce: pcf.genesisNonce, + GenesisRound: pcf.genesisRound, } gbc, err := processGenesis.NewGenesisBlockCreator(arg) diff --git a/genesis/process/argGenesisBlockCreator.go b/genesis/process/argGenesisBlockCreator.go index db18b8df61b..05b8e130a20 100644 --- a/genesis/process/argGenesisBlockCreator.go +++ b/genesis/process/argGenesisBlockCreator.go @@ -44,6 +44,8 @@ type dataComponentsHandler interface { // ArgsGenesisBlockCreator holds the arguments which are needed to create a genesis block type ArgsGenesisBlockCreator struct { GenesisTime uint64 + GenesisNonce uint64 + GenesisRound uint64 StartEpochNum uint32 GenesisEpoch uint32 Data dataComponentsHandler diff --git a/genesis/process/genesisBlockCreator.go b/genesis/process/genesisBlockCreator.go index 143dd39ef15..c4ec16e5871 100644 --- a/genesis/process/genesisBlockCreator.go +++ b/genesis/process/genesisBlockCreator.go @@ -38,9 +38,6 @@ import ( const accountStartNonce = uint64(0) -var genesisNonce uint64 -var genesisRound uint64 - type genesisBlockCreator struct { arg ArgsGenesisBlockCreator initialIndexingData map[uint32]*genesis.IndexingData @@ -85,17 +82,7 @@ func getGenesisBlocksRoundNonceEpoch(arg ArgsGenesisBlockCreator) (uint64, uint6 if arg.HardForkConfig.AfterHardFork { return arg.HardForkConfig.StartRound, arg.HardForkConfig.StartNonce, arg.HardForkConfig.StartEpoch } - return genesisRound, genesisNonce, arg.GenesisEpoch -} - -// SetGenesisRound will set the genesis round -func SetGenesisRound(round uint64) { - genesisRound = round -} - -// SetGenesisNonce will set the genesis nonce -func SetGenesisNonce(nonce uint64) { - genesisNonce = nonce + return arg.GenesisRound, arg.GenesisNonce, arg.GenesisEpoch } func (gbc *genesisBlockCreator) createHardForkImportHandler() error { diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 2da45d6c8e0..663a503423a 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -10,7 +10,6 @@ import ( "github.com/multiversx/mx-chain-core-go/core/sharding" "github.com/multiversx/mx-chain-core-go/data/endProcess" crypto "github.com/multiversx/mx-chain-crypto-go" - processGenesis "github.com/multiversx/mx-chain-go/genesis/process" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" @@ -61,9 +60,6 @@ func NewChainSimulator(args ArgsChainSimulator) (*simulator, error) { mutex: sync.RWMutex{}, } - processGenesis.SetGenesisNonce(args.InitialNonce) - processGenesis.SetGenesisRound(uint64(args.InitialRound)) - err := instance.createChainHandlers(args) if err != nil { return nil, err @@ -140,6 +136,7 @@ func (s *simulator) createTestNode( APIInterface: args.ApiInterface, BypassTxSignatureCheck: args.BypassTxSignatureCheck, InitialRound: args.InitialRound, + InitialNonce: args.InitialNonce, MinNodesPerShard: args.MinNodesPerShard, MinNodesMeta: args.MetaChainMinNodes, } diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 27b1e358614..1f466c5befe 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -49,6 +49,9 @@ type ArgsProcessComponentsHolder struct { Config config.Config EconomicsConfig config.EconomicsConfig SystemSCConfig config.SystemSmartContractsConfig + + GenesisNonce uint64 + GenesisRound uint64 } type processComponentsHolder struct { @@ -203,6 +206,8 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC HistoryRepo: historyRepository, FlagsConfig: args.FlagsConfig, TxExecutionOrderHandler: txExecutionOrderHandler, + GenesisNonce: args.GenesisNonce, + GenesisRound: args.GenesisRound, } processComponentsFactory, err := processComp.NewProcessComponentsFactory(processArgs) if err != nil { diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 8fe8fdaf6b6..43abc6e8076 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -39,6 +39,7 @@ type ArgsTestOnlyProcessingNode struct { SyncedBroadcastNetwork SyncedBroadcastNetworkHandler InitialRound int64 + InitialNonce uint64 GasScheduleFilename string NumShards uint32 ShardIDStr string @@ -205,6 +206,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces ConfigurationPathsHolder: *args.Configs.ConfigurationPathsHolder, NodesCoordinator: instance.NodesCoordinator, DataComponents: instance.DataComponentsHolder, + GenesisNonce: args.InitialNonce, + GenesisRound: uint64(args.InitialRound), }) if err != nil { return nil, err From a7aec8a092717485151f71a8d3c4308af97560f9 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 21 Feb 2024 18:48:21 +0200 Subject: [PATCH 868/958] - fixed genesis flags usage --- factory/processing/processComponents.go | 5 +- factory/processing/processComponents_test.go | 1 + genesis/process/argGenesisBlockCreator.go | 4 +- genesis/process/genesisBlockCreator.go | 8 +- genesis/process/genesisBlockCreator_test.go | 21 +-- genesis/process/metaGenesisBlockCreator.go | 13 +- genesis/process/shardGenesisBlockCreator.go | 128 ++++-------------- .../multiShard/hardFork/hardFork_test.go | 7 +- .../realcomponents/processorRunner.go | 1 + integrationTests/testInitializer.go | 11 +- integrationTests/testProcessorNode.go | 13 +- integrationTests/vm/esdt/common.go | 10 +- integrationTests/vm/testInitializer.go | 16 +-- integrationTests/vm/txsFee/asyncCall_test.go | 9 +- .../vm/txsFee/builtInFunctions_test.go | 3 +- integrationTests/vm/txsFee/dns_test.go | 5 +- .../vm/txsFee/guardAccount_test.go | 2 +- .../vm/txsFee/multiShard/asyncCall_test.go | 3 +- integrationTests/vm/txsFee/scCalls_test.go | 3 +- integrationTests/vm/wasm/utils.go | 2 +- .../components/processComponents.go | 2 + .../components/testOnlyProcessingNode.go | 1 + node/nodeRunner.go | 10 +- testscommon/components/components.go | 1 + testscommon/roundConfig.go | 14 ++ 25 files changed, 104 insertions(+), 189 deletions(-) create mode 100644 testscommon/roundConfig.go diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 9fad572d80a..1b70b9b120c 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -232,6 +232,7 @@ func NewProcessComponentsFactory(args ProcessComponentsFactoryArgs) (*processCom statusCoreComponents: args.StatusCoreComponents, flagsConfig: args.FlagsConfig, txExecutionOrderHandler: args.TxExecutionOrderHandler, + roundConfig: args.RoundConfig, }, nil } @@ -881,8 +882,8 @@ func (pcf *processComponentsFactory) generateGenesisHeadersAndApplyInitialBalanc HardForkConfig: pcf.config.Hardfork, TrieStorageManagers: pcf.state.TrieStorageManagers(), SystemSCConfig: *pcf.systemSCConfig, - RoundConfig: &pcf.roundConfig, - EpochConfig: &pcf.epochConfig, + RoundConfig: pcf.roundConfig, + EpochConfig: pcf.epochConfig, BlockSignKeyGen: pcf.crypto.BlockSignKeyGen(), HistoryRepository: pcf.historyRepo, GenesisNodePrice: genesisNodePrice, diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index dbbd8fff853..18ef7b3aa84 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -81,6 +81,7 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto args := processComp.ProcessComponentsFactoryArgs{ Config: testscommon.GetGeneralConfig(), EpochConfig: config.EpochConfig{}, + RoundConfig: testscommon.GetDefaultRoundsConfig(), PrefConfigs: config.Preferences{}, ImportDBConfig: config.ImportDbConfig{}, FlagsConfig: config.ContextFlagsConfig{ diff --git a/genesis/process/argGenesisBlockCreator.go b/genesis/process/argGenesisBlockCreator.go index db18b8df61b..60dee66ebc4 100644 --- a/genesis/process/argGenesisBlockCreator.go +++ b/genesis/process/argGenesisBlockCreator.go @@ -61,8 +61,8 @@ type ArgsGenesisBlockCreator struct { HardForkConfig config.HardforkConfig TrieStorageManagers map[string]common.StorageManager SystemSCConfig config.SystemSmartContractsConfig - RoundConfig *config.RoundConfig - EpochConfig *config.EpochConfig + RoundConfig config.RoundConfig + EpochConfig config.EpochConfig WorkingDir string BlockSignKeyGen crypto.KeyGenerator HistoryRepository dblookupext.HistoryRepository diff --git a/genesis/process/genesisBlockCreator.go b/genesis/process/genesisBlockCreator.go index ba01b319301..11917987f64 100644 --- a/genesis/process/genesisBlockCreator.go +++ b/genesis/process/genesisBlockCreator.go @@ -195,12 +195,6 @@ func checkArgumentsForBlockCreator(arg ArgsGenesisBlockCreator) error { if arg.TrieStorageManagers == nil { return genesis.ErrNilTrieStorageManager } - if arg.EpochConfig == nil { - return genesis.ErrNilEpochConfig - } - if arg.RoundConfig == nil { - return genesis.ErrNilRoundConfig - } if check.IfNil(arg.HistoryRepository) { return process.ErrNilHistoryRepository } @@ -225,7 +219,7 @@ func mustDoGenesisProcess(arg ArgsGenesisBlockCreator) bool { } func (gbc *genesisBlockCreator) createEmptyGenesisBlocks() (map[uint32]data.HeaderHandler, error) { - err := gbc.computeDNSAddresses(createGenesisConfig()) + err := gbc.computeDNSAddresses(createGenesisConfig(gbc.arg.EpochConfig.EnableEpochs)) if err != nil { return nil, err } diff --git a/genesis/process/genesisBlockCreator_test.go b/genesis/process/genesisBlockCreator_test.go index 90b46757a86..3dd51efd754 100644 --- a/genesis/process/genesisBlockCreator_test.go +++ b/genesis/process/genesisBlockCreator_test.go @@ -165,15 +165,14 @@ func createMockArgument( TrieStorageManagers: trieStorageManagers, BlockSignKeyGen: &mock.KeyGenMock{}, GenesisNodePrice: nodePrice, - EpochConfig: &config.EpochConfig{ + EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ - BuiltInFunctionsEnableEpoch: 0, - SCDeployEnableEpoch: 0, - RelayedTransactionsEnableEpoch: 0, - PenalizedTooMuchGasEnableEpoch: 0, + SCDeployEnableEpoch: unreachableEpoch, + CleanUpInformativeSCRsEnableEpoch: unreachableEpoch, + SCProcessorV2EnableEpoch: unreachableEpoch, }, }, - RoundConfig: &config.RoundConfig{ + RoundConfig: config.RoundConfig{ RoundActivations: map[string]config.ActivationRoundByName{ "DisableAsyncCallV1": { Round: "18446744073709551615", @@ -427,16 +426,6 @@ func TestNewGenesisBlockCreator(t *testing.T) { require.True(t, errors.Is(err, genesis.ErrNilTrieStorageManager)) require.Nil(t, gbc) }) - t.Run("nil EpochConfig should error", func(t *testing.T) { - t.Parallel() - - arg := createMockArgument(t, "testdata/genesisTest1.json", &mock.InitialNodesHandlerStub{}, big.NewInt(22000)) - arg.EpochConfig = nil - - gbc, err := NewGenesisBlockCreator(arg) - require.True(t, errors.Is(err, genesis.ErrNilEpochConfig)) - require.Nil(t, gbc) - }) t.Run("invalid GenesisNodePrice should error", func(t *testing.T) { t.Parallel() diff --git a/genesis/process/metaGenesisBlockCreator.go b/genesis/process/metaGenesisBlockCreator.go index 40b5f606241..8074484ebc5 100644 --- a/genesis/process/metaGenesisBlockCreator.go +++ b/genesis/process/metaGenesisBlockCreator.go @@ -48,9 +48,6 @@ import ( "github.com/multiversx/mx-chain-vm-common-go/parsers" ) -const unreachableEpoch = ^uint32(0) -const unreachableRound = ^uint64(0) - // CreateMetaGenesisBlock will create a metachain genesis block func CreateMetaGenesisBlock( arg ArgsGenesisBlockCreator, @@ -70,7 +67,11 @@ func CreateMetaGenesisBlock( DeployInitialScTxs: make([]data.TransactionHandler, 0), } - processors, err := createProcessorsForMetaGenesisBlock(arg, createGenesisConfig(), createGenesisRoundConfig()) + processors, err := createProcessorsForMetaGenesisBlock( + arg, + createGenesisConfig(arg.EpochConfig.EnableEpochs), + createGenesisRoundConfig(arg.RoundConfig), + ) if err != nil { return nil, nil, nil, err } @@ -295,7 +296,7 @@ func saveGenesisMetaToStorage( return nil } -func createProcessorsForMetaGenesisBlock(arg ArgsGenesisBlockCreator, enableEpochsConfig config.EnableEpochs, roundConfig *config.RoundConfig) (*genesisProcessors, error) { +func createProcessorsForMetaGenesisBlock(arg ArgsGenesisBlockCreator, enableEpochsConfig config.EnableEpochs, roundConfig config.RoundConfig) (*genesisProcessors, error) { epochNotifier := forking.NewGenericEpochNotifier() temporaryMetaHeader := &block.MetaBlock{ Epoch: arg.StartEpochNum, @@ -308,7 +309,7 @@ func createProcessorsForMetaGenesisBlock(arg ArgsGenesisBlockCreator, enableEpoc epochNotifier.CheckEpoch(temporaryMetaHeader) roundNotifier := forking.NewGenericRoundNotifier() - enableRoundsHandler, err := enablers.NewEnableRoundsHandler(*roundConfig, roundNotifier) + enableRoundsHandler, err := enablers.NewEnableRoundsHandler(roundConfig, roundNotifier) if err != nil { return nil, err } diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index 9fef8f05569..ed6d54a93db 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -5,7 +5,6 @@ import ( "fmt" "math" "math/big" - "strconv" "sync" "github.com/multiversx/mx-chain-core-go/core/check" @@ -45,8 +44,9 @@ import ( "github.com/multiversx/mx-chain-vm-common-go/parsers" ) -var log = logger.GetOrCreate("genesis/process") +const unreachableEpoch = ^uint32(0) +var log = logger.GetOrCreate("genesis/process") var zero = big.NewInt(0) type deployedScMetrics struct { @@ -54,112 +54,26 @@ type deployedScMetrics struct { numOtherTypes int } -func createGenesisConfig() config.EnableEpochs { - blsMultiSignerEnableEpoch := []config.MultiSignerConfig{ +func createGenesisConfig(providedEnableEpochs config.EnableEpochs) config.EnableEpochs { + clonedConfig := providedEnableEpochs + clonedConfig.BuiltInFunctionsEnableEpoch = 0 + clonedConfig.PenalizedTooMuchGasEnableEpoch = unreachableEpoch + clonedConfig.MaxNodesChangeEnableEpoch = []config.MaxNodesChangeConfig{ { - EnableEpoch: 0, - Type: "no-KOSK", + EpochEnable: unreachableEpoch, + MaxNumNodes: 0, + NodesToShufflePerShard: 0, }, } + clonedConfig.DoubleKeyProtectionEnableEpoch = 0 - return config.EnableEpochs{ - SCDeployEnableEpoch: unreachableEpoch, - BuiltInFunctionsEnableEpoch: 0, - RelayedTransactionsEnableEpoch: unreachableEpoch, - PenalizedTooMuchGasEnableEpoch: unreachableEpoch, - SwitchJailWaitingEnableEpoch: unreachableEpoch, - SwitchHysteresisForMinNodesEnableEpoch: unreachableEpoch, - BelowSignedThresholdEnableEpoch: unreachableEpoch, - TransactionSignedWithTxHashEnableEpoch: unreachableEpoch, - MetaProtectionEnableEpoch: unreachableEpoch, - AheadOfTimeGasUsageEnableEpoch: unreachableEpoch, - GasPriceModifierEnableEpoch: unreachableEpoch, - RepairCallbackEnableEpoch: unreachableEpoch, - MaxNodesChangeEnableEpoch: []config.MaxNodesChangeConfig{ - { - EpochEnable: unreachableEpoch, - MaxNumNodes: 0, - NodesToShufflePerShard: 0, - }, - }, - BlockGasAndFeesReCheckEnableEpoch: unreachableEpoch, - StakingV2EnableEpoch: unreachableEpoch, - StakeEnableEpoch: unreachableEpoch, // no need to enable this, we have builtin exceptions in staking system SC - DoubleKeyProtectionEnableEpoch: 0, - ESDTEnableEpoch: unreachableEpoch, - GovernanceEnableEpoch: unreachableEpoch, - DelegationManagerEnableEpoch: unreachableEpoch, - DelegationSmartContractEnableEpoch: unreachableEpoch, - CorrectLastUnjailedEnableEpoch: unreachableEpoch, - BalanceWaitingListsEnableEpoch: unreachableEpoch, - ReturnDataToLastTransferEnableEpoch: unreachableEpoch, - SenderInOutTransferEnableEpoch: unreachableEpoch, - RelayedTransactionsV2EnableEpoch: unreachableEpoch, - UnbondTokensV2EnableEpoch: unreachableEpoch, - SaveJailedAlwaysEnableEpoch: unreachableEpoch, - ValidatorToDelegationEnableEpoch: unreachableEpoch, - ReDelegateBelowMinCheckEnableEpoch: unreachableEpoch, - WaitingListFixEnableEpoch: unreachableEpoch, - IncrementSCRNonceInMultiTransferEnableEpoch: unreachableEpoch, - ESDTMultiTransferEnableEpoch: unreachableEpoch, - GlobalMintBurnDisableEpoch: unreachableEpoch, - ESDTTransferRoleEnableEpoch: unreachableEpoch, - BuiltInFunctionOnMetaEnableEpoch: unreachableEpoch, - ComputeRewardCheckpointEnableEpoch: unreachableEpoch, - SCRSizeInvariantCheckEnableEpoch: unreachableEpoch, - BackwardCompSaveKeyValueEnableEpoch: unreachableEpoch, - ESDTNFTCreateOnMultiShardEnableEpoch: unreachableEpoch, - MetaESDTSetEnableEpoch: unreachableEpoch, - AddTokensToDelegationEnableEpoch: unreachableEpoch, - MultiESDTTransferFixOnCallBackOnEnableEpoch: unreachableEpoch, - OptimizeGasUsedInCrossMiniBlocksEnableEpoch: unreachableEpoch, - CorrectFirstQueuedEpoch: unreachableEpoch, - CorrectJailedNotUnstakedEmptyQueueEpoch: unreachableEpoch, - FixOOGReturnCodeEnableEpoch: unreachableEpoch, - RemoveNonUpdatedStorageEnableEpoch: unreachableEpoch, - DeleteDelegatorAfterClaimRewardsEnableEpoch: unreachableEpoch, - OptimizeNFTStoreEnableEpoch: unreachableEpoch, - CreateNFTThroughExecByCallerEnableEpoch: unreachableEpoch, - StopDecreasingValidatorRatingWhenStuckEnableEpoch: unreachableEpoch, - FrontRunningProtectionEnableEpoch: unreachableEpoch, - IsPayableBySCEnableEpoch: unreachableEpoch, - CleanUpInformativeSCRsEnableEpoch: unreachableEpoch, - StorageAPICostOptimizationEnableEpoch: unreachableEpoch, - TransformToMultiShardCreateEnableEpoch: unreachableEpoch, - ESDTRegisterAndSetAllRolesEnableEpoch: unreachableEpoch, - ScheduledMiniBlocksEnableEpoch: unreachableEpoch, - FailExecutionOnEveryAPIErrorEnableEpoch: unreachableEpoch, - AddFailedRelayedTxToInvalidMBsDisableEpoch: unreachableEpoch, - SCRSizeInvariantOnBuiltInResultEnableEpoch: unreachableEpoch, - ManagedCryptoAPIsEnableEpoch: unreachableEpoch, - CheckCorrectTokenIDForTransferRoleEnableEpoch: unreachableEpoch, - DisableExecByCallerEnableEpoch: unreachableEpoch, - RefactorContextEnableEpoch: unreachableEpoch, - CheckFunctionArgumentEnableEpoch: unreachableEpoch, - CheckExecuteOnReadOnlyEnableEpoch: unreachableEpoch, - MiniBlockPartialExecutionEnableEpoch: unreachableEpoch, - ESDTMetadataContinuousCleanupEnableEpoch: unreachableEpoch, - FixAsyncCallBackArgsListEnableEpoch: unreachableEpoch, - FixOldTokenLiquidityEnableEpoch: unreachableEpoch, - SetSenderInEeiOutputTransferEnableEpoch: unreachableEpoch, - RefactorPeersMiniBlocksEnableEpoch: unreachableEpoch, - SCProcessorV2EnableEpoch: unreachableEpoch, - DoNotReturnOldBlockInBlockchainHookEnableEpoch: unreachableEpoch, - MaxBlockchainHookCountersEnableEpoch: unreachableEpoch, - BLSMultiSignerEnableEpoch: blsMultiSignerEnableEpoch, - SetGuardianEnableEpoch: unreachableEpoch, - ScToScLogEventEnableEpoch: unreachableEpoch, - } + return clonedConfig } -func createGenesisRoundConfig() *config.RoundConfig { - return &config.RoundConfig{ - RoundActivations: map[string]config.ActivationRoundByName{ - "DisableAsyncCallV1": { - Round: strconv.FormatUint(unreachableRound, 10), - }, - }, - } +func createGenesisRoundConfig(providedEnableRounds config.RoundConfig) config.RoundConfig { + clonedConfig := providedEnableRounds + + return clonedConfig } // CreateShardGenesisBlock will create a shard genesis block @@ -181,7 +95,11 @@ func CreateShardGenesisBlock( DeployInitialScTxs: make([]data.TransactionHandler, 0), } - processors, err := createProcessorsForShardGenesisBlock(arg, createGenesisConfig(), createGenesisRoundConfig()) + processors, err := createProcessorsForShardGenesisBlock( + arg, + createGenesisConfig(arg.EpochConfig.EnableEpochs), + createGenesisRoundConfig(arg.RoundConfig), + ) if err != nil { return nil, nil, nil, err } @@ -399,7 +317,7 @@ func setBalanceToTrie(arg ArgsGenesisBlockCreator, accnt genesis.InitialAccountH return arg.Accounts.SaveAccount(account) } -func createProcessorsForShardGenesisBlock(arg ArgsGenesisBlockCreator, enableEpochsConfig config.EnableEpochs, roundConfig *config.RoundConfig) (*genesisProcessors, error) { +func createProcessorsForShardGenesisBlock(arg ArgsGenesisBlockCreator, enableEpochsConfig config.EnableEpochs, roundConfig config.RoundConfig) (*genesisProcessors, error) { genesisWasmVMLocker := &sync.RWMutex{} // use a local instance as to not run in concurrent issues when doing bootstrap epochNotifier := forking.NewGenericEpochNotifier() enableEpochsHandler, err := enablers.NewEnableEpochsHandler(enableEpochsConfig, epochNotifier) @@ -408,7 +326,7 @@ func createProcessorsForShardGenesisBlock(arg ArgsGenesisBlockCreator, enableEpo } roundNotifier := forking.NewGenericRoundNotifier() - enableRoundsHandler, err := enablers.NewEnableRoundsHandler(*roundConfig, roundNotifier) + enableRoundsHandler, err := enablers.NewEnableRoundsHandler(roundConfig, roundNotifier) if err != nil { return nil, err } diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index 4cbf4cc92d0..c8c1e716717 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -21,6 +21,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" vmFactory "github.com/multiversx/mx-chain-go/process/factory" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" commonMocks "github.com/multiversx/mx-chain-go/testscommon/common" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/testscommon/dblookupext" @@ -406,7 +407,7 @@ func hardForkImport( dataComponents.DataPool = node.DataPool dataComponents.BlockChain = node.BlockChain - roundConfig := integrationTests.GetDefaultRoundsConfig() + roundConfig := testscommon.GetDefaultRoundsConfig() argsGenesis := process.ArgsGenesisBlockCreator{ GenesisTime: 0, @@ -479,7 +480,7 @@ func hardForkImport( AccountsParser: &genesisMocks.AccountsParserStub{}, SmartContractParser: &mock.SmartContractParserStub{}, BlockSignKeyGen: &mock.KeyGenMock{}, - EpochConfig: &config.EpochConfig{ + EpochConfig: config.EpochConfig{ EnableEpochs: config.EnableEpochs{ BuiltInFunctionsEnableEpoch: 0, SCDeployEnableEpoch: 0, @@ -491,7 +492,7 @@ func hardForkImport( DelegationSmartContractEnableEpoch: 0, }, }, - RoundConfig: &roundConfig, + RoundConfig: roundConfig, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } diff --git a/integrationTests/realcomponents/processorRunner.go b/integrationTests/realcomponents/processorRunner.go index 6881284899b..834a7589f40 100644 --- a/integrationTests/realcomponents/processorRunner.go +++ b/integrationTests/realcomponents/processorRunner.go @@ -406,6 +406,7 @@ func (pr *ProcessorRunner) createProcessComponents(tb testing.TB) { argsProcess := factoryProcessing.ProcessComponentsFactoryArgs{ Config: *pr.Config.GeneralConfig, EpochConfig: *pr.Config.EpochConfig, + RoundConfig: *pr.Config.RoundConfig, PrefConfigs: *pr.Config.PreferencesConfig, ImportDBConfig: *pr.Config.ImportDbConfig, FlagsConfig: config.ContextFlagsConfig{ diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 27a4d310d8a..89c9cbd616d 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -665,7 +665,7 @@ func CreateFullGenesisBlocks( dataComponents.DataPool = dataPool dataComponents.BlockChain = blkc - roundsConfig := GetDefaultRoundsConfig() + roundsConfig := testscommon.GetDefaultRoundsConfig() argsGenesis := genesisProcess.ArgsGenesisBlockCreator{ Core: coreComponents, @@ -729,10 +729,10 @@ func CreateFullGenesisBlocks( AccountsParser: accountsParser, SmartContractParser: smartContractParser, BlockSignKeyGen: &mock.KeyGenMock{}, - EpochConfig: &config.EpochConfig{ + EpochConfig: config.EpochConfig{ EnableEpochs: enableEpochsConfig, }, - RoundConfig: &roundsConfig, + RoundConfig: roundsConfig, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } @@ -835,9 +835,10 @@ func CreateGenesisMetaBlock( }, BlockSignKeyGen: &mock.KeyGenMock{}, GenesisNodePrice: big.NewInt(1000), - EpochConfig: &config.EpochConfig{ + EpochConfig: config.EpochConfig{ EnableEpochs: enableEpochsConfig, }, + RoundConfig: testscommon.GetDefaultRoundsConfig(), HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } @@ -1379,7 +1380,7 @@ func CreateNodesWithEnableEpochsAndVmConfig( nodesPerShard, numMetaChainNodes, epochConfig, - GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vmConfig, ) } diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 04fab3f3669..d43f7a2be78 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -483,7 +483,7 @@ func newBaseTestProcessorNode(args ArgTestProcessorNode) *TestProcessorNode { } if args.RoundsConfig == nil { - defaultRoundsConfig := GetDefaultRoundsConfig() + defaultRoundsConfig := testscommon.GetDefaultRoundsConfig() args.RoundsConfig = &defaultRoundsConfig } genericRoundNotifier := forking.NewGenericRoundNotifier() @@ -3525,14 +3525,3 @@ func GetDefaultEnableEpochsConfig() *config.EnableEpochs { DynamicGasCostForDataTrieStorageLoadEnableEpoch: UnreachableEpoch, } } - -// GetDefaultRoundsConfig - -func GetDefaultRoundsConfig() config.RoundConfig { - return config.RoundConfig{ - RoundActivations: map[string]config.ActivationRoundByName{ - "DisableAsyncCallV1": { - Round: "18446744073709551615", - }, - }, - } -} diff --git a/integrationTests/vm/esdt/common.go b/integrationTests/vm/esdt/common.go index 3287641d0e6..2d04331a85f 100644 --- a/integrationTests/vm/esdt/common.go +++ b/integrationTests/vm/esdt/common.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/process" vmFactory "github.com/multiversx/mx-chain-go/process/factory" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" "github.com/multiversx/mx-chain-go/vm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -170,7 +171,7 @@ func CreateNodesAndPrepareBalances(numOfShards int) ([]*integrationTests.TestPro ScheduledMiniBlocksEnableEpoch: integrationTests.UnreachableEpoch, MiniBlockPartialExecutionEnableEpoch: integrationTests.UnreachableEpoch, } - roundsConfig := integrationTests.GetDefaultRoundsConfig() + roundsConfig := testscommon.GetDefaultRoundsConfig() return CreateNodesAndPrepareBalancesWithEpochsAndRoundsConfig( numOfShards, enableEpochs, @@ -178,7 +179,7 @@ func CreateNodesAndPrepareBalances(numOfShards int) ([]*integrationTests.TestPro ) } -// CreateNodesAndPrepareBalances - +// CreateNodesAndPrepareBalancesWithEpochsAndRoundsConfig - func CreateNodesAndPrepareBalancesWithEpochsAndRoundsConfig(numOfShards int, enableEpochs config.EnableEpochs, roundsConfig config.RoundConfig) ([]*integrationTests.TestProcessorNode, []int) { nodesPerShard := 1 numMetachainNodes := 1 @@ -230,6 +231,7 @@ func IssueTestToken(nodes []*integrationTests.TestProcessorNode, initialSupply i issueTestToken(nodes, initialSupply, ticker, core.MinMetaTxExtraGasCost) } +// IssueTestTokenWithIssuerAccount - func IssueTestTokenWithIssuerAccount(nodes []*integrationTests.TestProcessorNode, issuerAccount *integrationTests.TestWalletAccount, initialSupply int64, ticker string) { issueTestTokenWithIssuerAccount(nodes, issuerAccount, initialSupply, ticker, core.MinMetaTxExtraGasCost) } @@ -302,6 +304,7 @@ func CheckNumCallBacks( } } +// CheckForwarderRawSavedCallbackArgs - func CheckForwarderRawSavedCallbackArgs( t *testing.T, address []byte, @@ -338,13 +341,14 @@ func CheckForwarderRawSavedCallbackArgs( } } -/// ForwarderRawSavedPaymentInfo contains token data to be checked in the forwarder-raw contract. +// ForwarderRawSavedPaymentInfo contains token data to be checked in the forwarder-raw contract. type ForwarderRawSavedPaymentInfo struct { TokenId string Nonce uint64 Payment *big.Int } +// CheckForwarderRawSavedCallbackPayments - func CheckForwarderRawSavedCallbackPayments( t *testing.T, address []byte, diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 5230a14c841..d64fc581e11 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -1080,7 +1080,7 @@ func CreatePreparedTxProcessorAndAccountsWithVMs( senderAddressBytes, senderBalance, enableEpochsConfig, - integrationTests.GetDefaultRoundsConfig()) + testscommon.GetDefaultRoundsConfig()) } // CreatePreparedTxProcessorAndAccountsWithVMsWithRoundsConfig - @@ -1178,13 +1178,13 @@ func CreatePreparedTxProcessorWithVMsAndCustomGasSchedule( mock.NewMultiShardsCoordinatorMock(2), integrationtests.CreateMemUnit(), createMockGasScheduleNotifierWithCustomGasSchedule(updateGasSchedule), - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), ) } // CreatePreparedTxProcessorWithVMsWithShardCoordinator - func CreatePreparedTxProcessorWithVMsWithShardCoordinator(enableEpochsConfig config.EnableEpochs, shardCoordinator sharding.Coordinator) (*VMTestContext, error) { - return CreatePreparedTxProcessorWithVMsWithShardCoordinatorAndRoundConfig(enableEpochsConfig, integrationTests.GetDefaultRoundsConfig(), shardCoordinator) + return CreatePreparedTxProcessorWithVMsWithShardCoordinatorAndRoundConfig(enableEpochsConfig, testscommon.GetDefaultRoundsConfig(), shardCoordinator) } // CreatePreparedTxProcessorWithVMsWithShardCoordinatorAndRoundConfig - @@ -1211,7 +1211,7 @@ func CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGas( shardCoordinator, db, gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vmConfig, ) } @@ -1324,7 +1324,7 @@ func CreateTxProcessorWasmVMWithGasSchedule( senderBalance, gasScheduleMap, enableEpochsConfig, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), ) } @@ -1409,7 +1409,7 @@ func CreateTxProcessorWasmVMWithVMConfig( ) (*VMTestContext, error) { return CreateTxProcessorArwenWithVMConfigAndRoundConfig( enableEpochsConfig, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vmConfig, gasSchedule, ) @@ -1499,7 +1499,7 @@ func CreatePreparedTxProcessorAndAccountsWithMockedVM( senderAddressBytes, senderBalance, enableEpochs, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), wasmVMChangeLocker, ) } @@ -1830,7 +1830,7 @@ func GetNodeIndex(nodeList []*integrationTests.TestProcessorNode, node *integrat // CreatePreparedTxProcessorWithVMsMultiShard - func CreatePreparedTxProcessorWithVMsMultiShard(selfShardID uint32, enableEpochsConfig config.EnableEpochs) (*VMTestContext, error) { - return CreatePreparedTxProcessorWithVMsMultiShardAndRoundConfig(selfShardID, enableEpochsConfig, integrationTests.GetDefaultRoundsConfig()) + return CreatePreparedTxProcessorWithVMsMultiShardAndRoundConfig(selfShardID, enableEpochsConfig, testscommon.GetDefaultRoundsConfig()) } // CreatePreparedTxProcessorWithVMsMultiShardAndRoundConfig - diff --git a/integrationTests/vm/txsFee/asyncCall_test.go b/integrationTests/vm/txsFee/asyncCall_test.go index cedf9ad825b..9608ad10d52 100644 --- a/integrationTests/vm/txsFee/asyncCall_test.go +++ b/integrationTests/vm/txsFee/asyncCall_test.go @@ -22,6 +22,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/integrationtests" vmcommon "github.com/multiversx/mx-chain-vm-common-go" wasmConfig "github.com/multiversx/mx-chain-vm-go/config" @@ -191,7 +192,7 @@ func testAsyncCallsOnInitFunctionOnUpgrade( shardCoordinatorForShard1, integrationtests.CreateMemUnit(), gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vm.CreateVMConfigWithVersion("v1.4"), ) require.Nil(t, err) @@ -200,7 +201,7 @@ func testAsyncCallsOnInitFunctionOnUpgrade( shardCoordinatorForShardMeta, integrationtests.CreateMemUnit(), gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vm.CreateVMConfigWithVersion("v1.4"), ) require.Nil(t, err) @@ -325,7 +326,7 @@ func testAsyncCallsOnInitFunctionOnDeploy(t *testing.T, shardCoordinatorForShard1, integrationtests.CreateMemUnit(), gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vm.CreateVMConfigWithVersion("v1.4"), ) require.Nil(t, err) @@ -334,7 +335,7 @@ func testAsyncCallsOnInitFunctionOnDeploy(t *testing.T, shardCoordinatorForShardMeta, integrationtests.CreateMemUnit(), gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vm.CreateVMConfigWithVersion("v1.4"), ) require.Nil(t, err) diff --git a/integrationTests/vm/txsFee/builtInFunctions_test.go b/integrationTests/vm/txsFee/builtInFunctions_test.go index 6a9b31bb674..3f5bec54e51 100644 --- a/integrationTests/vm/txsFee/builtInFunctions_test.go +++ b/integrationTests/vm/txsFee/builtInFunctions_test.go @@ -20,6 +20,7 @@ import ( "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/testscommon" "github.com/multiversx/mx-chain-go/testscommon/integrationtests" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" @@ -321,7 +322,7 @@ func TestBuildInFunctionSaveKeyValue_NotEnoughGasForTheSameKeyValue(t *testing.T shardCoord, integrationtests.CreateMemUnit(), gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vm.CreateVMConfigWithVersion("v1.5"), ) require.Nil(t, err) diff --git a/integrationTests/vm/txsFee/dns_test.go b/integrationTests/vm/txsFee/dns_test.go index 53c6644b679..515400c3d30 100644 --- a/integrationTests/vm/txsFee/dns_test.go +++ b/integrationTests/vm/txsFee/dns_test.go @@ -19,6 +19,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" logger "github.com/multiversx/mx-chain-logger-go" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" @@ -124,7 +125,7 @@ func TestDeployDNSContract_TestGasWhenSaveUsernameFailsCrossShardBackwardsCompat testContextForDNSContract, err := vm.CreatePreparedTxProcessorWithVMsMultiShardRoundVMConfig( 1, enableEpochs, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vmConfig, ) require.Nil(t, err) @@ -133,7 +134,7 @@ func TestDeployDNSContract_TestGasWhenSaveUsernameFailsCrossShardBackwardsCompat testContextForRelayerAndUser, err := vm.CreatePreparedTxProcessorWithVMsMultiShardRoundVMConfig( 2, enableEpochs, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), vmConfig, ) require.Nil(t, err) diff --git a/integrationTests/vm/txsFee/guardAccount_test.go b/integrationTests/vm/txsFee/guardAccount_test.go index 2baa497f991..4e55e232fe1 100644 --- a/integrationTests/vm/txsFee/guardAccount_test.go +++ b/integrationTests/vm/txsFee/guardAccount_test.go @@ -106,7 +106,7 @@ func prepareTestContextForGuardedAccounts(tb testing.TB) *vm.VMTestContext { testscommon.NewMultiShardsCoordinatorMock(2), db, gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), ) require.Nil(tb, err) diff --git a/integrationTests/vm/txsFee/multiShard/asyncCall_test.go b/integrationTests/vm/txsFee/multiShard/asyncCall_test.go index 181d937e55e..e799fd3efc6 100644 --- a/integrationTests/vm/txsFee/multiShard/asyncCall_test.go +++ b/integrationTests/vm/txsFee/multiShard/asyncCall_test.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" + "github.com/multiversx/mx-chain-go/testscommon" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/require" ) @@ -128,7 +129,7 @@ func TestAsyncCallDisabled(t *testing.T) { SCProcessorV2EnableEpoch: integrationTests.UnreachableEpoch, } - roundsConfig := integrationTests.GetDefaultRoundsConfig() + roundsConfig := testscommon.GetDefaultRoundsConfig() activationRound := roundsConfig.RoundActivations["DisableAsyncCallV1"] activationRound.Round = "0" roundsConfig.RoundActivations["DisableAsyncCallV1"] = activationRound diff --git a/integrationTests/vm/txsFee/scCalls_test.go b/integrationTests/vm/txsFee/scCalls_test.go index db01a33cd11..1f38759c4a6 100644 --- a/integrationTests/vm/txsFee/scCalls_test.go +++ b/integrationTests/vm/txsFee/scCalls_test.go @@ -23,6 +23,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/integrationtests" "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" "github.com/multiversx/mx-chain-go/vm/systemSmartContracts/defaults" @@ -69,7 +70,7 @@ func prepareTestContextForEpoch836(tb testing.TB) (*vm.VMTestContext, []byte) { mock.NewMultiShardsCoordinatorMock(2), db, gasScheduleNotifier, - integrationTests.GetDefaultRoundsConfig(), + testscommon.GetDefaultRoundsConfig(), ) require.Nil(tb, err) diff --git a/integrationTests/vm/wasm/utils.go b/integrationTests/vm/wasm/utils.go index e8987f24bd2..0f7bfd88b7d 100644 --- a/integrationTests/vm/wasm/utils.go +++ b/integrationTests/vm/wasm/utils.go @@ -157,7 +157,7 @@ func SetupTestContextWithGasSchedule(t *testing.T, gasSchedule map[string]map[st DynamicGasCostForDataTrieStorageLoadEnableEpoch: integrationTests.UnreachableEpoch, }, context.EpochNotifier) context.RoundNotifier = &epochNotifier.RoundNotifierStub{} - context.EnableRoundsHandler, _ = enablers.NewEnableRoundsHandler(integrationTests.GetDefaultRoundsConfig(), context.RoundNotifier) + context.EnableRoundsHandler, _ = enablers.NewEnableRoundsHandler(testscommon.GetDefaultRoundsConfig(), context.RoundNotifier) context.WasmVMChangeLocker = &sync.RWMutex{} context.initAccounts() diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 27b1e358614..28992756bbb 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -42,6 +42,7 @@ type ArgsProcessComponentsHolder struct { NodesCoordinator nodesCoordinator.NodesCoordinator EpochConfig config.EpochConfig + RoundConfig config.RoundConfig ConfigurationPathsHolder config.ConfigurationPathsHolder FlagsConfig config.ContextFlagsConfig ImportDBConfig config.ImportDbConfig @@ -180,6 +181,7 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC processArgs := processComp.ProcessComponentsFactoryArgs{ Config: args.Config, EpochConfig: args.EpochConfig, + RoundConfig: args.RoundConfig, PrefConfigs: args.PrefsConfig, ImportDBConfig: args.ImportDBConfig, AccountsParser: accountsParser, diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 8fe8fdaf6b6..0b16d7e5565 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -202,6 +202,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces EconomicsConfig: *args.Configs.EconomicsConfig, SystemSCConfig: *args.Configs.SystemSCConfig, EpochConfig: *args.Configs.EpochConfig, + RoundConfig: *args.Configs.RoundConfig, ConfigurationPathsHolder: *args.Configs.ConfigurationPathsHolder, NodesCoordinator: instance.NodesCoordinator, DataComponents: instance.DataComponentsHolder, diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 10021772c39..99021fcc0b8 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -430,7 +430,6 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( managedStateComponents, managedBootstrapComponents, managedProcessComponents, - managedStatusCoreComponents, ) if err != nil { return true, err @@ -559,7 +558,6 @@ func addSyncersToAccountsDB( stateComponents mainFactory.StateComponentsHolder, bootstrapComponents mainFactory.BootstrapComponentsHolder, processComponents mainFactory.ProcessComponentsHolder, - statusCoreComponents mainFactory.StatusCoreComponentsHolder, ) error { selfId := bootstrapComponents.ShardCoordinator().SelfId() if selfId == core.MetachainShardId { @@ -569,7 +567,6 @@ func addSyncersToAccountsDB( dataComponents, stateComponents, processComponents, - statusCoreComponents, ) if err != nil { return err @@ -593,7 +590,6 @@ func addSyncersToAccountsDB( stateComponents, bootstrapComponents, processComponents, - statusCoreComponents, ) if err != nil { return err @@ -613,7 +609,6 @@ func getUserAccountSyncer( stateComponents mainFactory.StateComponentsHolder, bootstrapComponents mainFactory.BootstrapComponentsHolder, processComponents mainFactory.ProcessComponentsHolder, - statusCoreComponents mainFactory.StatusCoreComponentsHolder, ) (process.AccountsDBSyncer, error) { maxTrieLevelInMemory := config.StateTriesConfig.MaxStateTrieLevelInMemory userTrie := stateComponents.TriesContainer().Get([]byte(dataRetriever.UserAccountsUnit.String())) @@ -631,7 +626,6 @@ func getUserAccountSyncer( dataComponents, processComponents, storageManager, - statusCoreComponents, maxTrieLevelInMemory, ), ShardId: bootstrapComponents.ShardCoordinator().SelfId(), @@ -648,7 +642,6 @@ func getValidatorAccountSyncer( dataComponents mainFactory.DataComponentsHolder, stateComponents mainFactory.StateComponentsHolder, processComponents mainFactory.ProcessComponentsHolder, - statusCoreComponents mainFactory.StatusCoreComponentsHolder, ) (process.AccountsDBSyncer, error) { maxTrieLevelInMemory := config.StateTriesConfig.MaxPeerTrieLevelInMemory peerTrie := stateComponents.TriesContainer().Get([]byte(dataRetriever.PeerAccountsUnit.String())) @@ -661,7 +654,6 @@ func getValidatorAccountSyncer( dataComponents, processComponents, storageManager, - statusCoreComponents, maxTrieLevelInMemory, ), } @@ -675,7 +667,6 @@ func getBaseAccountSyncerArgs( dataComponents mainFactory.DataComponentsHolder, processComponents mainFactory.ProcessComponentsHolder, storageManager common.StorageManager, - statusCoreComponents mainFactory.StatusCoreComponentsHolder, maxTrieLevelInMemory uint, ) syncer.ArgsNewBaseAccountsSyncer { return syncer.ArgsNewBaseAccountsSyncer{ @@ -1234,6 +1225,7 @@ func (nr *nodeRunner) CreateManagedProcessComponents( processArgs := processComp.ProcessComponentsFactoryArgs{ Config: *configs.GeneralConfig, EpochConfig: *configs.EpochConfig, + RoundConfig: *configs.RoundConfig, PrefConfigs: *configs.PreferencesConfig, ImportDBConfig: *configs.ImportDbConfig, AccountsParser: accountsParser, diff --git a/testscommon/components/components.go b/testscommon/components/components.go index cc4ec1b03ab..6be797df529 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -563,6 +563,7 @@ func GetProcessArgs( FlagsConfig: config.ContextFlagsConfig{ Version: "v1.0.0", }, + RoundConfig: testscommon.GetDefaultRoundsConfig(), TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } } diff --git a/testscommon/roundConfig.go b/testscommon/roundConfig.go new file mode 100644 index 00000000000..273fb04041a --- /dev/null +++ b/testscommon/roundConfig.go @@ -0,0 +1,14 @@ +package testscommon + +import "github.com/multiversx/mx-chain-go/config" + +// GetDefaultRoundsConfig - +func GetDefaultRoundsConfig() config.RoundConfig { + return config.RoundConfig{ + RoundActivations: map[string]config.ActivationRoundByName{ + "DisableAsyncCallV1": { + Round: "18446744073709551615", + }, + }, + } +} From b01c1c8a89c86d56c3e2fcd70072ef361842fd77 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 22 Feb 2024 11:47:23 +0200 Subject: [PATCH 869/958] - fixed genesis block creator --- factory/processing/processComponents.go | 1 + genesis/interface.go | 8 ++- genesis/process/argGenesisBlockCreator.go | 5 +- genesis/process/genesisBlockCreator.go | 29 ++++++++- genesis/process/genesisBlockCreator_test.go | 16 ++--- genesis/process/shardGenesisBlockCreator.go | 61 +++++++++++++------ go.mod | 2 +- go.sum | 4 +- .../multiShard/hardFork/hardFork_test.go | 5 +- integrationTests/testInitializer.go | 6 +- testscommon/headerHandlerStub.go | 10 ++- testscommon/roundConfig.go | 14 ----- testscommon/testConfigs.go | 36 +++++++++++ 13 files changed, 145 insertions(+), 52 deletions(-) delete mode 100644 testscommon/roundConfig.go create mode 100644 testscommon/testConfigs.go diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 1b70b9b120c..62a25a74e0f 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -884,6 +884,7 @@ func (pcf *processComponentsFactory) generateGenesisHeadersAndApplyInitialBalanc SystemSCConfig: *pcf.systemSCConfig, RoundConfig: pcf.roundConfig, EpochConfig: pcf.epochConfig, + HeaderVersionConfigs: pcf.config.Versions, BlockSignKeyGen: pcf.crypto.BlockSignKeyGen(), HistoryRepository: pcf.historyRepo, GenesisNodePrice: genesisNodePrice, diff --git a/genesis/interface.go b/genesis/interface.go index 1a618a44efe..e58708a236f 100644 --- a/genesis/interface.go +++ b/genesis/interface.go @@ -84,7 +84,7 @@ type InitialSmartContractHandler interface { } // InitialSmartContractParser contains the parsed genesis initial smart contracts -//json file and has some functionality regarding processed data +// json file and has some functionality regarding processed data type InitialSmartContractParser interface { InitialSmartContractsSplitOnOwnersShards(shardCoordinator sharding.Coordinator) (map[uint32][]InitialSmartContractHandler, error) GetDeployedSCAddresses(scType string) (map[string]struct{}, error) @@ -115,3 +115,9 @@ type DeployProcessor interface { Deploy(sc InitialSmartContractHandler) ([][]byte, error) IsInterfaceNil() bool } + +// VersionedHeaderFactory creates versioned headers +type VersionedHeaderFactory interface { + Create(epoch uint32) data.HeaderHandler + IsInterfaceNil() bool +} diff --git a/genesis/process/argGenesisBlockCreator.go b/genesis/process/argGenesisBlockCreator.go index 60dee66ebc4..b4f49ee9054 100644 --- a/genesis/process/argGenesisBlockCreator.go +++ b/genesis/process/argGenesisBlockCreator.go @@ -63,6 +63,7 @@ type ArgsGenesisBlockCreator struct { SystemSCConfig config.SystemSmartContractsConfig RoundConfig config.RoundConfig EpochConfig config.EpochConfig + HeaderVersionConfigs config.VersionsConfig WorkingDir string BlockSignKeyGen crypto.KeyGenerator HistoryRepository dblookupext.HistoryRepository @@ -70,6 +71,8 @@ type ArgsGenesisBlockCreator struct { GenesisNodePrice *big.Int GenesisString string + // created components - importHandler update.ImportHandler + importHandler update.ImportHandler + versionedHeaderFactory genesis.VersionedHeaderFactory } diff --git a/genesis/process/genesisBlockCreator.go b/genesis/process/genesisBlockCreator.go index 11917987f64..f5233390711 100644 --- a/genesis/process/genesisBlockCreator.go +++ b/genesis/process/genesisBlockCreator.go @@ -16,6 +16,7 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" + factoryBlock "github.com/multiversx/mx-chain-go/factory/block" "github.com/multiversx/mx-chain-go/genesis" "github.com/multiversx/mx-chain-go/genesis/process/disabled" "github.com/multiversx/mx-chain-go/genesis/process/intermediate" @@ -480,12 +481,17 @@ func (gbc *genesisBlockCreator) getNewArgForShard(shardID uint32) (ArgsGenesisBl var err error isCurrentShard := shardID == gbc.arg.ShardCoordinator.SelfId() + newArgument := gbc.arg // copy the arguments + newArgument.versionedHeaderFactory, err = gbc.createVersionedHeaderFactory() + if err != nil { + return ArgsGenesisBlockCreator{}, fmt.Errorf("'%w' while generating a VersionedHeaderFactory instance for shard %d", + err, shardID) + } + if isCurrentShard { - newArgument := gbc.arg // copy the arguments newArgument.Data = newArgument.Data.Clone().(dataComponentsHandler) return newArgument, nil } - newArgument := gbc.arg // copy the arguments argsAccCreator := factoryState.ArgsAccountCreator{ Hasher: newArgument.Core.Hasher(), @@ -524,6 +530,25 @@ func (gbc *genesisBlockCreator) getNewArgForShard(shardID uint32) (ArgsGenesisBl return newArgument, err } +func (gbc *genesisBlockCreator) createVersionedHeaderFactory() (genesis.VersionedHeaderFactory, error) { + cacheConfig := factory.GetCacherFromConfig(gbc.arg.HeaderVersionConfigs.Cache) + cache, err := storageunit.NewCache(cacheConfig) + if err != nil { + return nil, err + } + + headerVersionHandler, err := factoryBlock.NewHeaderVersionHandler( + gbc.arg.HeaderVersionConfigs.VersionsByEpochs, + gbc.arg.HeaderVersionConfigs.DefaultVersion, + cache, + ) + if err != nil { + return nil, err + } + + return factoryBlock.NewShardHeaderFactory(headerVersionHandler) +} + func (gbc *genesisBlockCreator) saveGenesisBlock(header data.HeaderHandler) error { blockBuff, err := gbc.arg.Core.InternalMarshalizer().Marshal(header) if err != nil { diff --git a/genesis/process/genesisBlockCreator_test.go b/genesis/process/genesisBlockCreator_test.go index 3dd51efd754..e57dccb500a 100644 --- a/genesis/process/genesisBlockCreator_test.go +++ b/genesis/process/genesisBlockCreator_test.go @@ -13,6 +13,8 @@ import ( "testing" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" @@ -172,15 +174,15 @@ func createMockArgument( SCProcessorV2EnableEpoch: unreachableEpoch, }, }, - RoundConfig: config.RoundConfig{ - RoundActivations: map[string]config.ActivationRoundByName{ - "DisableAsyncCallV1": { - Round: "18446744073709551615", - }, - }, - }, + RoundConfig: testscommon.GetDefaultRoundsConfig(), + HeaderVersionConfigs: testscommon.GetDefaultHeaderVersionConfig(), HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, + versionedHeaderFactory: &testscommon.VersionedHeaderFactoryStub{ + CreateCalled: func(epoch uint32) data.HeaderHandler { + return &block.Header{} + }, + }, } arg.ShardCoordinator = &mock.ShardCoordinatorMock{ diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index ed6d54a93db..3c7e47070c7 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -159,22 +159,10 @@ func CreateShardGenesisBlock( ) round, nonce, epoch := getGenesisBlocksRoundNonceEpoch(arg) - header := &block.Header{ - Epoch: epoch, - Round: round, - Nonce: nonce, - ShardID: arg.ShardCoordinator.SelfId(), - BlockBodyType: block.StateBlock, - PubKeysBitmap: []byte{1}, - Signature: rootHash, - RootHash: rootHash, - PrevRandSeed: rootHash, - RandSeed: rootHash, - TimeStamp: arg.GenesisTime, - AccumulatedFees: big.NewInt(0), - DeveloperFees: big.NewInt(0), - ChainID: []byte(arg.Core.ChainID()), - SoftwareVersion: []byte(""), + headerHandler := arg.versionedHeaderFactory.Create(epoch) + err = setInitialDataInHeader(headerHandler, arg, epoch, nonce, round, rootHash) + if err != nil { + return nil, nil, nil, err } err = processors.vmContainer.Close() @@ -187,7 +175,46 @@ func CreateShardGenesisBlock( return nil, nil, nil, err } - return header, scAddresses, indexingData, nil + return headerHandler, scAddresses, indexingData, nil +} + +func setInitialDataInHeader( + headerHandler data.HeaderHandler, + arg ArgsGenesisBlockCreator, + epoch uint32, + nonce uint64, + round uint64, + rootHash []byte, +) error { + shardHeaderHandler, ok := headerHandler.(data.ShardHeaderHandler) + if !ok { + return process.ErrWrongTypeAssertion + } + + setErrors := make([]error, 0) + setErrors = append(setErrors, shardHeaderHandler.SetEpoch(epoch)) + setErrors = append(setErrors, shardHeaderHandler.SetNonce(nonce)) + setErrors = append(setErrors, shardHeaderHandler.SetRound(round)) + setErrors = append(setErrors, shardHeaderHandler.SetShardID(arg.ShardCoordinator.SelfId())) + setErrors = append(setErrors, shardHeaderHandler.SetBlockBodyTypeInt32(int32(block.StateBlock))) + setErrors = append(setErrors, shardHeaderHandler.SetPubKeysBitmap([]byte{1})) + setErrors = append(setErrors, shardHeaderHandler.SetSignature(rootHash)) + setErrors = append(setErrors, shardHeaderHandler.SetRootHash(rootHash)) + setErrors = append(setErrors, shardHeaderHandler.SetPrevRandSeed(rootHash)) + setErrors = append(setErrors, shardHeaderHandler.SetRandSeed(rootHash)) + setErrors = append(setErrors, shardHeaderHandler.SetTimeStamp(arg.GenesisTime)) + setErrors = append(setErrors, shardHeaderHandler.SetAccumulatedFees(big.NewInt(0))) + setErrors = append(setErrors, shardHeaderHandler.SetDeveloperFees(big.NewInt(0))) + setErrors = append(setErrors, shardHeaderHandler.SetChainID([]byte(arg.Core.ChainID()))) + setErrors = append(setErrors, shardHeaderHandler.SetSoftwareVersion([]byte(""))) + + for _, err := range setErrors { + if err != nil { + return err + } + } + + return nil } func createShardGenesisBlockAfterHardFork( diff --git a/go.mod b/go.mod index 092a7006c38..52f83bdd387 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 github.com/mitchellh/mapstructure v1.5.0 github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad - github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 + github.com/multiversx/mx-chain-core-go v1.2.19-0.20240222081523-011c96ab2548 github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c diff --git a/go.sum b/go.sum index fcbb3672f50..98e010606fc 100644 --- a/go.sum +++ b/go.sum @@ -387,8 +387,8 @@ github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUY github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o= github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad h1:izxTyKCxvT7z2mhXCWAZibSxwRVgLmq/kDovs4Nx/6Y= github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad/go.mod h1:n4E8BWIV0g3AcNGe1gf+vcjUC8A2QCJ4ARQSbiUDGrI= -github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 h1:pFh9bwOTRgW173aHqA8Bmax+jYzLnRyXqRvi5alF7V4= -github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= +github.com/multiversx/mx-chain-core-go v1.2.19-0.20240222081523-011c96ab2548 h1:WQoVgQG9YWiYM5Q3MmnbnxeoQkfHr63iFJZScFYsMxk= +github.com/multiversx/mx-chain-core-go v1.2.19-0.20240222081523-011c96ab2548/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 h1:beVIhs5ysylwNplQ/bZ0h5DoDlqKNWgpWE/NMHHNmAw= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479/go.mod h1:Ap6p7QZFtwPlb++OvCG+85BfuZ+bLP/JtQp6EwjWJsI= github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a h1:mOMUhbsjTq7n5oAv4KkVnL67ngS0+wkqmkiv1XJfBIY= diff --git a/integrationTests/multiShard/hardFork/hardFork_test.go b/integrationTests/multiShard/hardFork/hardFork_test.go index c8c1e716717..09a0d629bd1 100644 --- a/integrationTests/multiShard/hardFork/hardFork_test.go +++ b/integrationTests/multiShard/hardFork/hardFork_test.go @@ -407,8 +407,6 @@ func hardForkImport( dataComponents.DataPool = node.DataPool dataComponents.BlockChain = node.BlockChain - roundConfig := testscommon.GetDefaultRoundsConfig() - argsGenesis := process.ArgsGenesisBlockCreator{ GenesisTime: 0, StartEpochNum: 100, @@ -492,7 +490,8 @@ func hardForkImport( DelegationSmartContractEnableEpoch: 0, }, }, - RoundConfig: roundConfig, + RoundConfig: testscommon.GetDefaultRoundsConfig(), + HeaderVersionConfigs: testscommon.GetDefaultHeaderVersionConfig(), HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index 89c9cbd616d..86f6db97dd5 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -665,8 +665,6 @@ func CreateFullGenesisBlocks( dataComponents.DataPool = dataPool dataComponents.BlockChain = blkc - roundsConfig := testscommon.GetDefaultRoundsConfig() - argsGenesis := genesisProcess.ArgsGenesisBlockCreator{ Core: coreComponents, Data: dataComponents, @@ -732,7 +730,8 @@ func CreateFullGenesisBlocks( EpochConfig: config.EpochConfig{ EnableEpochs: enableEpochsConfig, }, - RoundConfig: roundsConfig, + RoundConfig: testscommon.GetDefaultRoundsConfig(), + HeaderVersionConfigs: testscommon.GetDefaultHeaderVersionConfig(), HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } @@ -839,6 +838,7 @@ func CreateGenesisMetaBlock( EnableEpochs: enableEpochsConfig, }, RoundConfig: testscommon.GetDefaultRoundsConfig(), + HeaderVersionConfigs: testscommon.GetDefaultHeaderVersionConfig(), HistoryRepository: &dblookupext.HistoryRepositoryStub{}, TxExecutionOrderHandler: &commonMocks.TxExecutionOrderHandlerStub{}, } diff --git a/testscommon/headerHandlerStub.go b/testscommon/headerHandlerStub.go index 773a1f7413d..ab1d354ec60 100644 --- a/testscommon/headerHandlerStub.go +++ b/testscommon/headerHandlerStub.go @@ -12,6 +12,7 @@ type HeaderHandlerStub struct { EpochField uint32 RoundField uint64 TimestampField uint64 + BlockBodyTypeInt32Field int32 GetMiniBlockHeadersWithDstCalled func(destId uint32) map[string]uint32 GetOrderedCrossMiniblocksWithDstCalled func(destId uint32) []*data.MiniBlockInfo GetPubKeysBitmapCalled func() []byte @@ -290,7 +291,7 @@ func (hhs *HeaderHandlerStub) GetMetaBlockHashes() [][]byte { // GetBlockBodyTypeInt32 - func (hhs *HeaderHandlerStub) GetBlockBodyTypeInt32() int32 { - panic("implement me") + return hhs.BlockBodyTypeInt32Field } // GetValidatorStatsRootHash - @@ -419,3 +420,10 @@ func (hhs *HeaderHandlerStub) HasScheduledMiniBlocks() bool { } return false } + +// SetBlockBodyTypeInt32 - +func (hhs *HeaderHandlerStub) SetBlockBodyTypeInt32(blockBodyType int32) error { + hhs.BlockBodyTypeInt32Field = blockBodyType + + return nil +} diff --git a/testscommon/roundConfig.go b/testscommon/roundConfig.go deleted file mode 100644 index 273fb04041a..00000000000 --- a/testscommon/roundConfig.go +++ /dev/null @@ -1,14 +0,0 @@ -package testscommon - -import "github.com/multiversx/mx-chain-go/config" - -// GetDefaultRoundsConfig - -func GetDefaultRoundsConfig() config.RoundConfig { - return config.RoundConfig{ - RoundActivations: map[string]config.ActivationRoundByName{ - "DisableAsyncCallV1": { - Round: "18446744073709551615", - }, - }, - } -} diff --git a/testscommon/testConfigs.go b/testscommon/testConfigs.go new file mode 100644 index 00000000000..fc0840e5237 --- /dev/null +++ b/testscommon/testConfigs.go @@ -0,0 +1,36 @@ +package testscommon + +import "github.com/multiversx/mx-chain-go/config" + +// GetDefaultRoundsConfig - +func GetDefaultRoundsConfig() config.RoundConfig { + return config.RoundConfig{ + RoundActivations: map[string]config.ActivationRoundByName{ + "DisableAsyncCallV1": { + Round: "18446744073709551615", + }, + }, + } +} + +// GetDefaultHeaderVersionConfig - +func GetDefaultHeaderVersionConfig() config.VersionsConfig { + return config.VersionsConfig{ + DefaultVersion: "default", + VersionsByEpochs: []config.VersionByEpochs{ + { + StartEpoch: 0, + Version: "*", + }, + { + StartEpoch: 1, + Version: "2", + }, + }, + Cache: config.CacheConfig{ + Name: "VersionsCache", + Type: "LRU", + Capacity: 100, + }, + } +} From 818c5c718627b404646dad71cce17ef80d1664eb Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 22 Feb 2024 11:49:59 +0200 Subject: [PATCH 870/958] processComponentsHolder tests --- factory/api/apiResolverFactory_test.go | 2 +- factory/processing/processComponents_test.go | 2 +- factory/state/stateComponentsHandler_test.go | 14 +- factory/state/stateComponents_test.go | 18 +- .../components/dataComponents_test.go | 3 - .../components/processComponents.go | 10 +- .../components/processComponents_test.go | 403 ++++++++++++++++++ testscommon/components/components.go | 22 +- 8 files changed, 437 insertions(+), 37 deletions(-) create mode 100644 node/chainSimulator/components/processComponents_test.go diff --git a/factory/api/apiResolverFactory_test.go b/factory/api/apiResolverFactory_test.go index e43ac2962d8..47bc6913f0c 100644 --- a/factory/api/apiResolverFactory_test.go +++ b/factory/api/apiResolverFactory_test.go @@ -71,7 +71,7 @@ func createMockArgs(t *testing.T) *api.ApiResolverArgs { cryptoComponents := componentsMock.GetCryptoComponents(coreComponents) networkComponents := componentsMock.GetNetworkComponents(cryptoComponents) dataComponents := componentsMock.GetDataComponents(coreComponents, shardCoordinator) - stateComponents := componentsMock.GetStateComponents(coreComponents) + stateComponents := componentsMock.GetStateComponents(coreComponents, componentsMock.GetStatusCoreComponents()) processComponents := componentsMock.GetProcessComponents(shardCoordinator, coreComponents, networkComponents, dataComponents, cryptoComponents, stateComponents) argsB := componentsMock.GetBootStrapFactoryArgs() diff --git a/factory/processing/processComponents_test.go b/factory/processing/processComponents_test.go index dbbd8fff853..90c0ec84a28 100644 --- a/factory/processing/processComponents_test.go +++ b/factory/processing/processComponents_test.go @@ -244,7 +244,7 @@ func createMockProcessComponentsFactoryArgs() processComp.ProcessComponentsFacto TxExecutionOrderHandler: &txExecOrderStub.TxExecutionOrderHandlerStub{}, } - args.State = components.GetStateComponents(args.CoreData) + args.State = components.GetStateComponents(args.CoreData, args.StatusCoreComponents) return args } diff --git a/factory/state/stateComponentsHandler_test.go b/factory/state/stateComponentsHandler_test.go index ba552ed416a..e73600180ff 100644 --- a/factory/state/stateComponentsHandler_test.go +++ b/factory/state/stateComponentsHandler_test.go @@ -27,7 +27,7 @@ func TestNewManagedStateComponents(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, err := stateComp.NewManagedStateComponents(stateComponentsFactory) require.NoError(t, err) @@ -42,7 +42,7 @@ func TestManagedStateComponents_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, err := stateComp.NewManagedStateComponents(stateComponentsFactory) require.NoError(t, err) @@ -56,7 +56,7 @@ func TestManagedStateComponents_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, err := stateComp.NewManagedStateComponents(stateComponentsFactory) require.NoError(t, err) @@ -87,7 +87,7 @@ func TestManagedStateComponents_Close(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, _ := stateComp.NewManagedStateComponents(stateComponentsFactory) require.NoError(t, managedStateComponents.Close()) @@ -102,7 +102,7 @@ func TestManagedStateComponents_CheckSubcomponents(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, _ := stateComp.NewManagedStateComponents(stateComponentsFactory) err := managedStateComponents.CheckSubcomponents() @@ -121,7 +121,7 @@ func TestManagedStateComponents_Setters(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, _ := stateComp.NewManagedStateComponents(stateComponentsFactory) err := managedStateComponents.Create() @@ -153,7 +153,7 @@ func TestManagedStateComponents_IsInterfaceNil(t *testing.T) { require.True(t, managedStateComponents.IsInterfaceNil()) coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) stateComponentsFactory, _ := stateComp.NewStateComponentsFactory(args) managedStateComponents, _ = stateComp.NewManagedStateComponents(stateComponentsFactory) require.False(t, managedStateComponents.IsInterfaceNil()) diff --git a/factory/state/stateComponents_test.go b/factory/state/stateComponents_test.go index 177407226d8..bf5068e8dd7 100644 --- a/factory/state/stateComponents_test.go +++ b/factory/state/stateComponents_test.go @@ -20,7 +20,7 @@ func TestNewStateComponentsFactory(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) args.Core = nil scf, err := stateComp.NewStateComponentsFactory(args) @@ -31,7 +31,7 @@ func TestNewStateComponentsFactory(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) args.StatusCore = nil scf, err := stateComp.NewStateComponentsFactory(args) @@ -42,7 +42,7 @@ func TestNewStateComponentsFactory(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) scf, err := stateComp.NewStateComponentsFactory(args) require.NoError(t, err) @@ -57,7 +57,7 @@ func TestStateComponentsFactory_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) coreCompStub := factory.NewCoreComponentsHolderStubFromRealComponent(args.Core) coreCompStub.InternalMarshalizerCalled = func() marshal.Marshalizer { return nil @@ -73,7 +73,7 @@ func TestStateComponentsFactory_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) args.Config.EvictionWaitingList.RootHashesSize = 0 scf, _ := stateComp.NewStateComponentsFactory(args) @@ -85,7 +85,7 @@ func TestStateComponentsFactory_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) coreCompStub := factory.NewCoreComponentsHolderStubFromRealComponent(args.Core) cnt := 0 @@ -107,7 +107,7 @@ func TestStateComponentsFactory_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) coreCompStub := factory.NewCoreComponentsHolderStubFromRealComponent(args.Core) cnt := 0 @@ -129,7 +129,7 @@ func TestStateComponentsFactory_Create(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) scf, _ := stateComp.NewStateComponentsFactory(args) sc, err := scf.Create() @@ -143,7 +143,7 @@ func TestStateComponents_Close(t *testing.T) { t.Parallel() coreComponents := componentsMock.GetCoreComponents() - args := componentsMock.GetStateFactoryArgs(coreComponents) + args := componentsMock.GetStateFactoryArgs(coreComponents, componentsMock.GetStatusCoreComponents()) scf, _ := stateComp.NewStateComponentsFactory(args) sc, err := scf.Create() diff --git a/node/chainSimulator/components/dataComponents_test.go b/node/chainSimulator/components/dataComponents_test.go index 24c1ca532ce..d059200ff07 100644 --- a/node/chainSimulator/components/dataComponents_test.go +++ b/node/chainSimulator/components/dataComponents_test.go @@ -1,7 +1,6 @@ package components import ( - "errors" "testing" retriever "github.com/multiversx/mx-chain-go/dataRetriever" @@ -12,8 +11,6 @@ import ( "github.com/stretchr/testify/require" ) -var expectedErr = errors.New("expected error") - func createArgsDataComponentsHolder() ArgsDataComponentsHolder { return ArgsDataComponentsHolder{ Chain: &testscommon.ChainHandlerStub{}, diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 27b1e358614..2fd615f1583 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -93,11 +93,11 @@ type processComponentsHolder struct { processedMiniBlocksTracker process.ProcessedMiniBlocksTracker esdtDataStorageHandlerForAPI vmcommon.ESDTNFTStorageHandler accountsParser genesis.AccountsParser - sendSignatureTracker process.SentSignaturesTracker + sentSignatureTracker process.SentSignaturesTracker } // CreateProcessComponents will create the process components holder -func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessComponentsHandler, error) { +func CreateProcessComponents(args ArgsProcessComponentsHolder) (*processComponentsHolder, error) { importStartHandler, err := trigger.NewImportStartHandler(filepath.Join(args.FlagsConfig.DbDir, common.DefaultDBPath), args.FlagsConfig.Version) if err != nil { return nil, err @@ -261,7 +261,7 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC processedMiniBlocksTracker: managedProcessComponents.ProcessedMiniBlocksTracker(), esdtDataStorageHandlerForAPI: managedProcessComponents.ESDTDataStorageHandlerForAPI(), accountsParser: managedProcessComponents.AccountsParser(), - sendSignatureTracker: managedProcessComponents.SentSignaturesTracker(), + sentSignatureTracker: managedProcessComponents.SentSignaturesTracker(), } instance.collectClosableComponents() @@ -269,9 +269,9 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (factory.ProcessC return instance, nil } -// SentSignaturesTracker will return the send signature tracker +// SentSignaturesTracker will return the sent signature tracker func (p *processComponentsHolder) SentSignaturesTracker() process.SentSignaturesTracker { - return p.sendSignatureTracker + return p.sentSignatureTracker } // NodesCoordinator will return the nodes coordinator diff --git a/node/chainSimulator/components/processComponents_test.go b/node/chainSimulator/components/processComponents_test.go new file mode 100644 index 00000000000..3d261a796e7 --- /dev/null +++ b/node/chainSimulator/components/processComponents_test.go @@ -0,0 +1,403 @@ +package components + +import ( + "sync" + "testing" + + coreData "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-core-go/data/endProcess" + "github.com/multiversx/mx-chain-core-go/hashing/blake2b" + "github.com/multiversx/mx-chain-core-go/hashing/keccak" + "github.com/multiversx/mx-chain-core-go/marshal" + commonFactory "github.com/multiversx/mx-chain-go/common/factory" + disabledStatistics "github.com/multiversx/mx-chain-go/common/statistics/disabled" + "github.com/multiversx/mx-chain-go/config" + retriever "github.com/multiversx/mx-chain-go/dataRetriever" + mockFactory "github.com/multiversx/mx-chain-go/factory/mock" + "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/sharding" + chainStorage "github.com/multiversx/mx-chain-go/storage" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/bootstrapMocks" + "github.com/multiversx/mx-chain-go/testscommon/components" + "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" + "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" + "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + "github.com/multiversx/mx-chain-go/testscommon/guardianMocks" + "github.com/multiversx/mx-chain-go/testscommon/mainFactoryMocks" + "github.com/multiversx/mx-chain-go/testscommon/nodeTypeProviderMock" + "github.com/multiversx/mx-chain-go/testscommon/outport" + "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" + "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" + "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/multiversx/mx-chain-go/testscommon/storage" + updateMocks "github.com/multiversx/mx-chain-go/update/mock" + "github.com/stretchr/testify/require" +) + +const testingProtocolSustainabilityAddress = "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp" + +var ( + addrPubKeyConv, _ = commonFactory.NewPubkeyConverter(config.PubkeyConfig{ + Length: 32, + Type: "bech32", + SignatureLength: 0, + Hrp: "erd", + }) + valPubKeyConv, _ = commonFactory.NewPubkeyConverter(config.PubkeyConfig{ + Length: 96, + Type: "hex", + SignatureLength: 48, + }) +) + +func createArgsProcessComponentsHolder() ArgsProcessComponentsHolder { + //cnt := uint32(0) + nodesSetup, _ := sharding.NewNodesSetup("../../../integrationTests/factory/testdata/nodesSetup.json", addrPubKeyConv, valPubKeyConv, 3) + + args := ArgsProcessComponentsHolder{ + Config: testscommon.GetGeneralConfig(), + EpochConfig: config.EpochConfig{ + GasSchedule: config.GasScheduleConfig{ + GasScheduleByEpochs: []config.GasScheduleByEpochs{ + { + StartEpoch: 0, + FileName: "../../../cmd/node/config/gasSchedules/gasScheduleV7.toml", + }, + }, + }, + }, + PrefsConfig: config.Preferences{}, + ImportDBConfig: config.ImportDbConfig{}, + FlagsConfig: config.ContextFlagsConfig{ + Version: "v1.0.0", + }, + NodesCoordinator: &shardingMocks.NodesCoordinatorStub{}, + SystemSCConfig: config.SystemSmartContractsConfig{ + ESDTSystemSCConfig: config.ESDTSystemSCConfig{ + BaseIssuingCost: "1000", + OwnerAddress: "erd1fpkcgel4gcmh8zqqdt043yfcn5tyx8373kg6q2qmkxzu4dqamc0swts65c", + }, + GovernanceSystemSCConfig: config.GovernanceSystemSCConfig{ + V1: config.GovernanceSystemSCConfigV1{ + ProposalCost: "500", + NumNodes: 100, + MinQuorum: 50, + MinPassThreshold: 50, + MinVetoThreshold: 50, + }, + Active: config.GovernanceSystemSCConfigActive{ + ProposalCost: "500", + MinQuorum: 0.5, + MinPassThreshold: 0.5, + MinVetoThreshold: 0.5, + }, + OwnerAddress: "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80", + }, + StakingSystemSCConfig: config.StakingSystemSCConfig{ + GenesisNodePrice: "2500000000000000000000", + MinStakeValue: "1", + UnJailValue: "1", + MinStepValue: "1", + UnBondPeriod: 0, + NumRoundsWithoutBleed: 0, + MaximumPercentageToBleed: 0, + BleedPercentagePerRound: 0, + MaxNumberOfNodesForStake: 10, + ActivateBLSPubKeyMessageVerification: false, + MinUnstakeTokensValue: "1", + }, + DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ + MinCreationDeposit: "100", + MinStakeAmount: "100", + ConfigChangeAddress: "erd1vxy22x0fj4zv6hktmydg8vpfh6euv02cz4yg0aaws6rrad5a5awqgqky80", + }, + DelegationSystemSCConfig: config.DelegationSystemSCConfig{ + MinServiceFee: 0, + MaxServiceFee: 100, + }, + }, + DataComponents: &mock.DataComponentsStub{ + DataPool: dataRetriever.NewPoolsHolderMock(), + BlockChain: &testscommon.ChainHandlerStub{ + GetGenesisHeaderHashCalled: func() []byte { + return []byte("genesis hash") + }, + GetGenesisHeaderCalled: func() coreData.HeaderHandler { + return &testscommon.HeaderHandlerStub{} + }, + }, + MbProvider: &mock.MiniBlocksProviderStub{}, + Store: genericMocks.NewChainStorerMock(0), + }, + CoreComponents: &mockFactory.CoreComponentsMock{ + IntMarsh: &marshal.GogoProtoMarshalizer{}, + TxMarsh: &marshal.JsonMarshalizer{}, + UInt64ByteSliceConv: &mock.Uint64ByteSliceConverterMock{}, + AddrPubKeyConv: addrPubKeyConv, + ValPubKeyConv: valPubKeyConv, + NodesConfig: nodesSetup, + EpochChangeNotifier: &epochNotifier.EpochNotifierStub{}, + EconomicsHandler: &economicsmocks.EconomicsHandlerStub{ + ProtocolSustainabilityAddressCalled: func() string { + return testingProtocolSustainabilityAddress + }, + }, + Hash: blake2b.NewBlake2b(), + TxVersionCheckHandler: &testscommon.TxVersionCheckerStub{}, + RatingHandler: &testscommon.RaterMock{}, + EnableEpochsHandlerField: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + EnableRoundsHandlerField: &testscommon.EnableRoundsHandlerStub{}, + EpochNotifierWithConfirm: &updateMocks.EpochStartNotifierStub{}, + RoundHandlerField: &testscommon.RoundHandlerMock{}, + RoundChangeNotifier: &epochNotifier.RoundNotifierStub{}, + ChanStopProcess: make(chan endProcess.ArgEndProcess, 1), + TxSignHasherField: keccak.NewKeccak(), + HardforkTriggerPubKeyField: []byte("hardfork pub key"), + WasmVMChangeLockerInternal: &sync.RWMutex{}, + NodeTypeProviderField: &nodeTypeProviderMock.NodeTypeProviderStub{}, + RatingsConfig: &testscommon.RatingsInfoMock{}, + PathHdl: &testscommon.PathManagerStub{}, + ProcessStatusHandlerInternal: &testscommon.ProcessStatusHandlerStub{}, + }, + CryptoComponents: &mock.CryptoComponentsStub{ + BlKeyGen: &cryptoMocks.KeyGenStub{}, + BlockSig: &cryptoMocks.SingleSignerStub{}, + MultiSigContainer: &cryptoMocks.MultiSignerContainerMock{ + MultiSigner: &cryptoMocks.MultisignerMock{}, + }, + PrivKey: &cryptoMocks.PrivateKeyStub{}, + PubKey: &cryptoMocks.PublicKeyStub{}, + PubKeyString: "pub key string", + PubKeyBytes: []byte("pub key bytes"), + TxKeyGen: &cryptoMocks.KeyGenStub{}, + TxSig: &cryptoMocks.SingleSignerStub{}, + PeerSignHandler: &cryptoMocks.PeerSignatureHandlerStub{}, + MsgSigVerifier: &testscommon.MessageSignVerifierMock{}, + ManagedPeersHolderField: &testscommon.ManagedPeersHolderStub{}, + KeysHandlerField: &testscommon.KeysHandlerStub{}, + }, + NetworkComponents: &mock.NetworkComponentsStub{ + Messenger: &p2pmocks.MessengerStub{}, + FullArchiveNetworkMessengerField: &p2pmocks.MessengerStub{}, + InputAntiFlood: &mock.P2PAntifloodHandlerStub{}, + OutputAntiFlood: &mock.P2PAntifloodHandlerStub{}, + PreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + PeersRatingHandlerField: &p2pmocks.PeersRatingHandlerStub{}, + FullArchivePreferredPeersHolder: &p2pmocks.PeersHolderStub{}, + }, + BootstrapComponents: &mainFactoryMocks.BootstrapComponentsStub{ + ShCoordinator: mock.NewMultiShardsCoordinatorMock(2), + BootstrapParams: &bootstrapMocks.BootstrapParamsHandlerMock{}, + HdrIntegrityVerifier: &mock.HeaderIntegrityVerifierStub{}, + GuardedAccountHandlerField: &guardianMocks.GuardedAccountHandlerStub{}, + VersionedHdrFactory: &testscommon.VersionedHeaderFactoryStub{}, + }, + StatusComponents: &mock.StatusComponentsStub{ + Outport: &outport.OutportStub{}, + }, + StatusCoreComponents: &factory.StatusCoreComponentsStub{ + AppStatusHandlerField: &statusHandler.AppStatusHandlerStub{}, + StateStatsHandlerField: disabledStatistics.NewStateStatistics(), + }, + EconomicsConfig: config.EconomicsConfig{ + GlobalSettings: config.GlobalSettings{ + GenesisTotalSupply: "20000000000000000000000000", + MinimumInflation: 0, + GenesisMintingSenderAddress: "erd17rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rc0pu8s7rcqqkhty3", + YearSettings: []*config.YearSetting{ + { + Year: 0, + MaximumInflation: 0.01, + }, + }, + }, + }, + ConfigurationPathsHolder: config.ConfigurationPathsHolder{ + Genesis: "../../../integrationTests/factory/testdata/genesis.json", + SmartContracts: "../../../integrationTests/factory/testdata/genesisSmartContracts.json", + Nodes: "../../../integrationTests/factory/testdata/genesis.json", + }, + } + + args.StateComponents = components.GetStateComponents(args.CoreComponents, args.StatusCoreComponents) + return args +} + +func TestCreateProcessComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateProcessComponents(createArgsProcessComponentsHolder()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("NewImportStartHandler failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.FlagsConfig.Version = "" + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("total supply conversion failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.EconomicsConfig.GlobalSettings.GenesisTotalSupply = "invalid number" + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewAccountsParser failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.ConfigurationPathsHolder.Genesis = "" + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewSmartContractsParser failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.ConfigurationPathsHolder.SmartContracts = "" + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewHistoryRepositoryFactory failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + dataMock, ok := args.DataComponents.(*mock.DataComponentsStub) + require.True(t, ok) + dataMock.Store = nil + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("historyRepositoryFactory.Create failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.Config.DbLookupExtensions.Enabled = true + dataMock, ok := args.DataComponents.(*mock.DataComponentsStub) + require.True(t, ok) + dataMock.Store = &storage.ChainStorerStub{ + GetStorerCalled: func(unitType retriever.UnitType) (chainStorage.Storer, error) { + if unitType == retriever.ESDTSuppliesUnit { + return nil, expectedErr + } + return &storage.StorerStub{}, nil + }, + } + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewGasScheduleNotifier failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.EpochConfig.GasSchedule = config.GasScheduleConfig{} + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("NewProcessComponentsFactory failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + dataMock, ok := args.DataComponents.(*mock.DataComponentsStub) + require.True(t, ok) + dataMock.BlockChain = nil + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("managedProcessComponents.Create failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsProcessComponentsHolder() + args.NodesCoordinator = nil + comp, err := CreateProcessComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestProcessComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *processComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateProcessComponents(createArgsProcessComponentsHolder()) + require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) +} + +func TestProcessComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + comp, err := CreateProcessComponents(createArgsProcessComponentsHolder()) + require.NoError(t, err) + + require.NotNil(t, comp.SentSignaturesTracker()) + require.NotNil(t, comp.NodesCoordinator()) + require.NotNil(t, comp.ShardCoordinator()) + require.NotNil(t, comp.InterceptorsContainer()) + require.NotNil(t, comp.FullArchiveInterceptorsContainer()) + require.NotNil(t, comp.ResolversContainer()) + require.NotNil(t, comp.RequestersFinder()) + require.NotNil(t, comp.RoundHandler()) + require.NotNil(t, comp.EpochStartTrigger()) + require.NotNil(t, comp.EpochStartNotifier()) + require.NotNil(t, comp.ForkDetector()) + require.NotNil(t, comp.BlockProcessor()) + require.NotNil(t, comp.BlackListHandler()) + require.NotNil(t, comp.BootStorer()) + require.NotNil(t, comp.HeaderSigVerifier()) + require.NotNil(t, comp.HeaderIntegrityVerifier()) + require.NotNil(t, comp.ValidatorsStatistics()) + require.NotNil(t, comp.ValidatorsProvider()) + require.NotNil(t, comp.BlockTracker()) + require.NotNil(t, comp.PendingMiniBlocksHandler()) + require.NotNil(t, comp.RequestHandler()) + require.NotNil(t, comp.TxLogsProcessor()) + require.NotNil(t, comp.HeaderConstructionValidator()) + require.NotNil(t, comp.PeerShardMapper()) + require.NotNil(t, comp.FullArchivePeerShardMapper()) + require.NotNil(t, comp.FallbackHeaderValidator()) + require.NotNil(t, comp.APITransactionEvaluator()) + require.NotNil(t, comp.WhiteListHandler()) + require.NotNil(t, comp.WhiteListerVerifiedTxs()) + require.NotNil(t, comp.HistoryRepository()) + require.NotNil(t, comp.ImportStartHandler()) + require.NotNil(t, comp.RequestedItemsHandler()) + require.NotNil(t, comp.NodeRedundancyHandler()) + require.NotNil(t, comp.CurrentEpochProvider()) + require.NotNil(t, comp.ScheduledTxsExecutionHandler()) + require.NotNil(t, comp.TxsSenderHandler()) + require.NotNil(t, comp.HardforkTrigger()) + require.NotNil(t, comp.ProcessedMiniBlocksTracker()) + require.NotNil(t, comp.ESDTDataStorageHandlerForAPI()) + require.NotNil(t, comp.AccountsParser()) + require.NotNil(t, comp.ReceiptsRepository()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) + + require.Nil(t, comp.Close()) +} diff --git a/testscommon/components/components.go b/testscommon/components/components.go index cc4ec1b03ab..e4a4ea0f578 100644 --- a/testscommon/components/components.go +++ b/testscommon/components/components.go @@ -134,7 +134,7 @@ func GetConsensusArgs(shardCoordinator sharding.Coordinator) consensusComp.Conse coreComponents := GetCoreComponents() cryptoComponents := GetCryptoComponents(coreComponents) networkComponents := GetNetworkComponents(cryptoComponents) - stateComponents := GetStateComponents(coreComponents) + stateComponents := GetStateComponents(coreComponents, GetStatusCoreComponents()) dataComponents := GetDataComponents(coreComponents, shardCoordinator) processComponents := GetProcessComponents( shardCoordinator, @@ -325,7 +325,7 @@ func GetNetworkFactoryArgs() networkComp.NetworkComponentsFactoryArgs { } // GetStateFactoryArgs - -func GetStateFactoryArgs(coreComponents factory.CoreComponentsHolder) stateComp.StateComponentsFactoryArgs { +func GetStateFactoryArgs(coreComponents factory.CoreComponentsHolder, statusCoreComp factory.StatusCoreComponentsHolder) stateComp.StateComponentsFactoryArgs { tsm, _ := trie.NewTrieStorageManager(storage.GetStorageManagerArgs()) storageManagerUser, _ := trie.NewTrieStorageManagerWithoutPruning(tsm) tsm, _ = trie.NewTrieStorageManager(storage.GetStorageManagerArgs()) @@ -344,7 +344,7 @@ func GetStateFactoryArgs(coreComponents factory.CoreComponentsHolder) stateComp. stateComponentsFactoryArgs := stateComp.StateComponentsFactoryArgs{ Config: GetGeneralConfig(), Core: coreComponents, - StatusCore: GetStatusCoreComponents(), + StatusCore: statusCoreComp, StorageService: disabled.NewChainStorer(), ProcessingMode: common.Normal, ChainHandler: &testscommon.ChainHandlerStub{}, @@ -359,7 +359,7 @@ func GetProcessComponentsFactoryArgs(shardCoordinator sharding.Coordinator) proc cryptoComponents := GetCryptoComponents(coreComponents) networkComponents := GetNetworkComponents(cryptoComponents) dataComponents := GetDataComponents(coreComponents, shardCoordinator) - stateComponents := GetStateComponents(coreComponents) + stateComponents := GetStateComponents(coreComponents, GetStatusCoreComponents()) processArgs := GetProcessArgs( shardCoordinator, coreComponents, @@ -626,7 +626,7 @@ func GetStatusComponentsFactoryArgsAndProcessComponents(shardCoordinator shardin cryptoComponents := GetCryptoComponents(coreComponents) networkComponents := GetNetworkComponents(cryptoComponents) dataComponents := GetDataComponents(coreComponents, shardCoordinator) - stateComponents := GetStateComponents(coreComponents) + stateComponents := GetStateComponents(coreComponents, GetStatusCoreComponents()) processComponents := GetProcessComponents( shardCoordinator, coreComponents, @@ -718,22 +718,22 @@ func GetCryptoComponents(coreComponents factory.CoreComponentsHolder) factory.Cr } // GetStateComponents - -func GetStateComponents(coreComponents factory.CoreComponentsHolder) factory.StateComponentsHolder { - stateArgs := GetStateFactoryArgs(coreComponents) +func GetStateComponents(coreComponents factory.CoreComponentsHolder, statusCoreComponents factory.StatusCoreComponentsHolder) factory.StateComponentsHolder { + stateArgs := GetStateFactoryArgs(coreComponents, statusCoreComponents) stateComponentsFactory, err := stateComp.NewStateComponentsFactory(stateArgs) if err != nil { - log.Error("getStateComponents NewStateComponentsFactory", "error", err.Error()) + log.Error("GetStateComponents NewStateComponentsFactory", "error", err.Error()) return nil } stateComponents, err := stateComp.NewManagedStateComponents(stateComponentsFactory) if err != nil { - log.Error("getStateComponents NewManagedStateComponents", "error", err.Error()) + log.Error("GetStateComponents NewManagedStateComponents", "error", err.Error()) return nil } err = stateComponents.Create() if err != nil { - log.Error("getStateComponents Create", "error", err.Error()) + log.Error("GetStateComponents Create", "error", err.Error()) return nil } return stateComponents @@ -756,7 +756,7 @@ func GetStatusCoreComponents() factory.StatusCoreComponentsHolder { err = statusCoreComponents.Create() if err != nil { - log.Error("statusCoreComponents Create", "error", err.Error()) + log.Error("GetStatusCoreComponents Create", "error", err.Error()) return nil } From 5bc4c4dacd289767da624134429d84b9204c8df3 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Thu, 22 Feb 2024 12:51:14 +0200 Subject: [PATCH 871/958] fixes after review - refactor + update misleading comments --- .../staking/stakeAndUnStake_test.go | 163 +++++------------- 1 file changed, 46 insertions(+), 117 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 61383690eae..89cc3fb19ea 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -600,20 +600,7 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.Nil(t, err) log.Info("Step 1. Check the stake amount for the owner of the staked nodes") - scQuery := &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getTotalStaked", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) - - expectedStaked := big.NewInt(5000) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 5000) log.Info("Step 2. Create from the owner of the staked nodes a tx to stake 1 EGLD") @@ -628,20 +615,30 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.Nil(t, err) log.Info("Step 3. Check the stake amount for the owner of the staked nodes") - scQuery = &process.SCQuery{ + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 5001) +} + +func checkExpectedStakedValue(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte, expectedValue int64) { + totalStaked := getTotalStaked(t, metachainNode, blsKey) + + expectedStaked := big.NewInt(expectedValue) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(totalStaked)) +} + +func getTotalStaked(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) []byte { + scQuery := &process.SCQuery{ ScAddress: vm.ValidatorSCAddress, FuncName: "getTotalStaked", CallerAddr: vm.ValidatorSCAddress, CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, + Arguments: [][]byte{blsKey}, } - result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) require.Nil(t, err) require.Equal(t, okReturnCode, result.ReturnCode) - expectedStaked = big.NewInt(5001) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + return result.ReturnData[0] } // Test description: @@ -661,7 +658,7 @@ func TestChainSimulator_DirectStakingNodes_UnstakeFundsWithDeactivation(t *testi // Test Steps // 1. Check the stake amount and number of nodes for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance - // 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network + // 2. Create from the owner of staked nodes a transaction to unstake 10 EGLD and send it to the network // 3. Check the outcome of the TX & verify new stake state with vmquery "getTotalStaked" and "getUnStakedTokensList" // 4. Wait for change of epoch and check the outcome @@ -828,22 +825,9 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs testBLSKeyStaked(t, cs, metachainNode, blsKeys[1], targetEpoch) log.Info("Step 1. Check the stake amount for the owner of the staked nodes") - scQuery := &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getTotalStaked", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) - - expectedStaked := big.NewInt(5000) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 5000) - log.Info("Step 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network") + log.Info("Step 2. Create from the owner of staked nodes a transaction to unstake 10 EGLD and send it to the network") unStakeValue := big.NewInt(10) unStakeValue = unStakeValue.Mul(oneEGLD, unStakeValue) @@ -857,41 +841,34 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs require.Nil(t, err) log.Info("Step 3. Check the outcome of the TX & verify new stake state with vmquery getTotalStaked and getUnStakedTokensList") - scQuery = &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getTotalStaked", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 4990) + + unStakedTokensAmount := getUnStakedTokensList(t, metachainNode, validatorOwner.Bytes) + + expectedUnStaked := big.NewInt(10) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(unStakedTokensAmount).String()) + + log.Info("Step 4. Wait for change of epoch and check the outcome") + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) - expectedStaked = big.NewInt(4990) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + checkOneOfTheNodesIsUnstaked(t, metachainNode, blsKeys[:2]) +} - scQuery = &process.SCQuery{ +func getUnStakedTokensList(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, blsKey []byte) []byte { + scQuery := &process.SCQuery{ ScAddress: vm.ValidatorSCAddress, FuncName: "getUnStakedTokensList", CallerAddr: vm.ValidatorSCAddress, CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, + Arguments: [][]byte{blsKey}, } - result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) require.Nil(t, err) require.Equal(t, okReturnCode, result.ReturnCode) - expectedUnStaked := big.NewInt(10) - expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) - require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) - - log.Info("Step 4. Wait for change of epoch and check the outcome") - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) - require.Nil(t, err) - - checkOneOfTheNodesIsUnstaked(t, metachainNode, blsKeys[:2]) + return result.ReturnData[0] } func checkOneOfTheNodesIsUnstaked(t *testing.T, @@ -954,9 +931,9 @@ func TestChainSimulator_DirectStakingNodes_UnstakeFundsWithDeactivation_WithReac // Test Steps // 1. Check the stake amount and number of nodes for the owner of the staked nodes with the vmquery "getTotalStaked", and the account current EGLD balance - // 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network + // 2. Create from the owner of staked nodes a transaction to unstake 10 EGLD and send it to the network // 3. Check the outcome of the TX & verify new stake state with vmquery - // 4. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network + // 4. Create from the owner of staked nodes a transaction to stake 10 EGLD and send it to the network // 5. Check the outcome of the TX & verify new stake state with vmquery // 6. Wait for change of epoch and check the outcome @@ -1123,22 +1100,9 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t testBLSKeyStaked(t, cs, metachainNode, blsKeys[1], targetEpoch) log.Info("Step 1. Check the stake amount for the owner of the staked nodes") - scQuery := &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getTotalStaked", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) - - expectedStaked := big.NewInt(5000) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 5000) - log.Info("Step 2. Create from the owner of staked nodes a transaction to unstake 1 EGLD and send it to the network") + log.Info("Step 2. Create from the owner of staked nodes a transaction to unstake 10 EGLD and send it to the network") unStakeValue := big.NewInt(10) unStakeValue = unStakeValue.Mul(oneEGLD, unStakeValue) @@ -1152,37 +1116,15 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t require.Nil(t, err) log.Info("Step 3. Check the outcome of the TX & verify new stake state with vmquery getTotalStaked and getUnStakedTokensList") - scQuery = &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getTotalStaked", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 4990) - expectedStaked = big.NewInt(4990) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) - - scQuery = &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getUnStakedTokensList", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) + unStakedTokensAmount := getUnStakedTokensList(t, metachainNode, validatorOwner.Bytes) expectedUnStaked := big.NewInt(10) expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) - require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(unStakedTokensAmount).String()) - log.Info("Step 4. Create from the owner of staked nodes a transaction to stake 1 EGLD and send it to the network") + log.Info("Step 4. Create from the owner of staked nodes a transaction to stake 10 EGLD and send it to the network") newStakeValue := big.NewInt(10) newStakeValue = newStakeValue.Mul(oneEGLD, newStakeValue) @@ -1196,20 +1138,7 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t require.Nil(t, err) log.Info("5. Check the outcome of the TX & verify new stake state with vmquery") - scQuery = &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getTotalStaked", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{validatorOwner.Bytes}, - } - result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) - - expectedStaked = big.NewInt(5000) - expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) - require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + checkExpectedStakedValue(t, metachainNode, validatorOwner.Bytes, 5000) log.Info("Step 6. Wait for change of epoch and check the outcome") err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) From b0bdc7aeffe01eab7479581705029ceb28a69e21 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 22 Feb 2024 13:37:51 +0200 Subject: [PATCH 872/958] skip some tests with `cannot run with -race -short; requires Wasm VM fix` --- .../components/processComponents_test.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/components/processComponents_test.go b/node/chainSimulator/components/processComponents_test.go index 3d261a796e7..0599ca82538 100644 --- a/node/chainSimulator/components/processComponents_test.go +++ b/node/chainSimulator/components/processComponents_test.go @@ -56,7 +56,6 @@ var ( ) func createArgsProcessComponentsHolder() ArgsProcessComponentsHolder { - //cnt := uint32(0) nodesSetup, _ := sharding.NewNodesSetup("../../../integrationTests/factory/testdata/nodesSetup.json", addrPubKeyConv, valPubKeyConv, 3) args := ArgsProcessComponentsHolder{ @@ -232,6 +231,11 @@ func TestCreateProcessComponents(t *testing.T) { t.Parallel() t.Run("should work", func(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() comp, err := CreateProcessComponents(createArgsProcessComponentsHolder()) @@ -339,6 +343,11 @@ func TestCreateProcessComponents(t *testing.T) { } func TestProcessComponentsHolder_IsInterfaceNil(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() var comp *processComponentsHolder @@ -350,6 +359,11 @@ func TestProcessComponentsHolder_IsInterfaceNil(t *testing.T) { } func TestProcessComponentsHolder_Getters(t *testing.T) { + // TODO reinstate test after Wasm VM pointer fix + if testing.Short() { + t.Skip("cannot run with -race -short; requires Wasm VM fix") + } + t.Parallel() comp, err := CreateProcessComponents(createArgsProcessComponentsHolder()) From d3111de6fe782293eb2b55577b808bddbee4654c Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 22 Feb 2024 16:29:50 +0200 Subject: [PATCH 873/958] more chain simulator tests --- .../components/api/fixedAPIInterface_test.go | 20 +++ .../components/api/freeAPIInterface_test.go | 19 +++ .../components/api/noApiInterface_test.go | 18 +++ .../components/stateComponents.go | 2 +- .../components/stateComponents_test.go | 99 +++++++++++++ .../components/statusComponents.go | 3 +- .../components/statusComponents_test.go | 133 ++++++++++++++++++ .../components/statusCoreComponents.go | 2 +- .../components/statusCoreComponents_test.go | 112 +++++++++++++++ .../components/storageService_test.go | 51 +++++++ testscommon/generalConfig.go | 3 + 11 files changed, 458 insertions(+), 4 deletions(-) create mode 100644 node/chainSimulator/components/api/fixedAPIInterface_test.go create mode 100644 node/chainSimulator/components/api/freeAPIInterface_test.go create mode 100644 node/chainSimulator/components/api/noApiInterface_test.go create mode 100644 node/chainSimulator/components/stateComponents_test.go create mode 100644 node/chainSimulator/components/statusComponents_test.go create mode 100644 node/chainSimulator/components/statusCoreComponents_test.go create mode 100644 node/chainSimulator/components/storageService_test.go diff --git a/node/chainSimulator/components/api/fixedAPIInterface_test.go b/node/chainSimulator/components/api/fixedAPIInterface_test.go new file mode 100644 index 00000000000..7348b717831 --- /dev/null +++ b/node/chainSimulator/components/api/fixedAPIInterface_test.go @@ -0,0 +1,20 @@ +package api + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +const apiInterface = "127.0.0.1:8080" + +func TestNewFixedPortAPIConfigurator(t *testing.T) { + t.Parallel() + + instance := NewFixedPortAPIConfigurator(apiInterface, map[uint32]int{0: 123}) + require.NotNil(t, instance) + + interf := instance.RestApiInterface(0) + require.Equal(t, fmt.Sprintf("%s:123", apiInterface), interf) +} diff --git a/node/chainSimulator/components/api/freeAPIInterface_test.go b/node/chainSimulator/components/api/freeAPIInterface_test.go new file mode 100644 index 00000000000..0b215aa0a57 --- /dev/null +++ b/node/chainSimulator/components/api/freeAPIInterface_test.go @@ -0,0 +1,19 @@ +package api + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewFreePortAPIConfigurator(t *testing.T) { + t.Parallel() + + instance := NewFreePortAPIConfigurator(apiInterface) + require.NotNil(t, instance) + + interf := instance.RestApiInterface(0) + require.True(t, strings.Contains(interf, fmt.Sprintf("%s:", apiInterface))) +} diff --git a/node/chainSimulator/components/api/noApiInterface_test.go b/node/chainSimulator/components/api/noApiInterface_test.go new file mode 100644 index 00000000000..ee8efbc5783 --- /dev/null +++ b/node/chainSimulator/components/api/noApiInterface_test.go @@ -0,0 +1,18 @@ +package api + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/facade" + "github.com/stretchr/testify/require" +) + +func TestNewNoApiInterface(t *testing.T) { + t.Parallel() + + instance := NewNoApiInterface() + require.NotNil(t, instance) + + interf := instance.RestApiInterface(0) + require.Equal(t, facade.DefaultRestPortOff, interf) +} diff --git a/node/chainSimulator/components/stateComponents.go b/node/chainSimulator/components/stateComponents.go index 65a1a064fe7..11fdbaa330b 100644 --- a/node/chainSimulator/components/stateComponents.go +++ b/node/chainSimulator/components/stateComponents.go @@ -31,7 +31,7 @@ type stateComponentsHolder struct { } // CreateStateComponents will create the state components holder -func CreateStateComponents(args ArgsStateComponents) (factory.StateComponentsHandler, error) { +func CreateStateComponents(args ArgsStateComponents) (*stateComponentsHolder, error) { stateComponentsFactory, err := factoryState.NewStateComponentsFactory(factoryState.StateComponentsFactoryArgs{ Config: args.Config, Core: args.CoreComponents, diff --git a/node/chainSimulator/components/stateComponents_test.go b/node/chainSimulator/components/stateComponents_test.go new file mode 100644 index 00000000000..5422d2ea352 --- /dev/null +++ b/node/chainSimulator/components/stateComponents_test.go @@ -0,0 +1,99 @@ +package components + +import ( + "testing" + + disabledStatistics "github.com/multiversx/mx-chain-go/common/statistics/disabled" + mockFactory "github.com/multiversx/mx-chain-go/factory/mock" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" + "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/genericMocks" + "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/stretchr/testify/require" +) + +func createArgsStateComponents() ArgsStateComponents { + return ArgsStateComponents{ + Config: testscommon.GetGeneralConfig(), + CoreComponents: &mockFactory.CoreComponentsMock{ + IntMarsh: &testscommon.MarshallerStub{}, + Hash: &testscommon.HasherStub{}, + PathHdl: &testscommon.PathManagerStub{}, + ProcessStatusHandlerInternal: &testscommon.ProcessStatusHandlerStub{}, + EnableEpochsHandlerField: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + AddrPubKeyConv: &testscommon.PubkeyConverterStub{}, + }, + StatusCore: &factory.StatusCoreComponentsStub{ + AppStatusHandlerField: &statusHandler.AppStatusHandlerStub{}, + StateStatsHandlerField: disabledStatistics.NewStateStatistics(), + }, + StoreService: genericMocks.NewChainStorerMock(0), + ChainHandler: &testscommon.ChainHandlerStub{}, + } +} + +func TestCreateStateComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateStateComponents(createArgsStateComponents()) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("NewStateComponentsFactory failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsStateComponents() + args.CoreComponents = nil + comp, err := CreateStateComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("stateComp.Create failure should error", func(t *testing.T) { + t.Parallel() + + args := createArgsStateComponents() + coreMock, ok := args.CoreComponents.(*mockFactory.CoreComponentsMock) + require.True(t, ok) + coreMock.EnableEpochsHandlerField = nil + comp, err := CreateStateComponents(args) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestStateComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *stateComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateStateComponents(createArgsStateComponents()) + require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) +} + +func TestStateComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + comp, err := CreateStateComponents(createArgsStateComponents()) + require.NoError(t, err) + + require.NotNil(t, comp.PeerAccounts()) + require.NotNil(t, comp.AccountsAdapter()) + require.NotNil(t, comp.AccountsAdapterAPI()) + require.NotNil(t, comp.AccountsRepository()) + require.NotNil(t, comp.TriesContainer()) + require.NotNil(t, comp.TrieStorageManagers()) + require.NotNil(t, comp.MissingTrieNodesNotifier()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) + + require.Nil(t, comp.Close()) +} diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index 9aef2ea484b..65f9dbb7667 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -13,7 +13,6 @@ import ( "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/common/statistics" "github.com/multiversx/mx-chain-go/errors" - "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/outport" "github.com/multiversx/mx-chain-go/process" @@ -33,7 +32,7 @@ type statusComponentsHolder struct { } // CreateStatusComponents will create a new instance of status components holder -func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandler, statusPollingIntervalSec int) (factory.StatusComponentsHandler, error) { +func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandler, statusPollingIntervalSec int) (*statusComponentsHolder, error) { if check.IfNil(appStatusHandler) { return nil, core.ErrNilAppStatusHandler } diff --git a/node/chainSimulator/components/statusComponents_test.go b/node/chainSimulator/components/statusComponents_test.go new file mode 100644 index 00000000000..ad8bee9cea1 --- /dev/null +++ b/node/chainSimulator/components/statusComponents_test.go @@ -0,0 +1,133 @@ +package components + +import ( + "testing" + "time" + + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/stretchr/testify/require" +) + +func TestCreateStatusComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + comp, err := CreateStatusComponents(0, &statusHandler.AppStatusHandlerStub{}, 5) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("nil app status handler should error", func(t *testing.T) { + t.Parallel() + + comp, err := CreateStatusComponents(0, nil, 5) + require.Equal(t, core.ErrNilAppStatusHandler, err) + require.Nil(t, comp) + }) +} + +func TestStatusComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *statusComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + comp, _ = CreateStatusComponents(0, &statusHandler.AppStatusHandlerStub{}, 5) + require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) +} + +func TestStatusComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + comp, err := CreateStatusComponents(0, &statusHandler.AppStatusHandlerStub{}, 5) + require.NoError(t, err) + + require.NotNil(t, comp.OutportHandler()) + require.NotNil(t, comp.SoftwareVersionChecker()) + require.NotNil(t, comp.ManagedPeersMonitor()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) + + require.Nil(t, comp.Close()) +} +func TestStatusComponentsHolder_SetForkDetector(t *testing.T) { + t.Parallel() + + comp, err := CreateStatusComponents(0, &statusHandler.AppStatusHandlerStub{}, 5) + require.NoError(t, err) + + err = comp.SetForkDetector(nil) + require.Equal(t, process.ErrNilForkDetector, err) + + err = comp.SetForkDetector(&mock.ForkDetectorStub{}) + require.NoError(t, err) + + require.Nil(t, comp.Close()) +} + +func TestStatusComponentsHolder_StartPolling(t *testing.T) { + t.Parallel() + + t.Run("nil fork detector should error", func(t *testing.T) { + t.Parallel() + + comp, err := CreateStatusComponents(0, &statusHandler.AppStatusHandlerStub{}, 5) + require.NoError(t, err) + + err = comp.StartPolling() + require.Equal(t, process.ErrNilForkDetector, err) + }) + t.Run("NewAppStatusPolling failure should error", func(t *testing.T) { + t.Parallel() + + comp, err := CreateStatusComponents(0, &statusHandler.AppStatusHandlerStub{}, 0) + require.NoError(t, err) + + err = comp.SetForkDetector(&mock.ForkDetectorStub{}) + require.NoError(t, err) + + err = comp.StartPolling() + require.Error(t, err) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + providedHighestNonce := uint64(123) + providedStatusPollingIntervalSec := 1 + wasSetUInt64ValueCalled := false + appStatusHandler := &statusHandler.AppStatusHandlerStub{ + SetUInt64ValueHandler: func(key string, value uint64) { + require.Equal(t, common.MetricProbableHighestNonce, key) + require.Equal(t, providedHighestNonce, value) + wasSetUInt64ValueCalled = true + }, + } + comp, err := CreateStatusComponents(0, appStatusHandler, providedStatusPollingIntervalSec) + require.NoError(t, err) + + forkDetector := &mock.ForkDetectorStub{ + ProbableHighestNonceCalled: func() uint64 { + return providedHighestNonce + }, + } + err = comp.SetForkDetector(forkDetector) + require.NoError(t, err) + + err = comp.StartPolling() + require.NoError(t, err) + + time.Sleep(time.Duration(providedStatusPollingIntervalSec+1) * time.Second) + require.True(t, wasSetUInt64ValueCalled) + + require.Nil(t, comp.Close()) + }) +} diff --git a/node/chainSimulator/components/statusCoreComponents.go b/node/chainSimulator/components/statusCoreComponents.go index 47428f14a95..08b83cde29d 100644 --- a/node/chainSimulator/components/statusCoreComponents.go +++ b/node/chainSimulator/components/statusCoreComponents.go @@ -21,7 +21,7 @@ type statusCoreComponentsHolder struct { } // CreateStatusCoreComponents will create a new instance of factory.StatusCoreComponentsHandler -func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.CoreComponentsHolder) (factory.StatusCoreComponentsHandler, error) { +func CreateStatusCoreComponents(configs config.Configs, coreComponents factory.CoreComponentsHolder) (*statusCoreComponentsHolder, error) { var err error statusCoreComponentsFactory, err := statusCore.NewStatusCoreComponentsFactory(statusCore.StatusCoreComponentsFactoryArgs{ diff --git a/node/chainSimulator/components/statusCoreComponents_test.go b/node/chainSimulator/components/statusCoreComponents_test.go new file mode 100644 index 00000000000..6bb40d9db94 --- /dev/null +++ b/node/chainSimulator/components/statusCoreComponents_test.go @@ -0,0 +1,112 @@ +package components + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/factory/mock" + mockTests "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/components" + "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/stretchr/testify/require" +) + +func createArgs() (config.Configs, factory.CoreComponentsHolder) { + generalCfg := testscommon.GetGeneralConfig() + ratingsCfg := components.CreateDummyRatingsConfig() + economicsCfg := components.CreateDummyEconomicsConfig() + cfg := config.Configs{ + GeneralConfig: &generalCfg, + EpochConfig: &config.EpochConfig{ + GasSchedule: config.GasScheduleConfig{ + GasScheduleByEpochs: []config.GasScheduleByEpochs{ + { + StartEpoch: 0, + FileName: "gasScheduleV1.toml", + }, + }, + }, + }, + RoundConfig: &config.RoundConfig{ + RoundActivations: map[string]config.ActivationRoundByName{ + "Example": { + Round: "18446744073709551615", + }, + }, + }, + RatingsConfig: &ratingsCfg, + EconomicsConfig: &economicsCfg, + } + + return cfg, &mock.CoreComponentsMock{ + EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, + IntMarsh: &testscommon.MarshallerStub{}, + UInt64ByteSliceConv: &mockTests.Uint64ByteSliceConverterMock{}, + NodesConfig: &testscommon.NodesSetupStub{}, + } +} + +func TestCreateStatusCoreComponents(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + cfg, coreComp := createArgs() + comp, err := CreateStatusCoreComponents(cfg, coreComp) + require.NoError(t, err) + require.NotNil(t, comp) + + require.Nil(t, comp.Create()) + require.Nil(t, comp.Close()) + }) + t.Run("NewStatusCoreComponentsFactory failure should error", func(t *testing.T) { + t.Parallel() + + cfg, _ := createArgs() + comp, err := CreateStatusCoreComponents(cfg, nil) + require.Error(t, err) + require.Nil(t, comp) + }) + t.Run("managedStatusCoreComponents.Create failure should error", func(t *testing.T) { + t.Parallel() + + cfg, coreComp := createArgs() + cfg.GeneralConfig.ResourceStats.RefreshIntervalInSec = 0 + comp, err := CreateStatusCoreComponents(cfg, coreComp) + require.Error(t, err) + require.Nil(t, comp) + }) +} + +func TestStatusCoreComponentsHolder_IsInterfaceNil(t *testing.T) { + t.Parallel() + + var comp *statusCoreComponentsHolder + require.True(t, comp.IsInterfaceNil()) + + cfg, coreComp := createArgs() + comp, _ = CreateStatusCoreComponents(cfg, coreComp) + require.False(t, comp.IsInterfaceNil()) + require.Nil(t, comp.Close()) +} + +func TestStatusCoreComponentsHolder_Getters(t *testing.T) { + t.Parallel() + + cfg, coreComp := createArgs() + comp, err := CreateStatusCoreComponents(cfg, coreComp) + require.NoError(t, err) + + require.NotNil(t, comp.ResourceMonitor()) + require.NotNil(t, comp.NetworkStatistics()) + require.NotNil(t, comp.TrieSyncStatistics()) + require.NotNil(t, comp.AppStatusHandler()) + require.NotNil(t, comp.StatusMetrics()) + require.NotNil(t, comp.PersistentStatusHandler()) + require.NotNil(t, comp.StateStatsHandler()) + require.Nil(t, comp.CheckSubcomponents()) + require.Empty(t, comp.String()) +} diff --git a/node/chainSimulator/components/storageService_test.go b/node/chainSimulator/components/storageService_test.go new file mode 100644 index 00000000000..3be398b53e6 --- /dev/null +++ b/node/chainSimulator/components/storageService_test.go @@ -0,0 +1,51 @@ +package components + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/dataRetriever" + "github.com/stretchr/testify/require" +) + +func TestCreateStore(t *testing.T) { + t.Parallel() + + store := CreateStore(2) + require.NotNil(t, store) + + expectedUnits := []dataRetriever.UnitType{ + dataRetriever.TransactionUnit, + dataRetriever.MiniBlockUnit, + dataRetriever.MetaBlockUnit, + dataRetriever.PeerChangesUnit, + dataRetriever.BlockHeaderUnit, + dataRetriever.UnsignedTransactionUnit, + dataRetriever.RewardTransactionUnit, + dataRetriever.MetaHdrNonceHashDataUnit, + dataRetriever.BootstrapUnit, + dataRetriever.StatusMetricsUnit, + dataRetriever.ReceiptsUnit, + dataRetriever.ScheduledSCRsUnit, + dataRetriever.TxLogsUnit, + dataRetriever.UserAccountsUnit, + dataRetriever.PeerAccountsUnit, + dataRetriever.ESDTSuppliesUnit, + dataRetriever.RoundHdrHashDataUnit, + dataRetriever.MiniblocksMetadataUnit, + dataRetriever.MiniblockHashByTxHashUnit, + dataRetriever.EpochByHashUnit, + dataRetriever.ResultsHashesByTxHashUnit, + dataRetriever.TrieEpochRootHashUnit, + dataRetriever.ShardHdrNonceHashDataUnit, + dataRetriever.UnitType(101), // shard 2 + } + + all := store.GetAllStorers() + require.Equal(t, len(expectedUnits), len(all)) + + for i := 0; i < len(expectedUnits); i++ { + unit, err := store.GetStorer(expectedUnits[i]) + require.NoError(t, err) + require.NotNil(t, unit) + } +} diff --git a/testscommon/generalConfig.go b/testscommon/generalConfig.go index 111233effef..06814edb1f5 100644 --- a/testscommon/generalConfig.go +++ b/testscommon/generalConfig.go @@ -416,6 +416,9 @@ func GetGeneralConfig() config.Config { "erd1najnxxweyw6plhg8efql330nttrj6l5cf87wqsuym85s9ha0hmdqnqgenp", //shard 2 }, }, + ResourceStats: config.ResourceStatsConfig{ + RefreshIntervalInSec: 1, + }, } } From 7446804bf930d5f09d003d2d6f22ebe556c62201 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 22 Feb 2024 16:49:35 +0200 Subject: [PATCH 874/958] closeHandler tests --- .../components/closeHandler_test.go | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 node/chainSimulator/components/closeHandler_test.go diff --git a/node/chainSimulator/components/closeHandler_test.go b/node/chainSimulator/components/closeHandler_test.go new file mode 100644 index 00000000000..f8a88576c3c --- /dev/null +++ b/node/chainSimulator/components/closeHandler_test.go @@ -0,0 +1,69 @@ +package components + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +// localErrorlessCloser implements errorlessCloser interface +type localErrorlessCloser struct { + wasCalled bool +} + +// Close - +func (closer *localErrorlessCloser) Close() { + closer.wasCalled = true +} + +// localCloser implements io.Closer interface +type localCloser struct { + wasCalled bool + expectedError error +} + +// Close - +func (closer *localCloser) Close() error { + closer.wasCalled = true + return closer.expectedError +} + +// localCloseAllHandler implements allCloser interface +type localCloseAllHandler struct { + wasCalled bool + expectedError error +} + +// CloseAll - +func (closer *localCloseAllHandler) CloseAll() error { + closer.wasCalled = true + return closer.expectedError +} + +func TestCloseHandler(t *testing.T) { + t.Parallel() + + handler := NewCloseHandler() + require.NotNil(t, handler) + + handler.AddComponent(nil) // for coverage only + + lec := &localErrorlessCloser{} + handler.AddComponent(lec) + + lcNoError := &localCloser{} + handler.AddComponent(lcNoError) + + lcWithError := &localCloser{expectedError: expectedErr} + handler.AddComponent(lcWithError) + + lcahNoError := &localCloseAllHandler{} + handler.AddComponent(lcahNoError) + + lcahWithError := &localCloseAllHandler{expectedError: expectedErr} + handler.AddComponent(lcahWithError) + + err := handler.Close() + require.True(t, strings.Contains(err.Error(), expectedErr.Error())) +} From 141ebb660dea1af5f242275288d3657a7a6d1770 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 22 Feb 2024 17:07:08 +0200 Subject: [PATCH 875/958] facade tests --- node/chainSimulator/facade_test.go | 193 ++++++++++++++++++ .../chainSimulator/chainSimulatorMock.go | 21 ++ 2 files changed, 214 insertions(+) create mode 100644 node/chainSimulator/facade_test.go create mode 100644 testscommon/chainSimulator/chainSimulatorMock.go diff --git a/node/chainSimulator/facade_test.go b/node/chainSimulator/facade_test.go new file mode 100644 index 00000000000..908704c05a0 --- /dev/null +++ b/node/chainSimulator/facade_test.go @@ -0,0 +1,193 @@ +package chainSimulator + +import ( + "errors" + "testing" + + "github.com/multiversx/mx-chain-go/common" + "github.com/multiversx/mx-chain-go/factory" + factoryMock "github.com/multiversx/mx-chain-go/factory/mock" + "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/state" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/chainSimulator" + stateMock "github.com/multiversx/mx-chain-go/testscommon/state" + "github.com/multiversx/mx-chain-go/testscommon/vmcommonMocks" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/require" +) + +var expectedErr = errors.New("expected error") + +func TestNewChainSimulatorFacade(t *testing.T) { + t.Parallel() + + t.Run("should work", func(t *testing.T) { + t.Parallel() + + facade, err := NewChainSimulatorFacade(&chainSimulator.ChainSimulatorMock{ + GetNodeHandlerCalled: func(shardID uint32) process.NodeHandler { + return &chainSimulator.NodeHandlerMock{} + }, + }) + require.NoError(t, err) + require.NotNil(t, facade) + }) + t.Run("nil chain simulator should error", func(t *testing.T) { + t.Parallel() + + facade, err := NewChainSimulatorFacade(nil) + require.Equal(t, errNilChainSimulator, err) + require.Nil(t, facade) + }) + t.Run("nil node handler returned by chain simulator should error", func(t *testing.T) { + t.Parallel() + + facade, err := NewChainSimulatorFacade(&chainSimulator.ChainSimulatorMock{ + GetNodeHandlerCalled: func(shardID uint32) process.NodeHandler { + return nil + }, + }) + require.Equal(t, errNilMetachainNode, err) + require.Nil(t, facade) + }) +} + +func TestChainSimulatorFacade_GetExistingAccountFromBech32AddressString(t *testing.T) { + t.Parallel() + + t.Run("address decode failure should error", func(t *testing.T) { + t.Parallel() + + facade, err := NewChainSimulatorFacade(&chainSimulator.ChainSimulatorMock{ + GetNodeHandlerCalled: func(shardID uint32) process.NodeHandler { + return &chainSimulator.NodeHandlerMock{ + GetCoreComponentsCalled: func() factory.CoreComponentsHolder { + return &mock.CoreComponentsStub{ + AddressPubKeyConverterField: &testscommon.PubkeyConverterStub{ + DecodeCalled: func(humanReadable string) ([]byte, error) { + return nil, expectedErr + }, + }, + } + }, + } + }, + }) + require.NoError(t, err) + + handler, err := facade.GetExistingAccountFromBech32AddressString("address") + require.Equal(t, expectedErr, err) + require.Nil(t, handler) + }) + t.Run("nil shard node should error", func(t *testing.T) { + t.Parallel() + + facade, err := NewChainSimulatorFacade(&chainSimulator.ChainSimulatorMock{ + GetNodeHandlerCalled: func(shardID uint32) process.NodeHandler { + if shardID != common.MetachainShardId { + return nil + } + + return &chainSimulator.NodeHandlerMock{ + GetCoreComponentsCalled: func() factory.CoreComponentsHolder { + return &mock.CoreComponentsStub{ + AddressPubKeyConverterField: &testscommon.PubkeyConverterStub{}, + } + }, + GetShardCoordinatorCalled: func() sharding.Coordinator { + return &testscommon.ShardsCoordinatorMock{ + ComputeIdCalled: func(address []byte) uint32 { + return 0 + }, + } + }, + } + }, + }) + require.NoError(t, err) + + handler, err := facade.GetExistingAccountFromBech32AddressString("address") + require.True(t, errors.Is(err, errShardSetupError)) + require.Nil(t, handler) + }) + t.Run("shard node GetExistingAccount should error", func(t *testing.T) { + t.Parallel() + + facade, err := NewChainSimulatorFacade(&chainSimulator.ChainSimulatorMock{ + GetNodeHandlerCalled: func(shardID uint32) process.NodeHandler { + return &chainSimulator.NodeHandlerMock{ + GetCoreComponentsCalled: func() factory.CoreComponentsHolder { + return &mock.CoreComponentsStub{ + AddressPubKeyConverterField: &testscommon.PubkeyConverterStub{}, + } + }, + GetShardCoordinatorCalled: func() sharding.Coordinator { + return &testscommon.ShardsCoordinatorMock{ + ComputeIdCalled: func(address []byte) uint32 { + return 0 + }, + } + }, + GetStateComponentsCalled: func() factory.StateComponentsHolder { + return &factoryMock.StateComponentsHolderStub{ + AccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMock.AccountsStub{ + GetExistingAccountCalled: func(addressContainer []byte) (vmcommon.AccountHandler, error) { + return nil, expectedErr + }, + } + }, + } + }, + } + }, + }) + require.NoError(t, err) + + handler, err := facade.GetExistingAccountFromBech32AddressString("address") + require.Equal(t, expectedErr, err) + require.Nil(t, handler) + }) + t.Run("should work", func(t *testing.T) { + t.Parallel() + + providedAccount := &vmcommonMocks.UserAccountStub{} + facade, err := NewChainSimulatorFacade(&chainSimulator.ChainSimulatorMock{ + GetNodeHandlerCalled: func(shardID uint32) process.NodeHandler { + return &chainSimulator.NodeHandlerMock{ + GetCoreComponentsCalled: func() factory.CoreComponentsHolder { + return &mock.CoreComponentsStub{ + AddressPubKeyConverterField: &testscommon.PubkeyConverterStub{}, + } + }, + GetShardCoordinatorCalled: func() sharding.Coordinator { + return &testscommon.ShardsCoordinatorMock{ + ComputeIdCalled: func(address []byte) uint32 { + return 0 + }, + } + }, + GetStateComponentsCalled: func() factory.StateComponentsHolder { + return &factoryMock.StateComponentsHolderStub{ + AccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMock.AccountsStub{ + GetExistingAccountCalled: func(addressContainer []byte) (vmcommon.AccountHandler, error) { + return providedAccount, nil + }, + } + }, + } + }, + } + }, + }) + require.NoError(t, err) + + handler, err := facade.GetExistingAccountFromBech32AddressString("address") + require.NoError(t, err) + require.True(t, handler == providedAccount) // pointer testing + }) +} diff --git a/testscommon/chainSimulator/chainSimulatorMock.go b/testscommon/chainSimulator/chainSimulatorMock.go new file mode 100644 index 00000000000..5a49de21f05 --- /dev/null +++ b/testscommon/chainSimulator/chainSimulatorMock.go @@ -0,0 +1,21 @@ +package chainSimulator + +import "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + +// ChainSimulatorMock - +type ChainSimulatorMock struct { + GetNodeHandlerCalled func(shardID uint32) process.NodeHandler +} + +// GetNodeHandler - +func (mock *ChainSimulatorMock) GetNodeHandler(shardID uint32) process.NodeHandler { + if mock.GetNodeHandlerCalled != nil { + return mock.GetNodeHandlerCalled(shardID) + } + return nil +} + +// IsInterfaceNil - +func (mock *ChainSimulatorMock) IsInterfaceNil() bool { + return mock == nil +} From 72229cfcd7abedaf6dc81d7d2df3cc67c549d805 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 22 Feb 2024 17:16:55 +0200 Subject: [PATCH 876/958] fix race --- node/chainSimulator/components/statusComponents_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/components/statusComponents_test.go b/node/chainSimulator/components/statusComponents_test.go index ad8bee9cea1..69731c129c6 100644 --- a/node/chainSimulator/components/statusComponents_test.go +++ b/node/chainSimulator/components/statusComponents_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/process" @@ -103,12 +104,12 @@ func TestStatusComponentsHolder_StartPolling(t *testing.T) { providedHighestNonce := uint64(123) providedStatusPollingIntervalSec := 1 - wasSetUInt64ValueCalled := false + wasSetUInt64ValueCalled := atomic.Flag{} appStatusHandler := &statusHandler.AppStatusHandlerStub{ SetUInt64ValueHandler: func(key string, value uint64) { require.Equal(t, common.MetricProbableHighestNonce, key) require.Equal(t, providedHighestNonce, value) - wasSetUInt64ValueCalled = true + wasSetUInt64ValueCalled.SetValue(true) }, } comp, err := CreateStatusComponents(0, appStatusHandler, providedStatusPollingIntervalSec) @@ -126,7 +127,7 @@ func TestStatusComponentsHolder_StartPolling(t *testing.T) { require.NoError(t, err) time.Sleep(time.Duration(providedStatusPollingIntervalSec+1) * time.Second) - require.True(t, wasSetUInt64ValueCalled) + require.True(t, wasSetUInt64ValueCalled.IsSet()) require.Nil(t, comp.Close()) }) From 6b9a082cb5d3e5b768a0c4d40161e8015e1ab0b6 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 23 Feb 2024 10:40:09 +0200 Subject: [PATCH 877/958] fix after review --- node/chainSimulator/components/dataComponents_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/chainSimulator/components/dataComponents_test.go b/node/chainSimulator/components/dataComponents_test.go index d059200ff07..a74f0b751f6 100644 --- a/node/chainSimulator/components/dataComponents_test.go +++ b/node/chainSimulator/components/dataComponents_test.go @@ -41,7 +41,7 @@ func TestCreateDataComponents(t *testing.T) { require.Nil(t, comp.Create()) require.Nil(t, comp.Close()) }) - t.Run("", func(t *testing.T) { + t.Run("NewMiniBlockProvider failure should error", func(t *testing.T) { t.Parallel() args := createArgsDataComponentsHolder() @@ -54,7 +54,7 @@ func TestCreateDataComponents(t *testing.T) { require.Error(t, err) require.Nil(t, comp) }) - t.Run("", func(t *testing.T) { + t.Run("GetStorer failure should error", func(t *testing.T) { t.Parallel() args := createArgsDataComponentsHolder() From e8013b172e7f847eff7543c4ca45594db84746f3 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 23 Feb 2024 11:26:24 +0200 Subject: [PATCH 878/958] fixes after merge --- factory/bootstrap/bootstrapComponents.go | 3 +++ factory/bootstrap/bootstrapComponents_test.go | 14 ++++++++++++++ .../components/bootstrapComponents_test.go | 9 ++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/factory/bootstrap/bootstrapComponents.go b/factory/bootstrap/bootstrapComponents.go index da4b2a0fef4..a9ef7851ccb 100644 --- a/factory/bootstrap/bootstrapComponents.go +++ b/factory/bootstrap/bootstrapComponents.go @@ -72,6 +72,9 @@ func NewBootstrapComponentsFactory(args BootstrapComponentsFactoryArgs) (*bootst if check.IfNil(args.CoreComponents) { return nil, errors.ErrNilCoreComponentsHolder } + if check.IfNil(args.CoreComponents.EnableEpochsHandler()) { + return nil, errors.ErrNilEnableEpochsHandler + } if check.IfNil(args.CryptoComponents) { return nil, errors.ErrNilCryptoComponentsHolder } diff --git a/factory/bootstrap/bootstrapComponents_test.go b/factory/bootstrap/bootstrapComponents_test.go index 0c381df1554..180315b1f36 100644 --- a/factory/bootstrap/bootstrapComponents_test.go +++ b/factory/bootstrap/bootstrapComponents_test.go @@ -8,6 +8,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" errorsMx "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/factory/bootstrap" @@ -38,6 +39,19 @@ func TestNewBootstrapComponentsFactory(t *testing.T) { require.Nil(t, bcf) require.Equal(t, errorsMx.ErrNilCoreComponentsHolder, err) }) + t.Run("nil enable epochs handler should error", func(t *testing.T) { + t.Parallel() + + argsCopy := args + argsCopy.CoreComponents = &factory.CoreComponentsHolderStub{ + EnableEpochsHandlerCalled: func() common.EnableEpochsHandler { + return nil + }, + } + bcf, err := bootstrap.NewBootstrapComponentsFactory(argsCopy) + require.Nil(t, bcf) + require.Equal(t, errorsMx.ErrNilEnableEpochsHandler, err) + }) t.Run("nil crypto components should error", func(t *testing.T) { t.Parallel() diff --git a/node/chainSimulator/components/bootstrapComponents_test.go b/node/chainSimulator/components/bootstrapComponents_test.go index 0bfcc7146af..7e4becdc52e 100644 --- a/node/chainSimulator/components/bootstrapComponents_test.go +++ b/node/chainSimulator/components/bootstrapComponents_test.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data/typeConverters" "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/integrationTests/mock" @@ -17,8 +18,10 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/cryptoMocks" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" "github.com/multiversx/mx-chain-go/testscommon/factory" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/multiversx/mx-chain-go/testscommon/p2pmocks" "github.com/multiversx/mx-chain-go/testscommon/shardingMocks" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" @@ -32,7 +35,7 @@ func createArgsBootstrapComponentsHolder() ArgsBootstrapComponentsHolder { return "T" }, GenesisNodesSetupCalled: func() sharding.GenesisNodesSetupHandler { - return &testscommon.NodesSetupStub{} + return &genesisMocks.NodesSetupStub{} }, InternalMarshalizerCalled: func() marshal.Marshalizer { return &testscommon.MarshallerStub{} @@ -70,6 +73,9 @@ func createArgsBootstrapComponentsHolder() ArgsBootstrapComponentsHolder { TxSignHasherCalled: func() hashing.Hasher { return &testscommon.HasherStub{} }, + EnableEpochsHandlerCalled: func() common.EnableEpochsHandler { + return &enableEpochsHandlerMock.EnableEpochsHandlerStub{} + }, }, CryptoComponents: &mock.CryptoComponentsStub{ PubKey: &mock.PublicKeyMock{}, @@ -187,6 +193,7 @@ func TestBootstrapComponentsHolder_Getters(t *testing.T) { require.NotNil(t, comp.HeaderVersionHandler()) require.NotNil(t, comp.HeaderIntegrityVerifier()) require.NotNil(t, comp.GuardedAccountHandler()) + require.NotNil(t, comp.NodesCoordinatorRegistryFactory()) require.Nil(t, comp.CheckSubcomponents()) require.Empty(t, comp.String()) require.Nil(t, comp.Close()) From 29a112cdc46e39751dc292c83d81c5616fea6639 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 23 Feb 2024 12:02:26 +0200 Subject: [PATCH 879/958] fix chain simulator testst after merge --- .../components/coreComponents_test.go | 32 ++++++++++++++++ .../components/cryptoComponents.go | 37 ++++++++++--------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/node/chainSimulator/components/coreComponents_test.go b/node/chainSimulator/components/coreComponents_test.go index 1f6552aa421..619eb9d3a2e 100644 --- a/node/chainSimulator/components/coreComponents_test.go +++ b/node/chainSimulator/components/coreComponents_test.go @@ -93,6 +93,37 @@ func createArgsCoreComponentsHolder() ArgsCoreComponentsHolder { }, }, }, + RatingConfig: config.RatingsConfig{ + General: config.General{ + StartRating: 4000, + MaxRating: 10000, + MinRating: 1, + SignedBlocksThreshold: 0.025, + SelectionChances: []*config.SelectionChance{ + {MaxThreshold: 0, ChancePercent: 1}, + {MaxThreshold: 1, ChancePercent: 2}, + {MaxThreshold: 10000, ChancePercent: 4}, + }, + }, + ShardChain: config.ShardChain{ + RatingSteps: config.RatingSteps{ + HoursToMaxRatingFromStartRating: 2, + ProposerValidatorImportance: 1, + ProposerDecreaseFactor: -4, + ValidatorDecreaseFactor: -4, + ConsecutiveMissedBlocksPenalty: 1.2, + }, + }, + MetaChain: config.MetaChain{ + RatingSteps: config.RatingSteps{ + HoursToMaxRatingFromStartRating: 2, + ProposerValidatorImportance: 1, + ProposerDecreaseFactor: -4, + ValidatorDecreaseFactor: -4, + ConsecutiveMissedBlocksPenalty: 1.3, + }, + }, + }, ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), InitialRound: 0, NodesSetupPath: "../../../sharding/mock/testdata/nodesSetupMock.json", @@ -101,6 +132,7 @@ func createArgsCoreComponentsHolder() ArgsCoreComponentsHolder { WorkingDir: ".", MinNodesPerShard: 1, MinNodesMeta: 1, + RoundDurationInMs: 6000, } } diff --git a/node/chainSimulator/components/cryptoComponents.go b/node/chainSimulator/components/cryptoComponents.go index 7a1a456b6e6..3fcd7e205b7 100644 --- a/node/chainSimulator/components/cryptoComponents.go +++ b/node/chainSimulator/components/cryptoComponents.go @@ -222,24 +222,25 @@ func (c *cryptoComponentsHolder) KeysHandler() consensus.KeysHandler { // Clone will clone the cryptoComponentsHolder func (c *cryptoComponentsHolder) Clone() interface{} { return &cryptoComponentsHolder{ - publicKey: c.PublicKey(), - privateKey: c.PrivateKey(), - p2pPublicKey: c.P2pPublicKey(), - p2pPrivateKey: c.P2pPrivateKey(), - p2pSingleSigner: c.P2pSingleSigner(), - txSingleSigner: c.TxSingleSigner(), - blockSigner: c.BlockSigner(), - multiSignerContainer: c.MultiSignerContainer(), - peerSignatureHandler: c.PeerSignatureHandler(), - blockSignKeyGen: c.BlockSignKeyGen(), - txSignKeyGen: c.TxSignKeyGen(), - p2pKeyGen: c.P2pKeyGen(), - messageSignVerifier: c.MessageSignVerifier(), - consensusSigningHandler: c.ConsensusSigningHandler(), - managedPeersHolder: c.ManagedPeersHolder(), - keysHandler: c.KeysHandler(), - publicKeyBytes: c.PublicKeyBytes(), - publicKeyString: c.PublicKeyString(), + publicKey: c.PublicKey(), + privateKey: c.PrivateKey(), + p2pPublicKey: c.P2pPublicKey(), + p2pPrivateKey: c.P2pPrivateKey(), + p2pSingleSigner: c.P2pSingleSigner(), + txSingleSigner: c.TxSingleSigner(), + blockSigner: c.BlockSigner(), + multiSignerContainer: c.MultiSignerContainer(), + peerSignatureHandler: c.PeerSignatureHandler(), + blockSignKeyGen: c.BlockSignKeyGen(), + txSignKeyGen: c.TxSignKeyGen(), + p2pKeyGen: c.P2pKeyGen(), + messageSignVerifier: c.MessageSignVerifier(), + consensusSigningHandler: c.ConsensusSigningHandler(), + managedPeersHolder: c.ManagedPeersHolder(), + keysHandler: c.KeysHandler(), + publicKeyBytes: c.PublicKeyBytes(), + publicKeyString: c.PublicKeyString(), + managedCryptoComponentsCloser: c.managedCryptoComponentsCloser, } } From d03d8891d2c14f864b527926e0b120482fce92eb Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 23 Feb 2024 15:04:01 +0200 Subject: [PATCH 880/958] bug fixes set state --- node/chainSimulator/chainSimulator_test.go | 2 +- .../components/testOnlyProcessingNode.go | 92 ++++++++++++------- .../components/testOnlyProcessingNode_test.go | 7 +- node/chainSimulator/dtos/state.go | 2 +- 4 files changed, 68 insertions(+), 35 deletions(-) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index a986221c17c..bbb3950f981 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -355,7 +355,7 @@ func TestChainSimulator_SetEntireState(t *testing.T) { contractAddress := "erd1qqqqqqqqqqqqqpgqmzzm05jeav6d5qvna0q2pmcllelkz8xddz3syjszx5" accountState := &dtos.AddressState{ Address: contractAddress, - Nonce: 0, + Nonce: new(uint64), Balance: balance, Code: "0061736d010000000129086000006000017f60027f7f017f60027f7f0060017f0060037f7f7f017f60037f7f7f0060017f017f0290020b03656e7619626967496e74476574556e7369676e6564417267756d656e74000303656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000303656e76126d42756666657253746f726167654c6f6164000203656e76176d427566666572546f426967496e74556e7369676e6564000203656e76196d42756666657246726f6d426967496e74556e7369676e6564000203656e76136d42756666657253746f7261676553746f7265000203656e760f6d4275666665725365744279746573000503656e760e636865636b4e6f5061796d656e74000003656e7614626967496e7446696e697368556e7369676e6564000403656e7609626967496e744164640006030b0a010104070301000000000503010003060f027f0041a080080b7f0041a080080b074607066d656d6f7279020004696e697400110667657453756d00120361646400130863616c6c4261636b00140a5f5f646174615f656e6403000b5f5f686561705f6261736503010aca010a0e01017f4100100c2200100020000b1901017f419c8008419c800828020041016b220036020020000b1400100120004604400f0b4180800841191002000b16002000100c220010031a2000100c220010041a20000b1401017f100c2202200110051a2000200210061a0b1301017f100c220041998008410310071a20000b1401017f10084101100d100b210010102000100f0b0e0010084100100d1010100e10090b2201037f10084101100d100b210110102202100e220020002001100a20022000100f0b0300010b0b2f0200418080080b1c77726f6e67206e756d626572206f6620617267756d656e747373756d00419c80080b049cffffff", CodeHash: "n9EviPlHS6EV+3Xp0YqP28T0IUfeAFRFBIRC1Jw6pyU=", diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 43abc6e8076..f36fc7e8cac 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -444,16 +444,7 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt return err } - // set nonce to zero - userAccount.IncreaseNonce(-userAccount.GetNonce()) - // set nonce with the provided value - userAccount.IncreaseNonce(addressState.Nonce) - - bigValue, ok := big.NewInt(0).SetString(addressState.Balance, 10) - if !ok { - return errors.New("cannot convert string balance to *big.Int") - } - err = userAccount.AddToBalance(bigValue) + err = setNonceAndBalanceForAccount(userAccount, addressState.Nonce, addressState.Balance) if err != nil { return err } @@ -472,7 +463,9 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt if err != nil { return err } - userAccount.SetRootHash(rootHash) + if len(rootHash) != 0 { + userAccount.SetRootHash(rootHash) + } accountsAdapter := node.StateComponentsHolder.AccountsAdapter() err = accountsAdapter.SaveAccount(userAccount) @@ -484,40 +477,77 @@ func (node *testOnlyProcessingNode) SetStateForAddress(address []byte, addressSt return err } -func (node *testOnlyProcessingNode) setScDataIfNeeded(address []byte, userAccount state.UserAccountHandler, addressState *dtos.AddressState) error { - if !core.IsSmartContractAddress(address) { +func setNonceAndBalanceForAccount(userAccount state.UserAccountHandler, nonce *uint64, balance string) error { + if nonce != nil { + // set nonce to zero + userAccount.IncreaseNonce(-userAccount.GetNonce()) + // set nonce with the provided value + userAccount.IncreaseNonce(*nonce) + } + + if balance == "" { return nil } - decodedCode, err := hex.DecodeString(addressState.Code) - if err != nil { - return err + providedBalance, ok := big.NewInt(0).SetString(balance, 10) + if !ok { + return errors.New("cannot convert string balance to *big.Int") } - userAccount.SetCode(decodedCode) - codeHash, err := base64.StdEncoding.DecodeString(addressState.CodeHash) + // set balance to zero + userBalance := userAccount.GetBalance() + err := userAccount.AddToBalance(userBalance.Neg(userBalance)) if err != nil { return err } - userAccount.SetCodeHash(codeHash) + // set provided balance + return userAccount.AddToBalance(providedBalance) +} - decodedCodeMetadata, err := base64.StdEncoding.DecodeString(addressState.CodeMetadata) - if err != nil { - return err +func (node *testOnlyProcessingNode) setScDataIfNeeded(address []byte, userAccount state.UserAccountHandler, addressState *dtos.AddressState) error { + if !core.IsSmartContractAddress(address) { + return nil } - userAccount.SetCodeMetadata(decodedCodeMetadata) - ownerAddress, err := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(addressState.Owner) - if err != nil { - return err + if addressState.Code != "" { + decodedCode, err := hex.DecodeString(addressState.Code) + if err != nil { + return err + } + userAccount.SetCode(decodedCode) } - userAccount.SetOwnerAddress(ownerAddress) - developerRewards, ok := big.NewInt(0).SetString(addressState.DeveloperRewards, 10) - if !ok { - return errors.New("cannot convert string developer rewards to *big.Int") + if addressState.CodeHash != "" { + codeHash, errD := base64.StdEncoding.DecodeString(addressState.CodeHash) + if errD != nil { + return errD + } + userAccount.SetCodeHash(codeHash) + } + + if addressState.CodeMetadata != "" { + decodedCodeMetadata, errD := base64.StdEncoding.DecodeString(addressState.CodeMetadata) + if errD != nil { + return errD + } + userAccount.SetCodeMetadata(decodedCodeMetadata) + } + + if addressState.Owner != "" { + ownerAddress, errD := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(addressState.Owner) + if errD != nil { + return errD + } + userAccount.SetOwnerAddress(ownerAddress) + } + + if addressState.DeveloperRewards != "" { + developerRewards, ok := big.NewInt(0).SetString(addressState.DeveloperRewards, 10) + if !ok { + return errors.New("cannot convert string developer rewards to *big.Int") + } + userAccount.AddToDeveloperReward(developerRewards) } - userAccount.AddToDeveloperReward(developerRewards) return nil } diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 6ee1620f888..c3bba03f6e9 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -251,6 +251,7 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, err) + nonce := uint64(100) address := "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj" scAddress := "erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd" @@ -258,7 +259,7 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { scAddressBytes, _ := node.CoreComponentsHolder.AddressPubKeyConverter().Decode(scAddress) addressState := &dtos.AddressState{ Address: "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj", - Nonce: 100, + Nonce: &nonce, Balance: "1000000000000000000", Keys: map[string]string{ "01": "02", @@ -275,7 +276,7 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { account, err := node.StateComponentsHolder.AccountsAdapter().GetExistingAccount(addressBytes) require.NoError(t, err) - require.Equal(t, addressState.Nonce, account.GetNonce()) + require.Equal(t, *addressState.Nonce, account.GetNonce()) }) t.Run("LoadAccount failure should error", func(t *testing.T) { nodeLocal, errLocal := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) @@ -310,6 +311,7 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { AddToBalanceCalled: func(value *big.Int) error { return expectedErr }, + Balance: big.NewInt(0), }, nil }, }, @@ -330,6 +332,7 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { SaveKeyValueCalled: func(key []byte, value []byte) error { return expectedErr }, + Balance: big.NewInt(0), }, nil }, }, diff --git a/node/chainSimulator/dtos/state.go b/node/chainSimulator/dtos/state.go index 2d2d59f7763..a8edb7e212d 100644 --- a/node/chainSimulator/dtos/state.go +++ b/node/chainSimulator/dtos/state.go @@ -3,7 +3,7 @@ package dtos // AddressState will hold the address state type AddressState struct { Address string `json:"address"` - Nonce uint64 `json:"nonce,omitempty"` + Nonce *uint64 `json:"nonce,omitempty"` Balance string `json:"balance,omitempty"` Code string `json:"code,omitempty"` RootHash string `json:"rootHash,omitempty"` From 881a3158be295f465971aedb191dbacb1e974f6e Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 26 Feb 2024 12:50:29 +0200 Subject: [PATCH 881/958] added scenario with withdraw in batches --- .../staking/stakeAndUnStake_test.go | 357 ++++++++++++++++++ 1 file changed, 357 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 04f3a544fcd..f3fbaf43a8a 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -22,6 +22,7 @@ import ( "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/vm" logger "github.com/multiversx/mx-chain-logger-go" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -1709,3 +1710,359 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInFirstEpoch(t *testing. require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) } + +// Test description: +// Unstaking funds in different batches allows correct withdrawal for each batch +// at the corresponding epoch. +// +// Internal test scenario #30 +func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInBatches(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test Steps + // 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld. + // 2. Send the transactions in consecutive epochs, one TX in each epoch. + // 3. Wait for the epoch when first tx unbonding period ends. + // 4. Create a transaction for withdraw and send it to the network + // 5. Wait for an epoch + // 6. Create another transaction for withdraw and send it to the network + // 7. Wait for an epoch + // 8. Create another transasction for withdraw and send it to the network + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + + // cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriod = 144000 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 1) + }) + + // t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + + // defer cs.Close() + + // testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 2) + // }) + + // t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + + // defer cs.Close() + + // testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 3) + // }) + + // t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + + // defer cs.Close() + + // testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 4) + // }) +} + +func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(2700) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(2600)) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + shardIDValidatorOwner := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(validatorOwner.Bytes) + accountValidatorOwner, _, err := cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld.") + log.Info("Step 2. Send the transactions in consecutive epochs, one TX in each epoch.") + + unStakeValue1 := big.NewInt(11) + unStakeValue1 = unStakeValue1.Mul(oneEGLD, unStakeValue1) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue1.Bytes())) + txUnStake := generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + unStakeValue2 := big.NewInt(12) + unStakeValue2 = unStakeValue2.Mul(oneEGLD, unStakeValue2) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue2.Bytes())) + txUnStake = generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + unStakeValue3 := big.NewInt(13) + unStakeValue3 = unStakeValue3.Mul(oneEGLD, unStakeValue3) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue3.Bytes())) + txUnStake = generateTransaction(validatorOwner.Bytes, 3, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + // check bls key is still staked + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getUnStakedTokensList", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedUnStaked := big.NewInt(11) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked := big.NewInt(2600 - 11 - 12 - 13) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + log.Info("Step 1. Wait for the unbonding epoch to start") + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + require.Nil(t, err) + + log.Info("Step 2. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") + + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + + txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) + txUnBond := generateTransaction(validatorOwner.Bytes, 4, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) + unBondTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unBondTx) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + // the owner balance should increase with the (11 EGLD - tx fee) + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ = big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + // // substract unbonding value + // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) + + // txsFee, _ := big.NewInt(0).SetString(unBondTx.Fee, 10) + // balanceAfterUnbondingWithFee := big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + + // txsFee, _ = big.NewInt(0).SetString(unStakeTx.Fee, 10) + // balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + + // txsFee, _ = big.NewInt(0).SetString(stakeTx.Fee, 10) + // balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + + // assert.Equal(t, balanceAfterUnbondingWithFee.String(), balanceBeforeUnbonding.String()) + + assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + + // require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) + + /////////////////////////////// + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 2) + require.Nil(t, err) + + txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) + txUnBond = generateTransaction(validatorOwner.Bytes, 5, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) + unBondTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unBondTx) + + // the owner balance should increase with the (11 EGLD - tx fee) + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ = big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + // // substract unbonding value + // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) + // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) + + // txsFee, _ = big.NewInt(0).SetString(unBondTx.Fee, 10) + // balanceAfterUnbondingWithFee = big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + + // assert.Equal(t, balanceAfterUnbondingWithFee.String(), balanceBeforeUnbonding.String()) + + assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + + // require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) + + /////////////////////////////// + + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 2) + require.Nil(t, err) + + txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) + txUnBond = generateTransaction(validatorOwner.Bytes, 6, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) + unBondTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unBondTx) + + // the owner balance should increase with the (11 EGLD - tx fee) + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ = big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + // // substract unbonding value + // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) + // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) + // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue3) + + // txsFee, _ = big.NewInt(0).SetString(unBondTx.Fee, 10) + // balanceAfterUnbondingWithFee = big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + + // assert.Equal(t, balanceAfterUnbondingWithFee.String(), balanceBeforeUnbonding.String()) + + assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + + // require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) +} From daaa78f96dc6bd5a198f1bea84df521d826f5c7e Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 26 Feb 2024 14:28:55 +0200 Subject: [PATCH 882/958] fix after review --- node/chainSimulator/components/statusComponents_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/components/statusComponents_test.go b/node/chainSimulator/components/statusComponents_test.go index 69731c129c6..0e83e435003 100644 --- a/node/chainSimulator/components/statusComponents_test.go +++ b/node/chainSimulator/components/statusComponents_test.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-go/common" + mxErrors "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" @@ -97,7 +98,7 @@ func TestStatusComponentsHolder_StartPolling(t *testing.T) { require.NoError(t, err) err = comp.StartPolling() - require.Error(t, err) + require.Equal(t, mxErrors.ErrStatusPollingInit, err) }) t.Run("should work", func(t *testing.T) { t.Parallel() From 6b655f8cdd7743ffa0a5d703d022d5de9a1b526d Mon Sep 17 00:00:00 2001 From: ssd04 Date: Mon, 26 Feb 2024 17:00:08 +0200 Subject: [PATCH 883/958] fixes after review - renaming --- .../chainSimulator/staking/stakeAndUnStake_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 89cc3fb19ea..b512183ad1f 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -566,10 +566,10 @@ func testChainSimulatorDirectStakedNodesStakingFunds(t *testing.T, cs chainSimul require.Nil(t, err) log.Info("Preconditions. Have an account with 2 staked nodes") - privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) require.Nil(t, err) - err = cs.AddValidatorKeys(privateKey) + err = cs.AddValidatorKeys(privateKeys) require.Nil(t, err) metachainNode := cs.GetNodeHandler(core.MetachainShardId) @@ -787,10 +787,10 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivation(t *testing.T, cs err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) - privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) require.Nil(t, err) - err = cs.AddValidatorKeys(privateKey) + err = cs.AddValidatorKeys(privateKeys) require.Nil(t, err) metachainNode := cs.GetNodeHandler(core.MetachainShardId) @@ -1062,10 +1062,10 @@ func testChainSimulatorDirectStakedUnstakeFundsWithDeactivationAndReactivation(t err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) - privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) require.Nil(t, err) - err = cs.AddValidatorKeys(privateKey) + err = cs.AddValidatorKeys(privateKeys) require.Nil(t, err) metachainNode := cs.GetNodeHandler(core.MetachainShardId) From e13793684eed3d8cbccd7239c96ba016316637d4 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 27 Feb 2024 13:23:34 +0200 Subject: [PATCH 884/958] fixes after review --- go.mod | 2 +- go.sum | 4 ++-- node/external/transactionAPI/gasUsedAndFeeProcessor.go | 3 ++- outport/process/transactionsfee/transactionsFeeProcessor.go | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 092a7006c38..fd4c186373c 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 - github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 + github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 diff --git a/go.sum b/go.sum index fcbb3672f50..f8f68456da6 100644 --- a/go.sum +++ b/go.sum @@ -399,8 +399,8 @@ github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 h1:/EYv/HGX0OKbeNFt667J0yZRtuJiZH0lEK8YtobuH/c= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566 h1:zImJa/r6B5L2OLWbKTn5io53U11PPGDla12H2OaJ9y0= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240129145149-4fe61574f566/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a h1:4Dlk5Hcxlt6az5qqJfklgSlAKEYiFLv+xkFavQJgSNY= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 h1:NMHNT4NcqOdnHttYsT3ydZHVapwOctp6t+WDGDy0UEQ= github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= diff --git a/node/external/transactionAPI/gasUsedAndFeeProcessor.go b/node/external/transactionAPI/gasUsedAndFeeProcessor.go index c2f02be8e8f..f0036bc136b 100644 --- a/node/external/transactionAPI/gasUsedAndFeeProcessor.go +++ b/node/external/transactionAPI/gasUsedAndFeeProcessor.go @@ -5,6 +5,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" + datafield "github.com/multiversx/mx-chain-vm-common-go/parsers/dataField" ) type gasUsedAndFeeProcessor struct { @@ -52,7 +53,7 @@ func (gfp *gasUsedAndFeeProcessor) prepareTxWithResultsBasedOnLogs( tx *transaction.ApiTransactionResult, hasRefund bool, ) { - if tx.Logs == nil || (tx.Function == "" && tx.Operation == "transfer") { + if tx.Logs == nil || (tx.Function == "" && tx.Operation == datafield.OperationTransfer) { return } diff --git a/outport/process/transactionsfee/transactionsFeeProcessor.go b/outport/process/transactionsfee/transactionsFeeProcessor.go index ded9b1318d5..b73558ba650 100644 --- a/outport/process/transactionsfee/transactionsFeeProcessor.go +++ b/outport/process/transactionsfee/transactionsFeeProcessor.go @@ -148,7 +148,7 @@ func (tep *transactionsFeeProcessor) prepareTxWithResultsBasedOnLogs( tx := txWithResults.GetTxHandler() res := tep.dataFieldParser.Parse(tx.GetData(), tx.GetSndAddr(), tx.GetRcvAddr(), tep.shardCoordinator.NumberOfShards()) - if check.IfNilReflect(txWithResults.log) || (res.Function == "" && res.Operation == "transfer") { + if check.IfNilReflect(txWithResults.log) || (res.Function == "" && res.Operation == datafield.OperationTransfer) { return } From 20c6fb6b67286351be3fdf857c06ca669b73e654 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 27 Feb 2024 13:41:23 +0200 Subject: [PATCH 885/958] extra nil check --- .../process/transactionsfee/transactionsFeeProcessor.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/outport/process/transactionsfee/transactionsFeeProcessor.go b/outport/process/transactionsfee/transactionsFeeProcessor.go index b73558ba650..c77956f5365 100644 --- a/outport/process/transactionsfee/transactionsFeeProcessor.go +++ b/outport/process/transactionsfee/transactionsFeeProcessor.go @@ -137,17 +137,22 @@ func (tep *transactionsFeeProcessor) prepareTxWithResults(txHashHex string, txWi } } - tep.prepareTxWithResultsBasedOnLogs(txWithResults, hasRefund) + tep.prepareTxWithResultsBasedOnLogs(txHashHex, txWithResults, hasRefund) } func (tep *transactionsFeeProcessor) prepareTxWithResultsBasedOnLogs( + txHashHex string, txWithResults *transactionWithResults, hasRefund bool, ) { tx := txWithResults.GetTxHandler() - res := tep.dataFieldParser.Parse(tx.GetData(), tx.GetSndAddr(), tx.GetRcvAddr(), tep.shardCoordinator.NumberOfShards()) + if check.IfNil(tx) { + tep.log.Warn("tep.prepareTxWithResultsBasedOnLogs nil transaction handler", "txHash", txHashHex) + return + } + res := tep.dataFieldParser.Parse(tx.GetData(), tx.GetSndAddr(), tx.GetRcvAddr(), tep.shardCoordinator.NumberOfShards()) if check.IfNilReflect(txWithResults.log) || (res.Function == "" && res.Operation == datafield.OperationTransfer) { return } From 4c25093b40cf98e4f7c0880321bb06dc9e030de9 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 27 Feb 2024 16:44:40 +0200 Subject: [PATCH 886/958] - fixes after merge --- .../components/processComponents_test.go | 7 +++++++ .../components/statusCoreComponents_test.go | 3 ++- testscommon/chainSimulator/chainSimulatorMock.go | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/node/chainSimulator/components/processComponents_test.go b/node/chainSimulator/components/processComponents_test.go index 0599ca82538..9ededf0a71f 100644 --- a/node/chainSimulator/components/processComponents_test.go +++ b/node/chainSimulator/components/processComponents_test.go @@ -1,6 +1,7 @@ package components import ( + "math/big" "sync" "testing" @@ -109,6 +110,9 @@ func createArgsProcessComponentsHolder() ArgsProcessComponentsHolder { MaxNumberOfNodesForStake: 10, ActivateBLSPubKeyMessageVerification: false, MinUnstakeTokensValue: "1", + NodeLimitPercentage: 0.1, + StakeLimitPercentage: 1, + UnBondPeriodInEpochs: 10, }, DelegationManagerSystemSCConfig: config.DelegationManagerSystemSCConfig{ MinCreationDeposit: "100", @@ -145,6 +149,9 @@ func createArgsProcessComponentsHolder() ArgsProcessComponentsHolder { ProtocolSustainabilityAddressCalled: func() string { return testingProtocolSustainabilityAddress }, + GenesisTotalSupplyCalled: func() *big.Int { + return big.NewInt(0).Mul(big.NewInt(1000000000000000000), big.NewInt(20000000)) + }, }, Hash: blake2b.NewBlake2b(), TxVersionCheckHandler: &testscommon.TxVersionCheckerStub{}, diff --git a/node/chainSimulator/components/statusCoreComponents_test.go b/node/chainSimulator/components/statusCoreComponents_test.go index 6bb40d9db94..a616890644f 100644 --- a/node/chainSimulator/components/statusCoreComponents_test.go +++ b/node/chainSimulator/components/statusCoreComponents_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/components" "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" + "github.com/multiversx/mx-chain-go/testscommon/genesisMocks" "github.com/stretchr/testify/require" ) @@ -44,7 +45,7 @@ func createArgs() (config.Configs, factory.CoreComponentsHolder) { EconomicsHandler: &economicsmocks.EconomicsHandlerStub{}, IntMarsh: &testscommon.MarshallerStub{}, UInt64ByteSliceConv: &mockTests.Uint64ByteSliceConverterMock{}, - NodesConfig: &testscommon.NodesSetupStub{}, + NodesConfig: &genesisMocks.NodesSetupStub{}, } } diff --git a/testscommon/chainSimulator/chainSimulatorMock.go b/testscommon/chainSimulator/chainSimulatorMock.go index 5a49de21f05..07db474a07e 100644 --- a/testscommon/chainSimulator/chainSimulatorMock.go +++ b/testscommon/chainSimulator/chainSimulatorMock.go @@ -4,9 +4,19 @@ import "github.com/multiversx/mx-chain-go/node/chainSimulator/process" // ChainSimulatorMock - type ChainSimulatorMock struct { + GenerateBlocksCalled func(numOfBlocks int) error GetNodeHandlerCalled func(shardID uint32) process.NodeHandler } +// GenerateBlocks - +func (mock *ChainSimulatorMock) GenerateBlocks(numOfBlocks int) error { + if mock.GenerateBlocksCalled != nil { + return mock.GenerateBlocksCalled(numOfBlocks) + } + + return nil +} + // GetNodeHandler - func (mock *ChainSimulatorMock) GetNodeHandler(shardID uint32) process.NodeHandler { if mock.GetNodeHandlerCalled != nil { From 398171a9f313d2b7fc1a1ea21a0968f1693a241b Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 27 Feb 2024 17:36:09 +0200 Subject: [PATCH 887/958] - removed unnecessary config init --- node/chainSimulator/configs/configs.go | 1 - 1 file changed, 1 deletion(-) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 6c94475af36..f045c2c6489 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -119,7 +119,6 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi configs.GeneralConfig.EpochStartConfig.ExtraDelayForRequestBlockInfoInMilliseconds = 1 configs.GeneralConfig.EpochStartConfig.GenesisEpoch = args.InitialEpoch - configs.EpochConfig.EnableEpochs.StakingV2EnableEpoch = args.InitialEpoch + 1 if args.RoundsPerEpoch.HasValue { configs.GeneralConfig.EpochStartConfig.RoundsPerEpoch = int64(args.RoundsPerEpoch.Value) From 990bd745e1c6745e2ac87f3e5c0632c020bf8e98 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 28 Feb 2024 10:12:31 +0200 Subject: [PATCH 888/958] - fix after merge --- node/chainSimulator/components/processComponents_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/chainSimulator/components/processComponents_test.go b/node/chainSimulator/components/processComponents_test.go index 0599ca82538..26e85758f86 100644 --- a/node/chainSimulator/components/processComponents_test.go +++ b/node/chainSimulator/components/processComponents_test.go @@ -70,6 +70,7 @@ func createArgsProcessComponentsHolder() ArgsProcessComponentsHolder { }, }, }, + RoundConfig: testscommon.GetDefaultRoundsConfig(), PrefsConfig: config.Preferences{}, ImportDBConfig: config.ImportDbConfig{}, FlagsConfig: config.ContextFlagsConfig{ From 949cbd5673eb6c5b03044a885e7249044e6dc602 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 28 Feb 2024 18:10:25 +0200 Subject: [PATCH 889/958] - minor chain simulator refactor - added more unit tests --- .../staking/simpleStake_test.go | 2 +- node/chainSimulator/chainSimulator.go | 132 +++++++++++-- node/chainSimulator/chainSimulator_test.go | 176 ++++++++++++++++++ node/chainSimulator/errors.go | 9 +- node/chainSimulator/sendAndExecute.go | 83 --------- 5 files changed, 302 insertions(+), 100 deletions(-) delete mode 100644 node/chainSimulator/sendAndExecute.go diff --git a/integrationTests/chainSimulator/staking/simpleStake_test.go b/integrationTests/chainSimulator/staking/simpleStake_test.go index 79e606c0fa3..933e7888824 100644 --- a/integrationTests/chainSimulator/staking/simpleStake_test.go +++ b/integrationTests/chainSimulator/staking/simpleStake_test.go @@ -104,7 +104,7 @@ func testChainSimulatorSimpleStake(t *testing.T, targetEpoch int32, nodesStatus tx3Value := big.NewInt(0).Mul(big.NewInt(2501), oneEGLD) tx3 := generateTransaction(wallet2.Bytes, 0, vm.ValidatorSCAddress, tx3Value, dataFieldTx3, gasLimitForStakeOperation) - results, err := cs.SendTxsAndGenerateBlockTilTxIsExecuted([]*transaction.Transaction{tx1, tx2, tx3}, maxNumOfBlockToGenerateWhenExecutingTx) + results, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{tx1, tx2, tx3}, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) require.Equal(t, 3, len(results)) require.NotNil(t, results) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index c85749af57b..9fda42b3f82 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -13,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/core/sharding" + "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-core-go/data/endProcess" "github.com/multiversx/mx-chain-core-go/data/transaction" crypto "github.com/multiversx/mx-chain-crypto-go" @@ -27,8 +28,16 @@ import ( logger "github.com/multiversx/mx-chain-logger-go" ) +const delaySendTxs = time.Millisecond + var log = logger.GetOrCreate("chainSimulator") +type transactionWithResult struct { + hexHash string + tx *transaction.Transaction + result *transaction.ApiTransactionResult +} + // ArgsChainSimulator holds the arguments needed to create a new instance of simulator type ArgsChainSimulator struct { BypassTxSignatureCheck bool @@ -41,8 +50,8 @@ type ArgsChainSimulator struct { NumNodesWaitingListMeta uint32 GenesisTimestamp int64 InitialRound int64 - InitialEpoch uint32 - InitialNonce uint64 + InitialEpoch uint32 + InitialNonce uint64 RoundDurationInMillis uint64 RoundsPerEpoch core.OptionalUint64 ApiInterface components.APIConfigurator @@ -412,30 +421,119 @@ func (s *simulator) SetStateMultiple(stateSlice []*dtos.AddressState) error { return nil } -// SendTxAndGenerateBlockTilTxIsExecuted will the provided transaction and generate block -func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) { - txHashHex, err := s.sendTx(txToSend) +// SendTxAndGenerateBlockTilTxIsExecuted will send the provided transaction and generate block until the transaction is executed +func (s *simulator) SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlocksToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) { + result, err := s.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txToSend}, maxNumOfBlocksToGenerateWhenExecutingTx) if err != nil { return nil, err } + return result[0], nil +} + +// SendTxsAndGenerateBlocksTilAreExecuted will send the provided transactions and generate block until all transactions are executed +func (s *simulator) SendTxsAndGenerateBlocksTilAreExecuted(txsToSend []*transaction.Transaction, maxNumOfBlocksToGenerateWhenExecutingTx int) ([]*transaction.ApiTransactionResult, error) { + if len(txsToSend) == 0 { + return nil, errEmptySliceOfTxs + } + if maxNumOfBlocksToGenerateWhenExecutingTx == 0 { + return nil, errInvalidMaxNumOfBlocks + } + + transactionStatus := make([]*transactionWithResult, 0, len(txsToSend)) + for idx, tx := range txsToSend { + if tx == nil { + return nil, fmt.Errorf("%w on position %d", errNilTransaction, idx) + } + + txHashHex, err := s.sendTx(tx) + if err != nil { + return nil, err + } + + transactionStatus = append(transactionStatus, &transactionWithResult{ + hexHash: txHashHex, + tx: tx, + }) + } + time.Sleep(delaySendTxs) - destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txToSend.RcvAddr) - for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { - err = s.GenerateBlocks(1) + for count := 0; count < maxNumOfBlocksToGenerateWhenExecutingTx; count++ { + err := s.GenerateBlocks(1) if err != nil { return nil, err } - tx, errGet := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHashHex, true) - if errGet == nil && tx.Status != transaction.TxStatusPending { - log.Info("############## transaction was executed ##############", "txHash", txHashHex) - return tx, nil + txsAreExecuted := s.computeTransactionStatus(transactionStatus) + if txsAreExecuted { + return getApiTransactionsFromResult(transactionStatus), nil + } + } + + return nil, errors.New("something went wrong. Transaction(s) is/are still in pending") +} + +func (s *simulator) computeTransactionStatus(status []*transactionWithResult) bool { + allAreExecuted := true + for _, resultTx := range status { + if resultTx.result != nil { + continue + } + + sentTx := resultTx.tx + destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(sentTx.RcvAddr) + result, errGet := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(resultTx.hexHash, true) + if errGet == nil && result.Status != transaction.TxStatusPending { + log.Info("############## transaction was executed ##############", "txHash", resultTx.hexHash) + resultTx.result = result + continue } + + allAreExecuted = false + } + + return allAreExecuted +} + +func getApiTransactionsFromResult(txWithResult []*transactionWithResult) []*transaction.ApiTransactionResult { + result := make([]*transaction.ApiTransactionResult, 0, len(txWithResult)) + for _, tx := range txWithResult { + result = append(result, tx.result) } - return nil, errors.New("something went wrong transaction is still in pending") + return result +} + +func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { + shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) + err := s.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) + if err != nil { + return "", err + } + + node := s.GetNodeHandler(shardID) + txHash, err := core.CalculateHash(node.GetCoreComponents().InternalMarshalizer(), node.GetCoreComponents().Hasher(), tx) + if err != nil { + return "", err + } + + txHashHex := hex.EncodeToString(txHash) + _, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) + if err != nil { + return "", err + } + + for { + txs, _ := node.GetFacadeHandler().GetTransactionsPool("") + for _, sentTx := range txs.RegularTransactions { + if sentTx.TxFields["hash"] == txHashHex { + log.Info("############## send transaction ##############", "txHash", txHashHex) + return txHashHex, nil + } + } + time.Sleep(delaySendTxs) + } } func (s *simulator) setStateSystemAccount(state *dtos.AddressState) error { @@ -449,6 +547,14 @@ func (s *simulator) setStateSystemAccount(state *dtos.AddressState) error { return nil } +// GetAccount will fetch the account of the provided address +func (s *simulator) GetAccount(address dtos.WalletAddress) (api.AccountResponse, error) { + destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(address.Bytes) + + account, _, err := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetAccount(address.Bech32, api.AccountQueryOptions{}) + return account, err +} + // Close will stop and close the simulator func (s *simulator) Close() { s.mutex.Lock() diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index d761cd1c550..7d5108e8ca3 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -8,7 +8,9 @@ import ( "github.com/multiversx/mx-chain-core-go/core" coreAPI "github.com/multiversx/mx-chain-core-go/data/api" + "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/node/chainSimulator/components/api" + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/process" "github.com/stretchr/testify/assert" @@ -261,3 +263,177 @@ func TestChainSimulator_SetEntireState(t *testing.T) { require.Equal(t, accountState.Owner, account.OwnerAddress) require.Equal(t, accountState.RootHash, base64.StdEncoding.EncodeToString(account.RootHash)) } + +func TestChainSimulator_GetAccount(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, + }) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + + // the facade's GetAccount method requires that at least one block was produced over the genesis block + _ = chainSimulator.GenerateBlocks(1) + + defer chainSimulator.Close() + + address := dtos.WalletAddress{ + Bech32: "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj", + } + address.Bytes, err = chainSimulator.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(address.Bech32) + + account, err := chainSimulator.GetAccount(address) + assert.Nil(t, err) + assert.Equal(t, uint64(0), account.Nonce) + assert.Equal(t, "0", account.Balance) + + nonce := uint64(37) + err = chainSimulator.SetStateMultiple([]*dtos.AddressState{ + { + Address: address.Bech32, + Nonce: &nonce, + Balance: big.NewInt(38).String(), + }, + }) + assert.Nil(t, err) + + // without this call the test will fail because the latest produced block points to a state roothash that tells that + // the account has the nonce 0 + _ = chainSimulator.GenerateBlocks(1) + + account, err = chainSimulator.GetAccount(address) + assert.Nil(t, err) + assert.Equal(t, uint64(37), account.Nonce) + assert.Equal(t, "38", account.Balance) +} + +func TestSimulator_SendTransactions(t *testing.T) { + t.Parallel() + + startTime := time.Now().Unix() + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 20, + } + chainSimulator, err := NewChainSimulator(ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: startTime, + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 1, + MetaChainMinNodes: 1, + }) + require.Nil(t, err) + require.NotNil(t, chainSimulator) + + defer chainSimulator.Close() + + oneEgld := big.NewInt(1000000000000000000) + initialMinting := big.NewInt(0).Mul(oneEgld, big.NewInt(100)) + transferValue := big.NewInt(0).Mul(oneEgld, big.NewInt(5)) + + wallet0, err := chainSimulator.GenerateAndMintWalletAddress(0, initialMinting) + require.Nil(t, err) + + wallet1, err := chainSimulator.GenerateAndMintWalletAddress(1, initialMinting) + require.Nil(t, err) + + wallet2, err := chainSimulator.GenerateAndMintWalletAddress(2, initialMinting) + require.Nil(t, err) + + wallet3, err := chainSimulator.GenerateAndMintWalletAddress(2, initialMinting) + require.Nil(t, err) + + wallet4, err := chainSimulator.GenerateAndMintWalletAddress(2, initialMinting) + require.Nil(t, err) + + gasLimit := uint64(50000) + tx0 := generateTransaction(wallet0.Bytes, 0, wallet2.Bytes, transferValue, "", gasLimit) + tx1 := generateTransaction(wallet1.Bytes, 0, wallet2.Bytes, transferValue, "", gasLimit) + tx3 := generateTransaction(wallet3.Bytes, 0, wallet4.Bytes, transferValue, "", gasLimit) + + maxNumOfBlockToGenerateWhenExecutingTx := 15 + + t.Run("nil or empty slice of transactions should error", func(t *testing.T) { + sentTxs, errSend := chainSimulator.SendTxsAndGenerateBlocksTilAreExecuted(nil, 1) + assert.Equal(t, errEmptySliceOfTxs, errSend) + assert.Nil(t, sentTxs) + + sentTxs, errSend = chainSimulator.SendTxsAndGenerateBlocksTilAreExecuted(make([]*transaction.Transaction, 0), 1) + assert.Equal(t, errEmptySliceOfTxs, errSend) + assert.Nil(t, sentTxs) + }) + t.Run("invalid max number of blocks to generate should error", func(t *testing.T) { + sentTxs, errSend := chainSimulator.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{tx0, tx1}, 0) + assert.Equal(t, errInvalidMaxNumOfBlocks, errSend) + assert.Nil(t, sentTxs) + }) + t.Run("nil transaction in slice should error", func(t *testing.T) { + sentTxs, errSend := chainSimulator.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{nil}, 1) + assert.ErrorIs(t, errSend, errNilTransaction) + assert.Nil(t, sentTxs) + }) + t.Run("2 transactions from different shard should call send correctly", func(t *testing.T) { + sentTxs, errSend := chainSimulator.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{tx0, tx1}, maxNumOfBlockToGenerateWhenExecutingTx) + assert.Equal(t, 2, len(sentTxs)) + assert.Nil(t, errSend) + + account, errGet := chainSimulator.GetAccount(wallet2) + assert.Nil(t, errGet) + expectedBalance := big.NewInt(0).Add(initialMinting, transferValue) + expectedBalance.Add(expectedBalance, transferValue) + assert.Equal(t, expectedBalance.String(), account.Balance) + }) + t.Run("1 transaction should be sent correctly", func(t *testing.T) { + _, errSend := chainSimulator.SendTxAndGenerateBlockTilTxIsExecuted(tx3, maxNumOfBlockToGenerateWhenExecutingTx) + assert.Nil(t, errSend) + + account, errGet := chainSimulator.GetAccount(wallet4) + assert.Nil(t, errGet) + expectedBalance := big.NewInt(0).Add(initialMinting, transferValue) + assert.Equal(t, expectedBalance.String(), account.Balance) + }) +} + +func generateTransaction(sender []byte, nonce uint64, receiver []byte, value *big.Int, data string, gasLimit uint64) *transaction.Transaction { + minGasPrice := uint64(1000000000) + txVersion := uint32(1) + mockTxSignature := "sig" + + transferValue := big.NewInt(0).Set(value) + return &transaction.Transaction{ + Nonce: nonce, + Value: transferValue, + SndAddr: sender, + RcvAddr: receiver, + Data: []byte(data), + GasLimit: gasLimit, + GasPrice: minGasPrice, + ChainID: []byte(configs.ChainID), + Version: txVersion, + Signature: []byte(mockTxSignature), + } +} diff --git a/node/chainSimulator/errors.go b/node/chainSimulator/errors.go index 57f0db0c457..5e2dec0c16a 100644 --- a/node/chainSimulator/errors.go +++ b/node/chainSimulator/errors.go @@ -3,7 +3,10 @@ package chainSimulator import "errors" var ( - errNilChainSimulator = errors.New("nil chain simulator") - errNilMetachainNode = errors.New("nil metachain node") - errShardSetupError = errors.New("shard setup error") + errNilChainSimulator = errors.New("nil chain simulator") + errNilMetachainNode = errors.New("nil metachain node") + errShardSetupError = errors.New("shard setup error") + errEmptySliceOfTxs = errors.New("empty slice of transactions to send") + errNilTransaction = errors.New("nil transaction") + errInvalidMaxNumOfBlocks = errors.New("invalid max number of blocks to generate") ) diff --git a/node/chainSimulator/sendAndExecute.go b/node/chainSimulator/sendAndExecute.go deleted file mode 100644 index a53174d2832..00000000000 --- a/node/chainSimulator/sendAndExecute.go +++ /dev/null @@ -1,83 +0,0 @@ -package chainSimulator - -import ( - "encoding/hex" - "errors" - "time" - - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/data/transaction" -) - -const delaySendTxs = time.Millisecond - -func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { - shardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(tx.SndAddr) - err := s.GetNodeHandler(shardID).GetFacadeHandler().ValidateTransaction(tx) - if err != nil { - return "", err - } - - node := s.GetNodeHandler(shardID) - txHash, err := core.CalculateHash(node.GetCoreComponents().InternalMarshalizer(), node.GetCoreComponents().Hasher(), tx) - if err != nil { - return "", err - } - - txHashHex := hex.EncodeToString(txHash) - _, err = node.GetFacadeHandler().SendBulkTransactions([]*transaction.Transaction{tx}) - if err != nil { - return "", err - } - - for { - txs, _ := node.GetFacadeHandler().GetTransactionsPool("") - for _, sentTx := range txs.RegularTransactions { - if sentTx.TxFields["hash"] == txHashHex { - log.Info("############## send transaction ##############", "txHash", txHashHex) - return txHashHex, nil - } - } - time.Sleep(delaySendTxs) - } -} - -// SendTxsAndGenerateBlockTilTxIsExecuted will send the transactions provided and generate the blocks until the transactions are finished -func (s *simulator) SendTxsAndGenerateBlockTilTxIsExecuted(txsToSend []*transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) ([]*transaction.ApiTransactionResult, error) { - hashTxIndex := make(map[string]int) - for idx, txToSend := range txsToSend { - txHashHex, err := s.sendTx(txToSend) - if err != nil { - return nil, err - } - - hashTxIndex[txHashHex] = idx - } - - time.Sleep(delaySendTxs) - - txsFromAPI := make([]*transaction.ApiTransactionResult, 3) - for count := 0; count < maxNumOfBlockToGenerateWhenExecutingTx; count++ { - err := s.GenerateBlocks(1) - if err != nil { - return nil, err - } - - for txHash := range hashTxIndex { - destinationShardID := s.GetNodeHandler(0).GetShardCoordinator().ComputeId(txsToSend[hashTxIndex[txHash]].RcvAddr) - tx, errGet := s.GetNodeHandler(destinationShardID).GetFacadeHandler().GetTransaction(txHash, true) - if errGet == nil && tx.Status != transaction.TxStatusPending { - log.Info("############## transaction was executed ##############", "txHash", txHash) - - txsFromAPI[hashTxIndex[txHash]] = tx - delete(hashTxIndex, txHash) - continue - } - } - if len(hashTxIndex) == 0 { - return txsFromAPI, nil - } - } - - return nil, errors.New("something went wrong transactions are still in pending") -} From 9ea68ca07cc1ca4cb5b81f67e110796c0146e916 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 28 Feb 2024 18:42:07 +0200 Subject: [PATCH 890/958] - fixes --- node/chainSimulator/chainSimulator.go | 15 +++++++-------- node/chainSimulator/chainSimulator_test.go | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 9fda42b3f82..de538b89f2a 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -465,7 +465,7 @@ func (s *simulator) SendTxsAndGenerateBlocksTilAreExecuted(txsToSend []*transact return nil, err } - txsAreExecuted := s.computeTransactionStatus(transactionStatus) + txsAreExecuted := s.computeTransactionsStatus(transactionStatus) if txsAreExecuted { return getApiTransactionsFromResult(transactionStatus), nil } @@ -474,7 +474,7 @@ func (s *simulator) SendTxsAndGenerateBlocksTilAreExecuted(txsToSend []*transact return nil, errors.New("something went wrong. Transaction(s) is/are still in pending") } -func (s *simulator) computeTransactionStatus(status []*transactionWithResult) bool { +func (s *simulator) computeTransactionsStatus(status []*transactionWithResult) bool { allAreExecuted := true for _, resultTx := range status { if resultTx.result != nil { @@ -525,13 +525,12 @@ func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { } for { - txs, _ := node.GetFacadeHandler().GetTransactionsPool("") - for _, sentTx := range txs.RegularTransactions { - if sentTx.TxFields["hash"] == txHashHex { - log.Info("############## send transaction ##############", "txHash", txHashHex) - return txHashHex, nil - } + recoveredTx, _ := node.GetFacadeHandler().GetTransaction(txHashHex, true) + if recoveredTx != nil { + log.Info("############## send transaction ##############", "txHash", txHashHex) + return txHashHex, nil } + time.Sleep(delaySendTxs) } } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 7d5108e8ca3..a5e3945aa99 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -299,6 +299,7 @@ func TestChainSimulator_GetAccount(t *testing.T) { Bech32: "erd1qtc600lryvytxuy4h7vn7xmsy5tw6vuw3tskr75cwnmv4mnyjgsq6e5zgj", } address.Bytes, err = chainSimulator.GetNodeHandler(0).GetCoreComponents().AddressPubKeyConverter().Decode(address.Bech32) + assert.Nil(t, err) account, err := chainSimulator.GetAccount(address) assert.Nil(t, err) From 882f233ee1c94e73790c97ecb06562bc538b3ba4 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 28 Feb 2024 18:43:15 +0200 Subject: [PATCH 891/958] - optimized GetTransaction call --- node/chainSimulator/chainSimulator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index de538b89f2a..efd45706f29 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -525,7 +525,7 @@ func (s *simulator) sendTx(tx *transaction.Transaction) (string, error) { } for { - recoveredTx, _ := node.GetFacadeHandler().GetTransaction(txHashHex, true) + recoveredTx, _ := node.GetFacadeHandler().GetTransaction(txHashHex, false) if recoveredTx != nil { log.Info("############## send transaction ##############", "txHash", txHashHex) return txHashHex, nil From 7de84bdbda3684beb75ba9b14cdbc73b7c1645ce Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 29 Feb 2024 09:34:18 +0200 Subject: [PATCH 892/958] - fixes after review + fixed tests --- .../status/statusComponentsHandler_test.go | 36 +++++------------ factory/status/statusComponents_test.go | 40 +++---------------- node/chainSimulator/chainSimulator.go | 4 +- node/chainSimulator/chainSimulator_test.go | 4 +- 4 files changed, 20 insertions(+), 64 deletions(-) diff --git a/factory/status/statusComponentsHandler_test.go b/factory/status/statusComponentsHandler_test.go index ee81a353e31..c7252cbf6de 100644 --- a/factory/status/statusComponentsHandler_test.go +++ b/factory/status/statusComponentsHandler_test.go @@ -16,18 +16,14 @@ import ( ) func TestNewManagedStatusComponents(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("nil factory should error", func(t *testing.T) { - t.Parallel() - managedStatusComponents, err := statusComp.NewManagedStatusComponents(nil) require.Equal(t, errorsMx.ErrNilStatusComponentsFactory, err) require.Nil(t, managedStatusComponents) }) t.Run("should work", func(t *testing.T) { - t.Parallel() - scf, err := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) require.Nil(t, err) managedStatusComponents, err := statusComp.NewManagedStatusComponents(scf) @@ -37,11 +33,9 @@ func TestNewManagedStatusComponents(t *testing.T) { } func TestManagedStatusComponents_Create(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("invalid params should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.StatusCoreComponents = &factoryMocks.StatusCoreComponentsStub{ AppStatusHandlerField: nil, @@ -56,8 +50,6 @@ func TestManagedStatusComponents_Create(t *testing.T) { require.Error(t, err) }) t.Run("should work with getters", func(t *testing.T) { - t.Parallel() - scf, err := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) require.Nil(t, err) managedStatusComponents, err := statusComp.NewManagedStatusComponents(scf) @@ -78,7 +70,7 @@ func TestManagedStatusComponents_Create(t *testing.T) { } func TestManagedStatusComponents_Close(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components scf, _ := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) managedStatusComponents, _ := statusComp.NewManagedStatusComponents(scf) @@ -96,7 +88,7 @@ func TestManagedStatusComponents_Close(t *testing.T) { } func TestManagedStatusComponents_CheckSubcomponents(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components scf, _ := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) managedStatusComponents, _ := statusComp.NewManagedStatusComponents(scf) @@ -112,7 +104,7 @@ func TestManagedStatusComponents_CheckSubcomponents(t *testing.T) { } func TestManagedStatusComponents_SetForkDetector(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components scf, _ := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) managedStatusComponents, _ := statusComp.NewManagedStatusComponents(scf) @@ -126,11 +118,9 @@ func TestManagedStatusComponents_SetForkDetector(t *testing.T) { } func TestManagedStatusComponents_StartPolling(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("NewAppStatusPolling fails should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.Config.GeneralSettings.StatusPollingIntervalSec = 0 scf, _ := statusComp.NewStatusComponentsFactory(args) @@ -142,8 +132,6 @@ func TestManagedStatusComponents_StartPolling(t *testing.T) { require.Equal(t, errorsMx.ErrStatusPollingInit, err) }) t.Run("RegisterPollingFunc fails should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.Config.GeneralSettings.StatusPollingIntervalSec = 0 scf, _ := statusComp.NewStatusComponentsFactory(args) @@ -155,8 +143,6 @@ func TestManagedStatusComponents_StartPolling(t *testing.T) { require.Equal(t, errorsMx.ErrStatusPollingInit, err) }) t.Run("should work", func(t *testing.T) { - t.Parallel() - scf, _ := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) managedStatusComponents, _ := statusComp.NewManagedStatusComponents(scf) err := managedStatusComponents.Create() @@ -168,7 +154,7 @@ func TestManagedStatusComponents_StartPolling(t *testing.T) { } func TestComputeNumConnectedPeers(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("main network", testComputeNumConnectedPeers("")) t.Run("full archive network", testComputeNumConnectedPeers(common.FullArchiveMetricSuffix)) @@ -176,8 +162,6 @@ func TestComputeNumConnectedPeers(t *testing.T) { func testComputeNumConnectedPeers(suffix string) func(t *testing.T) { return func(t *testing.T) { - t.Parallel() - netMes := &p2pmocks.MessengerStub{ ConnectedAddressesCalled: func() []string { return []string{"addr1", "addr2", "addr3"} @@ -195,7 +179,7 @@ func testComputeNumConnectedPeers(suffix string) func(t *testing.T) { } func TestComputeConnectedPeers(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("main network", testComputeConnectedPeers("")) t.Run("full archive network", testComputeConnectedPeers(common.FullArchiveMetricSuffix)) @@ -203,8 +187,6 @@ func TestComputeConnectedPeers(t *testing.T) { func testComputeConnectedPeers(suffix string) func(t *testing.T) { return func(t *testing.T) { - t.Parallel() - netMes := &p2pmocks.MessengerStub{ GetConnectedPeersInfoCalled: func() *p2p.ConnectedPeersInfo { return &p2p.ConnectedPeersInfo{ @@ -294,7 +276,7 @@ func testComputeConnectedPeers(suffix string) func(t *testing.T) { } func TestManagedStatusComponents_IsInterfaceNil(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components managedStatusComponents, _ := statusComp.NewManagedStatusComponents(nil) require.True(t, managedStatusComponents.IsInterfaceNil()) diff --git a/factory/status/statusComponents_test.go b/factory/status/statusComponents_test.go index 4505a0d6a77..61809df0e7f 100644 --- a/factory/status/statusComponents_test.go +++ b/factory/status/statusComponents_test.go @@ -67,11 +67,9 @@ func createMockStatusComponentsFactoryArgs() statusComp.StatusComponentsFactoryA } func TestNewStatusComponentsFactory(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("nil CoreComponents should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.CoreComponents = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -79,8 +77,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilCoreComponentsHolder, err) }) t.Run("CoreComponents with nil GenesisNodesSetup should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.CoreComponents = &mock.CoreComponentsMock{ NodesConfig: nil, @@ -90,8 +86,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilGenesisNodesSetupHandler, err) }) t.Run("nil NetworkComponents should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.NetworkComponents = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -99,8 +93,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilNetworkComponentsHolder, err) }) t.Run("nil ShardCoordinator should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.ShardCoordinator = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -108,8 +100,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilShardCoordinator, err) }) t.Run("nil NodesCoordinator should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.NodesCoordinator = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -117,8 +107,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilNodesCoordinator, err) }) t.Run("nil EpochStartNotifier should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.EpochStartNotifier = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -126,8 +114,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilEpochStartNotifier, err) }) t.Run("nil StatusCoreComponents should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.StatusCoreComponents = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -135,8 +121,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilStatusCoreComponents, err) }) t.Run("nil CryptoComponents should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.CryptoComponents = nil scf, err := statusComp.NewStatusComponentsFactory(args) @@ -144,8 +128,6 @@ func TestNewStatusComponentsFactory(t *testing.T) { require.Equal(t, errorsMx.ErrNilCryptoComponents, err) }) t.Run("should work", func(t *testing.T) { - t.Parallel() - scf, err := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) require.NotNil(t, scf) require.NoError(t, err) @@ -153,11 +135,9 @@ func TestNewStatusComponentsFactory(t *testing.T) { } func TestStatusComponentsFactory_Create(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components t.Run("NewSoftwareVersionFactory fails should return error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.StatusCoreComponents = &factory.StatusCoreComponentsStub{ AppStatusHandlerField: nil, // make NewSoftwareVersionFactory fail @@ -170,8 +150,6 @@ func TestStatusComponentsFactory_Create(t *testing.T) { require.Nil(t, sc) }) t.Run("softwareVersionCheckerFactory.Create fails should return error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.Config.SoftwareVersionConfig.PollingIntervalInMinutes = 0 scf, _ := statusComp.NewStatusComponentsFactory(args) @@ -182,8 +160,6 @@ func TestStatusComponentsFactory_Create(t *testing.T) { require.Nil(t, sc) }) t.Run("invalid round duration should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.CoreComponents = &mock.CoreComponentsMock{ NodesConfig: &genesisMocks.NodesSetupStub{ @@ -200,8 +176,6 @@ func TestStatusComponentsFactory_Create(t *testing.T) { require.Nil(t, sc) }) t.Run("makeWebSocketDriverArgs fails due to invalid marshaller type should error", func(t *testing.T) { - t.Parallel() - args := createMockStatusComponentsFactoryArgs() args.ExternalConfig.HostDriversConfig[0].Enabled = true args.ExternalConfig.HostDriversConfig[0].MarshallerType = "invalid type" @@ -213,8 +187,6 @@ func TestStatusComponentsFactory_Create(t *testing.T) { require.Nil(t, sc) }) t.Run("should work", func(t *testing.T) { - t.Parallel() - shardCoordinator := mock.NewMultiShardsCoordinatorMock(2) shardCoordinator.SelfIDCalled = func() uint32 { return core.MetachainShardId // coverage @@ -233,7 +205,7 @@ func TestStatusComponentsFactory_Create(t *testing.T) { } func TestStatusComponentsFactory_epochStartEventHandler(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components args := createMockStatusComponentsFactoryArgs() args.NodesCoordinator = &shardingMocks.NodesCoordinatorStub{ @@ -253,7 +225,7 @@ func TestStatusComponentsFactory_epochStartEventHandler(t *testing.T) { } func TestStatusComponentsFactory_IsInterfaceNil(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components args := createMockStatusComponentsFactoryArgs() args.CoreComponents = nil @@ -265,7 +237,7 @@ func TestStatusComponentsFactory_IsInterfaceNil(t *testing.T) { } func TestStatusComponents_Close(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components scf, _ := statusComp.NewStatusComponentsFactory(createMockStatusComponentsFactoryArgs()) cc, err := scf.Create() @@ -276,7 +248,7 @@ func TestStatusComponents_Close(t *testing.T) { } func TestMakeHostDriversArgs(t *testing.T) { - t.Parallel() + // no t.Parallel for these tests as they create real components args := createMockStatusComponentsFactoryArgs() args.ExternalConfig.HostDriversConfig = []config.HostDriversConfig{ diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index efd45706f29..a5292d72e40 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -474,9 +474,9 @@ func (s *simulator) SendTxsAndGenerateBlocksTilAreExecuted(txsToSend []*transact return nil, errors.New("something went wrong. Transaction(s) is/are still in pending") } -func (s *simulator) computeTransactionsStatus(status []*transactionWithResult) bool { +func (s *simulator) computeTransactionsStatus(txsWithResult []*transactionWithResult) bool { allAreExecuted := true - for _, resultTx := range status { + for _, resultTx := range txsWithResult { if resultTx.result != nil { continue } diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index a5e3945aa99..1a65b37ff78 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -327,7 +327,9 @@ func TestChainSimulator_GetAccount(t *testing.T) { } func TestSimulator_SendTransactions(t *testing.T) { - t.Parallel() + if testing.Short() { + t.Skip("this is not a short test") + } startTime := time.Now().Unix() roundDurationInMillis := uint64(6000) From 88779d85a1425a4b59e5a0e10efb061980bfeb60 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 29 Feb 2024 21:27:01 +0200 Subject: [PATCH 893/958] - fixed chain simulator's synced messenger to prepare the Peer field in the message --- node/chainSimulator/components/syncedBroadcastNetwork.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/chainSimulator/components/syncedBroadcastNetwork.go b/node/chainSimulator/components/syncedBroadcastNetwork.go index 572689b0c0a..99e8168c45e 100644 --- a/node/chainSimulator/components/syncedBroadcastNetwork.go +++ b/node/chainSimulator/components/syncedBroadcastNetwork.go @@ -62,6 +62,7 @@ func (network *syncedBroadcastNetwork) Broadcast(pid core.PeerID, topic string, DataField: buff, TopicField: topic, BroadcastMethodField: p2p.Broadcast, + PeerField: pid, } handler.receive(pid, message) @@ -84,6 +85,7 @@ func (network *syncedBroadcastNetwork) SendDirectly(from core.PeerID, topic stri DataField: buff, TopicField: topic, BroadcastMethodField: p2p.Direct, + PeerField: from, } handler.receive(from, message) From 26883ef1e91b25f882404ded8cb36fe75b608756 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 29 Feb 2024 21:33:14 +0200 Subject: [PATCH 894/958] - unit tests --- .../components/syncedBroadcastNetwork_test.go | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/node/chainSimulator/components/syncedBroadcastNetwork_test.go b/node/chainSimulator/components/syncedBroadcastNetwork_test.go index 1067e1155be..74e061a819a 100644 --- a/node/chainSimulator/components/syncedBroadcastNetwork_test.go +++ b/node/chainSimulator/components/syncedBroadcastNetwork_test.go @@ -23,7 +23,7 @@ func TestSyncedBroadcastNetwork_BroadcastShouldWorkOn3Peers(t *testing.T) { peer1, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor1 := createMessageProcessor(messages, peer1.ID()) + processor1 := createMessageProcessor(t, messages, peer1.ID()) _ = peer1.CreateTopic(globalTopic, true) _ = peer1.RegisterMessageProcessor(globalTopic, "", processor1) _ = peer1.CreateTopic(oneTwoTopic, true) @@ -33,7 +33,7 @@ func TestSyncedBroadcastNetwork_BroadcastShouldWorkOn3Peers(t *testing.T) { peer2, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor2 := createMessageProcessor(messages, peer2.ID()) + processor2 := createMessageProcessor(t, messages, peer2.ID()) _ = peer2.CreateTopic(globalTopic, true) _ = peer2.RegisterMessageProcessor(globalTopic, "", processor2) _ = peer2.CreateTopic(oneTwoTopic, true) @@ -43,7 +43,7 @@ func TestSyncedBroadcastNetwork_BroadcastShouldWorkOn3Peers(t *testing.T) { peer3, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor3 := createMessageProcessor(messages, peer3.ID()) + processor3 := createMessageProcessor(t, messages, peer3.ID()) _ = peer3.CreateTopic(globalTopic, true) _ = peer3.RegisterMessageProcessor(globalTopic, "", processor3) _ = peer3.CreateTopic(oneThreeTopic, true) @@ -88,13 +88,13 @@ func TestSyncedBroadcastNetwork_BroadcastOnAnUnjoinedTopicShouldDiscardMessage(t peer1, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor1 := createMessageProcessor(messages, peer1.ID()) + processor1 := createMessageProcessor(t, messages, peer1.ID()) _ = peer1.CreateTopic(globalTopic, true) _ = peer1.RegisterMessageProcessor(globalTopic, "", processor1) peer2, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor2 := createMessageProcessor(messages, peer2.ID()) + processor2 := createMessageProcessor(t, messages, peer2.ID()) _ = peer2.CreateTopic(globalTopic, true) _ = peer2.RegisterMessageProcessor(globalTopic, "", processor2) _ = peer2.CreateTopic(twoThreeTopic, true) @@ -102,7 +102,7 @@ func TestSyncedBroadcastNetwork_BroadcastOnAnUnjoinedTopicShouldDiscardMessage(t peer3, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor3 := createMessageProcessor(messages, peer3.ID()) + processor3 := createMessageProcessor(t, messages, peer3.ID()) _ = peer3.CreateTopic(globalTopic, true) _ = peer3.RegisterMessageProcessor(globalTopic, "", processor3) _ = peer3.CreateTopic(twoThreeTopic, true) @@ -128,13 +128,13 @@ func TestSyncedBroadcastNetwork_SendDirectlyShouldWorkBetween2peers(t *testing.T peer1, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor1 := createMessageProcessor(messages, peer1.ID()) + processor1 := createMessageProcessor(t, messages, peer1.ID()) _ = peer1.CreateTopic(topic, true) _ = peer1.RegisterMessageProcessor(topic, "", processor1) peer2, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor2 := createMessageProcessor(messages, peer2.ID()) + processor2 := createMessageProcessor(t, messages, peer2.ID()) _ = peer2.CreateTopic(topic, true) _ = peer2.RegisterMessageProcessor(topic, "", processor2) @@ -156,13 +156,13 @@ func TestSyncedBroadcastNetwork_SendDirectlyToSelfShouldWork(t *testing.T) { peer1, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor1 := createMessageProcessor(messages, peer1.ID()) + processor1 := createMessageProcessor(t, messages, peer1.ID()) _ = peer1.CreateTopic(topic, true) _ = peer1.RegisterMessageProcessor(topic, "", processor1) peer2, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor2 := createMessageProcessor(messages, peer2.ID()) + processor2 := createMessageProcessor(t, messages, peer2.ID()) _ = peer2.CreateTopic(topic, true) _ = peer2.RegisterMessageProcessor(topic, "", processor2) @@ -184,7 +184,7 @@ func TestSyncedBroadcastNetwork_SendDirectlyShouldNotDeadlock(t *testing.T) { peer1, err := NewSyncedMessenger(network) assert.Nil(t, err) - processor1 := createMessageProcessor(messages, peer1.ID()) + processor1 := createMessageProcessor(t, messages, peer1.ID()) _ = peer1.CreateTopic(topic, true) _ = peer1.RegisterMessageProcessor(topic, "", processor1) @@ -283,7 +283,7 @@ func TestSyncedBroadcastNetwork_GetConnectedPeersOnTopic(t *testing.T) { assert.Equal(t, 3, len(peersInfo.UnknownPeers)) } -func createMessageProcessor(dataMap map[core.PeerID]map[string][]byte, pid core.PeerID) p2p.MessageProcessor { +func createMessageProcessor(t *testing.T, dataMap map[core.PeerID]map[string][]byte, pid core.PeerID) p2p.MessageProcessor { return &p2pmocks.MessageProcessorStub{ ProcessReceivedMessageCalled: func(message p2p.MessageP2P, fromConnectedPeer core.PeerID, source p2p.MessageHandler) error { m, found := dataMap[pid] @@ -292,6 +292,9 @@ func createMessageProcessor(dataMap map[core.PeerID]map[string][]byte, pid core. dataMap[pid] = m } + // some interceptors/resolvers require that the peer field should be the same + assert.Equal(t, message.Peer().Bytes(), message.From()) + assert.Equal(t, message.Peer(), fromConnectedPeer) m[message.Topic()] = message.Data() return nil From 707530bb764213f70df2f4cc38c689ad98f9007c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 1 Mar 2024 12:14:57 +0200 Subject: [PATCH 895/958] Remember latest queried epoch. --- process/smartContract/scQueryService.go | 31 +++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index b243a8db2b0..47d0348dab2 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -33,7 +33,6 @@ var logQueryService = logger.GetOrCreate("process/smartcontract.queryService") // MaxGasLimitPerQuery - each unit is the equivalent of 1 nanosecond processing time const MaxGasLimitPerQuery = 300_000_000_000 -const epochDifferenceToConsiderHistory = 2 // SCQueryService can execute Get functions over SC to fetch stored values type SCQueryService struct { @@ -53,6 +52,7 @@ type SCQueryService struct { marshaller marshal.Marshalizer hasher hashing.Hasher uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter + latestQueriedEpoch core.OptionalUint32 } // ArgsNewSCQueryService defines the arguments needed for the sc query service @@ -103,6 +103,7 @@ func NewSCQueryService( marshaller: args.Marshaller, hasher: args.Hasher, uint64ByteSliceConverter: args.Uint64ByteSliceConverter, + latestQueriedEpoch: core.OptionalUint32{}, }, nil } @@ -255,14 +256,36 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da } accountsAdapter := service.blockChainHook.GetAccountsAdapter() - if blockHeader.GetEpoch()+epochDifferenceToConsiderHistory >= service.getCurrentEpoch() { + + if service.isLatestQueriedEpoch(blockHeader.GetEpoch()) { logQueryService.Trace("calling RecreateTrie, for recent history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) - return accountsAdapter.RecreateTrie(blockRootHash) + + err := accountsAdapter.RecreateTrie(blockRootHash) + if err != nil { + return err + } + + service.rememberQueriedEpoch(blockHeader.GetEpoch()) } logQueryService.Trace("calling RecreateTrieFromEpoch, for older history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) - return accountsAdapter.RecreateTrieFromEpoch(holder) + + err := accountsAdapter.RecreateTrieFromEpoch(holder) + if err != nil { + return err + } + + service.rememberQueriedEpoch(blockHeader.GetEpoch()) + return err +} + +func (service *SCQueryService) isLatestQueriedEpoch(epoch uint32) bool { + return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epoch +} + +func (service *SCQueryService) rememberQueriedEpoch(epoch uint32) { + service.latestQueriedEpoch = core.OptionalUint32{Value: epoch, HasValue: true} } func (service *SCQueryService) getCurrentEpoch() uint32 { From 0bbe9dfb2ebe25a4991036b166b7ead56eba2fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 1 Mar 2024 13:24:54 +0200 Subject: [PATCH 896/958] Fix after review. --- process/smartContract/scQueryService.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 47d0348dab2..7e83f278272 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -266,6 +266,7 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da } service.rememberQueriedEpoch(blockHeader.GetEpoch()) + return nil } logQueryService.Trace("calling RecreateTrieFromEpoch, for older history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) @@ -277,7 +278,7 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da } service.rememberQueriedEpoch(blockHeader.GetEpoch()) - return err + return nil } func (service *SCQueryService) isLatestQueriedEpoch(epoch uint32) bool { From 8d43578cf0d40c3056ea849bb3577851eea31ae3 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 1 Mar 2024 13:56:33 +0200 Subject: [PATCH 897/958] - added staking v4 scenario 11 --- integrationTests/chainSimulator/interface.go | 4 + .../chainSimulator/staking/delegation_test.go | 280 +++++++++++++++++- 2 files changed, 283 insertions(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/interface.go b/integrationTests/chainSimulator/interface.go index 90d3793378e..6d66b9d62c0 100644 --- a/integrationTests/chainSimulator/interface.go +++ b/integrationTests/chainSimulator/interface.go @@ -3,6 +3,7 @@ package chainSimulator import ( "math/big" + "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/node/chainSimulator/process" @@ -15,6 +16,9 @@ type ChainSimulator interface { AddValidatorKeys(validatorsPrivateKeys [][]byte) error GetNodeHandler(shardID uint32) process.NodeHandler SendTxAndGenerateBlockTilTxIsExecuted(txToSend *transaction.Transaction, maxNumOfBlockToGenerateWhenExecutingTx int) (*transaction.ApiTransactionResult, error) + SendTxsAndGenerateBlocksTilAreExecuted(txsToSend []*transaction.Transaction, maxNumOfBlocksToGenerateWhenExecutingTx int) ([]*transaction.ApiTransactionResult, error) SetStateMultiple(stateSlice []*dtos.AddressState) error GenerateAndMintWalletAddress(targetShardID uint32, value *big.Int) (dtos.WalletAddress, error) + GetInitialWalletKeys() *dtos.InitialWalletKeys + GetAccount(address dtos.WalletAddress) (api.AccountResponse, error) } diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 73462ff46f8..831f1beaa05 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -361,7 +361,16 @@ func testBLSKeyIsInAuction( require.Equal(t, actionListSize, len(auctionList)) if actionListSize != 0 { require.Equal(t, 1, len(auctionList[0].Nodes)) - require.Equal(t, topUpInAuctionList.String(), auctionList[0].TopUpPerNode) + nodeWasFound := false + for _, item := range auctionList { + for _, node := range item.Nodes { + if node.BlsKey == blsKey { + require.Equal(t, topUpInAuctionList.String(), item.TopUpPerNode) + nodeWasFound = true + } + } + } + require.True(t, nodeWasFound) } // in staking ph 4 we should find the key in the validators statics @@ -370,6 +379,253 @@ func testBLSKeyIsInAuction( require.Equal(t, auctionStatus, validatorInfo.ValidatorStatus) } +// Test description: +// Test that 2 diferent contracts with different topups that came from the normal stake will be considered in auction list computing in the correct order +// 1. Add 2 new validator private keys in the multi key handler +// 2. Set the initial state for 2 owners (mint 2 new wallets) +// 3. Do 2 stake transactions and test that the new keys are on queue / auction list and have the correct topup - 100 and 200 EGLD, respectively +// 4. Convert both validators into staking providers and test that the new keys are on queue / auction list and have the correct topup +// 5. If the staking v4 is activated (regardless the steps), check that the auction list sorted the 2 BLS keys based on topup + +// Internal test scenario #11 +func TestChainSimulator_MakeNewContractFromValidatorDataWith2StakingContracts(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 1) + }) + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 2) + }) + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 3) + }) + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 4) + }) +} + +func testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + log.Info("Step 1. Add 2 new validator private keys in the multi key handler") + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(2) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKeys) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + log.Info("Step 2. Set the initial state for 2 owners") + mintValue := big.NewInt(3010) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwnerA, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + validatorOwnerB, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + log.Info("working with the following addresses", + "validatorOwnerA", validatorOwnerA.Bech32, "validatorOwnerB", validatorOwnerB.Bech32) + + log.Info("Step 3. Do 2 stake transactions and test that the new keys are on queue / auction list and have the correct topup") + + topupA := big.NewInt(0).Mul(oneEGLD, big.NewInt(100)) + stakeValueA := big.NewInt(0).Add(minimumStakeValue, topupA) + txStakeA := generateStakeTransaction(t, cs, validatorOwnerA, blsKeys[0], stakeValueA) + + topupB := big.NewInt(0).Mul(oneEGLD, big.NewInt(200)) + stakeValueB := big.NewInt(0).Add(minimumStakeValue, topupB) + txStakeB := generateStakeTransaction(t, cs, validatorOwnerB, blsKeys[1], stakeValueB) + + stakeTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txStakeA, txStakeB}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 2, len(stakeTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorOwnerA.Bytes, blsKeys[0], topupA, 2) + testBLSKeyIsInQueueOrAuction(t, metachainNode, validatorOwnerB.Bytes, blsKeys[1], topupB, 2) + + log.Info("Step 4. Convert both validators into staking providers and test that the new keys are on queue / auction list and have the correct topup") + + txConvertA := generateConvertToStakingProviderTransaction(t, cs, validatorOwnerA) + txConvertB := generateConvertToStakingProviderTransaction(t, cs, validatorOwnerB) + + convertTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txConvertA, txConvertB}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 2, len(convertTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + delegationAddressA := convertTxs[0].Logs.Events[0].Topics[1] + delegationAddressB := convertTxs[1].Logs.Events[0].Topics[1] + + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddressA, blsKeys[0], topupA, 2) + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddressB, blsKeys[1], topupB, 2) + + log.Info("Step 5. If the staking v4 is activated, check that the auction list sorted the 2 BLS keys based on topup") + step1ActivationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) + if step1ActivationEpoch > metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { + // we are in staking v3.5, the test ends here + return + } + + auctionList, err := metachainNode.GetProcessComponents().ValidatorsProvider().GetAuctionList() + require.Nil(t, err) + + firstAuctionPosition := auctionList[0] + secondAuctionPosition := auctionList[1] + // check the correct order of the nodes in the auction list based on topup + require.Equal(t, blsKeys[1], firstAuctionPosition.Nodes[0].BlsKey) + require.Equal(t, topupB.String(), firstAuctionPosition.TopUpPerNode) + + require.Equal(t, blsKeys[0], secondAuctionPosition.Nodes[0].BlsKey) + require.Equal(t, topupA.String(), secondAuctionPosition.TopUpPerNode) +} + +func generateStakeTransaction( + t *testing.T, + cs chainSimulatorIntegrationTests.ChainSimulator, + owner dtos.WalletAddress, + blsKeyHex string, + stakeValue *big.Int, +) *transaction.Transaction { + account, err := cs.GetAccount(owner) + require.Nil(t, err) + + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeyHex, mockBLSSignature) + return generateTransaction(owner.Bytes, account.Nonce, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) +} + +func generateConvertToStakingProviderTransaction( + t *testing.T, + cs chainSimulatorIntegrationTests.ChainSimulator, + owner dtos.WalletAddress, +) *transaction.Transaction { + account, err := cs.GetAccount(owner) + require.Nil(t, err) + + txDataField := fmt.Sprintf("makeNewContractFromValidatorData@%s@%s", maxCap, hexServiceFee) + return generateTransaction(owner.Bytes, account.Nonce, vm.DelegationManagerSCAddress, zeroValue, txDataField, gasLimitForConvertOperation) +} + // Test description // Test the creation of a new delegation contract, adding nodes to it, delegating, and undelegating. @@ -1110,3 +1366,25 @@ func getBLSKeyOwner(t *testing.T, metachainNode chainSimulatorProcess.NodeHandle return result.ReturnData[0] } + +func getBLSKeys(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, ownerKeyBytes []byte) [][]byte { + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getBlsKeysStatus", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{ownerKeyBytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + blsKeys := make([][]byte, 0) + for idx, data := range result.ReturnData { + if idx%2 == 0 { + blsKeys = append(blsKeys, data) + } + } + + return blsKeys +} From e731ccb53f2d7a53b1eee5dfe8be5432ea40b007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 1 Mar 2024 14:34:42 +0200 Subject: [PATCH 898/958] Fix tests. --- process/smartContract/scQueryService_test.go | 219 +++++++++---------- 1 file changed, 99 insertions(+), 120 deletions(-) diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index cd31bc165ec..10d57414305 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -367,10 +367,11 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) }) - t.Run("block hash should work - old epoch", func(t *testing.T) { + t.Run("block hash should work - when epoch is different from latest queried epoch", func(t *testing.T) { t.Parallel() runWasCalled := false + epoch := uint32(37) mockVM := &mock.VMExecutionHandlerStub{ RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { @@ -399,7 +400,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { return &block.Header{ - Epoch: 37, + Epoch: epoch, } }, } @@ -429,13 +430,20 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return true }, GetEpochByHashCalled: func(hash []byte) (uint32, error) { - return 12, nil + return epoch, nil }, } + recreateTrieWasCalled := false + recreateTrieFromEpochWasCalled := false + providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + RecreateTrieCalled: func(rootHash []byte) error { recreateTrieWasCalled = true + return nil + }, + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieFromEpochWasCalled = true assert.Equal(t, providedRootHash, options.GetRootHash()) return nil }, @@ -447,6 +455,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { } target, _ := NewSCQueryService(argsNewSCQuery) + target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 5} dataArgs := make([][]byte, len(args)) for i, arg := range args { @@ -461,12 +470,14 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, err := target.ExecuteQuery(&query) assert.True(t, runWasCalled) - assert.True(t, recreateTrieWasCalled) + assert.True(t, recreateTrieFromEpochWasCalled) + assert.False(t, recreateTrieWasCalled) assert.Nil(t, err) }) - t.Run("block hash should work - current epoch", func(t *testing.T) { + t.Run("block hash should work - when epoch is same as latest queried epoch", func(t *testing.T) { t.Parallel() + epoch := uint32(12) runWasCalled := false mockVM := &mock.VMExecutionHandlerStub{ @@ -502,6 +513,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { hdr := &block.Header{ RootHash: providedRootHash, + Epoch: epoch, } buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) return buff, nil @@ -514,16 +526,23 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return true }, GetEpochByHashCalled: func(hash []byte) (uint32, error) { - return 12, nil + return epoch, nil }, } + recreateTrieWasCalled := false + recreateTrieFromEpochWasCalled := false + providedAccountsAdapter := &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { recreateTrieWasCalled = true assert.Equal(t, providedRootHash, rootHash) return nil }, + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieFromEpochWasCalled = true + return nil + }, } argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ GetAccountsAdapterCalled: func() state.AccountsAdapter { @@ -532,6 +551,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { } target, _ := NewSCQueryService(argsNewSCQuery) + target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: epoch} dataArgs := make([][]byte, len(args)) for i, arg := range args { @@ -547,12 +567,14 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, err := target.ExecuteQuery(&query) assert.True(t, runWasCalled) assert.True(t, recreateTrieWasCalled) + assert.False(t, recreateTrieFromEpochWasCalled) assert.Nil(t, err) }) - t.Run("block nonce should work - old epoch", func(t *testing.T) { + t.Run("block nonce should work - when epoch is different from latest queried epoch", func(t *testing.T) { t.Parallel() runWasCalled := false + epoch := uint32(37) mockVM := &mock.VMExecutionHandlerStub{ RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { @@ -571,7 +593,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { return &block.Header{ - Epoch: 37, + Epoch: epoch, } }, } @@ -616,13 +638,20 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { }, GetEpochByHashCalled: func(hash []byte) (uint32, error) { require.Equal(t, providedHash, hash) - return 12, nil + return epoch, nil }, } + recreateTrieWasCalled := false + recreateTrieFromEpochWasCalled := false + providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + RecreateTrieCalled: func(rootHash []byte) error { recreateTrieWasCalled = true + return nil + }, + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieFromEpochWasCalled = true assert.Equal(t, providedRootHash, options.GetRootHash()) return nil }, @@ -634,6 +663,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { } target, _ := NewSCQueryService(argsNewSCQuery) + target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 5} dataArgs := make([][]byte, len(args)) for i, arg := range args { @@ -651,12 +681,14 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) - assert.True(t, recreateTrieWasCalled) + assert.True(t, recreateTrieFromEpochWasCalled) + assert.False(t, recreateTrieWasCalled) }) - t.Run("block nonce should work - current epoch", func(t *testing.T) { + t.Run("block nonce should work - when epoch is same as latest queried epoch", func(t *testing.T) { t.Parallel() runWasCalled := false + epoch := uint32(12) mockVM := &mock.VMExecutionHandlerStub{ RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { @@ -695,6 +727,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { hdr := &block.Header{ RootHash: providedRootHash, + Epoch: epoch, } buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) return buff, nil @@ -708,16 +741,23 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { }, GetEpochByHashCalled: func(hash []byte) (uint32, error) { require.Equal(t, providedHash, hash) - return 12, nil + return epoch, nil }, } + recreateTrieWasCalled := false + recreateTrieFromEpochWasCalled := false + providedAccountsAdapter := &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { recreateTrieWasCalled = true assert.Equal(t, providedRootHash, rootHash) return nil }, + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieFromEpochWasCalled = true + return nil + }, } argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ GetAccountsAdapterCalled: func() state.AccountsAdapter { @@ -726,6 +766,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { } target, _ := NewSCQueryService(argsNewSCQuery) + target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: epoch} dataArgs := make([][]byte, len(args)) for i, arg := range args { @@ -744,6 +785,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) assert.True(t, recreateTrieWasCalled) + assert.False(t, recreateTrieFromEpochWasCalled) }) } @@ -770,10 +812,12 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { err := service.recreateTrie(testRootHash, nil) assert.ErrorIs(t, err, process.ErrNilBlockHeader) }) - t.Run("should call RecreateTrie for genesis block", func(t *testing.T) { + t.Run("should call RecreateTrieFromEpoch, remember epoch, then call RecreateTrie (for genesis block, then blocks in other epochs)", func(t *testing.T) { t.Parallel() recreateTrieWasCalled := false + recreateTrieFromEpochWasCalled := false + argsNewSCQuery := createMockArgumentsForSCQuery() argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { @@ -785,36 +829,16 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { return &stateMocks.AccountsStub{ RecreateTrieCalled: func(rootHash []byte) error { recreateTrieWasCalled = true + recreateTrieFromEpochWasCalled = false + assert.Equal(t, testRootHash, rootHash) return nil }, - } - }, - } - - service, _ := NewSCQueryService(argsNewSCQuery) - err := service.recreateTrie(testRootHash, &block.Header{}) - assert.Nil(t, err) - assert.True(t, recreateTrieWasCalled) - }) - t.Run("should call RecreateTrie for block on epoch 0", func(t *testing.T) { - t.Parallel() + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieWasCalled = false + recreateTrieFromEpochWasCalled = true - recreateTrieWasCalled := false - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: 0, - } - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieWasCalled = true - assert.Equal(t, testRootHash, rootHash) + assert.Equal(t, testRootHash, options.GetRootHash()) return nil }, } @@ -822,102 +846,57 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { } service, _ := NewSCQueryService(argsNewSCQuery) + assert.Equal(t, core.OptionalUint32{HasValue: false}, service.latestQueriedEpoch) + + // For genesis block, RecreateTrieFromEpoch should be called err := service.recreateTrie(testRootHash, &block.Header{}) assert.Nil(t, err) - assert.True(t, recreateTrieWasCalled) - }) - t.Run("should call RecreateTrie for block on epoch 1", func(t *testing.T) { - t.Parallel() + assert.True(t, recreateTrieFromEpochWasCalled) + assert.False(t, recreateTrieWasCalled) + assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) - recreateTrieWasCalled := false - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: 1, - } - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieWasCalled = true - assert.Equal(t, testRootHash, rootHash) - return nil - }, - } - }, - } + // For genesis block, RecreateTrie should be called + err = service.recreateTrie(testRootHash, &block.Header{}) + assert.Nil(t, err) + assert.False(t, recreateTrieFromEpochWasCalled) + assert.True(t, recreateTrieWasCalled) + assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) - service, _ := NewSCQueryService(argsNewSCQuery) - err := service.recreateTrie(testRootHash, &block.Header{ + // For block in epoch 0, RecreateTrie should be called + err = service.recreateTrie(testRootHash, &block.Header{ Epoch: 0, }) assert.Nil(t, err) + assert.False(t, recreateTrieFromEpochWasCalled) assert.True(t, recreateTrieWasCalled) - }) - t.Run("should call RecreateTrie for block on epoch 2", func(t *testing.T) { - t.Parallel() + assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) - recreateTrieWasCalled := false - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: 3, - } - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieWasCalled = true - assert.Equal(t, testRootHash, rootHash) - return nil - }, - } - }, - } + // For block in epoch 1, RecreateTrieFromEpoch should be called + err = service.recreateTrie(testRootHash, &block.Header{ + Epoch: 1, + }) + assert.Nil(t, err) + assert.True(t, recreateTrieFromEpochWasCalled) + assert.False(t, recreateTrieWasCalled) + assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 1}, service.latestQueriedEpoch) - service, _ := NewSCQueryService(argsNewSCQuery) - err := service.recreateTrie(testRootHash, &block.Header{ - Epoch: 2, + // For block in epoch 1, RecreateTrie should be called + err = service.recreateTrie(testRootHash, &block.Header{ + Epoch: 1, }) assert.Nil(t, err) + assert.False(t, recreateTrieFromEpochWasCalled) assert.True(t, recreateTrieWasCalled) - }) - t.Run("should call RecreateTrieFromEpoch for block on epoch 3", func(t *testing.T) { - t.Parallel() - - recreateTrieWasCalled := false - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: 3, - } - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return &stateMocks.AccountsStub{ - RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - recreateTrieWasCalled = true - assert.Equal(t, testRootHash, options.GetRootHash()) - return nil - }, - } - }, - } + assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 1}, service.latestQueriedEpoch) - service, _ := NewSCQueryService(argsNewSCQuery) - err := service.recreateTrie(testRootHash, &block.Header{ + // For block in epoch 0, RecreateTrieFromEpoch should be called + err = service.recreateTrie(testRootHash, &block.Header{ Epoch: 0, }) assert.Nil(t, err) - assert.True(t, recreateTrieWasCalled) + assert.True(t, recreateTrieFromEpochWasCalled) + assert.False(t, recreateTrieWasCalled) + assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) }) } From 211beab90854f6902df1af403c0fb1a15fee3fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 1 Mar 2024 15:19:20 +0200 Subject: [PATCH 899/958] Fix condition for RecreateTrie. --- process/smartContract/scQueryService.go | 18 +++++-- process/smartContract/scQueryService_test.go | 50 +++++++++++++++++++- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 7e83f278272..8b65e1a203f 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -257,8 +257,8 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da accountsAdapter := service.blockChainHook.GetAccountsAdapter() - if service.isLatestQueriedEpoch(blockHeader.GetEpoch()) { - logQueryService.Trace("calling RecreateTrie, for recent history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + if service.shouldCallRecreateTrieWithoutEpoch(blockHeader.GetEpoch()) { + logQueryService.Trace("calling RecreateTrie", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) err := accountsAdapter.RecreateTrie(blockRootHash) if err != nil { @@ -269,7 +269,7 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da return nil } - logQueryService.Trace("calling RecreateTrieFromEpoch, for older history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + logQueryService.Trace("calling RecreateTrieFromEpoch", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) err := accountsAdapter.RecreateTrieFromEpoch(holder) @@ -281,8 +281,16 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da return nil } -func (service *SCQueryService) isLatestQueriedEpoch(epoch uint32) bool { - return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epoch +func (service *SCQueryService) shouldCallRecreateTrieWithoutEpoch(epochInQuestion uint32) bool { + if service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epochInQuestion { + return true + } + + if !service.latestQueriedEpoch.HasValue && epochInQuestion == service.getCurrentEpoch() { + return true + } + + return false } func (service *SCQueryService) rememberQueriedEpoch(epoch uint32) { diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 10d57414305..a411afaa97b 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -789,6 +789,54 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { }) } +func TestSCQueryService_ShouldCallRecreateTrieWithoutEpoch(t *testing.T) { + t.Parallel() + + currentEpoch := uint32(0) + + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: currentEpoch, + } + }, + } + + service, err := NewSCQueryService(argsNewSCQuery) + assert.Nil(t, err) + assert.NotNil(t, service) + + currentEpoch = 0 + + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(37)) + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) + + currentEpoch = 37 + + service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 29} + + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(37)) + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) + + service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 37} + + assert.True(t, service.shouldCallRecreateTrieWithoutEpoch(37)) + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) + + currentEpoch = 42 + + assert.True(t, service.shouldCallRecreateTrieWithoutEpoch(37)) + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(42)) + + service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 42} + + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(37)) + assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) + assert.True(t, service.shouldCallRecreateTrieWithoutEpoch(42)) +} + func TestSCQueryService_RecreateTrie(t *testing.T) { t.Parallel() @@ -846,7 +894,7 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { } service, _ := NewSCQueryService(argsNewSCQuery) - assert.Equal(t, core.OptionalUint32{HasValue: false}, service.latestQueriedEpoch) + service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 37} // For genesis block, RecreateTrieFromEpoch should be called err := service.recreateTrie(testRootHash, &block.Header{}) From 952ccc8d43f99c40c9674a9f6391f6e6486fdfeb Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 1 Mar 2024 15:22:38 +0200 Subject: [PATCH 900/958] - handled vm queries in snapshotless mode --- factory/api/apiResolverFactory.go | 1 + process/smartContract/scQueryService.go | 8 ++ process/smartContract/scQueryService_test.go | 113 +++++++++++++++++++ 3 files changed, 122 insertions(+) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 99b99f80c81..6053e4212ad 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -461,6 +461,7 @@ func createScQueryElement( Marshaller: args.coreComponents.InternalMarshalizer(), Hasher: args.coreComponents.Hasher(), Uint64ByteSliceConverter: args.coreComponents.Uint64ByteSliceConverter(), + IsInSnapshottingMode: args.generalConfig.StateTriesConfig.SnapshotsEnabled, } return smartContract.NewSCQueryService(argsNewSCQueryService) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 7e83f278272..75fe928a48a 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -53,6 +53,7 @@ type SCQueryService struct { hasher hashing.Hasher uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter latestQueriedEpoch core.OptionalUint32 + isInSnapshottingMode bool } // ArgsNewSCQueryService defines the arguments needed for the sc query service @@ -72,6 +73,7 @@ type ArgsNewSCQueryService struct { Marshaller marshal.Marshalizer Hasher hashing.Hasher Uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter + IsInSnapshottingMode bool } // NewSCQueryService returns a new instance of SCQueryService @@ -104,6 +106,7 @@ func NewSCQueryService( hasher: args.Hasher, uint64ByteSliceConverter: args.Uint64ByteSliceConverter, latestQueriedEpoch: core.OptionalUint32{}, + isInSnapshottingMode: args.IsInSnapshottingMode, }, nil } @@ -282,6 +285,11 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da } func (service *SCQueryService) isLatestQueriedEpoch(epoch uint32) bool { + if !service.isInSnapshottingMode { + // for snapshotless operation, we need to force this method to return true so the RecreateTrie will be called instead of RecreateTrieFromEpoch + return true + } + return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epoch } diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 10d57414305..7a0a3d032de 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -62,6 +62,7 @@ func createMockArgumentsForSCQuery() ArgsNewSCQueryService { Marshaller: &marshallerMock.MarshalizerStub{}, Hasher: &testscommon.HasherStub{}, Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, + IsInSnapshottingMode: true, } } @@ -684,6 +685,118 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { assert.True(t, recreateTrieFromEpochWasCalled) assert.False(t, recreateTrieWasCalled) }) + t.Run("block nonce should work - when epoch is different from latest queried epoch - in snapshotless mode", func(t *testing.T) { + t.Parallel() + + runWasCalled := false + epoch := uint32(37) + + mockVM := &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { + runWasCalled = true + assert.Equal(t, int64(42), big.NewInt(0).SetBytes(input.Arguments[0]).Int64()) + assert.Equal(t, int64(43), big.NewInt(0).SetBytes(input.Arguments[1]).Int64()) + assert.Equal(t, scAddress, input.CallerAddr) + assert.Equal(t, funcName, input.Function) + + return &vmcommon.VMOutput{ + ReturnCode: vmcommon.Ok, + }, nil + }, + } + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + Epoch: epoch, + } + }, + } + argsNewSCQuery.VmContainer = &mock.VMContainerMock{ + GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { + return mockVM, nil + }, + } + argsNewSCQuery.EconomicsFee = &economicsmocks.EconomicsHandlerStub{ + MaxGasLimitPerBlockCalled: func(_ uint32) uint64 { + return uint64(math.MaxUint64) + }, + } + providedHash := []byte("provided hash") + providedRootHash := []byte("provided root hash") + providedNonce := uint64(123) + argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} + counter := 0 + argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ + GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { + return &storageStubs.StorerStub{ + GetCalled: func(key []byte) ([]byte, error) { + return providedHash, nil + }, + GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { + counter++ + if counter > 2 { + return nil, fmt.Errorf("no scheduled") + } + hdr := &block.Header{ + RootHash: providedRootHash, + } + buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) + return buff, nil + }, + }, nil + }, + } + argsNewSCQuery.HistoryRepository = &dblookupext.HistoryRepositoryStub{ + IsEnabledCalled: func() bool { + return true + }, + GetEpochByHashCalled: func(hash []byte) (uint32, error) { + require.Equal(t, providedHash, hash) + return epoch, nil + }, + } + + recreateTrieWasCalled := false + + providedAccountsAdapter := &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + recreateTrieWasCalled = true + return nil + }, + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + assert.Fail(t, "should have not called RecreateTrieFromEpoch") + return nil + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return providedAccountsAdapter + }, + } + argsNewSCQuery.IsInSnapshottingMode = false + + target, _ := NewSCQueryService(argsNewSCQuery) + target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 5} + + dataArgs := make([][]byte, len(args)) + for i, arg := range args { + dataArgs[i] = append(dataArgs[i], arg.Bytes()...) + } + query := process.SCQuery{ + ScAddress: scAddress, + FuncName: funcName, + Arguments: dataArgs, + BlockNonce: core.OptionalUint64{ + Value: providedNonce, + HasValue: true, + }, + } + + _, _, _ = target.ExecuteQuery(&query) + assert.True(t, runWasCalled) + assert.True(t, recreateTrieWasCalled) + }) t.Run("block nonce should work - when epoch is same as latest queried epoch", func(t *testing.T) { t.Parallel() From d44648edfe5cc94c0a54a83a5b09a015086a0c46 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 1 Mar 2024 16:02:40 +0200 Subject: [PATCH 901/958] - fix after merge --- process/smartContract/scQueryService.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 88dac8059b7..d594fd39b9a 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -290,7 +290,7 @@ func (service *SCQueryService) shouldCallRecreateTrieWithoutEpoch(epochInQuestio return true } - return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epoch + return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epochInQuestion } func (service *SCQueryService) rememberQueriedEpoch(epoch uint32) { From d867f82b9f6373faaf5157274ca9cf536fcc2c93 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 1 Mar 2024 17:56:18 +0200 Subject: [PATCH 902/958] - refactored solution --- cmd/node/flags.go | 25 +- common/operationmodes/historicalBalances.go | 41 ++ .../operationmodes/historicalBalances_test.go | 141 ++++++ common/operationmodes/operationmodes.go | 1 + factory/api/apiResolverFactory.go | 161 +++--- process/smartContract/scQueryService.go | 138 ++--- process/smartContract/scQueryService_test.go | 470 ++---------------- 7 files changed, 368 insertions(+), 609 deletions(-) create mode 100644 common/operationmodes/historicalBalances.go create mode 100644 common/operationmodes/historicalBalances_test.go diff --git a/cmd/node/flags.go b/cmd/node/flags.go index f40de41ef86..3f55c187060 100644 --- a/cmd/node/flags.go +++ b/cmd/node/flags.go @@ -632,7 +632,8 @@ func applyCompatibleConfigs(log logger.Logger, configs *config.Configs) error { isInHistoricalBalancesMode := operationmodes.SliceContainsElement(operationModes, operationmodes.OperationModeHistoricalBalances) if isInHistoricalBalancesMode { - processHistoricalBalancesMode(log, configs) + // TODO move all operation modes settings in the common/operationmodes package and add tests + operationmodes.ProcessHistoricalBalancesMode(log, configs) } isInDbLookupExtensionMode := operationmodes.SliceContainsElement(operationModes, operationmodes.OperationModeDbLookupExtension) @@ -648,28 +649,6 @@ func applyCompatibleConfigs(log logger.Logger, configs *config.Configs) error { return nil } -func processHistoricalBalancesMode(log logger.Logger, configs *config.Configs) { - configs.GeneralConfig.StoragePruning.Enabled = true - configs.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData = false - configs.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData = false - configs.GeneralConfig.GeneralSettings.StartInEpochEnabled = false - configs.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData = false - configs.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled = false - configs.GeneralConfig.DbLookupExtensions.Enabled = true - configs.PreferencesConfig.Preferences.FullArchive = true - - log.Warn("the node is in historical balances mode! Will auto-set some config values", - "StoragePruning.Enabled", configs.GeneralConfig.StoragePruning.Enabled, - "StoragePruning.ValidatorCleanOldEpochsData", configs.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData, - "StoragePruning.ObserverCleanOldEpochsData", configs.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData, - "StoragePruning.AccountsTrieCleanOldEpochsData", configs.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData, - "GeneralSettings.StartInEpochEnabled", configs.GeneralConfig.GeneralSettings.StartInEpochEnabled, - "StateTriesConfig.AccountsStatePruningEnabled", configs.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled, - "DbLookupExtensions.Enabled", configs.GeneralConfig.DbLookupExtensions.Enabled, - "Preferences.FullArchive", configs.PreferencesConfig.Preferences.FullArchive, - ) -} - func processDbLookupExtensionMode(log logger.Logger, configs *config.Configs) { configs.GeneralConfig.DbLookupExtensions.Enabled = true configs.GeneralConfig.StoragePruning.Enabled = true diff --git a/common/operationmodes/historicalBalances.go b/common/operationmodes/historicalBalances.go new file mode 100644 index 00000000000..da3cfe98dde --- /dev/null +++ b/common/operationmodes/historicalBalances.go @@ -0,0 +1,41 @@ +package operationmodes + +import ( + "github.com/multiversx/mx-chain-go/config" + logger "github.com/multiversx/mx-chain-logger-go" +) + +// ProcessHistoricalBalancesMode will process the provided flags for the historical balances +func ProcessHistoricalBalancesMode(log logger.Logger, configs *config.Configs) { + configs.GeneralConfig.StoragePruning.Enabled = true + configs.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData = false + configs.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData = false + configs.GeneralConfig.GeneralSettings.StartInEpochEnabled = false + configs.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData = false + configs.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled = false + configs.GeneralConfig.DbLookupExtensions.Enabled = true + configs.PreferencesConfig.Preferences.FullArchive = true + + log.Warn("the node is in historical balances mode! Will auto-set some config values", + "StoragePruning.Enabled", configs.GeneralConfig.StoragePruning.Enabled, + "StoragePruning.ValidatorCleanOldEpochsData", configs.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData, + "StoragePruning.ObserverCleanOldEpochsData", configs.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData, + "StoragePruning.AccountsTrieCleanOldEpochsData", configs.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData, + "GeneralSettings.StartInEpochEnabled", configs.GeneralConfig.GeneralSettings.StartInEpochEnabled, + "StateTriesConfig.AccountsStatePruningEnabled", configs.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled, + "DbLookupExtensions.Enabled", configs.GeneralConfig.DbLookupExtensions.Enabled, + "Preferences.FullArchive", configs.PreferencesConfig.Preferences.FullArchive, + ) +} + +// IsInHistoricalBalancesMode returns true if the configuration provided denotes a historical balances mode +func IsInHistoricalBalancesMode(configs *config.Configs) bool { + return configs.GeneralConfig.StoragePruning.Enabled && + !configs.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData && + !configs.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData && + !configs.GeneralConfig.GeneralSettings.StartInEpochEnabled && + !configs.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData && + !configs.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled && + configs.GeneralConfig.DbLookupExtensions.Enabled && + configs.PreferencesConfig.Preferences.FullArchive +} diff --git a/common/operationmodes/historicalBalances_test.go b/common/operationmodes/historicalBalances_test.go new file mode 100644 index 00000000000..d06061c3027 --- /dev/null +++ b/common/operationmodes/historicalBalances_test.go @@ -0,0 +1,141 @@ +package operationmodes + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/stretchr/testify/assert" +) + +func TestProcessHistoricalBalancesMode(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + + assert.True(t, cfg.GeneralConfig.StoragePruning.Enabled) + assert.False(t, cfg.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData) + assert.False(t, cfg.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData) + assert.False(t, cfg.GeneralConfig.GeneralSettings.StartInEpochEnabled) + assert.False(t, cfg.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData) + assert.False(t, cfg.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled) + assert.True(t, cfg.GeneralConfig.DbLookupExtensions.Enabled) + assert.True(t, cfg.PreferencesConfig.Preferences.FullArchive) +} + +func TestIsInHistoricalBalancesMode(t *testing.T) { + t.Parallel() + + t.Run("empty configs should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("storage pruning disabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.StoragePruning.Enabled = false + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("validator clean old epoch data enabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.StoragePruning.ValidatorCleanOldEpochsData = true + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("observer clean old epoch data enabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.StoragePruning.ObserverCleanOldEpochsData = true + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("start in epoch enabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.GeneralSettings.StartInEpochEnabled = true + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("accounts trie clean old epoch data enabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.StoragePruning.AccountsTrieCleanOldEpochsData = true + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("accounts state pruning enabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.StateTriesConfig.AccountsStatePruningEnabled = true + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("db lookup extension disabled should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.GeneralConfig.DbLookupExtensions.Enabled = false + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("not a full archive node should return false", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + cfg.PreferencesConfig.Preferences.FullArchive = false + assert.False(t, IsInHistoricalBalancesMode(cfg)) + }) + t.Run("with historical balances config should return true", func(t *testing.T) { + t.Parallel() + + cfg := &config.Configs{ + GeneralConfig: &config.Config{}, + PreferencesConfig: &config.Preferences{}, + } + ProcessHistoricalBalancesMode(&testscommon.LoggerStub{}, cfg) + assert.True(t, IsInHistoricalBalancesMode(cfg)) + }) + +} diff --git a/common/operationmodes/operationmodes.go b/common/operationmodes/operationmodes.go index 70aed256f4b..1ae6a6fad70 100644 --- a/common/operationmodes/operationmodes.go +++ b/common/operationmodes/operationmodes.go @@ -5,6 +5,7 @@ import ( "strings" ) +// constants that define the operation mode of the node const ( OperationModeFullArchive = "full-archive" OperationModeDbLookupExtension = "db-lookup-extension" diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 6053e4212ad..dc015bad188 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/common/disabled" + "github.com/multiversx/mx-chain-go/common/operationmodes" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dataRetriever/blockchain" @@ -71,40 +72,42 @@ type ApiResolverArgs struct { } type scQueryServiceArgs struct { - generalConfig *config.Config - epochConfig *config.EpochConfig - coreComponents factory.CoreComponentsHolder - stateComponents factory.StateComponentsHolder - dataComponents factory.DataComponentsHolder - processComponents factory.ProcessComponentsHolder - statusCoreComponents factory.StatusCoreComponentsHolder - gasScheduleNotifier core.GasScheduleNotifier - messageSigVerifier vm.MessageSignVerifier - systemSCConfig *config.SystemSmartContractsConfig - bootstrapper process.Bootstrapper - guardedAccountHandler process.GuardedAccountHandler - allowVMQueriesChan chan struct{} - workingDir string - processingMode common.NodeProcessingMode + generalConfig *config.Config + epochConfig *config.EpochConfig + coreComponents factory.CoreComponentsHolder + stateComponents factory.StateComponentsHolder + dataComponents factory.DataComponentsHolder + processComponents factory.ProcessComponentsHolder + statusCoreComponents factory.StatusCoreComponentsHolder + gasScheduleNotifier core.GasScheduleNotifier + messageSigVerifier vm.MessageSignVerifier + systemSCConfig *config.SystemSmartContractsConfig + bootstrapper process.Bootstrapper + guardedAccountHandler process.GuardedAccountHandler + allowVMQueriesChan chan struct{} + workingDir string + processingMode common.NodeProcessingMode + isInHistoricalBalancesMode bool } type scQueryElementArgs struct { - generalConfig *config.Config - epochConfig *config.EpochConfig - coreComponents factory.CoreComponentsHolder - stateComponents factory.StateComponentsHolder - dataComponents factory.DataComponentsHolder - processComponents factory.ProcessComponentsHolder - statusCoreComponents factory.StatusCoreComponentsHolder - gasScheduleNotifier core.GasScheduleNotifier - messageSigVerifier vm.MessageSignVerifier - systemSCConfig *config.SystemSmartContractsConfig - bootstrapper process.Bootstrapper - guardedAccountHandler process.GuardedAccountHandler - allowVMQueriesChan chan struct{} - workingDir string - index int - processingMode common.NodeProcessingMode + generalConfig *config.Config + epochConfig *config.EpochConfig + coreComponents factory.CoreComponentsHolder + stateComponents factory.StateComponentsHolder + dataComponents factory.DataComponentsHolder + processComponents factory.ProcessComponentsHolder + statusCoreComponents factory.StatusCoreComponentsHolder + gasScheduleNotifier core.GasScheduleNotifier + messageSigVerifier vm.MessageSignVerifier + systemSCConfig *config.SystemSmartContractsConfig + bootstrapper process.Bootstrapper + guardedAccountHandler process.GuardedAccountHandler + allowVMQueriesChan chan struct{} + workingDir string + index int + processingMode common.NodeProcessingMode + isInHistoricalBalancesMode bool } // CreateApiResolver is able to create an ApiResolver instance that will solve the REST API requests through the node facade @@ -112,21 +115,22 @@ type scQueryElementArgs struct { func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { apiWorkingDir := filepath.Join(args.Configs.FlagsConfig.WorkingDir, common.TemporaryPath) argsSCQuery := &scQueryServiceArgs{ - generalConfig: args.Configs.GeneralConfig, - epochConfig: args.Configs.EpochConfig, - coreComponents: args.CoreComponents, - dataComponents: args.DataComponents, - stateComponents: args.StateComponents, - processComponents: args.ProcessComponents, - statusCoreComponents: args.StatusCoreComponents, - gasScheduleNotifier: args.GasScheduleNotifier, - messageSigVerifier: args.CryptoComponents.MessageSignVerifier(), - systemSCConfig: args.Configs.SystemSCConfig, - bootstrapper: args.Bootstrapper, - guardedAccountHandler: args.BootstrapComponents.GuardedAccountHandler(), - allowVMQueriesChan: args.AllowVMQueriesChan, - workingDir: apiWorkingDir, - processingMode: args.ProcessingMode, + generalConfig: args.Configs.GeneralConfig, + epochConfig: args.Configs.EpochConfig, + coreComponents: args.CoreComponents, + dataComponents: args.DataComponents, + stateComponents: args.StateComponents, + processComponents: args.ProcessComponents, + statusCoreComponents: args.StatusCoreComponents, + gasScheduleNotifier: args.GasScheduleNotifier, + messageSigVerifier: args.CryptoComponents.MessageSignVerifier(), + systemSCConfig: args.Configs.SystemSCConfig, + bootstrapper: args.Bootstrapper, + guardedAccountHandler: args.BootstrapComponents.GuardedAccountHandler(), + allowVMQueriesChan: args.AllowVMQueriesChan, + workingDir: apiWorkingDir, + processingMode: args.ProcessingMode, + isInHistoricalBalancesMode: operationmodes.IsInHistoricalBalancesMode(args.Configs), } scQueryService, err := createScQueryService(argsSCQuery) @@ -299,22 +303,23 @@ func createScQueryService( } argsQueryElem := &scQueryElementArgs{ - generalConfig: args.generalConfig, - epochConfig: args.epochConfig, - coreComponents: args.coreComponents, - stateComponents: args.stateComponents, - dataComponents: args.dataComponents, - processComponents: args.processComponents, - statusCoreComponents: args.statusCoreComponents, - gasScheduleNotifier: args.gasScheduleNotifier, - messageSigVerifier: args.messageSigVerifier, - systemSCConfig: args.systemSCConfig, - bootstrapper: args.bootstrapper, - guardedAccountHandler: args.guardedAccountHandler, - allowVMQueriesChan: args.allowVMQueriesChan, - workingDir: args.workingDir, - index: 0, - processingMode: args.processingMode, + generalConfig: args.generalConfig, + epochConfig: args.epochConfig, + coreComponents: args.coreComponents, + stateComponents: args.stateComponents, + dataComponents: args.dataComponents, + processComponents: args.processComponents, + statusCoreComponents: args.statusCoreComponents, + gasScheduleNotifier: args.gasScheduleNotifier, + messageSigVerifier: args.messageSigVerifier, + systemSCConfig: args.systemSCConfig, + bootstrapper: args.bootstrapper, + guardedAccountHandler: args.guardedAccountHandler, + allowVMQueriesChan: args.allowVMQueriesChan, + workingDir: args.workingDir, + index: 0, + processingMode: args.processingMode, + isInHistoricalBalancesMode: args.isInHistoricalBalancesMode, } var err error @@ -446,22 +451,22 @@ func createScQueryElement( } argsNewSCQueryService := smartContract.ArgsNewSCQueryService{ - VmContainer: vmContainer, - EconomicsFee: args.coreComponents.EconomicsData(), - BlockChainHook: vmFactory.BlockChainHookImpl(), - MainBlockChain: args.dataComponents.Blockchain(), - APIBlockChain: apiBlockchain, - WasmVMChangeLocker: args.coreComponents.WasmVMChangeLocker(), - Bootstrapper: args.bootstrapper, - AllowExternalQueriesChan: args.allowVMQueriesChan, - MaxGasLimitPerQuery: maxGasForVmQueries, - HistoryRepository: args.processComponents.HistoryRepository(), - ShardCoordinator: args.processComponents.ShardCoordinator(), - StorageService: args.dataComponents.StorageService(), - Marshaller: args.coreComponents.InternalMarshalizer(), - Hasher: args.coreComponents.Hasher(), - Uint64ByteSliceConverter: args.coreComponents.Uint64ByteSliceConverter(), - IsInSnapshottingMode: args.generalConfig.StateTriesConfig.SnapshotsEnabled, + VmContainer: vmContainer, + EconomicsFee: args.coreComponents.EconomicsData(), + BlockChainHook: vmFactory.BlockChainHookImpl(), + MainBlockChain: args.dataComponents.Blockchain(), + APIBlockChain: apiBlockchain, + WasmVMChangeLocker: args.coreComponents.WasmVMChangeLocker(), + Bootstrapper: args.bootstrapper, + AllowExternalQueriesChan: args.allowVMQueriesChan, + MaxGasLimitPerQuery: maxGasForVmQueries, + HistoryRepository: args.processComponents.HistoryRepository(), + ShardCoordinator: args.processComponents.ShardCoordinator(), + StorageService: args.dataComponents.StorageService(), + Marshaller: args.coreComponents.InternalMarshalizer(), + Hasher: args.coreComponents.Hasher(), + Uint64ByteSliceConverter: args.coreComponents.Uint64ByteSliceConverter(), + IsInHistoricalBalancesMode: args.isInHistoricalBalancesMode, } return smartContract.NewSCQueryService(argsNewSCQueryService) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index d594fd39b9a..10a5be173da 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -36,44 +36,43 @@ const MaxGasLimitPerQuery = 300_000_000_000 // SCQueryService can execute Get functions over SC to fetch stored values type SCQueryService struct { - vmContainer process.VirtualMachinesContainer - economicsFee process.FeeHandler - mutRunSc sync.Mutex - blockChainHook process.BlockChainHookWithAccountsAdapter - mainBlockChain data.ChainHandler - apiBlockChain data.ChainHandler - gasForQuery uint64 - wasmVMChangeLocker common.Locker - bootstrapper process.Bootstrapper - allowExternalQueriesChan chan struct{} - historyRepository dblookupext.HistoryRepository - shardCoordinator sharding.Coordinator - storageService dataRetriever.StorageService - marshaller marshal.Marshalizer - hasher hashing.Hasher - uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter - latestQueriedEpoch core.OptionalUint32 - isInSnapshottingMode bool + vmContainer process.VirtualMachinesContainer + economicsFee process.FeeHandler + mutRunSc sync.Mutex + blockChainHook process.BlockChainHookWithAccountsAdapter + mainBlockChain data.ChainHandler + apiBlockChain data.ChainHandler + gasForQuery uint64 + wasmVMChangeLocker common.Locker + bootstrapper process.Bootstrapper + allowExternalQueriesChan chan struct{} + historyRepository dblookupext.HistoryRepository + shardCoordinator sharding.Coordinator + storageService dataRetriever.StorageService + marshaller marshal.Marshalizer + hasher hashing.Hasher + uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter + isInHistoricalBalancesMode bool } // ArgsNewSCQueryService defines the arguments needed for the sc query service type ArgsNewSCQueryService struct { - VmContainer process.VirtualMachinesContainer - EconomicsFee process.FeeHandler - BlockChainHook process.BlockChainHookWithAccountsAdapter - MainBlockChain data.ChainHandler - APIBlockChain data.ChainHandler - WasmVMChangeLocker common.Locker - Bootstrapper process.Bootstrapper - AllowExternalQueriesChan chan struct{} - MaxGasLimitPerQuery uint64 - HistoryRepository dblookupext.HistoryRepository - ShardCoordinator sharding.Coordinator - StorageService dataRetriever.StorageService - Marshaller marshal.Marshalizer - Hasher hashing.Hasher - Uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter - IsInSnapshottingMode bool + VmContainer process.VirtualMachinesContainer + EconomicsFee process.FeeHandler + BlockChainHook process.BlockChainHookWithAccountsAdapter + MainBlockChain data.ChainHandler + APIBlockChain data.ChainHandler + WasmVMChangeLocker common.Locker + Bootstrapper process.Bootstrapper + AllowExternalQueriesChan chan struct{} + MaxGasLimitPerQuery uint64 + HistoryRepository dblookupext.HistoryRepository + ShardCoordinator sharding.Coordinator + StorageService dataRetriever.StorageService + Marshaller marshal.Marshalizer + Hasher hashing.Hasher + Uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter + IsInHistoricalBalancesMode bool } // NewSCQueryService returns a new instance of SCQueryService @@ -90,23 +89,22 @@ func NewSCQueryService( gasForQuery = args.MaxGasLimitPerQuery } return &SCQueryService{ - vmContainer: args.VmContainer, - economicsFee: args.EconomicsFee, - mainBlockChain: args.MainBlockChain, - apiBlockChain: args.APIBlockChain, - blockChainHook: args.BlockChainHook, - wasmVMChangeLocker: args.WasmVMChangeLocker, - bootstrapper: args.Bootstrapper, - gasForQuery: gasForQuery, - allowExternalQueriesChan: args.AllowExternalQueriesChan, - historyRepository: args.HistoryRepository, - shardCoordinator: args.ShardCoordinator, - storageService: args.StorageService, - marshaller: args.Marshaller, - hasher: args.Hasher, - uint64ByteSliceConverter: args.Uint64ByteSliceConverter, - latestQueriedEpoch: core.OptionalUint32{}, - isInSnapshottingMode: args.IsInSnapshottingMode, + vmContainer: args.VmContainer, + economicsFee: args.EconomicsFee, + mainBlockChain: args.MainBlockChain, + apiBlockChain: args.APIBlockChain, + blockChainHook: args.BlockChainHook, + wasmVMChangeLocker: args.WasmVMChangeLocker, + bootstrapper: args.Bootstrapper, + gasForQuery: gasForQuery, + allowExternalQueriesChan: args.AllowExternalQueriesChan, + historyRepository: args.HistoryRepository, + shardCoordinator: args.ShardCoordinator, + storageService: args.StorageService, + marshaller: args.Marshaller, + hasher: args.Hasher, + uint64ByteSliceConverter: args.Uint64ByteSliceConverter, + isInHistoricalBalancesMode: args.IsInHistoricalBalancesMode, }, nil } @@ -260,41 +258,15 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da accountsAdapter := service.blockChainHook.GetAccountsAdapter() - if service.shouldCallRecreateTrieWithoutEpoch(blockHeader.GetEpoch()) { - logQueryService.Trace("calling RecreateTrie", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + if service.isInHistoricalBalancesMode { + logQueryService.Trace("calling RecreateTrieFromEpoch", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) - err := accountsAdapter.RecreateTrie(blockRootHash) - if err != nil { - return err - } - - service.rememberQueriedEpoch(blockHeader.GetEpoch()) - return nil - } - - logQueryService.Trace("calling RecreateTrieFromEpoch", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) - holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true}) - - err := accountsAdapter.RecreateTrieFromEpoch(holder) - if err != nil { - return err + return accountsAdapter.RecreateTrieFromEpoch(holder) } - service.rememberQueriedEpoch(blockHeader.GetEpoch()) - return nil -} - -func (service *SCQueryService) shouldCallRecreateTrieWithoutEpoch(epochInQuestion uint32) bool { - if !service.isInSnapshottingMode { - // for snapshotless operation, we need to force this method to return true so the RecreateTrie will be called instead of RecreateTrieFromEpoch - return true - } - - return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epochInQuestion -} - -func (service *SCQueryService) rememberQueriedEpoch(epoch uint32) { - service.latestQueriedEpoch = core.OptionalUint32{Value: epoch, HasValue: true} + logQueryService.Trace("calling RecreateTrie", "block", blockHeader.GetNonce(), "rootHash", blockRootHash) + return accountsAdapter.RecreateTrie(blockRootHash) } func (service *SCQueryService) getCurrentEpoch() uint32 { diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index 2cf6f35d075..d71542a8aaa 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -11,7 +11,6 @@ import ( "testing" "time" - "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/transaction" @@ -59,10 +58,10 @@ func createMockArgumentsForSCQuery() ArgsNewSCQueryService { return &storageStubs.StorerStub{}, nil }, }, - Marshaller: &marshallerMock.MarshalizerStub{}, - Hasher: &testscommon.HasherStub{}, - Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, - IsInSnapshottingMode: true, + Marshaller: &marshallerMock.MarshalizerStub{}, + Hasher: &testscommon.HasherStub{}, + Uint64ByteSliceConverter: &mock.Uint64ByteSliceConverterMock{}, + IsInHistoricalBalancesMode: false, } } @@ -368,7 +367,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { _, _, _ = target.ExecuteQuery(&query) assert.True(t, runWasCalled) }) - t.Run("block hash should work - when epoch is different from latest queried epoch", func(t *testing.T) { + t.Run("block hash should work - in deep history mode", func(t *testing.T) { t.Parallel() runWasCalled := false @@ -454,9 +453,9 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return providedAccountsAdapter }, } + argsNewSCQuery.IsInHistoricalBalancesMode = true target, _ := NewSCQueryService(argsNewSCQuery) - target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 5} dataArgs := make([][]byte, len(args)) for i, arg := range args { @@ -475,7 +474,7 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { assert.False(t, recreateTrieWasCalled) assert.Nil(t, err) }) - t.Run("block hash should work - when epoch is same as latest queried epoch", func(t *testing.T) { + t.Run("block hash should work - in normal mode", func(t *testing.T) { t.Parallel() epoch := uint32(12) @@ -550,9 +549,9 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { return providedAccountsAdapter }, } + argsNewSCQuery.IsInHistoricalBalancesMode = false target, _ := NewSCQueryService(argsNewSCQuery) - target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: epoch} dataArgs := make([][]byte, len(args)) for i, arg := range args { @@ -571,383 +570,6 @@ func TestExecuteQuery_ShouldReceiveQueryCorrectly(t *testing.T) { assert.False(t, recreateTrieFromEpochWasCalled) assert.Nil(t, err) }) - t.Run("block nonce should work - when epoch is different from latest queried epoch", func(t *testing.T) { - t.Parallel() - - runWasCalled := false - epoch := uint32(37) - - mockVM := &mock.VMExecutionHandlerStub{ - RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { - runWasCalled = true - assert.Equal(t, int64(42), big.NewInt(0).SetBytes(input.Arguments[0]).Int64()) - assert.Equal(t, int64(43), big.NewInt(0).SetBytes(input.Arguments[1]).Int64()) - assert.Equal(t, scAddress, input.CallerAddr) - assert.Equal(t, funcName, input.Function) - - return &vmcommon.VMOutput{ - ReturnCode: vmcommon.Ok, - }, nil - }, - } - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: epoch, - } - }, - } - argsNewSCQuery.VmContainer = &mock.VMContainerMock{ - GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { - return mockVM, nil - }, - } - argsNewSCQuery.EconomicsFee = &economicsmocks.EconomicsHandlerStub{ - MaxGasLimitPerBlockCalled: func(_ uint32) uint64 { - return uint64(math.MaxUint64) - }, - } - providedHash := []byte("provided hash") - providedRootHash := []byte("provided root hash") - providedNonce := uint64(123) - argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} - counter := 0 - argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ - GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { - return &storageStubs.StorerStub{ - GetCalled: func(key []byte) ([]byte, error) { - return providedHash, nil - }, - GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { - counter++ - if counter > 2 { - return nil, fmt.Errorf("no scheduled") - } - hdr := &block.Header{ - RootHash: providedRootHash, - } - buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) - return buff, nil - }, - }, nil - }, - } - argsNewSCQuery.HistoryRepository = &dblookupext.HistoryRepositoryStub{ - IsEnabledCalled: func() bool { - return true - }, - GetEpochByHashCalled: func(hash []byte) (uint32, error) { - require.Equal(t, providedHash, hash) - return epoch, nil - }, - } - - recreateTrieWasCalled := false - recreateTrieFromEpochWasCalled := false - - providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieWasCalled = true - return nil - }, - RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - recreateTrieFromEpochWasCalled = true - assert.Equal(t, providedRootHash, options.GetRootHash()) - return nil - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return providedAccountsAdapter - }, - } - - target, _ := NewSCQueryService(argsNewSCQuery) - target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 5} - - dataArgs := make([][]byte, len(args)) - for i, arg := range args { - dataArgs[i] = append(dataArgs[i], arg.Bytes()...) - } - query := process.SCQuery{ - ScAddress: scAddress, - FuncName: funcName, - Arguments: dataArgs, - BlockNonce: core.OptionalUint64{ - Value: providedNonce, - HasValue: true, - }, - } - - _, _, _ = target.ExecuteQuery(&query) - assert.True(t, runWasCalled) - assert.True(t, recreateTrieFromEpochWasCalled) - assert.False(t, recreateTrieWasCalled) - }) - t.Run("block nonce should work - when epoch is different from latest queried epoch - in snapshotless mode", func(t *testing.T) { - t.Parallel() - - runWasCalled := false - epoch := uint32(37) - - mockVM := &mock.VMExecutionHandlerStub{ - RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { - runWasCalled = true - assert.Equal(t, int64(42), big.NewInt(0).SetBytes(input.Arguments[0]).Int64()) - assert.Equal(t, int64(43), big.NewInt(0).SetBytes(input.Arguments[1]).Int64()) - assert.Equal(t, scAddress, input.CallerAddr) - assert.Equal(t, funcName, input.Function) - - return &vmcommon.VMOutput{ - ReturnCode: vmcommon.Ok, - }, nil - }, - } - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: epoch, - } - }, - } - argsNewSCQuery.VmContainer = &mock.VMContainerMock{ - GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { - return mockVM, nil - }, - } - argsNewSCQuery.EconomicsFee = &economicsmocks.EconomicsHandlerStub{ - MaxGasLimitPerBlockCalled: func(_ uint32) uint64 { - return uint64(math.MaxUint64) - }, - } - providedHash := []byte("provided hash") - providedRootHash := []byte("provided root hash") - providedNonce := uint64(123) - argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} - counter := 0 - argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ - GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { - return &storageStubs.StorerStub{ - GetCalled: func(key []byte) ([]byte, error) { - return providedHash, nil - }, - GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { - counter++ - if counter > 2 { - return nil, fmt.Errorf("no scheduled") - } - hdr := &block.Header{ - RootHash: providedRootHash, - } - buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) - return buff, nil - }, - }, nil - }, - } - argsNewSCQuery.HistoryRepository = &dblookupext.HistoryRepositoryStub{ - IsEnabledCalled: func() bool { - return true - }, - GetEpochByHashCalled: func(hash []byte) (uint32, error) { - require.Equal(t, providedHash, hash) - return epoch, nil - }, - } - - recreateTrieWasCalled := false - - providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieWasCalled = true - return nil - }, - RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - assert.Fail(t, "should have not called RecreateTrieFromEpoch") - return nil - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return providedAccountsAdapter - }, - } - argsNewSCQuery.IsInSnapshottingMode = false - - target, _ := NewSCQueryService(argsNewSCQuery) - target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 5} - - dataArgs := make([][]byte, len(args)) - for i, arg := range args { - dataArgs[i] = append(dataArgs[i], arg.Bytes()...) - } - query := process.SCQuery{ - ScAddress: scAddress, - FuncName: funcName, - Arguments: dataArgs, - BlockNonce: core.OptionalUint64{ - Value: providedNonce, - HasValue: true, - }, - } - - _, _, _ = target.ExecuteQuery(&query) - assert.True(t, runWasCalled) - assert.True(t, recreateTrieWasCalled) - }) - t.Run("block nonce should work - when epoch is same as latest queried epoch", func(t *testing.T) { - t.Parallel() - - runWasCalled := false - epoch := uint32(12) - - mockVM := &mock.VMExecutionHandlerStub{ - RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { - runWasCalled = true - assert.Equal(t, int64(42), big.NewInt(0).SetBytes(input.Arguments[0]).Int64()) - assert.Equal(t, int64(43), big.NewInt(0).SetBytes(input.Arguments[1]).Int64()) - assert.Equal(t, scAddress, input.CallerAddr) - assert.Equal(t, funcName, input.Function) - - return &vmcommon.VMOutput{ - ReturnCode: vmcommon.Ok, - }, nil - }, - } - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.VmContainer = &mock.VMContainerMock{ - GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { - return mockVM, nil - }, - } - argsNewSCQuery.EconomicsFee = &economicsmocks.EconomicsHandlerStub{ - MaxGasLimitPerBlockCalled: func(_ uint32) uint64 { - return uint64(math.MaxUint64) - }, - } - providedHash := []byte("provided hash") - providedRootHash := []byte("provided root hash") - providedNonce := uint64(123) - argsNewSCQuery.Marshaller = &marshallerMock.MarshalizerMock{} - argsNewSCQuery.StorageService = &storageStubs.ChainStorerStub{ - GetStorerCalled: func(unitType dataRetriever.UnitType) (storage.Storer, error) { - return &storageStubs.StorerStub{ - GetCalled: func(key []byte) ([]byte, error) { - return providedHash, nil - }, - GetFromEpochCalled: func(key []byte, epoch uint32) ([]byte, error) { - hdr := &block.Header{ - RootHash: providedRootHash, - Epoch: epoch, - } - buff, _ := argsNewSCQuery.Marshaller.Marshal(hdr) - return buff, nil - }, - }, nil - }, - } - argsNewSCQuery.HistoryRepository = &dblookupext.HistoryRepositoryStub{ - IsEnabledCalled: func() bool { - return true - }, - GetEpochByHashCalled: func(hash []byte) (uint32, error) { - require.Equal(t, providedHash, hash) - return epoch, nil - }, - } - - recreateTrieWasCalled := false - recreateTrieFromEpochWasCalled := false - - providedAccountsAdapter := &stateMocks.AccountsStub{ - RecreateTrieCalled: func(rootHash []byte) error { - recreateTrieWasCalled = true - assert.Equal(t, providedRootHash, rootHash) - return nil - }, - RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { - recreateTrieFromEpochWasCalled = true - return nil - }, - } - argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ - GetAccountsAdapterCalled: func() state.AccountsAdapter { - return providedAccountsAdapter - }, - } - - target, _ := NewSCQueryService(argsNewSCQuery) - target.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: epoch} - - dataArgs := make([][]byte, len(args)) - for i, arg := range args { - dataArgs[i] = append(dataArgs[i], arg.Bytes()...) - } - query := process.SCQuery{ - ScAddress: scAddress, - FuncName: funcName, - Arguments: dataArgs, - BlockNonce: core.OptionalUint64{ - Value: providedNonce, - HasValue: true, - }, - } - - _, _, _ = target.ExecuteQuery(&query) - assert.True(t, runWasCalled) - assert.True(t, recreateTrieWasCalled) - assert.False(t, recreateTrieFromEpochWasCalled) - }) -} - -func TestSCQueryService_ShouldCallRecreateTrieWithoutEpoch(t *testing.T) { - t.Parallel() - - currentEpoch := uint32(0) - - argsNewSCQuery := createMockArgumentsForSCQuery() - argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - Epoch: currentEpoch, - } - }, - } - - service, err := NewSCQueryService(argsNewSCQuery) - assert.Nil(t, err) - assert.NotNil(t, service) - - currentEpoch = 0 - - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(37)) - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) - - currentEpoch = 37 - - service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 29} - - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(37)) - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) - - service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 37} - - assert.True(t, service.shouldCallRecreateTrieWithoutEpoch(37)) - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) - - currentEpoch = 42 - - assert.True(t, service.shouldCallRecreateTrieWithoutEpoch(37)) - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(42)) - - service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 42} - - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(37)) - assert.False(t, service.shouldCallRecreateTrieWithoutEpoch(5)) - assert.True(t, service.shouldCallRecreateTrieWithoutEpoch(42)) } func TestSCQueryService_RecreateTrie(t *testing.T) { @@ -973,13 +595,14 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { err := service.recreateTrie(testRootHash, nil) assert.ErrorIs(t, err, process.ErrNilBlockHeader) }) - t.Run("should call RecreateTrieFromEpoch, remember epoch, then call RecreateTrie (for genesis block, then blocks in other epochs)", func(t *testing.T) { + t.Run("should call RecreateTrieFromEpoch if in deep history mode", func(t *testing.T) { t.Parallel() recreateTrieWasCalled := false recreateTrieFromEpochWasCalled := false argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.IsInHistoricalBalancesMode = true argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { return nil // after the genesis we do not have a header as current block @@ -1007,57 +630,54 @@ func TestSCQueryService_RecreateTrie(t *testing.T) { } service, _ := NewSCQueryService(argsNewSCQuery) - service.latestQueriedEpoch = core.OptionalUint32{HasValue: true, Value: 37} // For genesis block, RecreateTrieFromEpoch should be called err := service.recreateTrie(testRootHash, &block.Header{}) assert.Nil(t, err) assert.True(t, recreateTrieFromEpochWasCalled) assert.False(t, recreateTrieWasCalled) - assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) + }) + t.Run("should call RecreateTrie if not in deep history mode", func(t *testing.T) { + t.Parallel() - // For genesis block, RecreateTrie should be called - err = service.recreateTrie(testRootHash, &block.Header{}) - assert.Nil(t, err) - assert.False(t, recreateTrieFromEpochWasCalled) - assert.True(t, recreateTrieWasCalled) - assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) + recreateTrieWasCalled := false + recreateTrieFromEpochWasCalled := false - // For block in epoch 0, RecreateTrie should be called - err = service.recreateTrie(testRootHash, &block.Header{ - Epoch: 0, - }) - assert.Nil(t, err) - assert.False(t, recreateTrieFromEpochWasCalled) - assert.True(t, recreateTrieWasCalled) - assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.IsInHistoricalBalancesMode = false + argsNewSCQuery.MainBlockChain = &testscommon.ChainHandlerStub{ + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return nil // after the genesis we do not have a header as current block + }, + } + argsNewSCQuery.BlockChainHook = &testscommon.BlockChainHookStub{ + GetAccountsAdapterCalled: func() state.AccountsAdapter { + return &stateMocks.AccountsStub{ + RecreateTrieCalled: func(rootHash []byte) error { + recreateTrieWasCalled = true + recreateTrieFromEpochWasCalled = false - // For block in epoch 1, RecreateTrieFromEpoch should be called - err = service.recreateTrie(testRootHash, &block.Header{ - Epoch: 1, - }) - assert.Nil(t, err) - assert.True(t, recreateTrieFromEpochWasCalled) - assert.False(t, recreateTrieWasCalled) - assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 1}, service.latestQueriedEpoch) + assert.Equal(t, testRootHash, rootHash) + return nil + }, + RecreateTrieFromEpochCalled: func(options common.RootHashHolder) error { + recreateTrieWasCalled = false + recreateTrieFromEpochWasCalled = true - // For block in epoch 1, RecreateTrie should be called - err = service.recreateTrie(testRootHash, &block.Header{ - Epoch: 1, - }) + assert.Equal(t, testRootHash, options.GetRootHash()) + return nil + }, + } + }, + } + + service, _ := NewSCQueryService(argsNewSCQuery) + + // For genesis block, RecreateTrieFromEpoch should be called + err := service.recreateTrie(testRootHash, &block.Header{}) assert.Nil(t, err) assert.False(t, recreateTrieFromEpochWasCalled) assert.True(t, recreateTrieWasCalled) - assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 1}, service.latestQueriedEpoch) - - // For block in epoch 0, RecreateTrieFromEpoch should be called - err = service.recreateTrie(testRootHash, &block.Header{ - Epoch: 0, - }) - assert.Nil(t, err) - assert.True(t, recreateTrieFromEpochWasCalled) - assert.False(t, recreateTrieWasCalled) - assert.Equal(t, core.OptionalUint32{HasValue: true, Value: 0}, service.latestQueriedEpoch) }) } From 0b561d7a1e18a0dea52021969a0e75fea341f8d9 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Sat, 2 Mar 2024 23:08:34 +0200 Subject: [PATCH 903/958] fix unstake in batches scenario --- .../staking/stakeAndUnStake_test.go | 292 +++++++++--------- 1 file changed, 148 insertions(+), 144 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index f3fbaf43a8a..6845c8502d2 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -22,7 +22,6 @@ import ( "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/vm" logger "github.com/multiversx/mx-chain-logger-go" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -1758,7 +1757,7 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInBatches(t *testing. cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 - // cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriod = 144000 + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 6 }, }) require.Nil(t, err) @@ -1769,95 +1768,101 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInBatches(t *testing. testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 1) }) - // t.Run("staking ph 4 step 1 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - - // defer cs.Close() - - // testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 2) - // }) - - // t.Run("staking ph 4 step 2 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - - // defer cs.Close() - - // testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 3) - // }) - - // t.Run("staking ph 4 step 3 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - - // defer cs.Close() - - // testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 4) - // }) + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 6 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 6 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 6 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t, cs, 4) + }) } func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { @@ -1884,7 +1889,9 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, stakeTx) - err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + stakeTxFee, _ := big.NewInt(0).SetString(stakeTx.Fee, 10) + + err = cs.GenerateBlocks(2) require.Nil(t, err) testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) @@ -1905,7 +1912,10 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unStakeTx) - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + unStakeTxFee, _ := big.NewInt(0).SetString(unStakeTx.Fee, 10) + + epochIncr := int32(1) + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) require.Nil(t, err) unStakeValue2 := big.NewInt(12) @@ -1916,7 +1926,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unStakeTx) - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + epochIncr++ + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) require.Nil(t, err) unStakeValue3 := big.NewInt(13) @@ -1927,7 +1938,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unStakeTx) - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + epochIncr++ + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) require.Nil(t, err) // check bls key is still staked @@ -1963,17 +1975,13 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) - log.Info("Step 1. Wait for the unbonding epoch to start") + log.Info("Step 3. Wait for the unbonding epoch to start") - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 1) + epochIncr += 3 + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) require.Nil(t, err) - log.Info("Step 2. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") - - accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) - require.Nil(t, err) - balanceAfterUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + log.Info("Step 4.1. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) txUnBond := generateTransaction(validatorOwner.Bytes, 4, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) @@ -1981,35 +1989,34 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unBondTx) + unBondTxFee, _ := big.NewInt(0).SetString(unBondTx.Fee, 10) + err = cs.GenerateBlocks(2) require.Nil(t, err) // the owner balance should increase with the (11 EGLD - tx fee) accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) require.Nil(t, err) - balanceAfterUnbonding, _ = big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - - // // substract unbonding value - // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) - - // txsFee, _ := big.NewInt(0).SetString(unBondTx.Fee, 10) - // balanceAfterUnbondingWithFee := big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + balanceAfterUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - // txsFee, _ = big.NewInt(0).SetString(unStakeTx.Fee, 10) - // balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) - // txsFee, _ = big.NewInt(0).SetString(stakeTx.Fee, 10) - // balanceAfterUnbondingWithFee.Add(balanceAfterUnbondingWithFee, txsFee) + txsFee := big.NewInt(0) - // assert.Equal(t, balanceAfterUnbondingWithFee.String(), balanceBeforeUnbonding.String()) + txsFee.Add(txsFee, stakeTxFee) + txsFee.Add(txsFee, unBondTxFee) + txsFee.Add(txsFee, unStakeTxFee) + txsFee.Add(txsFee, unStakeTxFee) + txsFee.Add(txsFee, unStakeTxFee) - assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + balanceAfterUnbonding.Add(balanceAfterUnbonding, txsFee) - // require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) + require.Equal(t, 1, balanceAfterUnbonding.Cmp(balanceBeforeUnbonding)) - /////////////////////////////// + log.Info("Step 4.2. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 2) + epochIncr++ + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) require.Nil(t, err) txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) @@ -2018,27 +2025,26 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unBondTx) - // the owner balance should increase with the (11 EGLD - tx fee) + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + // the owner balance should increase with the (11+12 EGLD - tx fee) accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) require.Nil(t, err) balanceAfterUnbonding, _ = big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - // // substract unbonding value - // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) - // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) - - // txsFee, _ = big.NewInt(0).SetString(unBondTx.Fee, 10) - // balanceAfterUnbondingWithFee = big.NewInt(0).Add(balanceAfterUnbonding, txsFee) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) - // assert.Equal(t, balanceAfterUnbondingWithFee.String(), balanceBeforeUnbonding.String()) + txsFee.Add(txsFee, unBondTxFee) + balanceAfterUnbonding.Add(balanceAfterUnbonding, txsFee) - assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + require.Equal(t, 1, balanceAfterUnbonding.Cmp(balanceBeforeUnbonding)) - // require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) + log.Info("Step 4.3. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") - /////////////////////////////// - - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + 2) + epochIncr++ + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) require.Nil(t, err) txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) @@ -2047,22 +2053,20 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unBondTx) - // the owner balance should increase with the (11 EGLD - tx fee) + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + // the owner balance should increase with the (11+12+13 EGLD - tx fee) accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) require.Nil(t, err) balanceAfterUnbonding, _ = big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - // // substract unbonding value - // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) - // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) - // balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue3) - - // txsFee, _ = big.NewInt(0).SetString(unBondTx.Fee, 10) - // balanceAfterUnbondingWithFee = big.NewInt(0).Add(balanceAfterUnbonding, txsFee) - - // assert.Equal(t, balanceAfterUnbondingWithFee.String(), balanceBeforeUnbonding.String()) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue3) - assert.Equal(t, balanceAfterUnbonding.String(), balanceBeforeUnbonding.String()) + txsFee.Add(txsFee, unBondTxFee) + balanceAfterUnbonding.Add(balanceAfterUnbonding, txsFee) - // require.Equal(t, 1, balanceAfterUnbondingWithFee.Cmp(balanceBeforeUnbonding)) + require.Equal(t, 1, balanceAfterUnbonding.Cmp(balanceBeforeUnbonding)) } From 8c2e732e1ea9c3ca595f682eff0a6113300ab40d Mon Sep 17 00:00:00 2001 From: ssd04 Date: Sat, 2 Mar 2024 23:18:42 +0200 Subject: [PATCH 904/958] added multiple unstake in same epoch scenario --- .../staking/stakeAndUnStake_test.go | 289 ++++++++++++++++++ 1 file changed, 289 insertions(+) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 6845c8502d2..536ffa4ac3b 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -2070,3 +2070,292 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Equal(t, 1, balanceAfterUnbonding.Cmp(balanceBeforeUnbonding)) } + +// Test description: +// Unstake funds in different batches in the same epoch allows correct withdrawal in the correct epoch +// +// Internal test scenario #31 +func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInEpoch(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 30, + } + + // Test Steps + // 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld. + // 2. Send the transactions consecutively in the same epoch + // 3. Wait for the epoch when unbonding period ends. + // 4. Create a transaction for withdraw and send it to the network + + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 3 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t, cs, 1) + }) + + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 3 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t, cs, 2) + }) + + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 3 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t, cs, 3) + }) + + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + + cfg.SystemSCConfig.StakingSystemSCConfig.UnBondPeriodInEpochs = 3 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t, cs, 4) + }) +} + +func testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + privateKey, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKey) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + mintValue := big.NewInt(2700) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + validatorOwner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + stakeValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(2600)) + txDataField := fmt.Sprintf("stake@01@%s@%s", blsKeys[0], mockBLSSignature) + txStake := generateTransaction(validatorOwner.Bytes, 0, vm.ValidatorSCAddress, stakeValue, txDataField, gasLimitForStakeOperation) + stakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, stakeTx) + + stakeTxFee, _ := big.NewInt(0).SetString(stakeTx.Fee, 10) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + shardIDValidatorOwner := cs.GetNodeHandler(0).GetShardCoordinator().ComputeId(validatorOwner.Bytes) + accountValidatorOwner, _, err := cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld.") + log.Info("Step 2. Send the transactions in consecutively in same epoch.") + + unStakeValue1 := big.NewInt(11) + unStakeValue1 = unStakeValue1.Mul(oneEGLD, unStakeValue1) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue1.Bytes())) + txUnStake := generateTransaction(validatorOwner.Bytes, 1, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + unStakeTxFee, _ := big.NewInt(0).SetString(unStakeTx.Fee, 10) + + unStakeValue2 := big.NewInt(12) + unStakeValue2 = unStakeValue2.Mul(oneEGLD, unStakeValue2) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue2.Bytes())) + txUnStake = generateTransaction(validatorOwner.Bytes, 2, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + unStakeValue3 := big.NewInt(13) + unStakeValue3 = unStakeValue3.Mul(oneEGLD, unStakeValue3) + txDataField = fmt.Sprintf("unStakeTokens@%s", hex.EncodeToString(unStakeValue3.Bytes())) + txUnStake = generateTransaction(validatorOwner.Bytes, 3, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForStakeOperation) + unStakeTx, err = cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnStake, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unStakeTx) + + // check bls key is still staked + testBLSKeyStaked(t, cs, metachainNode, blsKeys[0], targetEpoch) + + scQuery := &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getUnStakedTokensList", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedUnStaked := big.NewInt(11 + 12 + 13) + expectedUnStaked = expectedUnStaked.Mul(oneEGLD, expectedUnStaked) + require.Equal(t, expectedUnStaked.String(), big.NewInt(0).SetBytes(result.ReturnData[0]).String()) + + scQuery = &process.SCQuery{ + ScAddress: vm.ValidatorSCAddress, + FuncName: "getTotalStaked", + CallerAddr: vm.ValidatorSCAddress, + CallValue: big.NewInt(0), + Arguments: [][]byte{validatorOwner.Bytes}, + } + result, _, err = metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + expectedStaked := big.NewInt(2600 - 11 - 12 - 13) + expectedStaked = expectedStaked.Mul(oneEGLD, expectedStaked) + require.Equal(t, expectedStaked.String(), string(result.ReturnData[0])) + + log.Info("Step 3. Wait for the unbonding epoch to start") + + epochIncr := int32(3) + err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + require.Nil(t, err) + + log.Info("Step 4.1. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") + + txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) + txUnBond := generateTransaction(validatorOwner.Bytes, 4, vm.ValidatorSCAddress, zeroValue, txDataField, gasLimitForUnBond) + unBondTx, err := cs.SendTxAndGenerateBlockTilTxIsExecuted(txUnBond, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.NotNil(t, unBondTx) + + unBondTxFee, _ := big.NewInt(0).SetString(unBondTx.Fee, 10) + + err = cs.GenerateBlocks(2) + require.Nil(t, err) + + // the owner balance should increase with the (11+12+13 EGLD - tx fee) + accountValidatorOwner, _, err = cs.GetNodeHandler(shardIDValidatorOwner).GetFacadeHandler().GetAccount(validatorOwner.Bech32, coreAPI.AccountQueryOptions{}) + require.Nil(t, err) + balanceAfterUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) + + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue1) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue2) + balanceAfterUnbonding.Sub(balanceAfterUnbonding, unStakeValue3) + + txsFee := big.NewInt(0) + + txsFee.Add(txsFee, stakeTxFee) + txsFee.Add(txsFee, unBondTxFee) + txsFee.Add(txsFee, unStakeTxFee) + txsFee.Add(txsFee, unStakeTxFee) + txsFee.Add(txsFee, unStakeTxFee) + + balanceAfterUnbonding.Add(balanceAfterUnbonding, txsFee) + + require.Equal(t, 1, balanceAfterUnbonding.Cmp(balanceBeforeUnbonding)) +} From c8d348301b0f977009554a5618efe51528b1bcd2 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Sat, 2 Mar 2024 23:20:06 +0200 Subject: [PATCH 905/958] fix log messages --- .../chainSimulator/staking/stakeAndUnStake_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 536ffa4ac3b..3ee37d0046d 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -1727,7 +1727,7 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInBatches(t *testing. } // Test Steps - // 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld. + // 1. Create 3 transactions for unstaking: first one unstaking 11 egld each, second one unstaking 12 egld and third one unstaking 13 egld. // 2. Send the transactions in consecutive epochs, one TX in each epoch. // 3. Wait for the epoch when first tx unbonding period ends. // 4. Create a transaction for withdraw and send it to the network @@ -1901,7 +1901,7 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld.") + log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 11 egld each, second one unstaking 12 egld and third one unstaking 13 egld.") log.Info("Step 2. Send the transactions in consecutive epochs, one TX in each epoch.") unStakeValue1 := big.NewInt(11) @@ -2087,7 +2087,7 @@ func TestChainSimulator_DirectStakingNodes_WithdrawUnstakedInEpoch(t *testing.T) } // Test Steps - // 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld. + // 1. Create 3 transactions for unstaking: first one unstaking 11 egld each, second one unstaking 12 egld and third one unstaking 13 egld. // 2. Send the transactions consecutively in the same epoch // 3. Wait for the epoch when unbonding period ends. // 4. Create a transaction for withdraw and send it to the network @@ -2257,7 +2257,7 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t *testing.T, cs require.Nil(t, err) balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 1 egld each, second one unstaking 2 egld and third one unstaking 3 egld.") + log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 11 egld each, second one unstaking 12 egld and third one unstaking 13 egld.") log.Info("Step 2. Send the transactions in consecutively in same epoch.") unStakeValue1 := big.NewInt(11) From c50eb8cce0510023d97201b6993552d1490e34e5 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 4 Mar 2024 09:10:04 +0200 Subject: [PATCH 906/958] - linter fix --- .../chainSimulator/staking/delegation_test.go | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 831f1beaa05..b6d8946be5d 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -1366,25 +1366,3 @@ func getBLSKeyOwner(t *testing.T, metachainNode chainSimulatorProcess.NodeHandle return result.ReturnData[0] } - -func getBLSKeys(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, ownerKeyBytes []byte) [][]byte { - scQuery := &process.SCQuery{ - ScAddress: vm.ValidatorSCAddress, - FuncName: "getBlsKeysStatus", - CallerAddr: vm.ValidatorSCAddress, - CallValue: big.NewInt(0), - Arguments: [][]byte{ownerKeyBytes}, - } - result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) - require.Nil(t, err) - require.Equal(t, okReturnCode, result.ReturnCode) - - blsKeys := make([][]byte, 0) - for idx, data := range result.ReturnData { - if idx%2 == 0 { - blsKeys = append(blsKeys, data) - } - } - - return blsKeys -} From d8ac9b41a147c2674bda6cfcea9c784f475b8823 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 4 Mar 2024 12:14:11 +0200 Subject: [PATCH 907/958] - fixed typo --- integrationTests/chainSimulator/staking/delegation_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index b6d8946be5d..e848734525b 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -380,7 +380,7 @@ func testBLSKeyIsInAuction( } // Test description: -// Test that 2 diferent contracts with different topups that came from the normal stake will be considered in auction list computing in the correct order +// Test that 2 different contracts with different topups that came from the normal stake will be considered in auction list computing in the correct order // 1. Add 2 new validator private keys in the multi key handler // 2. Set the initial state for 2 owners (mint 2 new wallets) // 3. Do 2 stake transactions and test that the new keys are on queue / auction list and have the correct topup - 100 and 200 EGLD, respectively From 4d73dbbbd7d2d7c4ca47a49908a0a02e5cfc3de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 5 Mar 2024 12:12:26 +0200 Subject: [PATCH 908/958] Reference VMs with wasmer for MacOS ARM64. --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index fd4c186373c..7487e966bdd 100644 --- a/go.mod +++ b/go.mod @@ -22,10 +22,10 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240305093405-c9cf0617ec51 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index f8f68456da6..d5378245d39 100644 --- a/go.sum +++ b/go.sum @@ -401,14 +401,14 @@ github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a h1:4Dlk5Hcxlt6az5qqJfklgSlAKEYiFLv+xkFavQJgSNY= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72 h1:NMHNT4NcqOdnHttYsT3ydZHVapwOctp6t+WDGDy0UEQ= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216071136-6d748b5d6a72/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 h1:1uMlT5TjiHUlx81fEH/WQANWlY0PjF3opMlW+E3L3GI= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 h1:0y1k2+FjFfWgoPCMi0nkYkCYQJtPYJvph6bre4Elqxk= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240305093405-c9cf0617ec51 h1:gkU8R6UbhBcZw1yT/nUs0uW2vg3dz4zhuqaBnSgX+Sc= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240305093405-c9cf0617ec51/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162 h1:FxlO3DZ4ndatpaUMOesV+kC3KLIrb4aQgcw5++VLhDE= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b h1:upetIPDOAi1gXihIu5pS+KlqeTlvFUrBDHj7mv4wn9Q= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33 h1:zqMZBj8eM6sKUizbMcjfUZGrThXUj2wzbeo0b0Moq4w= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From 7fac17b137fb5baabd8cf3da752beac25b85a87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 5 Mar 2024 12:13:10 +0200 Subject: [PATCH 909/958] Attempt to make packages for MacOS, as well. --- .github/workflows/create_release.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 9916e67d744..454cda1d291 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -15,7 +15,7 @@ jobs: build: strategy: matrix: - runs-on: [ubuntu-latest] # TODO add macos-latest when builds are possible on macs + runs-on: [ubuntu-latest, macos-latest, macos-latest-xlarge] runs-on: ${{ matrix.runs-on }} name: Build steps: @@ -77,11 +77,19 @@ jobs: if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then cp -f ${WASMER_DIR}/libwasmer_darwin_amd64.dylib ${BUILD_DIR}; fi + if [[ "$GOOS" == darwin && "$GOARCH" == arm64 ]]; then + cp -f ${WASMER_DIR}/libwasmer_darwin_arm64_shim.dylib ${BUILD_DIR}; + fi cd ${BUILD_DIR} tar czvf "${GITHUB_WORKSPACE}/${ARCHIVE}" * stat ${GITHUB_WORKSPACE}/${ARCHIVE} + - name: Smoke test + run: | + cd ${BUILD_DIR} + ./node --version + - name: Save artifacts uses: actions/upload-artifact@v3 with: From 4b03546c107d604e6b4fb45071701e62de6b8d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 5 Mar 2024 12:23:32 +0200 Subject: [PATCH 910/958] Undo CI workflow. --- .github/workflows/create_release.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 454cda1d291..9916e67d744 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -15,7 +15,7 @@ jobs: build: strategy: matrix: - runs-on: [ubuntu-latest, macos-latest, macos-latest-xlarge] + runs-on: [ubuntu-latest] # TODO add macos-latest when builds are possible on macs runs-on: ${{ matrix.runs-on }} name: Build steps: @@ -77,19 +77,11 @@ jobs: if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then cp -f ${WASMER_DIR}/libwasmer_darwin_amd64.dylib ${BUILD_DIR}; fi - if [[ "$GOOS" == darwin && "$GOARCH" == arm64 ]]; then - cp -f ${WASMER_DIR}/libwasmer_darwin_arm64_shim.dylib ${BUILD_DIR}; - fi cd ${BUILD_DIR} tar czvf "${GITHUB_WORKSPACE}/${ARCHIVE}" * stat ${GITHUB_WORKSPACE}/${ARCHIVE} - - name: Smoke test - run: | - cd ${BUILD_DIR} - ./node --version - - name: Save artifacts uses: actions/upload-artifact@v3 with: From 4ffa41522179e9ff582b83031b71c9ff0694f365 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Tue, 5 Mar 2024 15:32:23 +0200 Subject: [PATCH 911/958] - fixes after merge --- go.mod | 4 ++-- go.sum | 12 ++++++------ .../chainSimulator/staking/simpleStake_test.go | 4 ++++ testscommon/stakingcommon/stakingCommon.go | 8 +++----- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 1b525ee715b..4159e58b3ca 100644 --- a/go.mod +++ b/go.mod @@ -21,8 +21,8 @@ require ( github.com/multiversx/mx-chain-logger-go v1.0.14-0.20240129144507-d00e967c890c github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 - github.com/multiversx/mx-chain-vm-common-go 2231c71162a2302aeb2515c92e563818539e7449 - github.com/multiversx/mx-chain-vm-go e2a4c8ed982347fdebbe3c864ee97930040846c6 + github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216171908-e2a4c8ed9823 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 diff --git a/go.sum b/go.sum index 9bb73d6b6a8..9846df6f1ca 100644 --- a/go.sum +++ b/go.sum @@ -387,8 +387,8 @@ github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUY github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o= github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad h1:izxTyKCxvT7z2mhXCWAZibSxwRVgLmq/kDovs4Nx/6Y= github.com/multiversx/mx-chain-communication-go v1.0.13-0.20240126121117-627adccf10ad/go.mod h1:n4E8BWIV0g3AcNGe1gf+vcjUC8A2QCJ4ARQSbiUDGrI= -github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2 h1:pFh9bwOTRgW173aHqA8Bmax+jYzLnRyXqRvi5alF7V4= -github.com/multiversx/mx-chain-core-go v1.2.19-0.20240129082057-a76d0c995cf2/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= +github.com/multiversx/mx-chain-core-go v1.2.19-0.20240222081523-011c96ab2548 h1:WQoVgQG9YWiYM5Q3MmnbnxeoQkfHr63iFJZScFYsMxk= +github.com/multiversx/mx-chain-core-go v1.2.19-0.20240222081523-011c96ab2548/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479 h1:beVIhs5ysylwNplQ/bZ0h5DoDlqKNWgpWE/NMHHNmAw= github.com/multiversx/mx-chain-crypto-go v1.2.10-0.20231206065052-38843c1f1479/go.mod h1:Ap6p7QZFtwPlb++OvCG+85BfuZ+bLP/JtQp6EwjWJsI= github.com/multiversx/mx-chain-es-indexer-go v1.4.19-0.20240129150813-a772c480d33a h1:mOMUhbsjTq7n5oAv4KkVnL67ngS0+wkqmkiv1XJfBIY= @@ -399,10 +399,10 @@ github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157/go.mod h1:ndk45i9J9McuCJpTcgiaK4ocd0yhnBBCPrlFwO6GRcs= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 h1:/EYv/HGX0OKbeNFt667J0yZRtuJiZH0lEK8YtobuH/c= github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130132341-93fdd39a4ebb h1:wIyvWXmCkEwN8sh1qzwAvU5Zix71tAR7wPOfOsacRE0= -github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240130132341-93fdd39a4ebb/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216161541-26d85a6428e1 h1:h/ehvb/5YPYY34Kr9ftICH8/sLwU3wmAsssg/vkR6Is= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216161541-26d85a6428e1/go.mod h1:Xs0xFsPv+c1p8pwurLV7VBS7bEpIN/0jZrCwXVU26zw= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2 h1:sBH1Zf5jdMqS+1LDfXBmsIdmol8CFloPzjDCtmBZGEc= +github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216171908-e2a4c8ed9823 h1:UMu8cs5nBli6oOZo7AEiWteJriSLV5//mc1tGoapMgY= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216171908-e2a4c8ed9823/go.mod h1:Xs0xFsPv+c1p8pwurLV7VBS7bEpIN/0jZrCwXVU26zw= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 h1:1uMlT5TjiHUlx81fEH/WQANWlY0PjF3opMlW+E3L3GI= diff --git a/integrationTests/chainSimulator/staking/simpleStake_test.go b/integrationTests/chainSimulator/staking/simpleStake_test.go index 933e7888824..6439e14d623 100644 --- a/integrationTests/chainSimulator/staking/simpleStake_test.go +++ b/integrationTests/chainSimulator/staking/simpleStake_test.go @@ -142,6 +142,10 @@ func testChainSimulatorSimpleStake(t *testing.T, targetEpoch int32, nodesStatus // 1. Stake 1 node and check that in stakingV4 step1 it is found in auction // 2. From stakingV4 step2 onwards, check that api returns 8 qualified + 1 unqualified nodes func TestChainSimulator_StakingV4Step2APICalls(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + stakingV4Step1Epoch := uint32(2) stakingV4Step2Epoch := uint32(3) stakingV4Step3Epoch := uint32(4) diff --git a/testscommon/stakingcommon/stakingCommon.go b/testscommon/stakingcommon/stakingCommon.go index 31585006e69..1af9b441b9c 100644 --- a/testscommon/stakingcommon/stakingCommon.go +++ b/testscommon/stakingcommon/stakingCommon.go @@ -9,7 +9,6 @@ import ( "github.com/multiversx/mx-chain-go/genesis/process/disabled" "github.com/multiversx/mx-chain-go/process" economicsHandler "github.com/multiversx/mx-chain-go/process/economics" - "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon/enableEpochsHandlerMock" "github.com/multiversx/mx-chain-go/testscommon/epochNotifier" @@ -275,10 +274,9 @@ func CreateEconomicsData() process.EconomicsDataHandler { MaxGasPriceSetGuardian: minGasPrice, }, }, - EpochNotifier: &epochNotifier.EpochNotifierStub{}, - BuiltInFunctionsCostHandler: &mock.BuiltInCostHandlerStub{}, - EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, - TxVersionChecker: &disabled.TxVersionChecker{}, + EpochNotifier: &epochNotifier.EpochNotifierStub{}, + EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + TxVersionChecker: &disabled.TxVersionChecker{}, } economicsData, _ := economicsHandler.NewEconomicsData(argsNewEconomicsData) return economicsData From 34badde8479276085348dd00f5f9509300bb5f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 5 Mar 2024 16:42:17 +0200 Subject: [PATCH 912/958] Conditional compilation. --- process/factory/shard/vmContainerFactory.go | 14 ------------ ...rFactory_createInProcessWasmVMByVersion.go | 22 +++++++++++++++++++ ...teInProcessWasmVMByVersion_darwin_arm64.go | 16 ++++++++++++++ 3 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go create mode 100644 process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go diff --git a/process/factory/shard/vmContainerFactory.go b/process/factory/shard/vmContainerFactory.go index 35c17f763a1..6e4456448b2 100644 --- a/process/factory/shard/vmContainerFactory.go +++ b/process/factory/shard/vmContainerFactory.go @@ -279,20 +279,6 @@ func (vmf *vmContainerFactory) getMatchingVersion(epoch uint32) config.WasmVMVer return matchingVersion } -func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { - logVMContainerFactory.Debug("createInProcessWasmVMByVersion", "version", version) - switch version.Version { - case "v1.2": - return vmf.createInProcessWasmVMV12() - case "v1.3": - return vmf.createInProcessWasmVMV13() - case "v1.4": - return vmf.createInProcessWasmVMV14() - default: - return vmf.createInProcessWasmVMV15() - } -} - func (vmf *vmContainerFactory) createInProcessWasmVMV12() (vmcommon.VMExecutionHandler, error) { logVMContainerFactory.Info("VM 1.2 created") hostParameters := &wasmvm12.VMHostParameters{ diff --git a/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go b/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go new file mode 100644 index 00000000000..607fe365697 --- /dev/null +++ b/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go @@ -0,0 +1,22 @@ +//go:build !(darwin && arm64) + +package shard + +import ( + "github.com/multiversx/mx-chain-go/config" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" +) + +func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { + logVMContainerFactory.Debug("createInProcessWasmVMByVersion !(darwin && arm64)", "version", version) + switch version.Version { + case "v1.2": + return vmf.createInProcessWasmVMV12() + case "v1.3": + return vmf.createInProcessWasmVMV13() + case "v1.4": + return vmf.createInProcessWasmVMV14() + default: + return vmf.createInProcessWasmVMV15() + } +} diff --git a/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go b/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go new file mode 100644 index 00000000000..34ece21cdb6 --- /dev/null +++ b/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go @@ -0,0 +1,16 @@ +//go:build darwin && arm64 + +package shard + +import ( + "github.com/multiversx/mx-chain-go/config" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" +) + +func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { + logVMContainerFactory.Debug("createInProcessWasmVMByVersion (darwin && arm64)", "version", version) + switch version.Version { + default: + return vmf.createInProcessWasmVMV15() + } +} From d21c9ebadeda1c474c89a3ee631aa2bcb6492a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 5 Mar 2024 16:48:23 +0200 Subject: [PATCH 913/958] Patch VM config wrt. architecture. --- process/factory/shard/vmConfigPatching.go | 8 +++++++ .../shard/vmConfigPatching_darwin_arm64.go.go | 8 +++++++ process/factory/shard/vmContainerFactory.go | 16 ++++++++++++++ ...rFactory_createInProcessWasmVMByVersion.go | 22 ------------------- ...teInProcessWasmVMByVersion_darwin_arm64.go | 16 -------------- 5 files changed, 32 insertions(+), 38 deletions(-) create mode 100644 process/factory/shard/vmConfigPatching.go create mode 100644 process/factory/shard/vmConfigPatching_darwin_arm64.go.go delete mode 100644 process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go delete mode 100644 process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go diff --git a/process/factory/shard/vmConfigPatching.go b/process/factory/shard/vmConfigPatching.go new file mode 100644 index 00000000000..2d0284a6e7e --- /dev/null +++ b/process/factory/shard/vmConfigPatching.go @@ -0,0 +1,8 @@ +//go:build !(darwin && arm64) + +package shard + +import "github.com/multiversx/mx-chain-go/config" + +func patchVirtualMachineConfigGivenArchitecture(config *config.VirtualMachineConfig) { +} diff --git a/process/factory/shard/vmConfigPatching_darwin_arm64.go.go b/process/factory/shard/vmConfigPatching_darwin_arm64.go.go new file mode 100644 index 00000000000..5186300b202 --- /dev/null +++ b/process/factory/shard/vmConfigPatching_darwin_arm64.go.go @@ -0,0 +1,8 @@ +//go:build darwin && arm64 + +package shard + +import "github.com/multiversx/mx-chain-go/config" + +func patchVirtualMachineConfigGivenArchitecture(config *config.VirtualMachineConfig) { +} diff --git a/process/factory/shard/vmContainerFactory.go b/process/factory/shard/vmContainerFactory.go index 6e4456448b2..048ea8a9990 100644 --- a/process/factory/shard/vmContainerFactory.go +++ b/process/factory/shard/vmContainerFactory.go @@ -87,6 +87,8 @@ func NewVMContainerFactory(args ArgVMContainerFactory) (*vmContainerFactory, err return nil, process.ErrNilHasher } + patchVirtualMachineConfigGivenArchitecture(&args.Config) + cryptoHook := hooks.NewVMCryptoHook() vmf := &vmContainerFactory{ @@ -279,6 +281,20 @@ func (vmf *vmContainerFactory) getMatchingVersion(epoch uint32) config.WasmVMVer return matchingVersion } +func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { + logVMContainerFactory.Debug("createInProcessWasmVMByVersion !(darwin && arm64)", "version", version) + switch version.Version { + case "v1.2": + return vmf.createInProcessWasmVMV12() + case "v1.3": + return vmf.createInProcessWasmVMV13() + case "v1.4": + return vmf.createInProcessWasmVMV14() + default: + return vmf.createInProcessWasmVMV15() + } +} + func (vmf *vmContainerFactory) createInProcessWasmVMV12() (vmcommon.VMExecutionHandler, error) { logVMContainerFactory.Info("VM 1.2 created") hostParameters := &wasmvm12.VMHostParameters{ diff --git a/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go b/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go deleted file mode 100644 index 607fe365697..00000000000 --- a/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build !(darwin && arm64) - -package shard - -import ( - "github.com/multiversx/mx-chain-go/config" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" -) - -func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { - logVMContainerFactory.Debug("createInProcessWasmVMByVersion !(darwin && arm64)", "version", version) - switch version.Version { - case "v1.2": - return vmf.createInProcessWasmVMV12() - case "v1.3": - return vmf.createInProcessWasmVMV13() - case "v1.4": - return vmf.createInProcessWasmVMV14() - default: - return vmf.createInProcessWasmVMV15() - } -} diff --git a/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go b/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go deleted file mode 100644 index 34ece21cdb6..00000000000 --- a/process/factory/shard/vmContainerFactory_createInProcessWasmVMByVersion_darwin_arm64.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build darwin && arm64 - -package shard - -import ( - "github.com/multiversx/mx-chain-go/config" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" -) - -func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { - logVMContainerFactory.Debug("createInProcessWasmVMByVersion (darwin && arm64)", "version", version) - switch version.Version { - default: - return vmf.createInProcessWasmVMV15() - } -} From b4baa9ab923cd42e45868da734e9cc4a332e06e1 Mon Sep 17 00:00:00 2001 From: ssd04 Date: Wed, 6 Mar 2024 11:42:28 +0200 Subject: [PATCH 914/958] fixes after review --- .../staking/stakeAndUnStake_test.go | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go index 24571eebdf6..34ab9c44f78 100644 --- a/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go +++ b/integrationTests/chainSimulator/staking/stakeAndUnStake_test.go @@ -1829,7 +1829,7 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) balanceBeforeUnbonding, _ := big.NewInt(0).SetString(accountValidatorOwner.Balance, 10) - log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 11 egld each, second one unstaking 12 egld and third one unstaking 13 egld.") + log.Info("Step 1. Create 3 transactions for unstaking: first one unstaking 11 egld, second one unstaking 12 egld and third one unstaking 13 egld.") log.Info("Step 2. Send the transactions in consecutive epochs, one TX in each epoch.") unStakeValue1 := big.NewInt(11) @@ -1842,8 +1842,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, unStakeTxFee, _ := big.NewInt(0).SetString(unStakeTx.Fee, 10) - epochIncr := int32(1) - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch := targetEpoch + 1 + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) unStakeValue2 := big.NewInt(12) @@ -1854,8 +1854,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unStakeTx) - epochIncr++ - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch++ + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) unStakeValue3 := big.NewInt(13) @@ -1866,8 +1866,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, require.Nil(t, err) require.NotNil(t, unStakeTx) - epochIncr++ - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch++ + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) // check bls key is still staked @@ -1905,8 +1905,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, log.Info("Step 3. Wait for the unbonding epoch to start") - epochIncr += 3 - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch += 3 + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) log.Info("Step 4.1. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") @@ -1943,8 +1943,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, log.Info("Step 4.2. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") - epochIncr++ - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch++ + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) @@ -1971,8 +1971,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInBatches(t *testing.T, log.Info("Step 4.3. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") - epochIncr++ - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch++ + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) txDataField = fmt.Sprintf("unBondTokens@%s", blsKeys[0]) @@ -2249,8 +2249,8 @@ func testChainSimulatorDirectStakedWithdrawUnstakedFundsInEpoch(t *testing.T, cs log.Info("Step 3. Wait for the unbonding epoch to start") - epochIncr := int32(3) - err = cs.GenerateBlocksUntilEpochIsReached(targetEpoch + epochIncr) + testEpoch := targetEpoch + 3 + err = cs.GenerateBlocksUntilEpochIsReached(testEpoch) require.Nil(t, err) log.Info("Step 4.1. Create from the owner of staked nodes a transaction to withdraw the unstaked funds") From 9318acbab83412b3094d123d0b57c118c31f9422 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 6 Mar 2024 11:44:59 +0200 Subject: [PATCH 915/958] fix integration tests --- integrationTests/chainSimulator/staking/jail_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrationTests/chainSimulator/staking/jail_test.go b/integrationTests/chainSimulator/staking/jail_test.go index 824b746c385..c2e6b13e9d1 100644 --- a/integrationTests/chainSimulator/staking/jail_test.go +++ b/integrationTests/chainSimulator/staking/jail_test.go @@ -71,8 +71,8 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus RoundDurationInMillis: roundDurationInMillis, RoundsPerEpoch: roundsPerEpoch, ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 3, - MetaChainMinNodes: 3, + MinNodesPerShard: 2, + MetaChainMinNodes: 2, AlterConfigsFunction: func(cfg *config.Configs) { configs.SetStakingV4ActivationEpochs(cfg, stakingV4JailUnJailStep1EnableEpoch) newNumNodes := cfg.SystemSCConfig.StakingSystemSCConfig.MaxNumberOfNodesForStake + 8 // 8 nodes until new nodes will be placed on queue @@ -85,7 +85,7 @@ func testChainSimulatorJailAndUnJail(t *testing.T, targetEpoch int32, nodeStatus defer cs.Close() metachainNode := cs.GetNodeHandler(core.MetachainShardId) - err = cs.GenerateBlocks(30) + err = cs.GenerateBlocksUntilEpochIsReached(1) require.Nil(t, err) _, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(1) From 50359d96cb297d18c90382fc71b15ec9c4690ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 6 Mar 2024 12:12:03 +0200 Subject: [PATCH 916/958] Linux ARM64, attempt 1. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7487e966bdd..905b33d0dbd 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240305093405-c9cf0617ec51 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306100836-6e29a4e483c0 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162 github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33 diff --git a/go.sum b/go.sum index d5378245d39..52e7642ac8a 100644 --- a/go.sum +++ b/go.sum @@ -401,8 +401,8 @@ github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a h1:4Dlk5Hcxlt6az5qqJfklgSlAKEYiFLv+xkFavQJgSNY= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240305093405-c9cf0617ec51 h1:gkU8R6UbhBcZw1yT/nUs0uW2vg3dz4zhuqaBnSgX+Sc= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240305093405-c9cf0617ec51/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306100836-6e29a4e483c0 h1:+V6zOvNsEopke1S/WNQdzeWYdezrGK8VEcdqka4bPts= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306100836-6e29a4e483c0/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162 h1:FxlO3DZ4ndatpaUMOesV+kC3KLIrb4aQgcw5++VLhDE= github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b h1:upetIPDOAi1gXihIu5pS+KlqeTlvFUrBDHj7mv4wn9Q= From 055aadae471a63353e7a3bc837815fc93dc43f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 6 Mar 2024 12:25:13 +0200 Subject: [PATCH 917/958] Use shim for Linux ARM64. --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 905b33d0dbd..decb459fd36 100644 --- a/go.mod +++ b/go.mod @@ -22,10 +22,10 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306100836-6e29a4e483c0 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162 - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306102000-5558831c0907 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306102416-19d1c5c4759d + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306102304-fe7398ed2e79 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306102152-36e9202dd8a0 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index 52e7642ac8a..28fcd51bcb4 100644 --- a/go.sum +++ b/go.sum @@ -401,14 +401,14 @@ github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a h1:4Dlk5Hcxlt6az5qqJfklgSlAKEYiFLv+xkFavQJgSNY= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306100836-6e29a4e483c0 h1:+V6zOvNsEopke1S/WNQdzeWYdezrGK8VEcdqka4bPts= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306100836-6e29a4e483c0/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162 h1:FxlO3DZ4ndatpaUMOesV+kC3KLIrb4aQgcw5++VLhDE= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240305095209-94f9bd328162/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b h1:upetIPDOAi1gXihIu5pS+KlqeTlvFUrBDHj7mv4wn9Q= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240305095024-3ab3bd16920b/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33 h1:zqMZBj8eM6sKUizbMcjfUZGrThXUj2wzbeo0b0Moq4w= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240305094707-88357383ed33/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306102000-5558831c0907 h1:jujNXZ1MJlkyWjP0uTDADNKLd3nj54awsN0CSuXcaEk= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306102000-5558831c0907/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306102416-19d1c5c4759d h1:5H88hiWOag+2/NvJbOBdjV6KkCbQMF31nnQ+QaM6dZw= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306102416-19d1c5c4759d/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306102304-fe7398ed2e79 h1:bGDApgyvSzmr28zIH9En1XeaGldVcuyJN8Ha5C93uJQ= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306102304-fe7398ed2e79/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306102152-36e9202dd8a0 h1:JqhdxL/oi2IwM1VP7Ty+Sn6gxbXFwf5igK+mXbwkaFM= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306102152-36e9202dd8a0/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From ef6063596abb2ef2e83dbce5d2d38a9e764d263a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 6 Mar 2024 17:34:55 +0200 Subject: [PATCH 918/958] Reference newer commits. --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index decb459fd36..73ceed94975 100644 --- a/go.mod +++ b/go.mod @@ -22,10 +22,10 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306102000-5558831c0907 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306102416-19d1c5c4759d - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306102304-fe7398ed2e79 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306102152-36e9202dd8a0 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306152414-d2c148d225e6 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index 28fcd51bcb4..6751d2dc83c 100644 --- a/go.sum +++ b/go.sum @@ -401,14 +401,14 @@ github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a h1:4Dlk5Hcxlt6az5qqJfklgSlAKEYiFLv+xkFavQJgSNY= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240227112124-bfd3f5676e5a/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306102000-5558831c0907 h1:jujNXZ1MJlkyWjP0uTDADNKLd3nj54awsN0CSuXcaEk= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306102000-5558831c0907/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306102416-19d1c5c4759d h1:5H88hiWOag+2/NvJbOBdjV6KkCbQMF31nnQ+QaM6dZw= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306102416-19d1c5c4759d/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306102304-fe7398ed2e79 h1:bGDApgyvSzmr28zIH9En1XeaGldVcuyJN8Ha5C93uJQ= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306102304-fe7398ed2e79/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306102152-36e9202dd8a0 h1:JqhdxL/oi2IwM1VP7Ty+Sn6gxbXFwf5igK+mXbwkaFM= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306102152-36e9202dd8a0/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306152414-d2c148d225e6 h1:W9d6t2vdaNFsCB1aZsteCarw1vKHmcYIrnIYy4DmAmU= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240306152414-d2c148d225e6/go.mod h1:YCD2Q+kpzx86ydowe/BKw/ZdzYjfH/4IxWHS0NsyuD0= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50 h1:pFNv0WBbQfvAY9Uvy9xnYjf3BE93C4QLHy0G75kla3Q= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87 h1:RpC4Gt2ttGBqHZNpF3sqBqOWfmhYceu+KAZSCQtueVI= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172 h1:ql66TYHXfyPjTYOUn7dohp98ZJYQDGEYSJ3aVXygmLk= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From 069b541dae01b23d95b336fe169c00f3a75e9417 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 7 Mar 2024 14:19:15 +0200 Subject: [PATCH 919/958] fixed linter issues by removing unused methods --- .../baseRequestersContainerFactory.go | 44 ------------------- process/smartContract/scQueryService.go | 9 ---- process/transaction/metaProcess.go | 12 ----- 3 files changed, 65 deletions(-) diff --git a/dataRetriever/factory/storageRequestersContainer/baseRequestersContainerFactory.go b/dataRetriever/factory/storageRequestersContainer/baseRequestersContainerFactory.go index e68b10d5e46..2682231a768 100644 --- a/dataRetriever/factory/storageRequestersContainer/baseRequestersContainerFactory.go +++ b/dataRetriever/factory/storageRequestersContainer/baseRequestersContainerFactory.go @@ -10,7 +10,6 @@ import ( "github.com/multiversx/mx-chain-core-go/hashing" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/common" - "github.com/multiversx/mx-chain-go/common/disabled" "github.com/multiversx/mx-chain-go/common/statistics" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" @@ -20,9 +19,6 @@ import ( "github.com/multiversx/mx-chain-go/p2p" "github.com/multiversx/mx-chain-go/process/factory" "github.com/multiversx/mx-chain-go/sharding" - "github.com/multiversx/mx-chain-go/storage" - storageFactory "github.com/multiversx/mx-chain-go/storage/factory" - trieFactory "github.com/multiversx/mx-chain-go/trie/factory" ) const defaultBeforeGracefulClose = time.Minute @@ -239,46 +235,6 @@ func (brcf *baseRequestersContainerFactory) createMiniBlocksRequester(responseTo return mbRequester, nil } -func (brcf *baseRequestersContainerFactory) newImportDBTrieStorage( - mainStorer storage.Storer, - storageIdentifier dataRetriever.UnitType, - handler common.EnableEpochsHandler, - stateStatsHandler common.StateStatisticsHandler, -) (common.StorageManager, dataRetriever.TrieDataGetter, error) { - pathManager, err := storageFactory.CreatePathManager( - storageFactory.ArgCreatePathManager{ - WorkingDir: brcf.workingDir, - ChainID: brcf.chainID, - }, - ) - if err != nil { - return nil, nil, err - } - - trieFactoryArgs := trieFactory.TrieFactoryArgs{ - Marshalizer: brcf.marshalizer, - Hasher: brcf.hasher, - PathManager: pathManager, - TrieStorageManagerConfig: brcf.generalConfig.TrieStorageManagerConfig, - } - trieFactoryInstance, err := trieFactory.NewTrieFactory(trieFactoryArgs) - if err != nil { - return nil, nil, err - } - - args := trieFactory.TrieCreateArgs{ - MainStorer: mainStorer, - PruningEnabled: brcf.generalConfig.StateTriesConfig.AccountsStatePruningEnabled, - MaxTrieLevelInMem: brcf.generalConfig.StateTriesConfig.MaxStateTrieLevelInMemory, - SnapshotsEnabled: brcf.snapshotsEnabled, - IdleProvider: disabled.NewProcessStatusHandler(), - Identifier: storageIdentifier.String(), - EnableEpochsHandler: handler, - StatsCollector: stateStatsHandler, - } - return trieFactoryInstance.Create(args) -} - func (brcf *baseRequestersContainerFactory) generatePeerAuthenticationRequester() error { identifierPeerAuth := common.PeerAuthenticationTopic peerAuthRequester := disabledRequesters.NewDisabledRequester() diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 10a5be173da..ec6ad67e87c 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -269,15 +269,6 @@ func (service *SCQueryService) recreateTrie(blockRootHash []byte, blockHeader da return accountsAdapter.RecreateTrie(blockRootHash) } -func (service *SCQueryService) getCurrentEpoch() uint32 { - header := service.mainBlockChain.GetCurrentBlockHeader() - if check.IfNil(header) { - return 0 - } - - return header.GetEpoch() -} - // TODO: extract duplicated code with nodeBlocks.go func (service *SCQueryService) extractBlockHeaderAndRootHash(query *process.SCQuery) (data.HeaderHandler, []byte, error) { if len(query.BlockHash) > 0 { diff --git a/process/transaction/metaProcess.go b/process/transaction/metaProcess.go index 963bfa31721..d1b88a012d4 100644 --- a/process/transaction/metaProcess.go +++ b/process/transaction/metaProcess.go @@ -184,18 +184,6 @@ func (txProc *metaTxProcessor) processSCInvoking( return txProc.scProcessor.ExecuteSmartContractTransaction(tx, acntSrc, acntDst) } -func (txProc *metaTxProcessor) processBuiltInFunctionCall( - tx *transaction.Transaction, - adrSrc, adrDst []byte, -) (vmcommon.ReturnCode, error) { - acntSrc, acntDst, err := txProc.getAccounts(adrSrc, adrDst) - if err != nil { - return 0, err - } - - return txProc.scProcessor.ExecuteBuiltInFunction(tx, acntSrc, acntDst) -} - // IsInterfaceNil returns true if there is no value under the interface func (txProc *metaTxProcessor) IsInterfaceNil() bool { return txProc == nil From 41cd68032d734f63999c30e1b29ec591944bb5ef Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 7 Mar 2024 15:04:16 +0200 Subject: [PATCH 920/958] - added generic configs tweaks based on architecture --- node/customConfigsDarwinArm64.go | 28 +++++++++ node/customConfigsDarwinArm64_test.go | 91 +++++++++++++++++++++++++++ node/customConfigsDefault.go | 13 ++++ node/customConfigsDefault_test.go | 74 ++++++++++++++++++++++ node/nodeRunner.go | 4 ++ 5 files changed, 210 insertions(+) create mode 100644 node/customConfigsDarwinArm64.go create mode 100644 node/customConfigsDarwinArm64_test.go create mode 100644 node/customConfigsDefault.go create mode 100644 node/customConfigsDefault_test.go diff --git a/node/customConfigsDarwinArm64.go b/node/customConfigsDarwinArm64.go new file mode 100644 index 00000000000..da7e3d05884 --- /dev/null +++ b/node/customConfigsDarwinArm64.go @@ -0,0 +1,28 @@ +//go:build darwin && arm64 + +package node + +import ( + "runtime" + + "github.com/multiversx/mx-chain-go/config" +) + +func applyArchCustomConfigs(configs *config.Configs) { + log.Debug("applyArchCustomConfigs", "architecture", runtime.GOARCH) + + firstSupportedWasmer2VMVersion := "v1.5" + log.Debug("applyArchCustomConfigs - hardcoding the initial VM to " + firstSupportedWasmer2VMVersion) + configs.GeneralConfig.VirtualMachine.Execution.WasmVMVersions = []config.WasmVMVersionByEpoch{ + { + StartEpoch: 0, + Version: firstSupportedWasmer2VMVersion, + }, + } + configs.GeneralConfig.VirtualMachine.Querying.WasmVMVersions = []config.WasmVMVersionByEpoch{ + { + StartEpoch: 0, + Version: firstSupportedWasmer2VMVersion, + }, + } +} diff --git a/node/customConfigsDarwinArm64_test.go b/node/customConfigsDarwinArm64_test.go new file mode 100644 index 00000000000..ac8e53463c1 --- /dev/null +++ b/node/customConfigsDarwinArm64_test.go @@ -0,0 +1,91 @@ +//go:build darwin && arm64 + +package node + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/config" + "github.com/stretchr/testify/assert" +) + +func TestApplyArchCustomConfigs(t *testing.T) { + t.Parallel() + + executionVMConfig := config.VirtualMachineConfig{ + WasmVMVersions: []config.WasmVMVersionByEpoch{ + { + StartEpoch: 0, + Version: "v1.2", + }, + { + StartEpoch: 1, + Version: "v1.3", + }, + { + StartEpoch: 2, + Version: "v1.4", + }, + { + StartEpoch: 3, + Version: "v1.5", + }, + }, + TimeOutForSCExecutionInMilliseconds: 1, + WasmerSIGSEGVPassthrough: true, + } + + queryVMConfig := config.QueryVirtualMachineConfig{ + VirtualMachineConfig: executionVMConfig, + NumConcurrentVMs: 15, + } + + expectedVMWasmVersionsConfig := []config.WasmVMVersionByEpoch{ + { + StartEpoch: 0, + Version: "v1.5", + }, + } + + t.Run("providing a configuration should alter it", func(t *testing.T) { + t.Parallel() + + providedConfigs := &config.Configs{ + GeneralConfig: &config.Config{ + VirtualMachine: config.VirtualMachineServicesConfig{ + Execution: executionVMConfig, + Querying: queryVMConfig, + }, + }, + } + + expectedVMConfig := providedConfigs.GeneralConfig.VirtualMachine + expectedVMConfig.Execution.WasmVMVersions = expectedVMWasmVersionsConfig + expectedVMConfig.Querying.WasmVMVersions = expectedVMWasmVersionsConfig + + applyArchCustomConfigs(providedConfigs) + + assert.Equal(t, expectedVMConfig, providedConfigs.GeneralConfig.VirtualMachine) + }) + t.Run("empty config should return an altered config", func(t *testing.T) { + t.Parallel() + + providedConfigs := &config.Configs{ + GeneralConfig: &config.Config{}, + } + + expectedVMConfig := providedConfigs.GeneralConfig.VirtualMachine + expectedVMConfig.Execution.WasmVMVersions = expectedVMWasmVersionsConfig + expectedVMConfig.Querying.WasmVMVersions = expectedVMWasmVersionsConfig + + applyArchCustomConfigs(providedConfigs) + + expectedConfig := &config.Configs{ + GeneralConfig: &config.Config{ + VirtualMachine: expectedVMConfig, + }, + } + + assert.Equal(t, expectedConfig, providedConfigs) + }) +} diff --git a/node/customConfigsDefault.go b/node/customConfigsDefault.go new file mode 100644 index 00000000000..c592c98f6b8 --- /dev/null +++ b/node/customConfigsDefault.go @@ -0,0 +1,13 @@ +//go:build !(darwin && arm64) + +package node + +import ( + "runtime" + + "github.com/multiversx/mx-chain-go/config" +) + +func applyArchCustomConfigs(_ *config.Configs) { + log.Debug("applyArchCustomConfigs - nothing to do", "architecture", runtime.GOARCH) +} diff --git a/node/customConfigsDefault_test.go b/node/customConfigsDefault_test.go new file mode 100644 index 00000000000..94b4620e1cc --- /dev/null +++ b/node/customConfigsDefault_test.go @@ -0,0 +1,74 @@ +//go:build !(darwin && arm64) + +package node + +import ( + "testing" + + "github.com/multiversx/mx-chain-go/config" + "github.com/stretchr/testify/assert" +) + +func TestApplyArchCustomConfigs(t *testing.T) { + t.Parallel() + + executionVMConfig := config.VirtualMachineConfig{ + WasmVMVersions: []config.WasmVMVersionByEpoch{ + { + StartEpoch: 0, + Version: "v1.2", + }, + { + StartEpoch: 1, + Version: "v1.3", + }, + { + StartEpoch: 2, + Version: "v1.4", + }, + { + StartEpoch: 3, + Version: "v1.5", + }, + }, + TimeOutForSCExecutionInMilliseconds: 1, + WasmerSIGSEGVPassthrough: true, + } + + queryVMConfig := config.QueryVirtualMachineConfig{ + VirtualMachineConfig: executionVMConfig, + NumConcurrentVMs: 15, + } + + t.Run("providing a configuration should not alter it", func(t *testing.T) { + t.Parallel() + + providedConfigs := &config.Configs{ + GeneralConfig: &config.Config{ + VirtualMachine: config.VirtualMachineServicesConfig{ + Execution: executionVMConfig, + Querying: queryVMConfig, + }, + }, + } + + applyArchCustomConfigs(providedConfigs) + + assert.Equal(t, executionVMConfig, providedConfigs.GeneralConfig.VirtualMachine.Execution) + assert.Equal(t, queryVMConfig, providedConfigs.GeneralConfig.VirtualMachine.Querying) + }) + t.Run("empty config should return an empty config", func(t *testing.T) { + t.Parallel() + + // this test will prevent adding new config changes without handling them in this test + providedConfigs := &config.Configs{ + GeneralConfig: &config.Config{}, + } + emptyConfigs := &config.Configs{ + GeneralConfig: &config.Config{}, + } + applyArchCustomConfigs(providedConfigs) + + assert.Equal(t, emptyConfigs, providedConfigs) + }) +} diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 99021fcc0b8..991ddf60eea 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -269,6 +269,10 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( chanStopNodeProcess chan endProcess.ArgEndProcess, ) (bool, error) { goRoutinesNumberStart := runtime.NumGoroutine() + + log.Debug("applying custom configs based on the current architecture") + applyArchCustomConfigs(nr.configs) + configs := nr.configs flagsConfig := configs.FlagsConfig configurationPaths := configs.ConfigurationPathsHolder From 4b95ffd4bad75df560ae210a95bf18c2b185a680 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 7 Mar 2024 15:06:00 +0200 Subject: [PATCH 921/958] - cleanup --- process/factory/shard/vmConfigPatching.go | 8 -------- process/factory/shard/vmConfigPatching_darwin_arm64.go.go | 8 -------- process/factory/shard/vmContainerFactory.go | 4 +--- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 process/factory/shard/vmConfigPatching.go delete mode 100644 process/factory/shard/vmConfigPatching_darwin_arm64.go.go diff --git a/process/factory/shard/vmConfigPatching.go b/process/factory/shard/vmConfigPatching.go deleted file mode 100644 index 2d0284a6e7e..00000000000 --- a/process/factory/shard/vmConfigPatching.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !(darwin && arm64) - -package shard - -import "github.com/multiversx/mx-chain-go/config" - -func patchVirtualMachineConfigGivenArchitecture(config *config.VirtualMachineConfig) { -} diff --git a/process/factory/shard/vmConfigPatching_darwin_arm64.go.go b/process/factory/shard/vmConfigPatching_darwin_arm64.go.go deleted file mode 100644 index 5186300b202..00000000000 --- a/process/factory/shard/vmConfigPatching_darwin_arm64.go.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build darwin && arm64 - -package shard - -import "github.com/multiversx/mx-chain-go/config" - -func patchVirtualMachineConfigGivenArchitecture(config *config.VirtualMachineConfig) { -} diff --git a/process/factory/shard/vmContainerFactory.go b/process/factory/shard/vmContainerFactory.go index 048ea8a9990..35c17f763a1 100644 --- a/process/factory/shard/vmContainerFactory.go +++ b/process/factory/shard/vmContainerFactory.go @@ -87,8 +87,6 @@ func NewVMContainerFactory(args ArgVMContainerFactory) (*vmContainerFactory, err return nil, process.ErrNilHasher } - patchVirtualMachineConfigGivenArchitecture(&args.Config) - cryptoHook := hooks.NewVMCryptoHook() vmf := &vmContainerFactory{ @@ -282,7 +280,7 @@ func (vmf *vmContainerFactory) getMatchingVersion(epoch uint32) config.WasmVMVer } func (vmf *vmContainerFactory) createInProcessWasmVMByVersion(version config.WasmVMVersionByEpoch) (vmcommon.VMExecutionHandler, error) { - logVMContainerFactory.Debug("createInProcessWasmVMByVersion !(darwin && arm64)", "version", version) + logVMContainerFactory.Debug("createInProcessWasmVMByVersion", "version", version) switch version.Version { case "v1.2": return vmf.createInProcessWasmVMV12() From 510bf5530dd18c5163bdfa29cae1385aa4a0895f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:04:30 +0200 Subject: [PATCH 922/958] Fix go.mod. --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 4159e58b3ca..525854862bc 100644 --- a/go.mod +++ b/go.mod @@ -22,10 +22,10 @@ require ( github.com/multiversx/mx-chain-scenario-go v1.4.3-0.20240212160120-cc32d1580157 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2 - github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216171908-e2a4c8ed9823 - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 + github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240307121727-b8d371971d9a + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87 + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index 9846df6f1ca..6aa1400b435 100644 --- a/go.sum +++ b/go.sum @@ -401,14 +401,14 @@ github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8/go.mod h1:zl1A6teNe39T8yhdZlkX3ckm5aLYrMIJJZ6Ord1E71M= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2 h1:sBH1Zf5jdMqS+1LDfXBmsIdmol8CFloPzjDCtmBZGEc= github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216171908-e2a4c8ed9823 h1:UMu8cs5nBli6oOZo7AEiWteJriSLV5//mc1tGoapMgY= -github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240216171908-e2a4c8ed9823/go.mod h1:Xs0xFsPv+c1p8pwurLV7VBS7bEpIN/0jZrCwXVU26zw= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb h1:UtiY8X73llF9OLtGb2CM7Xewae1chvPjLc8B+ZmDLjw= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240129145751-f814f5525edb/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618 h1:1uMlT5TjiHUlx81fEH/WQANWlY0PjF3opMlW+E3L3GI= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240129150004-536a22d9c618/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662 h1:0y1k2+FjFfWgoPCMi0nkYkCYQJtPYJvph6bre4Elqxk= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240216071525-f7d1b8ce8662/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240307121727-b8d371971d9a h1:QvIC6R5sf0koeSwAs+Ye8J+CjNkAdaosTMSNTVBB8sA= +github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240307121727-b8d371971d9a/go.mod h1:Xs0xFsPv+c1p8pwurLV7VBS7bEpIN/0jZrCwXVU26zw= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50 h1:pFNv0WBbQfvAY9Uvy9xnYjf3BE93C4QLHy0G75kla3Q= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87 h1:RpC4Gt2ttGBqHZNpF3sqBqOWfmhYceu+KAZSCQtueVI= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172 h1:ql66TYHXfyPjTYOUn7dohp98ZJYQDGEYSJ3aVXygmLk= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From 517d190015a941d8512adea4ed697109886bf789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:04:53 +0200 Subject: [PATCH 923/958] Adjust "build" workflow. --- .github/workflows/{build_and_test.yml => build.yml} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename .github/workflows/{build_and_test.yml => build.yml} (85%) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build.yml similarity index 85% rename from .github/workflows/build_and_test.yml rename to .github/workflows/build.yml index 10feacf5ef4..ce3ca7cb555 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build.yml @@ -2,16 +2,15 @@ name: Build on: pull_request: - branches: [ master, rc/* ] + branches: [master, rc/*] types: [opened, ready_for_review] - push: workflow_dispatch: jobs: build: strategy: matrix: - runs-on: [ubuntu-latest] + runs-on: [ubuntu-latest, macos-latest, macos-13-xlarge] runs-on: ${{ matrix.runs-on }} name: Build steps: @@ -34,6 +33,7 @@ jobs: - name: Build run: | cd ${GITHUB_WORKSPACE}/cmd/node && go build . + cd ${GITHUB_WORKSPACE}/cmd/seednode && go build . cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build . cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . cd ${GITHUB_WORKSPACE}/cmd/termui && go build . From d72cde88f2c07c203b8771ac5493b831a22171a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:05:16 +0200 Subject: [PATCH 924/958] Rename files, adjust build conditions. --- node/{customConfigsDarwinArm64.go => customConfigsArm64.go} | 2 +- ...tomConfigsDarwinArm64_test.go => customConfigsArm64_test.go} | 2 +- node/customConfigsDefault.go | 2 +- node/customConfigsDefault_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename node/{customConfigsDarwinArm64.go => customConfigsArm64.go} (96%) rename node/{customConfigsDarwinArm64_test.go => customConfigsArm64_test.go} (98%) diff --git a/node/customConfigsDarwinArm64.go b/node/customConfigsArm64.go similarity index 96% rename from node/customConfigsDarwinArm64.go rename to node/customConfigsArm64.go index da7e3d05884..90f4dd57c07 100644 --- a/node/customConfigsDarwinArm64.go +++ b/node/customConfigsArm64.go @@ -1,4 +1,4 @@ -//go:build darwin && arm64 +//go:build arm64 package node diff --git a/node/customConfigsDarwinArm64_test.go b/node/customConfigsArm64_test.go similarity index 98% rename from node/customConfigsDarwinArm64_test.go rename to node/customConfigsArm64_test.go index ac8e53463c1..3f7d5a1b278 100644 --- a/node/customConfigsDarwinArm64_test.go +++ b/node/customConfigsArm64_test.go @@ -1,4 +1,4 @@ -//go:build darwin && arm64 +//go:build arm64 package node diff --git a/node/customConfigsDefault.go b/node/customConfigsDefault.go index c592c98f6b8..2d1d5edea28 100644 --- a/node/customConfigsDefault.go +++ b/node/customConfigsDefault.go @@ -1,4 +1,4 @@ -//go:build !(darwin && arm64) +//go:build !arm64 package node diff --git a/node/customConfigsDefault_test.go b/node/customConfigsDefault_test.go index 94b4620e1cc..92287e6979a 100644 --- a/node/customConfigsDefault_test.go +++ b/node/customConfigsDefault_test.go @@ -1,4 +1,4 @@ -//go:build !(darwin && arm64) +//go:build !arm64 package node From 3944eb1c54f8c4feba2fc9e381ce1db1d2131895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:08:26 +0200 Subject: [PATCH 925/958] Adjust trigger. --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce3ca7cb555..aea21d215e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,6 @@ name: Build on: pull_request: branches: [master, rc/*] - types: [opened, ready_for_review] workflow_dispatch: jobs: From 5742a680bcfdd4b53673c6fca30fa24713e5bf97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:14:26 +0200 Subject: [PATCH 926/958] Add smoke test. --- .github/workflows/build.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aea21d215e2..81a05106a60 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,3 +36,11 @@ jobs: cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build . cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . cd ${GITHUB_WORKSPACE}/cmd/termui && go build . + + - name: Smoke test + run: | + cd ${GITHUB_WORKSPACE}/cmd/node && ./node --help + cd ${GITHUB_WORKSPACE}/cmd/seednode && ./seednode --smoke-test-failing + cd ${GITHUB_WORKSPACE}/cmd/keygenerator && ./keygenerator --help + cd ${GITHUB_WORKSPACE}/cmd/logviewer && ./logviewer --help + cd ${GITHUB_WORKSPACE}/cmd/termui && ./termui --help From 82a5153a71720df7bcf86e5dda5c40e4c70ede0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:16:57 +0200 Subject: [PATCH 927/958] Fix smoke tests. --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81a05106a60..578e85568cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,8 +39,8 @@ jobs: - name: Smoke test run: | - cd ${GITHUB_WORKSPACE}/cmd/node && ./node --help - cd ${GITHUB_WORKSPACE}/cmd/seednode && ./seednode --smoke-test-failing - cd ${GITHUB_WORKSPACE}/cmd/keygenerator && ./keygenerator --help - cd ${GITHUB_WORKSPACE}/cmd/logviewer && ./logviewer --help - cd ${GITHUB_WORKSPACE}/cmd/termui && ./termui --help + ${GITHUB_WORKSPACE}/cmd/node --help + ${GITHUB_WORKSPACE}/cmd/seednode --help + ${GITHUB_WORKSPACE}/cmd/keygenerator --help + ${GITHUB_WORKSPACE}/cmd/logviewer --help + ${GITHUB_WORKSPACE}/cmd/termui --help From 5b2b4ca03e28618fbb4521130c5ac80bbc16e801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:22:32 +0200 Subject: [PATCH 928/958] For MacOS, run short tests. --- .github/workflows/{build.yml => build_and_test.yml} | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) rename .github/workflows/{build.yml => build_and_test.yml} (82%) diff --git a/.github/workflows/build.yml b/.github/workflows/build_and_test.yml similarity index 82% rename from .github/workflows/build.yml rename to .github/workflows/build_and_test.yml index 578e85568cb..60e960211f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build_and_test.yml @@ -37,10 +37,17 @@ jobs: cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . cd ${GITHUB_WORKSPACE}/cmd/termui && go build . - - name: Smoke test + - name: Smoke test the binaries run: | ${GITHUB_WORKSPACE}/cmd/node --help ${GITHUB_WORKSPACE}/cmd/seednode --help ${GITHUB_WORKSPACE}/cmd/keygenerator --help ${GITHUB_WORKSPACE}/cmd/logviewer --help ${GITHUB_WORKSPACE}/cmd/termui --help + + # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. + - name: Run tests + run: | + if [[ "$GOOS" == darwin ]]; then + go test -short -v ./... + fi From 343340f718e2e0bd0e20f35f4ae9274b508c076d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:42:57 +0200 Subject: [PATCH 929/958] Adjust "create release" flow to include wasmer2, as well. --- .github/workflows/build_and_test.yml | 12 ++++---- .github/workflows/create_release.yml | 42 +++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 60e960211f5..3654925446f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -1,4 +1,4 @@ -name: Build +name: Build and smoke test on: pull_request: @@ -39,11 +39,11 @@ jobs: - name: Smoke test the binaries run: | - ${GITHUB_WORKSPACE}/cmd/node --help - ${GITHUB_WORKSPACE}/cmd/seednode --help - ${GITHUB_WORKSPACE}/cmd/keygenerator --help - ${GITHUB_WORKSPACE}/cmd/logviewer --help - ${GITHUB_WORKSPACE}/cmd/termui --help + ${GITHUB_WORKSPACE}/cmd/node/node --help + ${GITHUB_WORKSPACE}/cmd/seednode/seednode --help + ${GITHUB_WORKSPACE}/cmd/keygenerator/keygenerator --help + ${GITHUB_WORKSPACE}/cmd/logviewer/logviewer --help + ${GITHUB_WORKSPACE}/cmd/termui/termui --help # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 9916e67d744..c9ecbd75983 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -15,7 +15,7 @@ jobs: build: strategy: matrix: - runs-on: [ubuntu-latest] # TODO add macos-latest when builds are possible on macs + runs-on: [ubuntu-latest, macos-latest, macos-13-xlarge] runs-on: ${{ matrix.runs-on }} name: Build steps: @@ -47,14 +47,15 @@ jobs: GOPATH=$(go env GOPATH) ARCHIVE="multiversx_""$APP_VER_SHORT""_""$GOOS""_""$GOARCH"".tgz" BUILD_DIR=${GITHUB_WORKSPACE}/build - WASM_VERSION=$(cat go.mod | grep mx-chain-vm-v | sort -n | tail -n -1| awk -F '/' '{print$3}'| sed 's/ /@/g') - WASMER_DIR=${GOPATH}/pkg/mod/github.com/multiversx/${WASM_VERSION}/wasmer + VM_GO_VERSION=$(cat go.mod | grep mx-chain-vm-go | sort -n | tail -n -1| awk -F '/' '{print$3}'| sed 's/ /@/g') + VM_GO_DIR=${GOPATH}/pkg/mod/github.com/multiversx/${VM_GO_VERSION} echo "GOOS=${GOOS}" >> $GITHUB_ENV echo "GOARCH=${GOARCH}" >> $GITHUB_ENV echo "ARCHIVE=${ARCHIVE}" >> $GITHUB_ENV echo "BUILD_DIR=${BUILD_DIR}" >> $GITHUB_ENV - echo "WASMER_DIR=${WASMER_DIR}" >> $GITHUB_ENV + echo "VM_GO_VERSION=${VM_GO_VERSION}" >> $GITHUB_ENV + echo "VM_GO_DIR=${VM_GO_DIR}" >> $GITHUB_ENV - name: Build run: | @@ -69,13 +70,40 @@ jobs: cd ${GITHUB_WORKSPACE} if [[ "$GOOS" == linux && "$GOARCH" == amd64 ]]; then - cp -f ${WASMER_DIR}/libwasmer_linux_amd64.so ${BUILD_DIR}; + cp --verbose --no-preserve=mode,ownership ${VM_GO_DIR}/wasmer2/libvmexeccapi.so ${BUILD_DIR}/libvmexeccapi.so + cp --verbose --no-preserve=mode,ownership ${VM_GO_DIR}/wasmer/libwasmer_linux_amd64.so ${BUILD_DIR}/libwasmer_linux_amd64.so fi + + # Actually, there's no runner for this combination (as of March 2024). if [[ "$GOOS" == linux && "$GOARCH" == arm64 ]]; then - cp -f ${WASMER_DIR}/libwasmer_linux_arm64.so ${BUILD_DIR}; + cp --verbose --no-preserve=mode,ownership ${VM_GO_DIR}/wasmer2/libvmexeccapi_arm.so ${BUILD_DIR}/libvmexeccapi_arm.so + cp --verbose --no-preserve=mode,ownership ${VM_GO_DIR}/wasmer/libwasmer_linux_arm64_shim.so ${BUILD_DIR}/libwasmer_linux_arm64_shim.so fi + if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then - cp -f ${WASMER_DIR}/libwasmer_darwin_amd64.dylib ${BUILD_DIR}; + cp -v ${VM_GO_DIR}/wasmer2/libvmexeccapi.dylib ${BUILD_DIR}/libvmexeccapi.dylib + cp -v ${VM_GO_DIR}/wasmer/libwasmer_darwin_amd64.dylib ${BUILD_DIR}/libwasmer_darwin_amd64.dylib + fi + + if [[ "$GOOS" == darwin && "$GOARCH" == arm64 ]]; then + cp -v ${VM_GO_DIR}/wasmer2/libvmexeccapi_arm.dylib ${BUILD_DIR}/libvmexeccapi_arm.dylib + cp -v ${VM_GO_DIR}/wasmer/libwasmer_darwin_arm64_shim.dylib ${BUILD_DIR}/libwasmer_darwin_arm64_shim.dylib + fi + + if [[ "$GOOS" == linux ]]; then + patchelf --set-rpath "\$ORIGIN" ${BUILD_DIR}/node + patchelf --set-rpath "\$ORIGIN" ${BUILD_DIR}/seednode + + ldd ${BUILD_DIR}/node + ldd ${BUILD_DIR}/seednode + fi + + if [[ "$GOOS" == darwin ]]; then + install_name_tool -add_rpath "@loader_path" ${BUILD_DIR}/node + install_name_tool -add_rpath "@loader_path" ${BUILD_DIR}/seednode + + otool -L ${BUILD_DIR}/node + otool -L ${BUILD_DIR}/seednode fi cd ${BUILD_DIR} From c17aab3066fdbba22e6bc72db692cc8d2052ee35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 18:47:42 +0200 Subject: [PATCH 930/958] Adjust CI (trial and error). --- .github/workflows/create_release.yml | 55 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index c9ecbd75983..4a72868d29f 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -61,6 +61,7 @@ jobs: run: | mkdir -p ${BUILD_DIR} cd ${GITHUB_WORKSPACE}/cmd/node && go build -o "${BUILD_DIR}/node" -a -ldflags="-X main.appVersion=${APP_VER}" + cd ${GITHUB_WORKSPACE}/cmd/seednode && go build -o "${BUILD_DIR}/seednode" -a -ldflags="-X main.appVersion=${APP_VER}" cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build -o "${BUILD_DIR}/keygenerator" -a -ldflags="-X main.appVersion=${APP_VER}" cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build -o "${BUILD_DIR}/logviewer" -a -ldflags="-X main.appVersion=${APP_VER}" cd ${GITHUB_WORKSPACE}/cmd/termui && go build -o "${BUILD_DIR}/termui" -a -ldflags="-X main.appVersion=${APP_VER}" @@ -117,30 +118,30 @@ jobs: path: ${{ github.workspace }}/${{ env.ARCHIVE }} if-no-files-found: error - release: - needs: [build] - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v2 - - # https://docs.github.com/en/free-pro-team@latest/actions/guides/storing-workflow-data-as-artifacts#downloading-or-deleting-artifacts - # A directory for each artifact is created using its name - - name: Download all workflow run artifacts - uses: actions/download-artifact@v2 - with: - path: assets - - - name: Display structure of downloaded files - run: ls -R - working-directory: assets - - - name: Create release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release create --draft --notes="Release draft from Github Actions" vNext - sleep 10 - for i in $(find ./assets -name '*.tgz' -type f); do - gh release upload vNext ${i} - done + # release: + # needs: [build] + # runs-on: ubuntu-latest + # steps: + # - name: Check out code + # uses: actions/checkout@v2 + + # # https://docs.github.com/en/free-pro-team@latest/actions/guides/storing-workflow-data-as-artifacts#downloading-or-deleting-artifacts + # # A directory for each artifact is created using its name + # - name: Download all workflow run artifacts + # uses: actions/download-artifact@v2 + # with: + # path: assets + + # - name: Display structure of downloaded files + # run: ls -R + # working-directory: assets + + # - name: Create release + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # run: | + # gh release create --draft --notes="Release draft from Github Actions" vNext + # sleep 10 + # for i in $(find ./assets -name '*.tgz' -type f); do + # gh release upload vNext ${i} + # done From 50a3c0d4f7ec78e13efb7e93076bcf2e93126597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 19:14:59 +0200 Subject: [PATCH 931/958] Smoke tests. --- .github/workflows/build_and_test.yml | 10 +++++----- .github/workflows/create_release.yml | 28 +++++++++++++++++++++------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 3654925446f..1c97f1997d3 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -39,11 +39,11 @@ jobs: - name: Smoke test the binaries run: | - ${GITHUB_WORKSPACE}/cmd/node/node --help - ${GITHUB_WORKSPACE}/cmd/seednode/seednode --help - ${GITHUB_WORKSPACE}/cmd/keygenerator/keygenerator --help - ${GITHUB_WORKSPACE}/cmd/logviewer/logviewer --help - ${GITHUB_WORKSPACE}/cmd/termui/termui --help + ${GITHUB_WORKSPACE}/cmd/node/node --version + ${GITHUB_WORKSPACE}/cmd/seednode/seednode --version + ${GITHUB_WORKSPACE}/cmd/keygenerator/keygenerator --version + ${GITHUB_WORKSPACE}/cmd/logviewer/logviewer --version + ${GITHUB_WORKSPACE}/cmd/termui/termui --version # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 4a72868d29f..82a05e5927a 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -1,6 +1,7 @@ name: Create release on: + pull_request: push: branches: - master @@ -45,7 +46,7 @@ jobs: GOOS=$(go env GOOS) GOARCH=$(go env GOARCH) GOPATH=$(go env GOPATH) - ARCHIVE="multiversx_""$APP_VER_SHORT""_""$GOOS""_""$GOARCH"".tgz" + ARCHIVE="multiversx_""$APP_VER_SHORT""_""$GOOS""_""$GOARCH"".zip" BUILD_DIR=${GITHUB_WORKSPACE}/build VM_GO_VERSION=$(cat go.mod | grep mx-chain-vm-go | sort -n | tail -n -1| awk -F '/' '{print$3}'| sed 's/ /@/g') VM_GO_DIR=${GOPATH}/pkg/mod/github.com/multiversx/${VM_GO_VERSION} @@ -107,15 +108,28 @@ jobs: otool -L ${BUILD_DIR}/seednode fi - cd ${BUILD_DIR} - tar czvf "${GITHUB_WORKSPACE}/${ARCHIVE}" * - stat ${GITHUB_WORKSPACE}/${ARCHIVE} + - name: Smoke test + run: | + # Remove all downloaded Go packages, so that we can test the binary's independence from them (think of Wasmer libraries). + sudo rm -rf ${GOPATH}/pkg/mod + + # Test the binary in different current directories. + cd ${BUILD_DIR} && ./node --version + cd ${GITHUB_WORKSPACE} && ${BUILD_DIR}/node --version + cd / && ${BUILD_DIR}/node --version + + - name: Package build output + run: | + sudo chown -R $USER: ${BUILD_DIR} + chmod -R 755 ${BUILD_DIR} + ls -al ${BUILD_DIR} + zip -r -j ${ARCHIVE} ${BUILD_DIR} - name: Save artifacts uses: actions/upload-artifact@v3 with: - name: ${{ env.ARCHIVE }} - path: ${{ github.workspace }}/${{ env.ARCHIVE }} + name: build-output + path: ${{ env.ARCHIVE }} if-no-files-found: error # release: @@ -142,6 +156,6 @@ jobs: # run: | # gh release create --draft --notes="Release draft from Github Actions" vNext # sleep 10 - # for i in $(find ./assets -name '*.tgz' -type f); do + # for i in $(find ./assets -name '*.zip' -type f); do # gh release upload vNext ${i} # done From 0a7c96cd6dd15f55bf98d64fa162a36830f2a5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 19:31:51 +0200 Subject: [PATCH 932/958] Test assets upload. --- .github/workflows/create_release.yml | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 82a05e5927a..a0b74a03fe8 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -128,34 +128,34 @@ jobs: - name: Save artifacts uses: actions/upload-artifact@v3 with: - name: build-output + name: ${{ env.ARCHIVE }} path: ${{ env.ARCHIVE }} if-no-files-found: error - # release: - # needs: [build] - # runs-on: ubuntu-latest - # steps: - # - name: Check out code - # uses: actions/checkout@v2 - - # # https://docs.github.com/en/free-pro-team@latest/actions/guides/storing-workflow-data-as-artifacts#downloading-or-deleting-artifacts - # # A directory for each artifact is created using its name - # - name: Download all workflow run artifacts - # uses: actions/download-artifact@v2 - # with: - # path: assets - - # - name: Display structure of downloaded files - # run: ls -R - # working-directory: assets - - # - name: Create release - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # run: | - # gh release create --draft --notes="Release draft from Github Actions" vNext - # sleep 10 - # for i in $(find ./assets -name '*.zip' -type f); do - # gh release upload vNext ${i} - # done + release: + needs: [build] + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v2 + + # https://docs.github.com/en/free-pro-team@latest/actions/guides/storing-workflow-data-as-artifacts#downloading-or-deleting-artifacts + # A directory for each artifact is created using its name + - name: Download all workflow run artifacts + uses: actions/download-artifact@v2 + with: + path: assets + + - name: Display structure of downloaded files + run: ls -R + working-directory: assets + + - name: Create release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create --draft --notes="Release draft from Github Actions" vNext + sleep 10 + for i in $(find ./assets -name '*.zip' -type f); do + gh release upload vNext ${i} + done From 51c5e60df3b1687ad53097668173c2ac472bb2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 19:32:27 +0200 Subject: [PATCH 933/958] Undo trigger. --- .github/workflows/create_release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index a0b74a03fe8..82889085368 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -1,7 +1,6 @@ name: Create release on: - pull_request: push: branches: - master From 69c732d3c7762912b892aae686bfdb71730e603b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 20:12:56 +0200 Subject: [PATCH 934/958] Adjust smoke test. --- .github/workflows/build_and_test.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 1c97f1997d3..d45696691ad 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -39,15 +39,17 @@ jobs: - name: Smoke test the binaries run: | - ${GITHUB_WORKSPACE}/cmd/node/node --version - ${GITHUB_WORKSPACE}/cmd/seednode/seednode --version - ${GITHUB_WORKSPACE}/cmd/keygenerator/keygenerator --version - ${GITHUB_WORKSPACE}/cmd/logviewer/logviewer --version - ${GITHUB_WORKSPACE}/cmd/termui/termui --version + cd ${GITHUB_WORKSPACE}/cmd/node && node --version + cd ${GITHUB_WORKSPACE}/cmd/seednode && seednode --version + cd ${GITHUB_WORKSPACE}/cmd/keygenerator && keygenerator --version + cd ${GITHUB_WORKSPACE}/cmd/logviewer && logviewer --version + cd ${GITHUB_WORKSPACE}/cmd/termui && termui --version # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests run: | + GOOS=$(go env GOOS) + if [[ "$GOOS" == darwin ]]; then go test -short -v ./... fi From 6278e9539df47e11f1a3c1815e5187a5078ac7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 20:14:22 +0200 Subject: [PATCH 935/958] Better smoke testing. --- .github/workflows/create_release.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 82889085368..ca13a9f0313 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -112,11 +112,15 @@ jobs: # Remove all downloaded Go packages, so that we can test the binary's independence from them (think of Wasmer libraries). sudo rm -rf ${GOPATH}/pkg/mod - # Test the binary in different current directories. + # Test binaries in different current directories. cd ${BUILD_DIR} && ./node --version cd ${GITHUB_WORKSPACE} && ${BUILD_DIR}/node --version cd / && ${BUILD_DIR}/node --version + cd ${BUILD_DIR} && ./seednode --version + cd ${GITHUB_WORKSPACE} && ${BUILD_DIR}/seednode --version + cd / && ${BUILD_DIR}/seednode --version + - name: Package build output run: | sudo chown -R $USER: ${BUILD_DIR} From 41bbb8098811070f3695e9826500a12ad7c55681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 20:18:31 +0200 Subject: [PATCH 936/958] Fix tests. --- .github/workflows/build_and_test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index d45696691ad..4b550f4b0cc 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -39,11 +39,11 @@ jobs: - name: Smoke test the binaries run: | - cd ${GITHUB_WORKSPACE}/cmd/node && node --version - cd ${GITHUB_WORKSPACE}/cmd/seednode && seednode --version - cd ${GITHUB_WORKSPACE}/cmd/keygenerator && keygenerator --version - cd ${GITHUB_WORKSPACE}/cmd/logviewer && logviewer --version - cd ${GITHUB_WORKSPACE}/cmd/termui && termui --version + cd ${GITHUB_WORKSPACE}/cmd/node && ./node --version + cd ${GITHUB_WORKSPACE}/cmd/seednode && ./seednode --version + cd ${GITHUB_WORKSPACE}/cmd/keygenerator && ./keygenerator --version + cd ${GITHUB_WORKSPACE}/cmd/logviewer && ./logviewer --version + cd ${GITHUB_WORKSPACE}/cmd/termui && ./termui --version # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests From 290fc9ca432a3c9cdcf9e51c437539d331083460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 20:25:57 +0200 Subject: [PATCH 937/958] Remove smoke tests which aren't very useful (and failing on MacOS AMD64, due to libwasmer not having the proper name set - with "install_name_tool"). --- .github/workflows/build_and_test.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4b550f4b0cc..7a3fc1055f2 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -37,14 +37,6 @@ jobs: cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . cd ${GITHUB_WORKSPACE}/cmd/termui && go build . - - name: Smoke test the binaries - run: | - cd ${GITHUB_WORKSPACE}/cmd/node && ./node --version - cd ${GITHUB_WORKSPACE}/cmd/seednode && ./seednode --version - cd ${GITHUB_WORKSPACE}/cmd/keygenerator && ./keygenerator --version - cd ${GITHUB_WORKSPACE}/cmd/logviewer && ./logviewer --version - cd ${GITHUB_WORKSPACE}/cmd/termui && ./termui --version - # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests run: | From 4a21358569bbb165f8e36946b7260c0a278655f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 21:03:57 +0200 Subject: [PATCH 938/958] Skip some tests on darwin, on ARM64. --- common/statistics/osLevel/memStats_test.go | 5 +++++ integrationTests/vm/txsFee/asyncCall_test.go | 5 +++++ keysManagement/managedPeersHolder_test.go | 7 ++++++- .../components/testOnlyProcessingNode_test.go | 5 +++++ process/factory/shard/vmContainerFactory_test.go | 9 +++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/common/statistics/osLevel/memStats_test.go b/common/statistics/osLevel/memStats_test.go index 99724172e67..ff42ad516c2 100644 --- a/common/statistics/osLevel/memStats_test.go +++ b/common/statistics/osLevel/memStats_test.go @@ -3,12 +3,17 @@ package osLevel import ( + "runtime" "testing" "github.com/stretchr/testify/assert" ) func TestReadCurrentMemStats(t *testing.T) { + if runtime.GOOS == "darwin" { + t.Skip("skipping test on darwin") + } + t.Parallel() memStats, err := ReadCurrentMemStats() diff --git a/integrationTests/vm/txsFee/asyncCall_test.go b/integrationTests/vm/txsFee/asyncCall_test.go index 9608ad10d52..e75707d4a2b 100644 --- a/integrationTests/vm/txsFee/asyncCall_test.go +++ b/integrationTests/vm/txsFee/asyncCall_test.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "fmt" "math/big" + "runtime" "strings" "testing" @@ -141,6 +142,10 @@ func TestMinterContractWithAsyncCalls(t *testing.T) { } func TestAsyncCallsOnInitFunctionOnUpgrade(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + firstContractCode := wasm.GetSCCode("./testdata/first/output/first.wasm") newContractCode := wasm.GetSCCode("./testdata/asyncOnInit/asyncOnInitAndUpgrade.wasm") diff --git a/keysManagement/managedPeersHolder_test.go b/keysManagement/managedPeersHolder_test.go index fa7d84209a2..9a8c66fb849 100644 --- a/keysManagement/managedPeersHolder_test.go +++ b/keysManagement/managedPeersHolder_test.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "errors" "fmt" + "runtime" "strings" "sync" "testing" @@ -13,7 +14,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" - "github.com/multiversx/mx-chain-crypto-go" + crypto "github.com/multiversx/mx-chain-crypto-go" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/keysManagement" @@ -905,6 +906,10 @@ func TestManagedPeersHolder_IsKeyValidator(t *testing.T) { } func TestManagedPeersHolder_GetNextPeerAuthenticationTime(t *testing.T) { + if runtime.GOOS == "darwin" { + t.Skip("skipping on darwin") + } + t.Parallel() holder, _ := keysManagement.NewManagedPeersHolder(createMockArgsManagedPeersHolder()) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 90562977f7a..02371739415 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -3,6 +3,7 @@ package components import ( "errors" "math/big" + "runtime" "strings" "testing" "time" @@ -49,6 +50,10 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo } func TestNewTestOnlyProcessingNode(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + t.Run("should work", func(t *testing.T) { args := createMockArgsTestOnlyProcessingNode(t) node, err := NewTestOnlyProcessingNode(args) diff --git a/process/factory/shard/vmContainerFactory_test.go b/process/factory/shard/vmContainerFactory_test.go index df3ffab673e..ac0a2dd6608 100644 --- a/process/factory/shard/vmContainerFactory_test.go +++ b/process/factory/shard/vmContainerFactory_test.go @@ -1,6 +1,7 @@ package shard import ( + "runtime" "sync" "testing" @@ -150,6 +151,10 @@ func TestNewVMContainerFactory_OkValues(t *testing.T) { } func TestVmContainerFactory_Create(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + t.Parallel() args := createMockVMAccountsArguments() @@ -175,6 +180,10 @@ func TestVmContainerFactory_Create(t *testing.T) { } func TestVmContainerFactory_ResolveWasmVMVersion(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + epochNotifierInstance := forking.NewGenericEpochNotifier() numCalled := 0 From 5afa0a37b2e86426196421dd503e0ca15034b7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 21:16:45 +0200 Subject: [PATCH 939/958] Skip some tests. --- integrationTests/vm/txsFee/asyncCall_test.go | 4 ++++ .../components/testOnlyProcessingNode_test.go | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/integrationTests/vm/txsFee/asyncCall_test.go b/integrationTests/vm/txsFee/asyncCall_test.go index e75707d4a2b..78030ff6b39 100644 --- a/integrationTests/vm/txsFee/asyncCall_test.go +++ b/integrationTests/vm/txsFee/asyncCall_test.go @@ -281,6 +281,10 @@ func testAsyncCallsOnInitFunctionOnUpgrade( } func TestAsyncCallsOnInitFunctionOnDeploy(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + firstSCCode := wasm.GetSCCode("./testdata/first/output/first.wasm") pathToSecondSC := "./testdata/asyncOnInit/asyncOnInitAndUpgrade.wasm" secondSCCode := wasm.GetSCCode(pathToSecondSC) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index 02371739415..c48a8456086 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -419,6 +419,10 @@ func TestTestOnlyProcessingNode_SetStateForAddress(t *testing.T) { } func TestTestOnlyProcessingNode_IsInterfaceNil(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + var node *testOnlyProcessingNode require.True(t, node.IsInterfaceNil()) @@ -427,6 +431,10 @@ func TestTestOnlyProcessingNode_IsInterfaceNil(t *testing.T) { } func TestTestOnlyProcessingNode_Close(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + node, err := NewTestOnlyProcessingNode(createMockArgsTestOnlyProcessingNode(t)) require.NoError(t, err) @@ -434,6 +442,10 @@ func TestTestOnlyProcessingNode_Close(t *testing.T) { } func TestTestOnlyProcessingNode_Getters(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + node := &testOnlyProcessingNode{} require.Nil(t, node.GetProcessComponents()) require.Nil(t, node.GetChainHandler()) From 7a287d86bd38e336144ab8efef03c5fd1cfef948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 22:08:33 +0200 Subject: [PATCH 940/958] Skip test. --- integrationTests/vm/txsFee/dns_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/integrationTests/vm/txsFee/dns_test.go b/integrationTests/vm/txsFee/dns_test.go index 515400c3d30..6a2b9315162 100644 --- a/integrationTests/vm/txsFee/dns_test.go +++ b/integrationTests/vm/txsFee/dns_test.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "fmt" "math/big" + "runtime" "testing" "unicode/utf8" @@ -116,6 +117,10 @@ func TestDeployDNSContract_TestRegisterAndResolveAndSendTxWithSndAndRcvUserName( // relayer address is in shard 2, creates a transaction on the behalf of the user from shard 2, that will call the DNS contract // from shard 1. func TestDeployDNSContract_TestGasWhenSaveUsernameFailsCrossShardBackwardsCompatibility(t *testing.T) { + if runtime.GOARCH == "arm64" { + t.Skip("skipping test on arm64") + } + enableEpochs := config.EnableEpochs{ ChangeUsernameEnableEpoch: 1000, // flag disabled, backwards compatibility SCProcessorV2EnableEpoch: 1000, From f3d8afef82a6621b2506be7293cbe83d3ee3d0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 22:33:46 +0200 Subject: [PATCH 941/958] Drop -v on short tests. --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 7a3fc1055f2..28735a010c9 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -43,5 +43,5 @@ jobs: GOOS=$(go env GOOS) if [[ "$GOOS" == darwin ]]; then - go test -short -v ./... + go test -short ./... fi From 1459637f7e44f29ca3101b5664a57d4c35b988e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 23:13:22 +0200 Subject: [PATCH 942/958] Fix tests for MacOS AMD64. --- .github/workflows/build_and_test.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 28735a010c9..fda8421f74c 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -41,6 +41,23 @@ jobs: - name: Run tests run: | GOOS=$(go env GOOS) + GOARCH=$(go env GOARCH) + GOPATH=$(go env GOPATH) + + # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it: + if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then + python3 - << "EOF" + import os + import subprocess + import pathlib + + GOPATH = os.getenv("GOPATH", "") + + for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): + subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) + + EOF + fi if [[ "$GOOS" == darwin ]]; then go test -short ./... From bf0eb1cd49e122bb41ad7269ad87b71cad9a599c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 23:29:04 +0200 Subject: [PATCH 943/958] Fix workflow. --- .github/workflows/build_and_test.yml | 29 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index fda8421f74c..501ad846dcc 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -37,27 +37,26 @@ jobs: cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . cd ${GITHUB_WORKSPACE}/cmd/termui && go build . - # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - - name: Run tests + # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. + - name: Patch libwasmer_darwin_amd64.dylib run: | - GOOS=$(go env GOOS) - GOARCH=$(go env GOARCH) GOPATH=$(go env GOPATH) - # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it: - if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then - python3 - << "EOF" - import os - import subprocess - import pathlib + python3 - << "EOF" + import os + import subprocess + import pathlib - GOPATH = os.getenv("GOPATH", "") + GOPATH = os.getenv("GOPATH", "") - for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): - subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) + for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): + subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) + EOF - EOF - fi + # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. + - name: Run tests + run: | + GOOS=$(go env GOOS) if [[ "$GOOS" == darwin ]]; then go test -short ./... From be72e676e8a682ffc4f1a47afaa32f17f3aa1efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 23:39:59 +0200 Subject: [PATCH 944/958] Trial and error. --- .github/workflows/build_and_test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 501ad846dcc..5a49a2d4a22 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -9,7 +9,8 @@ jobs: build: strategy: matrix: - runs-on: [ubuntu-latest, macos-latest, macos-13-xlarge] + runs-on: [macos-latest] + # runs-on: [ubuntu-latest, macos-latest, macos-13-xlarge] runs-on: ${{ matrix.runs-on }} name: Build steps: @@ -50,7 +51,8 @@ jobs: GOPATH = os.getenv("GOPATH", "") for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): - subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) + print(f"Fixing {file}") + subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) EOF # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. From 42fd24b84e19aba262a9536a1475691ccdf2153c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 23:51:59 +0200 Subject: [PATCH 945/958] Trial and error. --- .github/workflows/build_and_test.yml | 43 +++++++------------ .../workflows/patch_libwasmer_darwin_amd64.py | 9 ++++ 2 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/patch_libwasmer_darwin_amd64.py diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 5a49a2d4a22..92402f489b5 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -27,39 +27,28 @@ jobs: run: | go get -v -t -d ./... if [ -f Gopkg.toml ]; then - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure fi - - name: Build - run: | - cd ${GITHUB_WORKSPACE}/cmd/node && go build . - cd ${GITHUB_WORKSPACE}/cmd/seednode && go build . - cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build . - cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . - cd ${GITHUB_WORKSPACE}/cmd/termui && go build . - - # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. - - name: Patch libwasmer_darwin_amd64.dylib - run: | - GOPATH=$(go env GOPATH) - - python3 - << "EOF" - import os - import subprocess - import pathlib - - GOPATH = os.getenv("GOPATH", "") - - for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): - print(f"Fixing {file}") - subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) - EOF + # - name: Build + # run: | + # cd ${GITHUB_WORKSPACE}/cmd/node && go build . + # cd ${GITHUB_WORKSPACE}/cmd/seednode && go build . + # cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build . + # cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . + # cd ${GITHUB_WORKSPACE}/cmd/termui && go build . # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests run: | GOOS=$(go env GOOS) + GOARCH=$(go env GOARCH) + + if [[ "$GOOS" == linux && "$GOARCH" == amd64 ]]; then + # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. + GOPATH=$(go env GOPATH) python3 ${GITHUB_WORKSPACE}/.github/workflows/patch_libwasmer_darwin_amd64.py + fi if [[ "$GOOS" == darwin ]]; then - go test -short ./... + go test -short ./... fi diff --git a/.github/workflows/patch_libwasmer_darwin_amd64.py b/.github/workflows/patch_libwasmer_darwin_amd64.py new file mode 100644 index 00000000000..fbe507f32b6 --- /dev/null +++ b/.github/workflows/patch_libwasmer_darwin_amd64.py @@ -0,0 +1,9 @@ +import os +import pathlib +import subprocess + +GOPATH = os.getenv("GOPATH", "") + +for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): + print(f"Running install_name_tool on: {file}") + subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) From 56d45ce9e9dec10621b78b439fc79cf126306ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 7 Mar 2024 23:54:03 +0200 Subject: [PATCH 946/958] Trial and error. --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 92402f489b5..76c42bbc9dd 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -44,7 +44,7 @@ jobs: GOOS=$(go env GOOS) GOARCH=$(go env GOARCH) - if [[ "$GOOS" == linux && "$GOARCH" == amd64 ]]; then + if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. GOPATH=$(go env GOPATH) python3 ${GITHUB_WORKSPACE}/.github/workflows/patch_libwasmer_darwin_amd64.py fi From eb1588372e1702f03e882a1e51e243d884ad7ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 8 Mar 2024 00:02:58 +0200 Subject: [PATCH 947/958] Re-enable runners. --- .github/workflows/build_and_test.yml | 18 +++++++++--------- .../workflows/patch_libwasmer_darwin_amd64.py | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 76c42bbc9dd..bef6fa1db5f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -9,8 +9,7 @@ jobs: build: strategy: matrix: - runs-on: [macos-latest] - # runs-on: [ubuntu-latest, macos-latest, macos-13-xlarge] + runs-on: [ubuntu-latest, macos-latest, macos-13-xlarge] runs-on: ${{ matrix.runs-on }} name: Build steps: @@ -30,13 +29,14 @@ jobs: curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh dep ensure fi - # - name: Build - # run: | - # cd ${GITHUB_WORKSPACE}/cmd/node && go build . - # cd ${GITHUB_WORKSPACE}/cmd/seednode && go build . - # cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build . - # cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . - # cd ${GITHUB_WORKSPACE}/cmd/termui && go build . + + - name: Build + run: | + cd ${GITHUB_WORKSPACE}/cmd/node && go build . + cd ${GITHUB_WORKSPACE}/cmd/seednode && go build . + cd ${GITHUB_WORKSPACE}/cmd/keygenerator && go build . + cd ${GITHUB_WORKSPACE}/cmd/logviewer && go build . + cd ${GITHUB_WORKSPACE}/cmd/termui && go build . # On GitHub, we only run the short tests, and we only run them for some OS/ARCH combinations. - name: Run tests diff --git a/.github/workflows/patch_libwasmer_darwin_amd64.py b/.github/workflows/patch_libwasmer_darwin_amd64.py index fbe507f32b6..1c9479521b4 100644 --- a/.github/workflows/patch_libwasmer_darwin_amd64.py +++ b/.github/workflows/patch_libwasmer_darwin_amd64.py @@ -4,6 +4,7 @@ GOPATH = os.getenv("GOPATH", "") +# "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): print(f"Running install_name_tool on: {file}") subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) From 6f3afe20d73ea5de4c752b465c013a2c3063b7b1 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 8 Mar 2024 10:34:50 +0200 Subject: [PATCH 948/958] - initialized 2 new metrics --- node/metrics/metrics.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/metrics/metrics.go b/node/metrics/metrics.go index c13c328ae12..ca2cd4e910a 100644 --- a/node/metrics/metrics.go +++ b/node/metrics/metrics.go @@ -53,6 +53,8 @@ func InitBaseMetrics(appStatusHandler core.AppStatusHandler) error { appStatusHandler.SetUInt64Value(common.MetricTrieSyncNumReceivedBytes, initUint) appStatusHandler.SetUInt64Value(common.MetricAccountsSnapshotInProgress, initUint) appStatusHandler.SetUInt64Value(common.MetricPeersSnapshotInProgress, initUint) + appStatusHandler.SetUInt64Value(common.MetricNonceAtEpochStart, initUint) + appStatusHandler.SetUInt64Value(common.MetricRoundAtEpochStart, initUint) appStatusHandler.SetInt64Value(common.MetricLastAccountsSnapshotDurationSec, initInt) appStatusHandler.SetInt64Value(common.MetricLastPeersSnapshotDurationSec, initInt) From 629ebc91b1d77c24344af3a6b260eb7a044ccecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 8 Mar 2024 10:54:29 +0200 Subject: [PATCH 949/958] Use patched "libwasmer_darwin_amd64.dylib". --- .github/workflows/build_and_test.yml | 6 ------ .github/workflows/patch_libwasmer_darwin_amd64.py | 10 ---------- go.mod | 6 +++--- go.sum | 12 ++++++------ 4 files changed, 9 insertions(+), 25 deletions(-) delete mode 100644 .github/workflows/patch_libwasmer_darwin_amd64.py diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index bef6fa1db5f..f238785e8fd 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -42,12 +42,6 @@ jobs: - name: Run tests run: | GOOS=$(go env GOOS) - GOARCH=$(go env GOARCH) - - if [[ "$GOOS" == darwin && "$GOARCH" == amd64 ]]; then - # "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. - GOPATH=$(go env GOPATH) python3 ${GITHUB_WORKSPACE}/.github/workflows/patch_libwasmer_darwin_amd64.py - fi if [[ "$GOOS" == darwin ]]; then go test -short ./... diff --git a/.github/workflows/patch_libwasmer_darwin_amd64.py b/.github/workflows/patch_libwasmer_darwin_amd64.py deleted file mode 100644 index 1c9479521b4..00000000000 --- a/.github/workflows/patch_libwasmer_darwin_amd64.py +++ /dev/null @@ -1,10 +0,0 @@ -import os -import pathlib -import subprocess - -GOPATH = os.getenv("GOPATH", "") - -# "libwasmer_darwin_amd64.dylib" was built with an unfortunate identifier (in the past), so we need to fix it. -for file in pathlib.Path(f"{GOPATH}/pkg/mod/github.com/multiversx").rglob("libwasmer_darwin_amd64.dylib"): - print(f"Running install_name_tool on: {file}") - subprocess.check_output(f"sudo install_name_tool -id @rpath/libwasmer_darwin_amd64.dylib {file}", shell=True) diff --git a/go.mod b/go.mod index 525854862bc..86225522dcc 100644 --- a/go.mod +++ b/go.mod @@ -23,9 +23,9 @@ require ( github.com/multiversx/mx-chain-storage-go v1.0.15-0.20240129144933-b1c0d642d7f8 github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2 github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240307121727-b8d371971d9a - github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50 - github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87 - github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172 + github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240308085208-3b5a4ab4dd34 + github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240308082903-132f9002736b + github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240308082831-f05004a05b35 github.com/pelletier/go-toml v1.9.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 diff --git a/go.sum b/go.sum index 6aa1400b435..f12ab723392 100644 --- a/go.sum +++ b/go.sum @@ -403,12 +403,12 @@ github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a github.com/multiversx/mx-chain-vm-common-go v1.5.12-0.20240305123516-2231c71162a2/go.mod h1:OUyhCFqZKqUk1uaPsenyPDwO1830SlHNDU7Q7b6CBVI= github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240307121727-b8d371971d9a h1:QvIC6R5sf0koeSwAs+Ye8J+CjNkAdaosTMSNTVBB8sA= github.com/multiversx/mx-chain-vm-go v1.5.28-0.20240307121727-b8d371971d9a/go.mod h1:Xs0xFsPv+c1p8pwurLV7VBS7bEpIN/0jZrCwXVU26zw= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50 h1:pFNv0WBbQfvAY9Uvy9xnYjf3BE93C4QLHy0G75kla3Q= -github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240306152931-0abbb8212f50/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87 h1:RpC4Gt2ttGBqHZNpF3sqBqOWfmhYceu+KAZSCQtueVI= -github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240306152914-eb6fe409fe87/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172 h1:ql66TYHXfyPjTYOUn7dohp98ZJYQDGEYSJ3aVXygmLk= -github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240306152831-fb879235f172/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240308085208-3b5a4ab4dd34 h1:aLJhYiDBtWW4yjizhvQgTU00KfkK3oL3GnEh7pVUPRs= +github.com/multiversx/mx-chain-vm-v1_2-go v1.2.66-0.20240308085208-3b5a4ab4dd34/go.mod h1:8uugq3HUeDiE6G4AS3F8/B3zA1Pabzbl7SSD6Cebwz8= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240308082903-132f9002736b h1:iDDarqnGFZBXxqpaPWp8ePOqhG5G3DeAoopGgRLteu0= +github.com/multiversx/mx-chain-vm-v1_3-go v1.3.67-0.20240308082903-132f9002736b/go.mod h1:4uezxguZiX42kUaYMK/x46LLbgpYqn/iQXbcGM7zdM0= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240308082831-f05004a05b35 h1:yRfY/Mj1CXPoGd21F3y84cqBIKsktSgPuxz/5a7FA3w= +github.com/multiversx/mx-chain-vm-v1_4-go v1.4.96-0.20240308082831-f05004a05b35/go.mod h1:Nvanb5BZVhqnFFlWUtn7PQ/GIsl72zPVcMEw/ZvYiQA= github.com/multiversx/mx-components-big-int v1.0.0 h1:Wkr8lSzK2nDqixOrrBa47VNuqdhV1m/aJhaP1EMaiS8= github.com/multiversx/mx-components-big-int v1.0.0/go.mod h1:maIEMgHlNE2u78JaDD0oLzri+ShgU4okHfzP3LWGdQM= github.com/multiversx/protobuf v1.3.2 h1:RaNkxvGTGbA0lMcnHAN24qE1G1i+Xs5yHA6MDvQ4mSM= From 2370e258f6848329fc4dc906fabb6da5af65856c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 8 Mar 2024 11:14:13 +0200 Subject: [PATCH 950/958] Verbose mode - to catch the failing test on MacOS. --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index f238785e8fd..19fdaec07e0 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -44,5 +44,5 @@ jobs: GOOS=$(go env GOOS) if [[ "$GOOS" == darwin ]]; then - go test -short ./... + go test -short -v ./... fi From 324f285ef44708c0da63b566ba50643d262ef6ca Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Fri, 8 Mar 2024 11:39:14 +0200 Subject: [PATCH 951/958] - fixed test --- node/metrics/metrics_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/metrics/metrics_test.go b/node/metrics/metrics_test.go index c7b5a6ccdaa..7da1a582626 100644 --- a/node/metrics/metrics_test.go +++ b/node/metrics/metrics_test.go @@ -64,6 +64,8 @@ func TestInitBaseMetrics(t *testing.T) { common.MetricAccountsSnapshotNumNodes, common.MetricTrieSyncNumProcessedNodes, common.MetricTrieSyncNumReceivedBytes, + common.MetricRoundAtEpochStart, + common.MetricNonceAtEpochStart, } keys := make(map[string]struct{}) From 16504d47d3606db356473e6aacb100e7556399ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 11 Mar 2024 11:42:19 +0200 Subject: [PATCH 952/958] Skip test on Darwin AMD64. --- factory/status/statusComponents_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/factory/status/statusComponents_test.go b/factory/status/statusComponents_test.go index 61809df0e7f..3e1c0f8ba53 100644 --- a/factory/status/statusComponents_test.go +++ b/factory/status/statusComponents_test.go @@ -2,6 +2,7 @@ package status_test import ( "errors" + "runtime" "testing" "github.com/multiversx/mx-chain-communication-go/websocket/data" @@ -187,6 +188,10 @@ func TestStatusComponentsFactory_Create(t *testing.T) { require.Nil(t, sc) }) t.Run("should work", func(t *testing.T) { + if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" { + t.Skip("skipping test on darwin amd64") + } + shardCoordinator := mock.NewMultiShardsCoordinatorMock(2) shardCoordinator.SelfIDCalled = func() uint32 { return core.MetachainShardId // coverage From 730349a95a52f5b7a92325ed2477c9e57f8adccc Mon Sep 17 00:00:00 2001 From: MariusC Date: Mon, 11 Mar 2024 11:52:09 +0200 Subject: [PATCH 953/958] FIX: Warn for too low waiting list to debug --- sharding/nodesCoordinator/hashValidatorShuffler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding/nodesCoordinator/hashValidatorShuffler.go b/sharding/nodesCoordinator/hashValidatorShuffler.go index b918b5cc980..ceecc9ca352 100644 --- a/sharding/nodesCoordinator/hashValidatorShuffler.go +++ b/sharding/nodesCoordinator/hashValidatorShuffler.go @@ -624,7 +624,7 @@ func shouldDistributeShuffledToWaitingInStakingV4(shuffledNodesCfg *shuffledNode distributeShuffledToWaitingInStakingV4 := false if totalNodes <= shuffledNodesCfg.maxNumNodes { - log.Warn("num of total nodes in waiting is too low after shuffling; will distribute " + + log.Debug("num of total nodes in waiting is too low after shuffling; will distribute " + "shuffled out nodes directly to waiting and skip sending them to auction") distributeShuffledToWaitingInStakingV4 = true From e4c6e062a3c72eccb64a2060a0067ec174f546bd Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Mon, 11 Mar 2024 20:45:00 +0200 Subject: [PATCH 954/958] - added stake-unstake-unbond scenario --- .../chainSimulator/staking/delegation_test.go | 315 +++++++++++++++++- 1 file changed, 313 insertions(+), 2 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 679f3df95a9..497bbe06239 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -44,6 +44,7 @@ const txVersion = 1 const mockTxSignature = "sig" const queuedStatus = "queued" const stakedStatus = "staked" +const notStakedStatus = "notStaked" const unStakedStatus = "unStaked" const auctionStatus = "auction" const okReturnCode = "ok" @@ -324,7 +325,7 @@ func testBLSKeyIsInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProc activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { - testBLSKeyIsInAuction(t, metachainNode, decodedBLSKey, blsKey, expectedTopUp, actionListSize, statistics) + testBLSKeyIsInAuction(t, metachainNode, decodedBLSKey, blsKey, expectedTopUp, actionListSize, statistics, 1, address) return } @@ -342,6 +343,8 @@ func testBLSKeyIsInAuction( topUpInAuctionList *big.Int, actionListSize int, validatorStatistics map[string]*validator.ValidatorStatistics, + numNodes int, + owner []byte, ) { require.Equal(t, stakedStatus, getBLSKeyStatus(t, metachainNode, blsKeyBytes)) @@ -361,10 +364,16 @@ func testBLSKeyIsInAuction( } require.Equal(t, actionListSize, len(auctionList)) + ownerAsBech32, err := metachainNode.GetCoreComponents().AddressPubKeyConverter().Encode(owner) + require.Nil(t, err) if actionListSize != 0 { - require.Equal(t, 1, len(auctionList[0].Nodes)) nodeWasFound := false for _, item := range auctionList { + if item.Owner != ownerAsBech32 { + continue + } + + require.Equal(t, numNodes, len(auctionList[0].Nodes)) for _, node := range item.Nodes { if node.BlsKey == blsKey { require.Equal(t, topUpInAuctionList.String(), item.TopUpPerNode) @@ -381,6 +390,31 @@ func testBLSKeyIsInAuction( require.Equal(t, auctionStatus, validatorInfo.ValidatorStatus) } +func testBLSKeysAreInQueueOrAuction(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte, blsKeys []string, totalTopUp *big.Int, actionListSize int) { + err := metachainNode.GetProcessComponents().ValidatorsProvider().ForceUpdate() + require.Nil(t, err) + statistics, err := metachainNode.GetFacadeHandler().ValidatorStatisticsApi() + require.Nil(t, err) + assert.Equal(t, totalTopUp, getBLSTopUpValue(t, metachainNode, address)) + + individualTopup := big.NewInt(0).Set(totalTopUp) + individualTopup.Div(individualTopup, big.NewInt(int64(len(blsKeys)))) + + for _, blsKey := range blsKeys { + decodedBLSKey, _ := hex.DecodeString(blsKey) + activationEpoch := metachainNode.GetCoreComponents().EnableEpochsHandler().GetActivationEpoch(common.StakingV4Step1Flag) + if activationEpoch <= metachainNode.GetCoreComponents().EnableEpochsHandler().GetCurrentEpoch() { + testBLSKeyIsInAuction(t, metachainNode, decodedBLSKey, blsKey, individualTopup, actionListSize, statistics, len(blsKeys), address) + continue + } + + // in staking ph 2/3.5 we do not find the bls key on the validator statistics + _, found := statistics[blsKey] + require.False(t, found) + require.Equal(t, queuedStatus, getBLSKeyStatus(t, metachainNode, decodedBLSKey)) + } +} + // Test description: // Test that 2 different contracts with different topups that came from the normal stake will be considered in auction list computing in the correct order // 1. Add 2 new validator private keys in the multi key handler @@ -602,6 +636,283 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t * require.Equal(t, topupA.String(), secondAuctionPosition.TopUpPerNode) } +func TestWIP(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + roundDurationInMillis := uint64(6000) + roundsPerEpoch := core.OptionalUint64{ + HasValue: true, + Value: 80, + } + + //t.Run("staking ph 4 is not active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + // + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + // + // defer cs.Close() + // + // testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 1) + //}) + //t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + // + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + // + // defer cs.Close() + // + // testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 2) + //}) + //t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + // BypassTxSignatureCheck: false, + // TempDir: t.TempDir(), + // PathToInitialConfig: defaultPathToInitialConfig, + // NumOfShards: 3, + // GenesisTimestamp: time.Now().Unix(), + // RoundDurationInMillis: roundDurationInMillis, + // RoundsPerEpoch: roundsPerEpoch, + // ApiInterface: api.NewNoApiInterface(), + // MinNodesPerShard: 3, + // MetaChainMinNodes: 3, + // NumNodesWaitingListMeta: 3, + // NumNodesWaitingListShard: 3, + // AlterConfigsFunction: func(cfg *config.Configs) { + // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + // + // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + // }, + // }) + // require.Nil(t, err) + // require.NotNil(t, cs) + // + // defer cs.Close() + // + // testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 3) + //}) + t.Run("staking ph 4 step 3 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t, cs, 4) + }) +} + +func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { + err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) + require.Nil(t, err) + + log.Info("Step 1. Add 3 new validator private keys in the multi key handler") + privateKeys, blsKeys, err := chainSimulator.GenerateBlsPrivateKeys(3) + require.Nil(t, err) + + err = cs.AddValidatorKeys(privateKeys) + require.Nil(t, err) + metachainNode := cs.GetNodeHandler(core.MetachainShardId) + + log.Info("Step 2. Set the initial state for 1 owner and 1 delegator") + mintValue := big.NewInt(10001) + mintValue = mintValue.Mul(oneEGLD, mintValue) + + owner, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + delegator, err := cs.GenerateAndMintWalletAddress(core.AllShardId, mintValue) + require.Nil(t, err) + + log.Info("working with the following addresses", + "owner", owner.Bech32, "", delegator.Bech32) + + log.Info("Step 3. Do a stake transaction and test that the new key is on queue / auction list and has the correct topup") + + topup := big.NewInt(0).Mul(oneEGLD, big.NewInt(99)) + stakeValue := big.NewInt(0).Add(minimumStakeValue, topup) + txStake := generateStakeTransaction(t, cs, owner, blsKeys[0], stakeValue) + + stakeTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txStake}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(stakeTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + testBLSKeyIsInQueueOrAuction(t, metachainNode, owner.Bytes, blsKeys[0], topup, 1) + + log.Info("Step 4. Convert the validator into a staking providers and test that the key is on queue / auction list and has the correct topup") + + txConvert := generateConvertToStakingProviderTransaction(t, cs, owner) + + convertTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txConvert}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(convertTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the node + assert.Nil(t, err) + + delegationAddress := convertTxs[0].Logs.Events[0].Topics[1] + + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], topup, 1) + + log.Info("Step 5. Add 2 nodes in the staking contract") + txDataFieldAddNodes := fmt.Sprintf("addNodes@%s@%s@%s@%s", blsKeys[1], mockBLSSignature+"02", blsKeys[2], mockBLSSignature+"03") + ownerAccount, err := cs.GetAccount(owner) + txAddNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldAddNodes, gasLimitForStakeOperation) + + addNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txAddNodes}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(addNodesTxs)) + + log.Info("Step 6. Delegate 5000 EGLD to the contract") + delegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(5000)) + txDataFieldDelegate := "delegate" + delegatorAccount, err := cs.GetAccount(delegator) + txDelegate := generateTransaction(delegator.Bytes, delegatorAccount.Nonce, delegationAddress, delegateValue, txDataFieldDelegate, gasLimitForStakeOperation) + + delegateTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txDelegate}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(delegateTxs)) + + log.Info("Step 7. Stake the 2 nodes") + txDataFieldStakeNodes := fmt.Sprintf("stakeNodes@%s@%s", blsKeys[1], blsKeys[2]) + ownerAccount, err = cs.GetAccount(owner) + txStakeNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldStakeNodes, gasLimitForStakeOperation) + + stakeNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txStakeNodes}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(stakeNodesTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the nodes + assert.Nil(t, err) + + // all 3 nodes should be staked (auction list is 1 as there is one delegation SC with 3 BLS keys in the auction list) + testBLSKeysAreInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys, topup, 1) + + log.Info("Step 8. UnStake 2 nodes (latest staked)") + + txDataFieldUnStakeNodes := fmt.Sprintf("unStakeNodes@%s@%s", blsKeys[1], blsKeys[2]) + ownerAccount, err = cs.GetAccount(owner) + txUnStakeNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldUnStakeNodes, gasLimitForStakeOperation) + + unStakeNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txUnStakeNodes}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(unStakeNodesTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the nodes + assert.Nil(t, err) + + // all that only one node is staked (auction list is 1 as there is one delegation SC with 1 BLS key in the auction list) + expectedTopUp := big.NewInt(0) + expectedTopUp.Add(topup, delegateValue) // 99 + 5000 = 5099 + testBLSKeyIsInQueueOrAuction(t, metachainNode, delegationAddress, blsKeys[0], expectedTopUp, 1) + + log.Info("Step 9. Unbond the 2 nodes (that were un staked)") + + txDataFieldUnBondNodes := fmt.Sprintf("unBondNodes@%s@%s", blsKeys[1], blsKeys[2]) + ownerAccount, err = cs.GetAccount(owner) + txUnBondNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldUnBondNodes, gasLimitForStakeOperation) + + unBondNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txUnBondNodes}, maxNumOfBlockToGenerateWhenExecutingTx) + require.Nil(t, err) + require.Equal(t, 1, len(unBondNodesTxs)) + + err = cs.GenerateBlocks(2) // allow the metachain to finalize the block that contains the staking of the nodes + assert.Nil(t, err) + + keyStatus := getAllNodeStates(t, metachainNode, delegationAddress) + require.Equal(t, len(blsKeys), len(keyStatus)) + // key[0] should be staked + require.Equal(t, stakedStatus, keyStatus[blsKeys[0]]) + // key[1] and key[2] should be not-staked + require.Equal(t, notStakedStatus, keyStatus[blsKeys[1]]) + require.Equal(t, notStakedStatus, keyStatus[blsKeys[2]]) +} + +func getAllNodeStates(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte) map[string]string { + scQuery := &process.SCQuery{ + ScAddress: address, + FuncName: "getAllNodeStates", + CallerAddr: vm.StakingSCAddress, + CallValue: big.NewInt(0), + } + result, _, err := metachainNode.GetFacadeHandler().ExecuteSCQuery(scQuery) + require.Nil(t, err) + require.Equal(t, okReturnCode, result.ReturnCode) + + m := make(map[string]string) + for i := 0; i < len(result.ReturnData)-1; i += 2 { + m[hex.EncodeToString(result.ReturnData[i+1])] = string(result.ReturnData[i]) + } + + return m +} + func generateStakeTransaction( t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, From e7039aa4e387dd56483452e98a48ca9a3d6f4545 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 13 Mar 2024 13:16:19 +0200 Subject: [PATCH 955/958] - finished scenarios - fixed the EEI context merging --- cmd/node/config/enableEpochs.toml | 15 +- common/constants.go | 1 + common/enablers/enableEpochsHandler.go | 6 + common/enablers/enableEpochsHandler_test.go | 3 + config/epochConfig.go | 3 +- config/tomlConfig_test.go | 4 + .../chainSimulator/staking/delegation_test.go | 217 ++++++++++-------- vm/systemSmartContracts/eei.go | 8 +- 8 files changed, 154 insertions(+), 103 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 05d86c788f8..10e51b24a86 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -287,12 +287,6 @@ # CurrentRandomnessOnSortingEnableEpoch represents the epoch when the current randomness on sorting is enabled CurrentRandomnessOnSortingEnableEpoch = 4 - # BLSMultiSignerEnableEpoch represents the activation epoch for different types of BLS multi-signers - BLSMultiSignerEnableEpoch = [ - { EnableEpoch = 0, Type = "no-KOSK" }, - { EnableEpoch = 1, Type = "KOSK" } - ] - # StakeLimitsEnableEpoch represents the epoch when stake limits on validators are enabled StakeLimitsEnableEpoch = 5 @@ -307,6 +301,15 @@ # StakingV4Step3EnableEpoch represents the epoch in which selected nodes from auction will be distributed to waiting list StakingV4Step3EnableEpoch = 6 + # AlwaysMergeContextsInEEIEnableEpoch represents the epoch in which the EEI will always merge the contexts + AlwaysMergeContextsInEEIEnableEpoch = 4 + + # BLSMultiSignerEnableEpoch represents the activation epoch for different types of BLS multi-signers + BLSMultiSignerEnableEpoch = [ + { EnableEpoch = 0, Type = "no-KOSK" }, + { EnableEpoch = 1, Type = "KOSK" } + ] + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 48, NodesToShufflePerShard = 4 }, # 4 shuffled out keys / shard will not be reached normally diff --git a/common/constants.go b/common/constants.go index a70fc81b9c7..5d4e15e9fc5 100644 --- a/common/constants.go +++ b/common/constants.go @@ -1010,5 +1010,6 @@ const ( StakingV4Step3Flag core.EnableEpochFlag = "StakingV4Step3Flag" StakingQueueFlag core.EnableEpochFlag = "StakingQueueFlag" StakingV4StartedFlag core.EnableEpochFlag = "StakingV4StartedFlag" + AlwaysMergeContextsInEEIFlag core.EnableEpochFlag = "AlwaysMergeContextsInEEIFlag" // all new flags must be added to createAllFlagsMap method, as part of enableEpochsHandler allFlagsDefined ) diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index 45c2bb497af..d560a432462 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -725,6 +725,12 @@ func (handler *enableEpochsHandler) createAllFlagsMap() { }, activationEpoch: handler.enableEpochsConfig.StakingV4Step1EnableEpoch, }, + common.AlwaysMergeContextsInEEIFlag: { + isActiveInEpoch: func(epoch uint32) bool { + return epoch >= handler.enableEpochsConfig.AlwaysMergeContextsInEEIEnableEpoch + }, + activationEpoch: handler.enableEpochsConfig.AlwaysMergeContextsInEEIEnableEpoch, + }, } } diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index e53344b1fae..c91f65b805a 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -113,6 +113,7 @@ func createEnableEpochsConfig() config.EnableEpochs { StakingV4Step1EnableEpoch: 96, StakingV4Step2EnableEpoch: 97, StakingV4Step3EnableEpoch: 98, + AlwaysMergeContextsInEEIEnableEpoch: 99, } } @@ -319,6 +320,7 @@ func TestEnableEpochsHandler_IsFlagEnabled(t *testing.T) { require.True(t, handler.IsFlagEnabled(common.StakingV4Step3Flag)) require.False(t, handler.IsFlagEnabled(common.StakingQueueFlag)) require.True(t, handler.IsFlagEnabled(common.StakingV4StartedFlag)) + require.True(t, handler.IsFlagEnabled(common.AlwaysMergeContextsInEEIFlag)) } func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { @@ -434,6 +436,7 @@ func TestEnableEpochsHandler_GetActivationEpoch(t *testing.T) { require.Equal(t, cfg.StakingV4Step3EnableEpoch, handler.GetActivationEpoch(common.StakingV4Step3Flag)) require.Equal(t, cfg.StakingV4Step1EnableEpoch, handler.GetActivationEpoch(common.StakingQueueFlag)) require.Equal(t, cfg.StakingV4Step1EnableEpoch, handler.GetActivationEpoch(common.StakingV4StartedFlag)) + require.Equal(t, cfg.AlwaysMergeContextsInEEIEnableEpoch, handler.GetActivationEpoch(common.AlwaysMergeContextsInEEIFlag)) } func TestEnableEpochsHandler_IsInterfaceNil(t *testing.T) { diff --git a/config/epochConfig.go b/config/epochConfig.go index dfb243e2b3a..7789ecc72b3 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -108,11 +108,12 @@ type EnableEpochs struct { ChangeOwnerAddressCrossShardThroughSCEnableEpoch uint32 FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch uint32 CurrentRandomnessOnSortingEnableEpoch uint32 - BLSMultiSignerEnableEpoch []MultiSignerConfig StakeLimitsEnableEpoch uint32 StakingV4Step1EnableEpoch uint32 StakingV4Step2EnableEpoch uint32 StakingV4Step3EnableEpoch uint32 + AlwaysMergeContextsInEEIEnableEpoch uint32 + BLSMultiSignerEnableEpoch []MultiSignerConfig } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 30a42a439a7..16ab3a30f90 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -840,6 +840,9 @@ func TestEnableEpochConfig(t *testing.T) { # CurrentRandomnessOnSortingEnableEpoch represents the epoch when the current randomness on sorting is enabled CurrentRandomnessOnSortingEnableEpoch = 93 + # AlwaysMergeContextsInEEI represents the epoch in which the EEI will always merge the contexts + AlwaysMergeContextsInEEI = 93 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 44, MaxNumNodes = 2169, NodesToShufflePerShard = 80 }, @@ -951,6 +954,7 @@ func TestEnableEpochConfig(t *testing.T) { FixGasRemainingForSaveKeyValueBuiltinFunctionEnableEpoch: 91, MigrateDataTrieEnableEpoch: 92, CurrentRandomnessOnSortingEnableEpoch: 93, + AlwaysMergeContextsInEEIEnableEpoch: 94, MaxNodesChangeEnableEpoch: []MaxNodesChangeConfig{ { EpochEnable: 44, diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 497bbe06239..7e96d32a704 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -636,6 +636,19 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t * require.Equal(t, topupA.String(), secondAuctionPosition.TopUpPerNode) } +// Test description: +// Test that 1 contract having 3 BLS keys proper handles the stakeNodes-unstakeNodes-unBondNodes sequence for 2 of the BLS keys +// 1. Add 3 new validator private keys in the multi key handler +// 2. Set the initial state for 1 owner and 1 delegator +// 3. Do a stake transaction and test that the new key is on queue / auction list and has the correct topup +// 4. Convert the validator into a staking providers and test that the key is on queue / auction list and has the correct topup +// 5. Add 2 nodes in the staking contract +// 6. Delegate 5000 EGLD to the contract +// 7. Stake the 2 nodes +// 8. UnStake 2 nodes (latest staked) +// 9. Unbond the 2 nodes (that were un staked) + +// Internal test scenario #85 func TestWIP(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -647,93 +660,96 @@ func TestWIP(t *testing.T) { Value: 80, } - //t.Run("staking ph 4 is not active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 - // - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - // - // defer cs.Close() - // - // testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 1) - //}) - //t.Run("staking ph 4 step 1 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - // - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - // - // defer cs.Close() - // - // testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 2) - //}) - //t.Run("staking ph 4 step 2 is active", func(t *testing.T) { - // cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ - // BypassTxSignatureCheck: false, - // TempDir: t.TempDir(), - // PathToInitialConfig: defaultPathToInitialConfig, - // NumOfShards: 3, - // GenesisTimestamp: time.Now().Unix(), - // RoundDurationInMillis: roundDurationInMillis, - // RoundsPerEpoch: roundsPerEpoch, - // ApiInterface: api.NewNoApiInterface(), - // MinNodesPerShard: 3, - // MetaChainMinNodes: 3, - // NumNodesWaitingListMeta: 3, - // NumNodesWaitingListShard: 3, - // AlterConfigsFunction: func(cfg *config.Configs) { - // cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 - // cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 - // cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 - // - // cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 - // }, - // }) - // require.Nil(t, err) - // require.NotNil(t, cs) - // - // defer cs.Close() - // - // testChainSimulatorMakeNewContractFromValidatorDataWith2StakingContracts(t, cs, 3) - //}) + t.Run("staking ph 4 is not active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 102 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + // unbond succeeded because the nodes were on queue + testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t, cs, 1, notStakedStatus) + }) + t.Run("staking ph 4 step 1 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + cfg.EpochConfig.EnableEpochs.AlwaysMergeContextsInEEIEnableEpoch = 1 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t, cs, 2, unStakedStatus) + }) + t.Run("staking ph 4 step 2 is active", func(t *testing.T) { + cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ + BypassTxSignatureCheck: false, + TempDir: t.TempDir(), + PathToInitialConfig: defaultPathToInitialConfig, + NumOfShards: 3, + GenesisTimestamp: time.Now().Unix(), + RoundDurationInMillis: roundDurationInMillis, + RoundsPerEpoch: roundsPerEpoch, + ApiInterface: api.NewNoApiInterface(), + MinNodesPerShard: 3, + MetaChainMinNodes: 3, + NumNodesWaitingListMeta: 3, + NumNodesWaitingListShard: 3, + AlterConfigsFunction: func(cfg *config.Configs) { + cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 + cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 + cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + cfg.EpochConfig.EnableEpochs.AlwaysMergeContextsInEEIEnableEpoch = 1 + + cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 + }, + }) + require.Nil(t, err) + require.NotNil(t, cs) + + defer cs.Close() + + testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t, cs, 3, unStakedStatus) + }) t.Run("staking ph 4 step 3 is active", func(t *testing.T) { cs, err := chainSimulator.NewChainSimulator(chainSimulator.ArgsChainSimulator{ BypassTxSignatureCheck: false, @@ -752,6 +768,7 @@ func TestWIP(t *testing.T) { cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 2 cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 3 cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 4 + cfg.EpochConfig.EnableEpochs.AlwaysMergeContextsInEEIEnableEpoch = 1 cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch[2].EpochEnable = 4 }, @@ -761,11 +778,16 @@ func TestWIP(t *testing.T) { defer cs.Close() - testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t, cs, 4) + testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t, cs, 4, unStakedStatus) }) } -func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, targetEpoch int32) { +func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnstakeAndUnbond( + t *testing.T, + cs chainSimulatorIntegrationTests.ChainSimulator, + targetEpoch int32, + nodesStatusAfterUnBondTx string, +) { err := cs.GenerateBlocksUntilEpochIsReached(targetEpoch) require.Nil(t, err) @@ -889,9 +911,9 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta require.Equal(t, len(blsKeys), len(keyStatus)) // key[0] should be staked require.Equal(t, stakedStatus, keyStatus[blsKeys[0]]) - // key[1] and key[2] should be not-staked - require.Equal(t, notStakedStatus, keyStatus[blsKeys[1]]) - require.Equal(t, notStakedStatus, keyStatus[blsKeys[2]]) + // key[1] and key[2] should be unstaked (unbond was not executed) + require.Equal(t, nodesStatusAfterUnBondTx, keyStatus[blsKeys[1]]) + require.Equal(t, nodesStatusAfterUnBondTx, keyStatus[blsKeys[2]]) } func getAllNodeStates(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte) map[string]string { @@ -906,8 +928,15 @@ func getAllNodeStates(t *testing.T, metachainNode chainSimulatorProcess.NodeHand require.Equal(t, okReturnCode, result.ReturnCode) m := make(map[string]string) - for i := 0; i < len(result.ReturnData)-1; i += 2 { - m[hex.EncodeToString(result.ReturnData[i+1])] = string(result.ReturnData[i]) + status := "" + for _, resultData := range result.ReturnData { + if len(resultData) != 96 { + // not a BLS key + status = string(resultData) + continue + } + + m[hex.EncodeToString(resultData)] = status } return m diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index c56b2019d69..82d84029bf4 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -76,6 +76,7 @@ func NewVMContext(args VMContextArgs) (*vmContext, error) { err := core.CheckHandlerCompatibility(args.EnableEpochsHandler, []core.EnableEpochFlag{ common.MultiClaimOnDelegationFlag, common.SetSenderInEeiOutputTransferFlag, + common.AlwaysMergeContextsInEEIFlag, }) if err != nil { return nil, err @@ -339,8 +340,11 @@ func (host *vmContext) properMergeContexts(parentContext *vmContext, returnCode host.scAddress = parentContext.scAddress host.AddReturnMessage(parentContext.returnMessage) - if returnCode != vmcommon.Ok { - // no need to merge - revert was done - transaction will fail + + // merge contexts if the return code is OK or the fix flag is activated because it was wrong not to merge them if the call failed + shouldMergeContexts := returnCode == vmcommon.Ok || host.enableEpochsHandler.IsFlagEnabled(common.AlwaysMergeContextsInEEIFlag) + if !shouldMergeContexts { + // backwards compatibility return } From 7a1e189aa0d97b91bdfa0e9cebe421b396d5ffd3 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 13 Mar 2024 18:17:20 +0200 Subject: [PATCH 956/958] - fixes after review --- .../chainSimulator/staking/delegation_test.go | 27 ++++++++++++------- vm/systemSmartContracts/eei.go | 2 ++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/integrationTests/chainSimulator/staking/delegation_test.go b/integrationTests/chainSimulator/staking/delegation_test.go index 7e96d32a704..b7e2e628d98 100644 --- a/integrationTests/chainSimulator/staking/delegation_test.go +++ b/integrationTests/chainSimulator/staking/delegation_test.go @@ -844,8 +844,8 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta log.Info("Step 5. Add 2 nodes in the staking contract") txDataFieldAddNodes := fmt.Sprintf("addNodes@%s@%s@%s@%s", blsKeys[1], mockBLSSignature+"02", blsKeys[2], mockBLSSignature+"03") - ownerAccount, err := cs.GetAccount(owner) - txAddNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldAddNodes, gasLimitForStakeOperation) + ownerNonce := getNonce(t, cs, owner) + txAddNodes := generateTransaction(owner.Bytes, ownerNonce, delegationAddress, big.NewInt(0), txDataFieldAddNodes, gasLimitForStakeOperation) addNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txAddNodes}, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -854,8 +854,8 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta log.Info("Step 6. Delegate 5000 EGLD to the contract") delegateValue := big.NewInt(0).Mul(oneEGLD, big.NewInt(5000)) txDataFieldDelegate := "delegate" - delegatorAccount, err := cs.GetAccount(delegator) - txDelegate := generateTransaction(delegator.Bytes, delegatorAccount.Nonce, delegationAddress, delegateValue, txDataFieldDelegate, gasLimitForStakeOperation) + delegatorNonce := getNonce(t, cs, delegator) + txDelegate := generateTransaction(delegator.Bytes, delegatorNonce, delegationAddress, delegateValue, txDataFieldDelegate, gasLimitForStakeOperation) delegateTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txDelegate}, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -863,8 +863,8 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta log.Info("Step 7. Stake the 2 nodes") txDataFieldStakeNodes := fmt.Sprintf("stakeNodes@%s@%s", blsKeys[1], blsKeys[2]) - ownerAccount, err = cs.GetAccount(owner) - txStakeNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldStakeNodes, gasLimitForStakeOperation) + ownerNonce = getNonce(t, cs, owner) + txStakeNodes := generateTransaction(owner.Bytes, ownerNonce, delegationAddress, big.NewInt(0), txDataFieldStakeNodes, gasLimitForStakeOperation) stakeNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txStakeNodes}, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -879,8 +879,8 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta log.Info("Step 8. UnStake 2 nodes (latest staked)") txDataFieldUnStakeNodes := fmt.Sprintf("unStakeNodes@%s@%s", blsKeys[1], blsKeys[2]) - ownerAccount, err = cs.GetAccount(owner) - txUnStakeNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldUnStakeNodes, gasLimitForStakeOperation) + ownerNonce = getNonce(t, cs, owner) + txUnStakeNodes := generateTransaction(owner.Bytes, ownerNonce, delegationAddress, big.NewInt(0), txDataFieldUnStakeNodes, gasLimitForStakeOperation) unStakeNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txUnStakeNodes}, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -897,8 +897,8 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta log.Info("Step 9. Unbond the 2 nodes (that were un staked)") txDataFieldUnBondNodes := fmt.Sprintf("unBondNodes@%s@%s", blsKeys[1], blsKeys[2]) - ownerAccount, err = cs.GetAccount(owner) - txUnBondNodes := generateTransaction(owner.Bytes, ownerAccount.Nonce, delegationAddress, big.NewInt(0), txDataFieldUnBondNodes, gasLimitForStakeOperation) + ownerNonce = getNonce(t, cs, owner) + txUnBondNodes := generateTransaction(owner.Bytes, ownerNonce, delegationAddress, big.NewInt(0), txDataFieldUnBondNodes, gasLimitForStakeOperation) unBondNodesTxs, err := cs.SendTxsAndGenerateBlocksTilAreExecuted([]*transaction.Transaction{txUnBondNodes}, maxNumOfBlockToGenerateWhenExecutingTx) require.Nil(t, err) @@ -916,6 +916,13 @@ func testChainSimulatorMakeNewContractFromValidatorDataWith1StakingContractUnsta require.Equal(t, nodesStatusAfterUnBondTx, keyStatus[blsKeys[2]]) } +func getNonce(t *testing.T, cs chainSimulatorIntegrationTests.ChainSimulator, address dtos.WalletAddress) uint64 { + account, err := cs.GetAccount(address) + require.Nil(t, err) + + return account.Nonce +} + func getAllNodeStates(t *testing.T, metachainNode chainSimulatorProcess.NodeHandler, address []byte) map[string]string { scQuery := &process.SCQuery{ ScAddress: address, diff --git a/vm/systemSmartContracts/eei.go b/vm/systemSmartContracts/eei.go index 82d84029bf4..55f554d11b0 100644 --- a/vm/systemSmartContracts/eei.go +++ b/vm/systemSmartContracts/eei.go @@ -534,6 +534,8 @@ func (host *vmContext) ExecuteOnDestContext(destination []byte, sender []byte, v vmOutput := &vmcommon.VMOutput{ReturnCode: vmcommon.UserError} currContext := host.copyToNewContext() defer func() { + // we need to reset here the output since it was already transferred in the vmOutput (host.CreateVMOutput() function) + // and we do not want to duplicate them host.output = make([][]byte, 0) host.properMergeContexts(currContext, vmOutput.ReturnCode) }() From 7e2ac983c6ea3d1f340c6e99966005eeaee80d65 Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Wed, 13 Mar 2024 18:30:03 +0200 Subject: [PATCH 957/958] - fixed test --- config/tomlConfig_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 16ab3a30f90..45dd2c7ef00 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -840,8 +840,8 @@ func TestEnableEpochConfig(t *testing.T) { # CurrentRandomnessOnSortingEnableEpoch represents the epoch when the current randomness on sorting is enabled CurrentRandomnessOnSortingEnableEpoch = 93 - # AlwaysMergeContextsInEEI represents the epoch in which the EEI will always merge the contexts - AlwaysMergeContextsInEEI = 93 + # AlwaysMergeContextsInEEIEnableEpoch represents the epoch in which the EEI will always merge the contexts + AlwaysMergeContextsInEEIEnableEpoch = 94 # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ From 6d81fe82511773bd039957c957ab28dc06bdeb0e Mon Sep 17 00:00:00 2001 From: Iulian Pascalau Date: Thu, 14 Mar 2024 11:29:52 +0200 Subject: [PATCH 958/958] - applied custom arch config tweaks on the chain simulator --- node/chainSimulator/configs/configs.go | 3 +++ node/customConfigsArm64.go | 7 ++++--- node/customConfigsArm64_test.go | 4 ++-- node/customConfigsDefault.go | 5 +++-- node/customConfigsDefault_test.go | 4 ++-- node/nodeRunner.go | 2 +- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index c354791d248..d781a3f8a5d 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -21,6 +21,7 @@ import ( "github.com/multiversx/mx-chain-go/common/factory" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/genesis/data" + "github.com/multiversx/mx-chain-go/node" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/sharding" "github.com/multiversx/mx-chain-go/storage/storageunit" @@ -125,6 +126,8 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi return nil, err } + node.ApplyArchCustomConfigs(configs) + if args.AlterConfigsFunction != nil { args.AlterConfigsFunction(configs) } diff --git a/node/customConfigsArm64.go b/node/customConfigsArm64.go index 90f4dd57c07..ce62a5fa604 100644 --- a/node/customConfigsArm64.go +++ b/node/customConfigsArm64.go @@ -8,11 +8,12 @@ import ( "github.com/multiversx/mx-chain-go/config" ) -func applyArchCustomConfigs(configs *config.Configs) { - log.Debug("applyArchCustomConfigs", "architecture", runtime.GOARCH) +// ApplyArchCustomConfigs will apply configuration tweaks based on the architecture the node is running on +func ApplyArchCustomConfigs(configs *config.Configs) { + log.Debug("ApplyArchCustomConfigs", "architecture", runtime.GOARCH) firstSupportedWasmer2VMVersion := "v1.5" - log.Debug("applyArchCustomConfigs - hardcoding the initial VM to " + firstSupportedWasmer2VMVersion) + log.Debug("ApplyArchCustomConfigs - hardcoding the initial VM to " + firstSupportedWasmer2VMVersion) configs.GeneralConfig.VirtualMachine.Execution.WasmVMVersions = []config.WasmVMVersionByEpoch{ { StartEpoch: 0, diff --git a/node/customConfigsArm64_test.go b/node/customConfigsArm64_test.go index 3f7d5a1b278..925774a3318 100644 --- a/node/customConfigsArm64_test.go +++ b/node/customConfigsArm64_test.go @@ -63,7 +63,7 @@ func TestApplyArchCustomConfigs(t *testing.T) { expectedVMConfig.Execution.WasmVMVersions = expectedVMWasmVersionsConfig expectedVMConfig.Querying.WasmVMVersions = expectedVMWasmVersionsConfig - applyArchCustomConfigs(providedConfigs) + ApplyArchCustomConfigs(providedConfigs) assert.Equal(t, expectedVMConfig, providedConfigs.GeneralConfig.VirtualMachine) }) @@ -78,7 +78,7 @@ func TestApplyArchCustomConfigs(t *testing.T) { expectedVMConfig.Execution.WasmVMVersions = expectedVMWasmVersionsConfig expectedVMConfig.Querying.WasmVMVersions = expectedVMWasmVersionsConfig - applyArchCustomConfigs(providedConfigs) + ApplyArchCustomConfigs(providedConfigs) expectedConfig := &config.Configs{ GeneralConfig: &config.Config{ diff --git a/node/customConfigsDefault.go b/node/customConfigsDefault.go index 2d1d5edea28..b762871db10 100644 --- a/node/customConfigsDefault.go +++ b/node/customConfigsDefault.go @@ -8,6 +8,7 @@ import ( "github.com/multiversx/mx-chain-go/config" ) -func applyArchCustomConfigs(_ *config.Configs) { - log.Debug("applyArchCustomConfigs - nothing to do", "architecture", runtime.GOARCH) +// ApplyArchCustomConfigs will apply configuration tweaks based on the architecture the node is running on +func ApplyArchCustomConfigs(_ *config.Configs) { + log.Debug("ApplyArchCustomConfigs - nothing to do", "architecture", runtime.GOARCH) } diff --git a/node/customConfigsDefault_test.go b/node/customConfigsDefault_test.go index 92287e6979a..8f9e8eb6521 100644 --- a/node/customConfigsDefault_test.go +++ b/node/customConfigsDefault_test.go @@ -52,7 +52,7 @@ func TestApplyArchCustomConfigs(t *testing.T) { }, } - applyArchCustomConfigs(providedConfigs) + ApplyArchCustomConfigs(providedConfigs) assert.Equal(t, executionVMConfig, providedConfigs.GeneralConfig.VirtualMachine.Execution) assert.Equal(t, queryVMConfig, providedConfigs.GeneralConfig.VirtualMachine.Querying) @@ -67,7 +67,7 @@ func TestApplyArchCustomConfigs(t *testing.T) { emptyConfigs := &config.Configs{ GeneralConfig: &config.Config{}, } - applyArchCustomConfigs(providedConfigs) + ApplyArchCustomConfigs(providedConfigs) assert.Equal(t, emptyConfigs, providedConfigs) }) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 1e0c45603f6..54ffe84b4e3 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -274,7 +274,7 @@ func (nr *nodeRunner) executeOneComponentCreationCycle( goRoutinesNumberStart := runtime.NumGoroutine() log.Debug("applying custom configs based on the current architecture") - applyArchCustomConfigs(nr.configs) + ApplyArchCustomConfigs(nr.configs) configs := nr.configs flagsConfig := configs.FlagsConfig